Diffdown is a real-time collaborative Markdown editor/previewer built on the AT Protocol
diffdown.com
1'use strict';
2
3var css$1 = require('@lezer/css');
4var language = require('@codemirror/language');
5var common = require('@lezer/common');
6
7let _properties = null;
8function properties() {
9 if (!_properties && typeof document == "object" && document.body) {
10 let { style } = document.body, names = [], seen = new Set;
11 for (let prop in style)
12 if (prop != "cssText" && prop != "cssFloat") {
13 if (typeof style[prop] == "string") {
14 if (/[A-Z]/.test(prop))
15 prop = prop.replace(/[A-Z]/g, ch => "-" + ch.toLowerCase());
16 if (!seen.has(prop)) {
17 names.push(prop);
18 seen.add(prop);
19 }
20 }
21 }
22 _properties = names.sort().map(name => ({ type: "property", label: name, apply: name + ": " }));
23 }
24 return _properties || [];
25}
26const pseudoClasses = [
27 "active", "after", "any-link", "autofill", "backdrop", "before",
28 "checked", "cue", "default", "defined", "disabled", "empty",
29 "enabled", "file-selector-button", "first", "first-child",
30 "first-letter", "first-line", "first-of-type", "focus",
31 "focus-visible", "focus-within", "fullscreen", "has", "host",
32 "host-context", "hover", "in-range", "indeterminate", "invalid",
33 "is", "lang", "last-child", "last-of-type", "left", "link", "marker",
34 "modal", "not", "nth-child", "nth-last-child", "nth-last-of-type",
35 "nth-of-type", "only-child", "only-of-type", "optional", "out-of-range",
36 "part", "placeholder", "placeholder-shown", "read-only", "read-write",
37 "required", "right", "root", "scope", "selection", "slotted", "target",
38 "target-text", "valid", "visited", "where"
39].map(name => ({ type: "class", label: name }));
40const values = [
41 "above", "absolute", "activeborder", "additive", "activecaption", "after-white-space",
42 "ahead", "alias", "all", "all-scroll", "alphabetic", "alternate", "always",
43 "antialiased", "appworkspace", "asterisks", "attr", "auto", "auto-flow", "avoid", "avoid-column",
44 "avoid-page", "avoid-region", "axis-pan", "background", "backwards", "baseline", "below",
45 "bidi-override", "blink", "block", "block-axis", "bold", "bolder", "border", "border-box",
46 "both", "bottom", "break", "break-all", "break-word", "bullets", "button", "button-bevel",
47 "buttonface", "buttonhighlight", "buttonshadow", "buttontext", "calc", "capitalize",
48 "caps-lock-indicator", "caption", "captiontext", "caret", "cell", "center", "checkbox", "circle",
49 "cjk-decimal", "clear", "clip", "close-quote", "col-resize", "collapse", "color", "color-burn",
50 "color-dodge", "column", "column-reverse", "compact", "condensed", "contain", "content",
51 "contents", "content-box", "context-menu", "continuous", "copy", "counter", "counters", "cover",
52 "crop", "cross", "crosshair", "currentcolor", "cursive", "cyclic", "darken", "dashed", "decimal",
53 "decimal-leading-zero", "default", "default-button", "dense", "destination-atop", "destination-in",
54 "destination-out", "destination-over", "difference", "disc", "discard", "disclosure-closed",
55 "disclosure-open", "document", "dot-dash", "dot-dot-dash", "dotted", "double", "down", "e-resize",
56 "ease", "ease-in", "ease-in-out", "ease-out", "element", "ellipse", "ellipsis", "embed", "end",
57 "ethiopic-abegede-gez", "ethiopic-halehame-aa-er", "ethiopic-halehame-gez", "ew-resize", "exclusion",
58 "expanded", "extends", "extra-condensed", "extra-expanded", "fantasy", "fast", "fill", "fill-box",
59 "fixed", "flat", "flex", "flex-end", "flex-start", "footnotes", "forwards", "from",
60 "geometricPrecision", "graytext", "grid", "groove", "hand", "hard-light", "help", "hidden", "hide",
61 "higher", "highlight", "highlighttext", "horizontal", "hsl", "hsla", "hue", "icon", "ignore",
62 "inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite", "infobackground", "infotext",
63 "inherit", "initial", "inline", "inline-axis", "inline-block", "inline-flex", "inline-grid",
64 "inline-table", "inset", "inside", "intrinsic", "invert", "italic", "justify", "keep-all",
65 "landscape", "large", "larger", "left", "level", "lighter", "lighten", "line-through", "linear",
66 "linear-gradient", "lines", "list-item", "listbox", "listitem", "local", "logical", "loud", "lower",
67 "lower-hexadecimal", "lower-latin", "lower-norwegian", "lowercase", "ltr", "luminosity", "manipulation",
68 "match", "matrix", "matrix3d", "medium", "menu", "menutext", "message-box", "middle", "min-intrinsic",
69 "mix", "monospace", "move", "multiple", "multiple_mask_images", "multiply", "n-resize", "narrower",
70 "ne-resize", "nesw-resize", "no-close-quote", "no-drop", "no-open-quote", "no-repeat", "none",
71 "normal", "not-allowed", "nowrap", "ns-resize", "numbers", "numeric", "nw-resize", "nwse-resize",
72 "oblique", "opacity", "open-quote", "optimizeLegibility", "optimizeSpeed", "outset", "outside",
73 "outside-shape", "overlay", "overline", "padding", "padding-box", "painted", "page", "paused",
74 "perspective", "pinch-zoom", "plus-darker", "plus-lighter", "pointer", "polygon", "portrait",
75 "pre", "pre-line", "pre-wrap", "preserve-3d", "progress", "push-button", "radial-gradient", "radio",
76 "read-only", "read-write", "read-write-plaintext-only", "rectangle", "region", "relative", "repeat",
77 "repeating-linear-gradient", "repeating-radial-gradient", "repeat-x", "repeat-y", "reset", "reverse",
78 "rgb", "rgba", "ridge", "right", "rotate", "rotate3d", "rotateX", "rotateY", "rotateZ", "round",
79 "row", "row-resize", "row-reverse", "rtl", "run-in", "running", "s-resize", "sans-serif", "saturation",
80 "scale", "scale3d", "scaleX", "scaleY", "scaleZ", "screen", "scroll", "scrollbar", "scroll-position",
81 "se-resize", "self-start", "self-end", "semi-condensed", "semi-expanded", "separate", "serif", "show",
82 "single", "skew", "skewX", "skewY", "skip-white-space", "slide", "slider-horizontal",
83 "slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow", "small", "small-caps",
84 "small-caption", "smaller", "soft-light", "solid", "source-atop", "source-in", "source-out",
85 "source-over", "space", "space-around", "space-between", "space-evenly", "spell-out", "square", "start",
86 "static", "status-bar", "stretch", "stroke", "stroke-box", "sub", "subpixel-antialiased", "svg_masks",
87 "super", "sw-resize", "symbolic", "symbols", "system-ui", "table", "table-caption", "table-cell",
88 "table-column", "table-column-group", "table-footer-group", "table-header-group", "table-row",
89 "table-row-group", "text", "text-bottom", "text-top", "textarea", "textfield", "thick", "thin",
90 "threeddarkshadow", "threedface", "threedhighlight", "threedlightshadow", "threedshadow", "to", "top",
91 "transform", "translate", "translate3d", "translateX", "translateY", "translateZ", "transparent",
92 "ultra-condensed", "ultra-expanded", "underline", "unidirectional-pan", "unset", "up", "upper-latin",
93 "uppercase", "url", "var", "vertical", "vertical-text", "view-box", "visible", "visibleFill",
94 "visiblePainted", "visibleStroke", "visual", "w-resize", "wait", "wave", "wider", "window", "windowframe",
95 "windowtext", "words", "wrap", "wrap-reverse", "x-large", "x-small", "xor", "xx-large", "xx-small"
96].map(name => ({ type: "keyword", label: name })).concat([
97 "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige",
98 "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown",
99 "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue",
100 "cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod",
101 "darkgray", "darkgreen", "darkkhaki", "darkmagenta", "darkolivegreen",
102 "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen",
103 "darkslateblue", "darkslategray", "darkturquoise", "darkviolet",
104 "deeppink", "deepskyblue", "dimgray", "dodgerblue", "firebrick",
105 "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite",
106 "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew",
107 "hotpink", "indianred", "indigo", "ivory", "khaki", "lavender",
108 "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral",
109 "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightpink",
110 "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray",
111 "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta",
112 "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple",
113 "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise",
114 "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin",
115 "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered",
116 "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred",
117 "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue",
118 "purple", "rebeccapurple", "red", "rosybrown", "royalblue", "saddlebrown",
119 "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue",
120 "slateblue", "slategray", "snow", "springgreen", "steelblue", "tan",
121 "teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white",
122 "whitesmoke", "yellow", "yellowgreen"
123].map(name => ({ type: "constant", label: name })));
124const tags = [
125 "a", "abbr", "address", "article", "aside", "b", "bdi", "bdo", "blockquote", "body",
126 "br", "button", "canvas", "caption", "cite", "code", "col", "colgroup", "dd", "del",
127 "details", "dfn", "dialog", "div", "dl", "dt", "em", "figcaption", "figure", "footer",
128 "form", "header", "hgroup", "h1", "h2", "h3", "h4", "h5", "h6", "hr", "html", "i", "iframe",
129 "img", "input", "ins", "kbd", "label", "legend", "li", "main", "meter", "nav", "ol", "output",
130 "p", "pre", "ruby", "section", "select", "small", "source", "span", "strong", "sub", "summary",
131 "sup", "table", "tbody", "td", "template", "textarea", "tfoot", "th", "thead", "tr", "u", "ul"
132].map(name => ({ type: "type", label: name }));
133const atRules = [
134 "@charset", "@color-profile", "@container", "@counter-style", "@font-face", "@font-feature-values",
135 "@font-palette-values", "@import", "@keyframes", "@layer", "@media", "@namespace", "@page",
136 "@position-try", "@property", "@scope", "@starting-style", "@supports", "@view-transition"
137].map(label => ({ type: "keyword", label }));
138const identifier = /^(\w[\w-]*|-\w[\w-]*|)$/, variable = /^-(-[\w-]*)?$/;
139function isVarArg(node, doc) {
140 var _a;
141 if (node.name == "(" || node.type.isError)
142 node = node.parent || node;
143 if (node.name != "ArgList")
144 return false;
145 let callee = (_a = node.parent) === null || _a === void 0 ? void 0 : _a.firstChild;
146 if ((callee === null || callee === void 0 ? void 0 : callee.name) != "Callee")
147 return false;
148 return doc.sliceString(callee.from, callee.to) == "var";
149}
150const VariablesByNode = new common.NodeWeakMap();
151const declSelector = ["Declaration"];
152function astTop(node) {
153 for (let cur = node;;) {
154 if (cur.type.isTop)
155 return cur;
156 if (!(cur = cur.parent))
157 return node;
158 }
159}
160function variableNames(doc, node, isVariable) {
161 if (node.to - node.from > 4096) {
162 let known = VariablesByNode.get(node);
163 if (known)
164 return known;
165 let result = [], seen = new Set, cursor = node.cursor(common.IterMode.IncludeAnonymous);
166 if (cursor.firstChild())
167 do {
168 for (let option of variableNames(doc, cursor.node, isVariable))
169 if (!seen.has(option.label)) {
170 seen.add(option.label);
171 result.push(option);
172 }
173 } while (cursor.nextSibling());
174 VariablesByNode.set(node, result);
175 return result;
176 }
177 else {
178 let result = [], seen = new Set;
179 node.cursor().iterate(node => {
180 var _a;
181 if (isVariable(node) && node.matchContext(declSelector) && ((_a = node.node.nextSibling) === null || _a === void 0 ? void 0 : _a.name) == ":") {
182 let name = doc.sliceString(node.from, node.to);
183 if (!seen.has(name)) {
184 seen.add(name);
185 result.push({ label: name, type: "variable" });
186 }
187 }
188 });
189 return result;
190 }
191}
192/**
193Create a completion source for a CSS dialect, providing a
194predicate for determining what kind of syntax node can act as a
195completable variable. This is used by language modes like Sass and
196Less to reuse this package's completion logic.
197*/
198const defineCSSCompletionSource = (isVariable) => context => {
199 let { state, pos } = context, node = language.syntaxTree(state).resolveInner(pos, -1);
200 let isDash = node.type.isError && node.from == node.to - 1 && state.doc.sliceString(node.from, node.to) == "-";
201 if (node.name == "PropertyName" ||
202 (isDash || node.name == "TagName") && /^(Block|Styles)$/.test(node.resolve(node.to).name))
203 return { from: node.from, options: properties(), validFor: identifier };
204 if (node.name == "ValueName")
205 return { from: node.from, options: values, validFor: identifier };
206 if (node.name == "PseudoClassName")
207 return { from: node.from, options: pseudoClasses, validFor: identifier };
208 if (isVariable(node) || (context.explicit || isDash) && isVarArg(node, state.doc))
209 return { from: isVariable(node) || isDash ? node.from : pos,
210 options: variableNames(state.doc, astTop(node), isVariable),
211 validFor: variable };
212 if (node.name == "TagName") {
213 for (let { parent } = node; parent; parent = parent.parent)
214 if (parent.name == "Block")
215 return { from: node.from, options: properties(), validFor: identifier };
216 return { from: node.from, options: tags, validFor: identifier };
217 }
218 if (node.name == "AtKeyword")
219 return { from: node.from, options: atRules, validFor: identifier };
220 if (!context.explicit)
221 return null;
222 let above = node.resolve(pos), before = above.childBefore(pos);
223 if (before && before.name == ":" && above.name == "PseudoClassSelector")
224 return { from: pos, options: pseudoClasses, validFor: identifier };
225 if (before && before.name == ":" && above.name == "Declaration" || above.name == "ArgList")
226 return { from: pos, options: values, validFor: identifier };
227 if (above.name == "Block" || above.name == "Styles")
228 return { from: pos, options: properties(), validFor: identifier };
229 return null;
230};
231/**
232CSS property, variable, and value keyword completion source.
233*/
234const cssCompletionSource = defineCSSCompletionSource(n => n.name == "VariableName");
235
236/**
237A language provider based on the [Lezer CSS
238parser](https://github.com/lezer-parser/css), extended with
239highlighting and indentation information.
240*/
241const cssLanguage = language.LRLanguage.define({
242 name: "css",
243 parser: css$1.parser.configure({
244 props: [
245 language.indentNodeProp.add({
246 Declaration: language.continuedIndent()
247 }),
248 language.foldNodeProp.add({
249 "Block KeyframeList": language.foldInside
250 })
251 ]
252 }),
253 languageData: {
254 commentTokens: { block: { open: "/*", close: "*/" } },
255 indentOnInput: /^\s*\}$/,
256 wordChars: "-"
257 }
258});
259/**
260Language support for CSS.
261*/
262function css() {
263 return new language.LanguageSupport(cssLanguage, cssLanguage.data.of({ autocomplete: cssCompletionSource }));
264}
265
266exports.css = css;
267exports.cssCompletionSource = cssCompletionSource;
268exports.cssLanguage = cssLanguage;
269exports.defineCSSCompletionSource = defineCSSCompletionSource;