primo commit
This commit is contained in:
		
							
								
								
									
										667
									
								
								media/vendor/codemirror/js/codemirror-lang-html.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										667
									
								
								media/vendor/codemirror/js/codemirror-lang-html.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,667 @@ | ||||
| import { parser, configureNesting } from '@lezer/html'; | ||||
| import { cssLanguage, css } from '@codemirror/lang-css'; | ||||
| import { typescriptLanguage, jsxLanguage, tsxLanguage, javascriptLanguage, javascript } from '@codemirror/lang-javascript'; | ||||
| import { EditorView } from '@codemirror/view'; | ||||
| import { EditorSelection } from '@codemirror/state'; | ||||
| import { LRLanguage, indentNodeProp, foldNodeProp, bracketMatchingHandle, LanguageSupport, syntaxTree } from '@codemirror/language'; | ||||
|  | ||||
| const Targets = ["_blank", "_self", "_top", "_parent"]; | ||||
| const Charsets = ["ascii", "utf-8", "utf-16", "latin1", "latin1"]; | ||||
| const Methods = ["get", "post", "put", "delete"]; | ||||
| const Encs = ["application/x-www-form-urlencoded", "multipart/form-data", "text/plain"]; | ||||
| const Bool = ["true", "false"]; | ||||
| const S = {}; // Empty tag spec | ||||
| const Tags = { | ||||
|     a: { | ||||
|         attrs: { | ||||
|             href: null, ping: null, type: null, | ||||
|             media: null, | ||||
|             target: Targets, | ||||
|             hreflang: null | ||||
|         } | ||||
|     }, | ||||
|     abbr: S, | ||||
|     address: S, | ||||
|     area: { | ||||
|         attrs: { | ||||
|             alt: null, coords: null, href: null, target: null, ping: null, | ||||
|             media: null, hreflang: null, type: null, | ||||
|             shape: ["default", "rect", "circle", "poly"] | ||||
|         } | ||||
|     }, | ||||
|     article: S, | ||||
|     aside: S, | ||||
|     audio: { | ||||
|         attrs: { | ||||
|             src: null, mediagroup: null, | ||||
|             crossorigin: ["anonymous", "use-credentials"], | ||||
|             preload: ["none", "metadata", "auto"], | ||||
|             autoplay: ["autoplay"], | ||||
|             loop: ["loop"], | ||||
|             controls: ["controls"] | ||||
|         } | ||||
|     }, | ||||
|     b: S, | ||||
|     base: { attrs: { href: null, target: Targets } }, | ||||
|     bdi: S, | ||||
|     bdo: S, | ||||
|     blockquote: { attrs: { cite: null } }, | ||||
|     body: S, | ||||
|     br: S, | ||||
|     button: { | ||||
|         attrs: { | ||||
|             form: null, formaction: null, name: null, value: null, | ||||
|             autofocus: ["autofocus"], | ||||
|             disabled: ["autofocus"], | ||||
|             formenctype: Encs, | ||||
|             formmethod: Methods, | ||||
|             formnovalidate: ["novalidate"], | ||||
|             formtarget: Targets, | ||||
|             type: ["submit", "reset", "button"] | ||||
|         } | ||||
|     }, | ||||
|     canvas: { attrs: { width: null, height: null } }, | ||||
|     caption: S, | ||||
|     center: S, | ||||
|     cite: S, | ||||
|     code: S, | ||||
|     col: { attrs: { span: null } }, | ||||
|     colgroup: { attrs: { span: null } }, | ||||
|     command: { | ||||
|         attrs: { | ||||
|             type: ["command", "checkbox", "radio"], | ||||
|             label: null, icon: null, radiogroup: null, command: null, title: null, | ||||
|             disabled: ["disabled"], | ||||
|             checked: ["checked"] | ||||
|         } | ||||
|     }, | ||||
|     data: { attrs: { value: null } }, | ||||
|     datagrid: { attrs: { disabled: ["disabled"], multiple: ["multiple"] } }, | ||||
|     datalist: { attrs: { data: null } }, | ||||
|     dd: S, | ||||
|     del: { attrs: { cite: null, datetime: null } }, | ||||
|     details: { attrs: { open: ["open"] } }, | ||||
|     dfn: S, | ||||
|     div: S, | ||||
|     dl: S, | ||||
|     dt: S, | ||||
|     em: S, | ||||
|     embed: { attrs: { src: null, type: null, width: null, height: null } }, | ||||
|     eventsource: { attrs: { src: null } }, | ||||
|     fieldset: { attrs: { disabled: ["disabled"], form: null, name: null } }, | ||||
|     figcaption: S, | ||||
|     figure: S, | ||||
|     footer: S, | ||||
|     form: { | ||||
|         attrs: { | ||||
|             action: null, name: null, | ||||
|             "accept-charset": Charsets, | ||||
|             autocomplete: ["on", "off"], | ||||
|             enctype: Encs, | ||||
|             method: Methods, | ||||
|             novalidate: ["novalidate"], | ||||
|             target: Targets | ||||
|         } | ||||
|     }, | ||||
|     h1: S, h2: S, h3: S, h4: S, h5: S, h6: S, | ||||
|     head: { | ||||
|         children: ["title", "base", "link", "style", "meta", "script", "noscript", "command"] | ||||
|     }, | ||||
|     header: S, | ||||
|     hgroup: S, | ||||
|     hr: S, | ||||
|     html: { | ||||
|         attrs: { manifest: null } | ||||
|     }, | ||||
|     i: S, | ||||
|     iframe: { | ||||
|         attrs: { | ||||
|             src: null, srcdoc: null, name: null, width: null, height: null, | ||||
|             sandbox: ["allow-top-navigation", "allow-same-origin", "allow-forms", "allow-scripts"], | ||||
|             seamless: ["seamless"] | ||||
|         } | ||||
|     }, | ||||
|     img: { | ||||
|         attrs: { | ||||
|             alt: null, src: null, ismap: null, usemap: null, width: null, height: null, | ||||
|             crossorigin: ["anonymous", "use-credentials"] | ||||
|         } | ||||
|     }, | ||||
|     input: { | ||||
|         attrs: { | ||||
|             alt: null, dirname: null, form: null, formaction: null, | ||||
|             height: null, list: null, max: null, maxlength: null, min: null, | ||||
|             name: null, pattern: null, placeholder: null, size: null, src: null, | ||||
|             step: null, value: null, width: null, | ||||
|             accept: ["audio/*", "video/*", "image/*"], | ||||
|             autocomplete: ["on", "off"], | ||||
|             autofocus: ["autofocus"], | ||||
|             checked: ["checked"], | ||||
|             disabled: ["disabled"], | ||||
|             formenctype: Encs, | ||||
|             formmethod: Methods, | ||||
|             formnovalidate: ["novalidate"], | ||||
|             formtarget: Targets, | ||||
|             multiple: ["multiple"], | ||||
|             readonly: ["readonly"], | ||||
|             required: ["required"], | ||||
|             type: ["hidden", "text", "search", "tel", "url", "email", "password", "datetime", "date", "month", | ||||
|                 "week", "time", "datetime-local", "number", "range", "color", "checkbox", "radio", | ||||
|                 "file", "submit", "image", "reset", "button"] | ||||
|         } | ||||
|     }, | ||||
|     ins: { attrs: { cite: null, datetime: null } }, | ||||
|     kbd: S, | ||||
|     keygen: { | ||||
|         attrs: { | ||||
|             challenge: null, form: null, name: null, | ||||
|             autofocus: ["autofocus"], | ||||
|             disabled: ["disabled"], | ||||
|             keytype: ["RSA"] | ||||
|         } | ||||
|     }, | ||||
|     label: { attrs: { for: null, form: null } }, | ||||
|     legend: S, | ||||
|     li: { attrs: { value: null } }, | ||||
|     link: { | ||||
|         attrs: { | ||||
|             href: null, type: null, | ||||
|             hreflang: null, | ||||
|             media: null, | ||||
|             sizes: ["all", "16x16", "16x16 32x32", "16x16 32x32 64x64"] | ||||
|         } | ||||
|     }, | ||||
|     map: { attrs: { name: null } }, | ||||
|     mark: S, | ||||
|     menu: { attrs: { label: null, type: ["list", "context", "toolbar"] } }, | ||||
|     meta: { | ||||
|         attrs: { | ||||
|             content: null, | ||||
|             charset: Charsets, | ||||
|             name: ["viewport", "application-name", "author", "description", "generator", "keywords"], | ||||
|             "http-equiv": ["content-language", "content-type", "default-style", "refresh"] | ||||
|         } | ||||
|     }, | ||||
|     meter: { attrs: { value: null, min: null, low: null, high: null, max: null, optimum: null } }, | ||||
|     nav: S, | ||||
|     noscript: S, | ||||
|     object: { | ||||
|         attrs: { | ||||
|             data: null, type: null, name: null, usemap: null, form: null, width: null, height: null, | ||||
|             typemustmatch: ["typemustmatch"] | ||||
|         } | ||||
|     }, | ||||
|     ol: { attrs: { reversed: ["reversed"], start: null, type: ["1", "a", "A", "i", "I"] }, | ||||
|         children: ["li", "script", "template", "ul", "ol"] }, | ||||
|     optgroup: { attrs: { disabled: ["disabled"], label: null } }, | ||||
|     option: { attrs: { disabled: ["disabled"], label: null, selected: ["selected"], value: null } }, | ||||
|     output: { attrs: { for: null, form: null, name: null } }, | ||||
|     p: S, | ||||
|     param: { attrs: { name: null, value: null } }, | ||||
|     pre: S, | ||||
|     progress: { attrs: { value: null, max: null } }, | ||||
|     q: { attrs: { cite: null } }, | ||||
|     rp: S, | ||||
|     rt: S, | ||||
|     ruby: S, | ||||
|     samp: S, | ||||
|     script: { | ||||
|         attrs: { | ||||
|             type: ["text/javascript"], | ||||
|             src: null, | ||||
|             async: ["async"], | ||||
|             defer: ["defer"], | ||||
|             charset: Charsets | ||||
|         } | ||||
|     }, | ||||
|     section: S, | ||||
|     select: { | ||||
|         attrs: { | ||||
|             form: null, name: null, size: null, | ||||
|             autofocus: ["autofocus"], | ||||
|             disabled: ["disabled"], | ||||
|             multiple: ["multiple"] | ||||
|         } | ||||
|     }, | ||||
|     slot: { attrs: { name: null } }, | ||||
|     small: S, | ||||
|     source: { attrs: { src: null, type: null, media: null } }, | ||||
|     span: S, | ||||
|     strong: S, | ||||
|     style: { | ||||
|         attrs: { | ||||
|             type: ["text/css"], | ||||
|             media: null, | ||||
|             scoped: null | ||||
|         } | ||||
|     }, | ||||
|     sub: S, | ||||
|     summary: S, | ||||
|     sup: S, | ||||
|     table: S, | ||||
|     tbody: S, | ||||
|     td: { attrs: { colspan: null, rowspan: null, headers: null } }, | ||||
|     template: S, | ||||
|     textarea: { | ||||
|         attrs: { | ||||
|             dirname: null, form: null, maxlength: null, name: null, placeholder: null, | ||||
|             rows: null, cols: null, | ||||
|             autofocus: ["autofocus"], | ||||
|             disabled: ["disabled"], | ||||
|             readonly: ["readonly"], | ||||
|             required: ["required"], | ||||
|             wrap: ["soft", "hard"] | ||||
|         } | ||||
|     }, | ||||
|     tfoot: S, | ||||
|     th: { attrs: { colspan: null, rowspan: null, headers: null, scope: ["row", "col", "rowgroup", "colgroup"] } }, | ||||
|     thead: S, | ||||
|     time: { attrs: { datetime: null } }, | ||||
|     title: S, | ||||
|     tr: S, | ||||
|     track: { | ||||
|         attrs: { | ||||
|             src: null, label: null, default: null, | ||||
|             kind: ["subtitles", "captions", "descriptions", "chapters", "metadata"], | ||||
|             srclang: null | ||||
|         } | ||||
|     }, | ||||
|     ul: { children: ["li", "script", "template", "ul", "ol"] }, | ||||
|     var: S, | ||||
|     video: { | ||||
|         attrs: { | ||||
|             src: null, poster: null, width: null, height: null, | ||||
|             crossorigin: ["anonymous", "use-credentials"], | ||||
|             preload: ["auto", "metadata", "none"], | ||||
|             autoplay: ["autoplay"], | ||||
|             mediagroup: ["movie"], | ||||
|             muted: ["muted"], | ||||
|             controls: ["controls"] | ||||
|         } | ||||
|     }, | ||||
|     wbr: S | ||||
| }; | ||||
| const GlobalAttrs = { | ||||
|     accesskey: null, | ||||
|     class: null, | ||||
|     contenteditable: Bool, | ||||
|     contextmenu: null, | ||||
|     dir: ["ltr", "rtl", "auto"], | ||||
|     draggable: ["true", "false", "auto"], | ||||
|     dropzone: ["copy", "move", "link", "string:", "file:"], | ||||
|     hidden: ["hidden"], | ||||
|     id: null, | ||||
|     inert: ["inert"], | ||||
|     itemid: null, | ||||
|     itemprop: null, | ||||
|     itemref: null, | ||||
|     itemscope: ["itemscope"], | ||||
|     itemtype: null, | ||||
|     lang: ["ar", "bn", "de", "en-GB", "en-US", "es", "fr", "hi", "id", "ja", "pa", "pt", "ru", "tr", "zh"], | ||||
|     spellcheck: Bool, | ||||
|     autocorrect: Bool, | ||||
|     autocapitalize: Bool, | ||||
|     style: null, | ||||
|     tabindex: null, | ||||
|     title: null, | ||||
|     translate: ["yes", "no"], | ||||
|     rel: ["stylesheet", "alternate", "author", "bookmark", "help", "license", "next", "nofollow", "noreferrer", "prefetch", "prev", "search", "tag"], | ||||
|     role: /*@__PURE__*/"alert application article banner button cell checkbox complementary contentinfo dialog document feed figure form grid gridcell heading img list listbox listitem main navigation region row rowgroup search switch tab table tabpanel textbox timer".split(" "), | ||||
|     "aria-activedescendant": null, | ||||
|     "aria-atomic": Bool, | ||||
|     "aria-autocomplete": ["inline", "list", "both", "none"], | ||||
|     "aria-busy": Bool, | ||||
|     "aria-checked": ["true", "false", "mixed", "undefined"], | ||||
|     "aria-controls": null, | ||||
|     "aria-describedby": null, | ||||
|     "aria-disabled": Bool, | ||||
|     "aria-dropeffect": null, | ||||
|     "aria-expanded": ["true", "false", "undefined"], | ||||
|     "aria-flowto": null, | ||||
|     "aria-grabbed": ["true", "false", "undefined"], | ||||
|     "aria-haspopup": Bool, | ||||
|     "aria-hidden": Bool, | ||||
|     "aria-invalid": ["true", "false", "grammar", "spelling"], | ||||
|     "aria-label": null, | ||||
|     "aria-labelledby": null, | ||||
|     "aria-level": null, | ||||
|     "aria-live": ["off", "polite", "assertive"], | ||||
|     "aria-multiline": Bool, | ||||
|     "aria-multiselectable": Bool, | ||||
|     "aria-owns": null, | ||||
|     "aria-posinset": null, | ||||
|     "aria-pressed": ["true", "false", "mixed", "undefined"], | ||||
|     "aria-readonly": Bool, | ||||
|     "aria-relevant": null, | ||||
|     "aria-required": Bool, | ||||
|     "aria-selected": ["true", "false", "undefined"], | ||||
|     "aria-setsize": null, | ||||
|     "aria-sort": ["ascending", "descending", "none", "other"], | ||||
|     "aria-valuemax": null, | ||||
|     "aria-valuemin": null, | ||||
|     "aria-valuenow": null, | ||||
|     "aria-valuetext": null | ||||
| }; | ||||
| const eventAttributes = /*@__PURE__*/("beforeunload copy cut dragstart dragover dragleave dragenter dragend " + | ||||
|     "drag paste focus blur change click load mousedown mouseenter mouseleave " + | ||||
|     "mouseup keydown keyup resize scroll unload").split(" ").map(n => "on" + n); | ||||
| for (let a of eventAttributes) | ||||
|     GlobalAttrs[a] = null; | ||||
| class Schema { | ||||
|     constructor(extraTags, extraAttrs) { | ||||
|         this.tags = Object.assign(Object.assign({}, Tags), extraTags); | ||||
|         this.globalAttrs = Object.assign(Object.assign({}, GlobalAttrs), extraAttrs); | ||||
|         this.allTags = Object.keys(this.tags); | ||||
|         this.globalAttrNames = Object.keys(this.globalAttrs); | ||||
|     } | ||||
| } | ||||
| Schema.default = /*@__PURE__*/new Schema; | ||||
| function elementName(doc, tree, max = doc.length) { | ||||
|     if (!tree) | ||||
|         return ""; | ||||
|     let tag = tree.firstChild; | ||||
|     let name = tag && tag.getChild("TagName"); | ||||
|     return name ? doc.sliceString(name.from, Math.min(name.to, max)) : ""; | ||||
| } | ||||
| function findParentElement(tree, skip = false) { | ||||
|     for (; tree; tree = tree.parent) | ||||
|         if (tree.name == "Element") { | ||||
|             if (skip) | ||||
|                 skip = false; | ||||
|             else | ||||
|                 return tree; | ||||
|         } | ||||
|     return null; | ||||
| } | ||||
| function allowedChildren(doc, tree, schema) { | ||||
|     let parentInfo = schema.tags[elementName(doc, findParentElement(tree))]; | ||||
|     return (parentInfo === null || parentInfo === void 0 ? void 0 : parentInfo.children) || schema.allTags; | ||||
| } | ||||
| function openTags(doc, tree) { | ||||
|     let open = []; | ||||
|     for (let parent = findParentElement(tree); parent && !parent.type.isTop; parent = findParentElement(parent.parent)) { | ||||
|         let tagName = elementName(doc, parent); | ||||
|         if (tagName && parent.lastChild.name == "CloseTag") | ||||
|             break; | ||||
|         if (tagName && open.indexOf(tagName) < 0 && (tree.name == "EndTag" || tree.from >= parent.firstChild.to)) | ||||
|             open.push(tagName); | ||||
|     } | ||||
|     return open; | ||||
| } | ||||
| const identifier = /^[:\-\.\w\u00b7-\uffff]*$/; | ||||
| function completeTag(state, schema, tree, from, to) { | ||||
|     let end = /\s*>/.test(state.sliceDoc(to, to + 5)) ? "" : ">"; | ||||
|     let parent = findParentElement(tree, true); | ||||
|     return { from, to, | ||||
|         options: allowedChildren(state.doc, parent, schema).map(tagName => ({ label: tagName, type: "type" })).concat(openTags(state.doc, tree).map((tag, i) => ({ label: "/" + tag, apply: "/" + tag + end, | ||||
|             type: "type", boost: 99 - i }))), | ||||
|         validFor: /^\/?[:\-\.\w\u00b7-\uffff]*$/ }; | ||||
| } | ||||
| function completeCloseTag(state, tree, from, to) { | ||||
|     let end = /\s*>/.test(state.sliceDoc(to, to + 5)) ? "" : ">"; | ||||
|     return { from, to, | ||||
|         options: openTags(state.doc, tree).map((tag, i) => ({ label: tag, apply: tag + end, type: "type", boost: 99 - i })), | ||||
|         validFor: identifier }; | ||||
| } | ||||
| function completeStartTag(state, schema, tree, pos) { | ||||
|     let options = [], level = 0; | ||||
|     for (let tagName of allowedChildren(state.doc, tree, schema)) | ||||
|         options.push({ label: "<" + tagName, type: "type" }); | ||||
|     for (let open of openTags(state.doc, tree)) | ||||
|         options.push({ label: "</" + open + ">", type: "type", boost: 99 - level++ }); | ||||
|     return { from: pos, to: pos, options, validFor: /^<\/?[:\-\.\w\u00b7-\uffff]*$/ }; | ||||
| } | ||||
| function completeAttrName(state, schema, tree, from, to) { | ||||
|     let elt = findParentElement(tree), info = elt ? schema.tags[elementName(state.doc, elt)] : null; | ||||
|     let localAttrs = info && info.attrs ? Object.keys(info.attrs) : []; | ||||
|     let names = info && info.globalAttrs === false ? localAttrs | ||||
|         : localAttrs.length ? localAttrs.concat(schema.globalAttrNames) : schema.globalAttrNames; | ||||
|     return { from, to, | ||||
|         options: names.map(attrName => ({ label: attrName, type: "property" })), | ||||
|         validFor: identifier }; | ||||
| } | ||||
| function completeAttrValue(state, schema, tree, from, to) { | ||||
|     var _a; | ||||
|     let nameNode = (_a = tree.parent) === null || _a === void 0 ? void 0 : _a.getChild("AttributeName"); | ||||
|     let options = [], token = undefined; | ||||
|     if (nameNode) { | ||||
|         let attrName = state.sliceDoc(nameNode.from, nameNode.to); | ||||
|         let attrs = schema.globalAttrs[attrName]; | ||||
|         if (!attrs) { | ||||
|             let elt = findParentElement(tree), info = elt ? schema.tags[elementName(state.doc, elt)] : null; | ||||
|             attrs = (info === null || info === void 0 ? void 0 : info.attrs) && info.attrs[attrName]; | ||||
|         } | ||||
|         if (attrs) { | ||||
|             let base = state.sliceDoc(from, to).toLowerCase(), quoteStart = '"', quoteEnd = '"'; | ||||
|             if (/^['"]/.test(base)) { | ||||
|                 token = base[0] == '"' ? /^[^"]*$/ : /^[^']*$/; | ||||
|                 quoteStart = ""; | ||||
|                 quoteEnd = state.sliceDoc(to, to + 1) == base[0] ? "" : base[0]; | ||||
|                 base = base.slice(1); | ||||
|                 from++; | ||||
|             } | ||||
|             else { | ||||
|                 token = /^[^\s<>='"]*$/; | ||||
|             } | ||||
|             for (let value of attrs) | ||||
|                 options.push({ label: value, apply: quoteStart + value + quoteEnd, type: "constant" }); | ||||
|         } | ||||
|     } | ||||
|     return { from, to, options, validFor: token }; | ||||
| } | ||||
| function htmlCompletionFor(schema, context) { | ||||
|     let { state, pos } = context, tree = syntaxTree(state).resolveInner(pos, -1), around = tree.resolve(pos); | ||||
|     for (let scan = pos, before; around == tree && (before = tree.childBefore(scan));) { | ||||
|         let last = before.lastChild; | ||||
|         if (!last || !last.type.isError || last.from < last.to) | ||||
|             break; | ||||
|         around = tree = before; | ||||
|         scan = last.from; | ||||
|     } | ||||
|     if (tree.name == "TagName") { | ||||
|         return tree.parent && /CloseTag$/.test(tree.parent.name) ? completeCloseTag(state, tree, tree.from, pos) | ||||
|             : completeTag(state, schema, tree, tree.from, pos); | ||||
|     } | ||||
|     else if (tree.name == "StartTag") { | ||||
|         return completeTag(state, schema, tree, pos, pos); | ||||
|     } | ||||
|     else if (tree.name == "StartCloseTag" || tree.name == "IncompleteCloseTag") { | ||||
|         return completeCloseTag(state, tree, pos, pos); | ||||
|     } | ||||
|     else if (tree.name == "OpenTag" || tree.name == "SelfClosingTag" || tree.name == "AttributeName") { | ||||
|         return completeAttrName(state, schema, tree, tree.name == "AttributeName" ? tree.from : pos, pos); | ||||
|     } | ||||
|     else if (tree.name == "Is" || tree.name == "AttributeValue" || tree.name == "UnquotedAttributeValue") { | ||||
|         return completeAttrValue(state, schema, tree, tree.name == "Is" ? pos : tree.from, pos); | ||||
|     } | ||||
|     else if (context.explicit && (around.name == "Element" || around.name == "Text" || around.name == "Document")) { | ||||
|         return completeStartTag(state, schema, tree, pos); | ||||
|     } | ||||
|     else { | ||||
|         return null; | ||||
|     } | ||||
| } | ||||
| /** | ||||
| HTML tag completion. Opens and closes tags and attributes in a | ||||
| context-aware way. | ||||
| */ | ||||
| function htmlCompletionSource(context) { | ||||
|     return htmlCompletionFor(Schema.default, context); | ||||
| } | ||||
| /** | ||||
| Create a completion source for HTML extended with additional tags | ||||
| or attributes. | ||||
| */ | ||||
| function htmlCompletionSourceWith(config) { | ||||
|     let { extraTags, extraGlobalAttributes: extraAttrs } = config; | ||||
|     let schema = extraAttrs || extraTags ? new Schema(extraTags, extraAttrs) : Schema.default; | ||||
|     return (context) => htmlCompletionFor(schema, context); | ||||
| } | ||||
|  | ||||
| const jsonParser = /*@__PURE__*/javascriptLanguage.parser.configure({ top: "SingleExpression" }); | ||||
| const defaultNesting = [ | ||||
|     { tag: "script", | ||||
|         attrs: attrs => attrs.type == "text/typescript" || attrs.lang == "ts", | ||||
|         parser: typescriptLanguage.parser }, | ||||
|     { tag: "script", | ||||
|         attrs: attrs => attrs.type == "text/babel" || attrs.type == "text/jsx", | ||||
|         parser: jsxLanguage.parser }, | ||||
|     { tag: "script", | ||||
|         attrs: attrs => attrs.type == "text/typescript-jsx", | ||||
|         parser: tsxLanguage.parser }, | ||||
|     { tag: "script", | ||||
|         attrs(attrs) { | ||||
|             return /^(importmap|speculationrules|application\/(.+\+)?json)$/i.test(attrs.type); | ||||
|         }, | ||||
|         parser: jsonParser }, | ||||
|     { tag: "script", | ||||
|         attrs(attrs) { | ||||
|             return !attrs.type || /^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^module$|^$/i.test(attrs.type); | ||||
|         }, | ||||
|         parser: javascriptLanguage.parser }, | ||||
|     { tag: "style", | ||||
|         attrs(attrs) { | ||||
|             return (!attrs.lang || attrs.lang == "css") && (!attrs.type || /^(text\/)?(x-)?(stylesheet|css)$/i.test(attrs.type)); | ||||
|         }, | ||||
|         parser: cssLanguage.parser } | ||||
| ]; | ||||
| const defaultAttrs = /*@__PURE__*/[ | ||||
|     { name: "style", | ||||
|         parser: /*@__PURE__*/cssLanguage.parser.configure({ top: "Styles" }) } | ||||
| ].concat(/*@__PURE__*/eventAttributes.map(name => ({ name, parser: javascriptLanguage.parser }))); | ||||
| /** | ||||
| A language provider based on the [Lezer HTML | ||||
| parser](https://github.com/lezer-parser/html), extended with the | ||||
| JavaScript and CSS parsers to parse the content of `<script>` and | ||||
| `<style>` tags. | ||||
| */ | ||||
| const htmlPlain = /*@__PURE__*/LRLanguage.define({ | ||||
|     name: "html", | ||||
|     parser: /*@__PURE__*/parser.configure({ | ||||
|         props: [ | ||||
|             /*@__PURE__*/indentNodeProp.add({ | ||||
|                 Element(context) { | ||||
|                     let after = /^(\s*)(<\/)?/.exec(context.textAfter); | ||||
|                     if (context.node.to <= context.pos + after[0].length) | ||||
|                         return context.continue(); | ||||
|                     return context.lineIndent(context.node.from) + (after[2] ? 0 : context.unit); | ||||
|                 }, | ||||
|                 "OpenTag CloseTag SelfClosingTag"(context) { | ||||
|                     return context.column(context.node.from) + context.unit; | ||||
|                 }, | ||||
|                 Document(context) { | ||||
|                     if (context.pos + /\s*/.exec(context.textAfter)[0].length < context.node.to) | ||||
|                         return context.continue(); | ||||
|                     let endElt = null, close; | ||||
|                     for (let cur = context.node;;) { | ||||
|                         let last = cur.lastChild; | ||||
|                         if (!last || last.name != "Element" || last.to != cur.to) | ||||
|                             break; | ||||
|                         endElt = cur = last; | ||||
|                     } | ||||
|                     if (endElt && !((close = endElt.lastChild) && (close.name == "CloseTag" || close.name == "SelfClosingTag"))) | ||||
|                         return context.lineIndent(endElt.from) + context.unit; | ||||
|                     return null; | ||||
|                 } | ||||
|             }), | ||||
|             /*@__PURE__*/foldNodeProp.add({ | ||||
|                 Element(node) { | ||||
|                     let first = node.firstChild, last = node.lastChild; | ||||
|                     if (!first || first.name != "OpenTag") | ||||
|                         return null; | ||||
|                     return { from: first.to, to: last.name == "CloseTag" ? last.from : node.to }; | ||||
|                 } | ||||
|             }), | ||||
|             /*@__PURE__*/bracketMatchingHandle.add({ | ||||
|                 "OpenTag CloseTag": node => node.getChild("TagName") | ||||
|             }) | ||||
|         ] | ||||
|     }), | ||||
|     languageData: { | ||||
|         commentTokens: { block: { open: "<!--", close: "-->" } }, | ||||
|         indentOnInput: /^\s*<\/\w+\W$/, | ||||
|         wordChars: "-._" | ||||
|     } | ||||
| }); | ||||
| /** | ||||
| A language provider based on the [Lezer HTML | ||||
| parser](https://github.com/lezer-parser/html), extended with the | ||||
| JavaScript and CSS parsers to parse the content of `<script>` and | ||||
| `<style>` tags. | ||||
| */ | ||||
| const htmlLanguage = /*@__PURE__*/htmlPlain.configure({ | ||||
|     wrap: /*@__PURE__*/configureNesting(defaultNesting, defaultAttrs) | ||||
| }); | ||||
| /** | ||||
| Language support for HTML, including | ||||
| [`htmlCompletion`](https://codemirror.net/6/docs/ref/#lang-html.htmlCompletion) and JavaScript and | ||||
| CSS support extensions. | ||||
| */ | ||||
| function html(config = {}) { | ||||
|     let dialect = "", wrap; | ||||
|     if (config.matchClosingTags === false) | ||||
|         dialect = "noMatch"; | ||||
|     if (config.selfClosingTags === true) | ||||
|         dialect = (dialect ? dialect + " " : "") + "selfClosing"; | ||||
|     if (config.nestedLanguages && config.nestedLanguages.length || | ||||
|         config.nestedAttributes && config.nestedAttributes.length) | ||||
|         wrap = configureNesting((config.nestedLanguages || []).concat(defaultNesting), (config.nestedAttributes || []).concat(defaultAttrs)); | ||||
|     let lang = wrap ? htmlPlain.configure({ wrap, dialect }) : dialect ? htmlLanguage.configure({ dialect }) : htmlLanguage; | ||||
|     return new LanguageSupport(lang, [ | ||||
|         htmlLanguage.data.of({ autocomplete: htmlCompletionSourceWith(config) }), | ||||
|         config.autoCloseTags !== false ? autoCloseTags : [], | ||||
|         javascript().support, | ||||
|         css().support | ||||
|     ]); | ||||
| } | ||||
| const selfClosers = /*@__PURE__*/new Set(/*@__PURE__*/"area base br col command embed frame hr img input keygen link meta param source track wbr menuitem".split(" ")); | ||||
| /** | ||||
| Extension that will automatically insert close tags when a `>` or | ||||
| `/` is typed. | ||||
| */ | ||||
| const autoCloseTags = /*@__PURE__*/EditorView.inputHandler.of((view, from, to, text, insertTransaction) => { | ||||
|     if (view.composing || view.state.readOnly || from != to || (text != ">" && text != "/") || | ||||
|         !htmlLanguage.isActiveAt(view.state, from, -1)) | ||||
|         return false; | ||||
|     let base = insertTransaction(), { state } = base; | ||||
|     let closeTags = state.changeByRange(range => { | ||||
|         var _a, _b, _c; | ||||
|         let didType = state.doc.sliceString(range.from - 1, range.to) == text; | ||||
|         let { head } = range, after = syntaxTree(state).resolveInner(head, -1), name; | ||||
|         if (didType && text == ">" && after.name == "EndTag") { | ||||
|             let tag = after.parent; | ||||
|             if (((_b = (_a = tag.parent) === null || _a === void 0 ? void 0 : _a.lastChild) === null || _b === void 0 ? void 0 : _b.name) != "CloseTag" && | ||||
|                 (name = elementName(state.doc, tag.parent, head)) && | ||||
|                 !selfClosers.has(name)) { | ||||
|                 let to = head + (state.doc.sliceString(head, head + 1) === ">" ? 1 : 0); | ||||
|                 let insert = `</${name}>`; | ||||
|                 return { range, changes: { from: head, to, insert } }; | ||||
|             } | ||||
|         } | ||||
|         else if (didType && text == "/" && after.name == "IncompleteCloseTag") { | ||||
|             let tag = after.parent; | ||||
|             if (after.from == head - 2 && ((_c = tag.lastChild) === null || _c === void 0 ? void 0 : _c.name) != "CloseTag" && | ||||
|                 (name = elementName(state.doc, tag, head)) && !selfClosers.has(name)) { | ||||
|                 let to = head + (state.doc.sliceString(head, head + 1) === ">" ? 1 : 0); | ||||
|                 let insert = `${name}>`; | ||||
|                 return { | ||||
|                     range: EditorSelection.cursor(head + insert.length, -1), | ||||
|                     changes: { from: head, to, insert } | ||||
|                 }; | ||||
|             } | ||||
|         } | ||||
|         return { range }; | ||||
|     }); | ||||
|     if (closeTags.changes.empty) | ||||
|         return false; | ||||
|     view.dispatch([ | ||||
|         base, | ||||
|         state.update(closeTags, { | ||||
|             userEvent: "input.complete", | ||||
|             scrollIntoView: true | ||||
|         }) | ||||
|     ]); | ||||
|     return true; | ||||
| }); | ||||
|  | ||||
| export { autoCloseTags, html, htmlCompletionSource, htmlCompletionSourceWith, htmlLanguage, htmlPlain }; | ||||
		Reference in New Issue
	
	Block a user