diff --git a/src/lib/codemirror/mode/coffeescript/coffeescript.js b/src/lib/codemirror/mode/coffeescript/coffeescript.js
index adf2184..5609872 100644
--- a/src/lib/codemirror/mode/coffeescript/coffeescript.js
+++ b/src/lib/codemirror/mode/coffeescript/coffeescript.js
@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
+// Distributed under an MIT license: https://codemirror.net/5/LICENSE
/**
* Link to the project's GitHub page:
@@ -349,6 +349,10 @@ CodeMirror.defineMode("coffeescript", function(conf, parserConf) {
return external;
});
+// IANA registered media type
+// https://www.iana.org/assignments/media-types/
+CodeMirror.defineMIME("application/vnd.coffeescript", "coffeescript");
+
CodeMirror.defineMIME("text/x-coffeescript", "coffeescript");
CodeMirror.defineMIME("text/coffeescript", "coffeescript");
diff --git a/src/lib/codemirror/mode/css/css.js b/src/lib/codemirror/mode/css/css.js
index e9656e3..b0721b4 100644
--- a/src/lib/codemirror/mode/css/css.js
+++ b/src/lib/codemirror/mode/css/css.js
@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
+// Distributed under an MIT license: https://codemirror.net/5/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
@@ -28,7 +28,9 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
colorKeywords = parserConfig.colorKeywords || {},
valueKeywords = parserConfig.valueKeywords || {},
allowNested = parserConfig.allowNested,
- supportsAtComponent = parserConfig.supportsAtComponent === true;
+ lineComment = parserConfig.lineComment,
+ supportsAtComponent = parserConfig.supportsAtComponent === true,
+ highlightNonStandardPropertyKeywords = config.highlightNonStandardPropertyKeywords !== false;
var type, override;
function ret(style, tp) { type = tp; return style; }
@@ -62,7 +64,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
if (/[\d.]/.test(stream.peek())) {
stream.eatWhile(/[\w.%]/);
return ret("number", "unit");
- } else if (stream.match(/^-[\w\\\-]+/)) {
+ } else if (stream.match(/^-[\w\\\-]*/)) {
stream.eatWhile(/[\w\\\-]/);
if (stream.match(/^\s*:/, false))
return ret("variable-2", "variable-definition");
@@ -76,12 +78,11 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
return ret("qualifier", "qualifier");
} else if (/[:;{}\[\]\(\)]/.test(ch)) {
return ret(null, ch);
- } else if ((ch == "u" && stream.match(/rl(-prefix)?\(/)) ||
- (ch == "d" && stream.match("omain(")) ||
- (ch == "r" && stream.match("egexp("))) {
- stream.backUp(1);
- state.tokenize = tokenParenthesized;
- return ret("property", "word");
+ } else if (stream.match(/^[\w-.]+(?=\()/)) {
+ if (/^(url(-prefix)?|domain|regexp)$/i.test(stream.current())) {
+ state.tokenize = tokenParenthesized;
+ }
+ return ret("variable callee", "variable");
} else if (/[\w\\\-]/.test(ch)) {
stream.eatWhile(/[\w\\\-]/);
return ret("property", "word");
@@ -107,7 +108,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
function tokenParenthesized(stream, state) {
stream.next(); // Must be '('
- if (!stream.match(/\s*[\"\')]/, false))
+ if (!stream.match(/^\s*[\"\')]/, false))
state.tokenize = tokenString(")");
else
state.tokenize = null;
@@ -161,16 +162,16 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
return pushContext(state, stream, "block");
} else if (type == "}" && state.context.prev) {
return popContext(state);
- } else if (supportsAtComponent && /@component/.test(type)) {
+ } else if (supportsAtComponent && /@component/i.test(type)) {
return pushContext(state, stream, "atComponentBlock");
- } else if (/^@(-moz-)?document$/.test(type)) {
+ } else if (/^@(-moz-)?document$/i.test(type)) {
return pushContext(state, stream, "documentTypes");
- } else if (/^@(media|supports|(-moz-)?document|import)$/.test(type)) {
+ } else if (/^@(media|supports|(-moz-)?document|import)$/i.test(type)) {
return pushContext(state, stream, "atBlock");
- } else if (/^@(font-face|counter-style)/.test(type)) {
+ } else if (/^@(font-face|counter-style)/i.test(type)) {
state.stateArg = type;
return "restricted_atBlock_before";
- } else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/.test(type)) {
+ } else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/i.test(type)) {
return "keyframes";
} else if (type && type.charAt(0) == "@") {
return pushContext(state, stream, "at");
@@ -197,7 +198,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
override = "property";
return "maybeprop";
} else if (nonStandardPropertyKeywords.hasOwnProperty(word)) {
- override = "string-2";
+ override = highlightNonStandardPropertyKeywords ? "string-2" : "property";
return "maybeprop";
} else if (allowNested) {
override = stream.match(/^\s*:(?:\s|$)/, false) ? "property" : "tag";
@@ -227,7 +228,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
if (type == "}" || type == "{") return popAndPass(type, stream, state);
if (type == "(") return pushContext(state, stream, "parens");
- if (type == "hash" && !/^#([0-9a-fA-f]{3,4}|[0-9a-fA-f]{6}|[0-9a-fA-f]{8})$/.test(stream.current())) {
+ if (type == "hash" && !/^#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(stream.current())) {
override += " error";
} else if (type == "word") {
wordAsValue(stream);
@@ -253,6 +254,8 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
};
states.pseudo = function(type, stream, state) {
+ if (type == "meta") return "pseudo";
+
if (type == "word") {
override = "variable-3";
return state.context.type;
@@ -289,7 +292,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
else if (propertyKeywords.hasOwnProperty(word))
override = "property";
else if (nonStandardPropertyKeywords.hasOwnProperty(word))
- override = "string-2";
+ override = highlightNonStandardPropertyKeywords ? "string-2" : "property";
else if (valueKeywords.hasOwnProperty(word))
override = "atom";
else if (colorKeywords.hasOwnProperty(word))
@@ -380,7 +383,8 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
style = style[0];
}
override = style;
- state.state = states[state.state](type, stream, state);
+ if (type != "comment")
+ state.state = states[state.state](type, stream, state);
return override;
},
@@ -398,7 +402,6 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
ch == "{" && (cx.type == "at" || cx.type == "atBlock")) {
// Dedent relative to current context.
indent = Math.max(0, cx.indent - indentUnit);
- cx = cx.prev;
}
}
return indent;
@@ -407,6 +410,8 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
electricChars: "}",
blockCommentStart: "/*",
blockCommentEnd: "*/",
+ blockCommentContinue: " * ",
+ lineComment: lineComment,
fold: "brace"
};
});
@@ -414,7 +419,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
function keySet(array) {
var keys = {};
for (var i = 0; i < array.length; ++i) {
- keys[array[i]] = true;
+ keys[array[i].toLowerCase()] = true;
}
return keys;
}
@@ -438,117 +443,151 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"monochrome", "min-monochrome", "max-monochrome", "resolution",
"min-resolution", "max-resolution", "scan", "grid", "orientation",
"device-pixel-ratio", "min-device-pixel-ratio", "max-device-pixel-ratio",
- "pointer", "any-pointer", "hover", "any-hover"
+ "pointer", "any-pointer", "hover", "any-hover", "prefers-color-scheme",
+ "dynamic-range", "video-dynamic-range"
], mediaFeatures = keySet(mediaFeatures_);
var mediaValueKeywords_ = [
"landscape", "portrait", "none", "coarse", "fine", "on-demand", "hover",
- "interlace", "progressive"
+ "interlace", "progressive",
+ "dark", "light",
+ "standard", "high"
], mediaValueKeywords = keySet(mediaValueKeywords_);
var propertyKeywords_ = [
"align-content", "align-items", "align-self", "alignment-adjust",
- "alignment-baseline", "anchor-point", "animation", "animation-delay",
+ "alignment-baseline", "all", "anchor-point", "animation", "animation-delay",
"animation-direction", "animation-duration", "animation-fill-mode",
"animation-iteration-count", "animation-name", "animation-play-state",
- "animation-timing-function", "appearance", "azimuth", "backface-visibility",
- "background", "background-attachment", "background-blend-mode", "background-clip",
- "background-color", "background-image", "background-origin", "background-position",
- "background-repeat", "background-size", "baseline-shift", "binding",
- "bleed", "bookmark-label", "bookmark-level", "bookmark-state",
- "bookmark-target", "border", "border-bottom", "border-bottom-color",
- "border-bottom-left-radius", "border-bottom-right-radius",
- "border-bottom-style", "border-bottom-width", "border-collapse",
- "border-color", "border-image", "border-image-outset",
+ "animation-timing-function", "appearance", "azimuth", "backdrop-filter",
+ "backface-visibility", "background", "background-attachment",
+ "background-blend-mode", "background-clip", "background-color",
+ "background-image", "background-origin", "background-position",
+ "background-position-x", "background-position-y", "background-repeat",
+ "background-size", "baseline-shift", "binding", "bleed", "block-size",
+ "bookmark-label", "bookmark-level", "bookmark-state", "bookmark-target",
+ "border", "border-bottom", "border-bottom-color", "border-bottom-left-radius",
+ "border-bottom-right-radius", "border-bottom-style", "border-bottom-width",
+ "border-collapse", "border-color", "border-image", "border-image-outset",
"border-image-repeat", "border-image-slice", "border-image-source",
- "border-image-width", "border-left", "border-left-color",
- "border-left-style", "border-left-width", "border-radius", "border-right",
- "border-right-color", "border-right-style", "border-right-width",
- "border-spacing", "border-style", "border-top", "border-top-color",
- "border-top-left-radius", "border-top-right-radius", "border-top-style",
- "border-top-width", "border-width", "bottom", "box-decoration-break",
- "box-shadow", "box-sizing", "break-after", "break-before", "break-inside",
- "caption-side", "clear", "clip", "color", "color-profile", "column-count",
- "column-fill", "column-gap", "column-rule", "column-rule-color",
- "column-rule-style", "column-rule-width", "column-span", "column-width",
- "columns", "content", "counter-increment", "counter-reset", "crop", "cue",
- "cue-after", "cue-before", "cursor", "direction", "display",
- "dominant-baseline", "drop-initial-after-adjust",
- "drop-initial-after-align", "drop-initial-before-adjust",
- "drop-initial-before-align", "drop-initial-size", "drop-initial-value",
- "elevation", "empty-cells", "fit", "fit-position", "flex", "flex-basis",
- "flex-direction", "flex-flow", "flex-grow", "flex-shrink", "flex-wrap",
- "float", "float-offset", "flow-from", "flow-into", "font", "font-feature-settings",
- "font-family", "font-kerning", "font-language-override", "font-size", "font-size-adjust",
- "font-stretch", "font-style", "font-synthesis", "font-variant",
- "font-variant-alternates", "font-variant-caps", "font-variant-east-asian",
- "font-variant-ligatures", "font-variant-numeric", "font-variant-position",
- "font-weight", "grid", "grid-area", "grid-auto-columns", "grid-auto-flow",
- "grid-auto-position", "grid-auto-rows", "grid-column", "grid-column-end",
- "grid-column-start", "grid-row", "grid-row-end", "grid-row-start",
+ "border-image-width", "border-left", "border-left-color", "border-left-style",
+ "border-left-width", "border-radius", "border-right", "border-right-color",
+ "border-right-style", "border-right-width", "border-spacing", "border-style",
+ "border-top", "border-top-color", "border-top-left-radius",
+ "border-top-right-radius", "border-top-style", "border-top-width",
+ "border-width", "bottom", "box-decoration-break", "box-shadow", "box-sizing",
+ "break-after", "break-before", "break-inside", "caption-side", "caret-color",
+ "clear", "clip", "color", "color-profile", "column-count", "column-fill",
+ "column-gap", "column-rule", "column-rule-color", "column-rule-style",
+ "column-rule-width", "column-span", "column-width", "columns", "contain",
+ "content", "counter-increment", "counter-reset", "crop", "cue", "cue-after",
+ "cue-before", "cursor", "direction", "display", "dominant-baseline",
+ "drop-initial-after-adjust", "drop-initial-after-align",
+ "drop-initial-before-adjust", "drop-initial-before-align", "drop-initial-size",
+ "drop-initial-value", "elevation", "empty-cells", "fit", "fit-content", "fit-position",
+ "flex", "flex-basis", "flex-direction", "flex-flow", "flex-grow",
+ "flex-shrink", "flex-wrap", "float", "float-offset", "flow-from", "flow-into",
+ "font", "font-family", "font-feature-settings", "font-kerning",
+ "font-language-override", "font-optical-sizing", "font-size",
+ "font-size-adjust", "font-stretch", "font-style", "font-synthesis",
+ "font-variant", "font-variant-alternates", "font-variant-caps",
+ "font-variant-east-asian", "font-variant-ligatures", "font-variant-numeric",
+ "font-variant-position", "font-variation-settings", "font-weight", "gap",
+ "grid", "grid-area", "grid-auto-columns", "grid-auto-flow", "grid-auto-rows",
+ "grid-column", "grid-column-end", "grid-column-gap", "grid-column-start",
+ "grid-gap", "grid-row", "grid-row-end", "grid-row-gap", "grid-row-start",
"grid-template", "grid-template-areas", "grid-template-columns",
- "grid-template-rows", "hanging-punctuation", "height", "hyphens",
- "icon", "image-orientation", "image-rendering", "image-resolution",
- "inline-box-align", "justify-content", "left", "letter-spacing",
- "line-break", "line-height", "line-stacking", "line-stacking-ruby",
+ "grid-template-rows", "hanging-punctuation", "height", "hyphens", "icon",
+ "image-orientation", "image-rendering", "image-resolution", "inline-box-align",
+ "inset", "inset-block", "inset-block-end", "inset-block-start", "inset-inline",
+ "inset-inline-end", "inset-inline-start", "isolation", "justify-content",
+ "justify-items", "justify-self", "left", "letter-spacing", "line-break",
+ "line-height", "line-height-step", "line-stacking", "line-stacking-ruby",
"line-stacking-shift", "line-stacking-strategy", "list-style",
"list-style-image", "list-style-position", "list-style-type", "margin",
- "margin-bottom", "margin-left", "margin-right", "margin-top",
- "marker-offset", "marks", "marquee-direction", "marquee-loop",
- "marquee-play-count", "marquee-speed", "marquee-style", "max-height",
- "max-width", "min-height", "min-width", "move-to", "nav-down", "nav-index",
- "nav-left", "nav-right", "nav-up", "object-fit", "object-position",
- "opacity", "order", "orphans", "outline",
- "outline-color", "outline-offset", "outline-style", "outline-width",
- "overflow", "overflow-style", "overflow-wrap", "overflow-x", "overflow-y",
- "padding", "padding-bottom", "padding-left", "padding-right", "padding-top",
- "page", "page-break-after", "page-break-before", "page-break-inside",
- "page-policy", "pause", "pause-after", "pause-before", "perspective",
- "perspective-origin", "pitch", "pitch-range", "play-during", "position",
- "presentation-level", "punctuation-trim", "quotes", "region-break-after",
- "region-break-before", "region-break-inside", "region-fragment",
- "rendering-intent", "resize", "rest", "rest-after", "rest-before", "richness",
- "right", "rotation", "rotation-point", "ruby-align", "ruby-overhang",
- "ruby-position", "ruby-span", "shape-image-threshold", "shape-inside", "shape-margin",
- "shape-outside", "size", "speak", "speak-as", "speak-header",
- "speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set",
- "tab-size", "table-layout", "target", "target-name", "target-new",
- "target-position", "text-align", "text-align-last", "text-decoration",
+ "margin-bottom", "margin-left", "margin-right", "margin-top", "marks",
+ "marquee-direction", "marquee-loop", "marquee-play-count", "marquee-speed",
+ "marquee-style", "mask-clip", "mask-composite", "mask-image", "mask-mode",
+ "mask-origin", "mask-position", "mask-repeat", "mask-size","mask-type",
+ "max-block-size", "max-height", "max-inline-size",
+ "max-width", "min-block-size", "min-height", "min-inline-size", "min-width",
+ "mix-blend-mode", "move-to", "nav-down", "nav-index", "nav-left", "nav-right",
+ "nav-up", "object-fit", "object-position", "offset", "offset-anchor",
+ "offset-distance", "offset-path", "offset-position", "offset-rotate",
+ "opacity", "order", "orphans", "outline", "outline-color", "outline-offset",
+ "outline-style", "outline-width", "overflow", "overflow-style",
+ "overflow-wrap", "overflow-x", "overflow-y", "padding", "padding-bottom",
+ "padding-left", "padding-right", "padding-top", "page", "page-break-after",
+ "page-break-before", "page-break-inside", "page-policy", "pause",
+ "pause-after", "pause-before", "perspective", "perspective-origin", "pitch",
+ "pitch-range", "place-content", "place-items", "place-self", "play-during",
+ "position", "presentation-level", "punctuation-trim", "quotes",
+ "region-break-after", "region-break-before", "region-break-inside",
+ "region-fragment", "rendering-intent", "resize", "rest", "rest-after",
+ "rest-before", "richness", "right", "rotate", "rotation", "rotation-point",
+ "row-gap", "ruby-align", "ruby-overhang", "ruby-position", "ruby-span",
+ "scale", "scroll-behavior", "scroll-margin", "scroll-margin-block",
+ "scroll-margin-block-end", "scroll-margin-block-start", "scroll-margin-bottom",
+ "scroll-margin-inline", "scroll-margin-inline-end",
+ "scroll-margin-inline-start", "scroll-margin-left", "scroll-margin-right",
+ "scroll-margin-top", "scroll-padding", "scroll-padding-block",
+ "scroll-padding-block-end", "scroll-padding-block-start",
+ "scroll-padding-bottom", "scroll-padding-inline", "scroll-padding-inline-end",
+ "scroll-padding-inline-start", "scroll-padding-left", "scroll-padding-right",
+ "scroll-padding-top", "scroll-snap-align", "scroll-snap-type",
+ "shape-image-threshold", "shape-inside", "shape-margin", "shape-outside",
+ "size", "speak", "speak-as", "speak-header", "speak-numeral",
+ "speak-punctuation", "speech-rate", "stress", "string-set", "tab-size",
+ "table-layout", "target", "target-name", "target-new", "target-position",
+ "text-align", "text-align-last", "text-combine-upright", "text-decoration",
"text-decoration-color", "text-decoration-line", "text-decoration-skip",
- "text-decoration-style", "text-emphasis", "text-emphasis-color",
- "text-emphasis-position", "text-emphasis-style", "text-height",
- "text-indent", "text-justify", "text-outline", "text-overflow", "text-shadow",
- "text-size-adjust", "text-space-collapse", "text-transform", "text-underline-position",
- "text-wrap", "top", "transform", "transform-origin", "transform-style",
- "transition", "transition-delay", "transition-duration",
- "transition-property", "transition-timing-function", "unicode-bidi",
- "vertical-align", "visibility", "voice-balance", "voice-duration",
- "voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress",
- "voice-volume", "volume", "white-space", "widows", "width", "word-break",
- "word-spacing", "word-wrap", "z-index",
+ "text-decoration-skip-ink", "text-decoration-style", "text-emphasis",
+ "text-emphasis-color", "text-emphasis-position", "text-emphasis-style",
+ "text-height", "text-indent", "text-justify", "text-orientation",
+ "text-outline", "text-overflow", "text-rendering", "text-shadow",
+ "text-size-adjust", "text-space-collapse", "text-transform",
+ "text-underline-position", "text-wrap", "top", "touch-action", "transform", "transform-origin",
+ "transform-style", "transition", "transition-delay", "transition-duration",
+ "transition-property", "transition-timing-function", "translate",
+ "unicode-bidi", "user-select", "vertical-align", "visibility", "voice-balance",
+ "voice-duration", "voice-family", "voice-pitch", "voice-range", "voice-rate",
+ "voice-stress", "voice-volume", "volume", "white-space", "widows", "width",
+ "will-change", "word-break", "word-spacing", "word-wrap", "writing-mode", "z-index",
// SVG-specific
"clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color",
"flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events",
"color-interpolation", "color-interpolation-filters",
"color-rendering", "fill", "fill-opacity", "fill-rule", "image-rendering",
- "marker", "marker-end", "marker-mid", "marker-start", "shape-rendering", "stroke",
+ "marker", "marker-end", "marker-mid", "marker-start", "paint-order", "shape-rendering", "stroke",
"stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin",
"stroke-miterlimit", "stroke-opacity", "stroke-width", "text-rendering",
"baseline-shift", "dominant-baseline", "glyph-orientation-horizontal",
- "glyph-orientation-vertical", "text-anchor", "writing-mode"
+ "glyph-orientation-vertical", "text-anchor", "writing-mode",
], propertyKeywords = keySet(propertyKeywords_);
var nonStandardPropertyKeywords_ = [
+ "accent-color", "aspect-ratio", "border-block", "border-block-color", "border-block-end",
+ "border-block-end-color", "border-block-end-style", "border-block-end-width",
+ "border-block-start", "border-block-start-color", "border-block-start-style",
+ "border-block-start-width", "border-block-style", "border-block-width",
+ "border-inline", "border-inline-color", "border-inline-end",
+ "border-inline-end-color", "border-inline-end-style",
+ "border-inline-end-width", "border-inline-start", "border-inline-start-color",
+ "border-inline-start-style", "border-inline-start-width",
+ "border-inline-style", "border-inline-width", "content-visibility", "margin-block",
+ "margin-block-end", "margin-block-start", "margin-inline", "margin-inline-end",
+ "margin-inline-start", "overflow-anchor", "overscroll-behavior", "padding-block", "padding-block-end",
+ "padding-block-start", "padding-inline", "padding-inline-end",
+ "padding-inline-start", "scroll-snap-stop", "scrollbar-3d-light-color",
"scrollbar-arrow-color", "scrollbar-base-color", "scrollbar-dark-shadow-color",
"scrollbar-face-color", "scrollbar-highlight-color", "scrollbar-shadow-color",
- "scrollbar-3d-light-color", "scrollbar-track-color", "shape-inside",
- "searchfield-cancel-button", "searchfield-decoration", "searchfield-results-button",
- "searchfield-results-decoration", "zoom"
+ "scrollbar-track-color", "searchfield-cancel-button", "searchfield-decoration",
+ "searchfield-results-button", "searchfield-results-decoration", "shape-inside", "zoom"
], nonStandardPropertyKeywords = keySet(nonStandardPropertyKeywords_);
var fontProperties_ = [
- "font-family", "src", "unicode-range", "font-variant", "font-feature-settings",
- "font-stretch", "font-weight", "font-style"
+ "font-display", "font-family", "src", "unicode-range", "font-variant",
+ "font-feature-settings", "font-stretch", "font-weight", "font-style"
], fontProperties = keySet(fontProperties_);
var counterDescriptors_ = [
@@ -561,16 +600,16 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown",
"burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue",
"cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod",
- "darkgray", "darkgreen", "darkkhaki", "darkmagenta", "darkolivegreen",
+ "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen",
"darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen",
- "darkslateblue", "darkslategray", "darkturquoise", "darkviolet",
- "deeppink", "deepskyblue", "dimgray", "dodgerblue", "firebrick",
+ "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet",
+ "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick",
"floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite",
"gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew",
"hotpink", "indianred", "indigo", "ivory", "khaki", "lavender",
"lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral",
- "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightpink",
- "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray",
+ "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink",
+ "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey",
"lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta",
"maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple",
"mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise",
@@ -580,7 +619,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue",
"purple", "rebeccapurple", "red", "rosybrown", "royalblue", "saddlebrown",
"salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue",
- "slateblue", "slategray", "snow", "springgreen", "steelblue", "tan",
+ "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan",
"teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white",
"whitesmoke", "yellow", "yellowgreen"
], colorKeywords = keySet(colorKeywords_);
@@ -589,23 +628,23 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"above", "absolute", "activeborder", "additive", "activecaption", "afar",
"after-white-space", "ahead", "alias", "all", "all-scroll", "alphabetic", "alternate",
"always", "amharic", "amharic-abegede", "antialiased", "appworkspace",
- "arabic-indic", "armenian", "asterisks", "attr", "auto", "avoid", "avoid-column", "avoid-page",
- "avoid-region", "background", "backwards", "baseline", "below", "bidi-override", "binary",
- "bengali", "blink", "block", "block-axis", "bold", "bolder", "border", "border-box",
- "both", "bottom", "break", "break-all", "break-word", "bullets", "button", "button-bevel",
+ "arabic-indic", "armenian", "asterisks", "attr", "auto", "auto-flow", "avoid", "avoid-column", "avoid-page",
+ "avoid-region", "axis-pan", "background", "backwards", "baseline", "below", "bidi-override", "binary",
+ "bengali", "blink", "block", "block-axis", "blur", "bold", "bolder", "border", "border-box",
+ "both", "bottom", "break", "break-all", "break-word", "brightness", "bullets", "button",
"buttonface", "buttonhighlight", "buttonshadow", "buttontext", "calc", "cambodian",
"capitalize", "caps-lock-indicator", "caption", "captiontext", "caret",
"cell", "center", "checkbox", "circle", "cjk-decimal", "cjk-earthly-branch",
"cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote",
"col-resize", "collapse", "color", "color-burn", "color-dodge", "column", "column-reverse",
- "compact", "condensed", "contain", "content",
- "content-box", "context-menu", "continuous", "copy", "counter", "counters", "cover", "crop",
- "cross", "crosshair", "currentcolor", "cursive", "cyclic", "darken", "dashed", "decimal",
- "decimal-leading-zero", "default", "default-button", "destination-atop",
+ "compact", "condensed", "conic-gradient", "contain", "content", "contents",
+ "content-box", "context-menu", "continuous", "contrast", "copy", "counter", "counters", "cover", "crop",
+ "cross", "crosshair", "cubic-bezier", "currentcolor", "cursive", "cyclic", "darken", "dashed", "decimal",
+ "decimal-leading-zero", "default", "default-button", "dense", "destination-atop",
"destination-in", "destination-out", "destination-over", "devanagari", "difference",
"disc", "discard", "disclosure-closed", "disclosure-open", "document",
"dot-dash", "dot-dot-dash",
- "dotted", "double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out",
+ "dotted", "double", "down", "drop-shadow", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out",
"element", "ellipse", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede",
"ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er",
"ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er",
@@ -614,14 +653,14 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"ethiopic-halehame-sid-et", "ethiopic-halehame-so-et",
"ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et", "ethiopic-halehame-tig",
"ethiopic-numeric", "ew-resize", "exclusion", "expanded", "extends", "extra-condensed",
- "extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "flex", "flex-end", "flex-start", "footnotes",
- "forwards", "from", "geometricPrecision", "georgian", "graytext", "groove",
+ "extra-expanded", "fantasy", "fast", "fill", "fill-box", "fixed", "flat", "flex", "flex-end", "flex-start", "footnotes",
+ "forwards", "from", "geometricPrecision", "georgian", "grayscale", "graytext", "grid", "groove",
"gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hard-light", "hebrew",
"help", "hidden", "hide", "higher", "highlight", "highlighttext",
- "hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "hue", "icon", "ignore",
+ "hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "hue", "hue-rotate", "icon", "ignore",
"inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite",
"infobackground", "infotext", "inherit", "initial", "inline", "inline-axis",
- "inline-block", "inline-flex", "inline-table", "inset", "inside", "intrinsic", "invert",
+ "inline-block", "inline-flex", "inline-grid", "inline-table", "inset", "inside", "intrinsic", "invert",
"italic", "japanese-formal", "japanese-informal", "justify", "kannada",
"katakana", "katakana-iroha", "keep-all", "khmer",
"korean-hangul-formal", "korean-hanja-formal", "korean-hanja-informal",
@@ -629,41 +668,37 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"line-through", "linear", "linear-gradient", "lines", "list-item", "listbox", "listitem",
"local", "logical", "loud", "lower", "lower-alpha", "lower-armenian",
"lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian",
- "lower-roman", "lowercase", "ltr", "luminosity", "malayalam", "match", "matrix", "matrix3d",
- "media-controls-background", "media-current-time-display",
- "media-fullscreen-button", "media-mute-button", "media-play-button",
- "media-return-to-realtime-button", "media-rewind-button",
- "media-seek-back-button", "media-seek-forward-button", "media-slider",
- "media-sliderthumb", "media-time-remaining-display", "media-volume-slider",
- "media-volume-slider-container", "media-volume-sliderthumb", "medium",
- "menu", "menulist", "menulist-button", "menulist-text",
- "menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic",
- "mix", "mongolian", "monospace", "move", "multiple", "multiply", "myanmar", "n-resize",
+ "lower-roman", "lowercase", "ltr", "luminosity", "malayalam", "manipulation", "match", "matrix", "matrix3d",
+ "media-play-button", "media-slider", "media-sliderthumb",
+ "media-volume-slider", "media-volume-sliderthumb", "medium",
+ "menu", "menulist", "menulist-button",
+ "menutext", "message-box", "middle", "min-intrinsic",
+ "mix", "mongolian", "monospace", "move", "multiple", "multiple_mask_images", "multiply", "myanmar", "n-resize",
"narrower", "ne-resize", "nesw-resize", "no-close-quote", "no-drop",
"no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap",
- "ns-resize", "numbers", "numeric", "nw-resize", "nwse-resize", "oblique", "octal", "open-quote",
+ "ns-resize", "numbers", "numeric", "nw-resize", "nwse-resize", "oblique", "octal", "opacity", "open-quote",
"optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset",
"outside", "outside-shape", "overlay", "overline", "padding", "padding-box",
- "painted", "page", "paused", "persian", "perspective", "plus-darker", "plus-lighter",
+ "painted", "page", "paused", "persian", "perspective", "pinch-zoom", "plus-darker", "plus-lighter",
"pointer", "polygon", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d",
"progress", "push-button", "radial-gradient", "radio", "read-only",
"read-write", "read-write-plaintext-only", "rectangle", "region",
- "relative", "repeat", "repeating-linear-gradient",
- "repeating-radial-gradient", "repeat-x", "repeat-y", "reset", "reverse",
+ "relative", "repeat", "repeating-linear-gradient", "repeating-radial-gradient",
+ "repeating-conic-gradient", "repeat-x", "repeat-y", "reset", "reverse",
"rgb", "rgba", "ridge", "right", "rotate", "rotate3d", "rotateX", "rotateY",
"rotateZ", "round", "row", "row-resize", "row-reverse", "rtl", "run-in", "running",
- "s-resize", "sans-serif", "saturation", "scale", "scale3d", "scaleX", "scaleY", "scaleZ", "screen",
- "scroll", "scrollbar", "se-resize", "searchfield",
+ "s-resize", "sans-serif", "saturate", "saturation", "scale", "scale3d", "scaleX", "scaleY", "scaleZ", "screen",
+ "scroll", "scrollbar", "scroll-position", "se-resize", "searchfield",
"searchfield-cancel-button", "searchfield-decoration",
- "searchfield-results-button", "searchfield-results-decoration",
- "semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama",
+ "searchfield-results-button", "searchfield-results-decoration", "self-start", "self-end",
+ "semi-condensed", "semi-expanded", "separate", "sepia", "serif", "show", "sidama",
"simp-chinese-formal", "simp-chinese-informal", "single",
"skew", "skewX", "skewY", "skip-white-space", "slide", "slider-horizontal",
"slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow",
"small", "small-caps", "small-caption", "smaller", "soft-light", "solid", "somali",
- "source-atop", "source-in", "source-out", "source-over", "space", "space-around", "space-between", "spell-out", "square",
- "square-button", "start", "static", "status-bar", "stretch", "stroke", "sub",
- "subpixel-antialiased", "super", "sw-resize", "symbolic", "symbols", "table",
+ "source-atop", "source-in", "source-out", "source-over", "space", "space-around", "space-between", "space-evenly", "spell-out", "square",
+ "square-button", "start", "static", "status-bar", "stretch", "stroke", "stroke-box", "sub",
+ "subpixel-antialiased", "svg_masks", "super", "sw-resize", "symbolic", "symbols", "system-ui", "table",
"table-caption", "table-cell", "table-column", "table-column-group",
"table-footer-group", "table-header-group", "table-row", "table-row-group",
"tamil",
@@ -671,12 +706,12 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"thick", "thin", "threeddarkshadow", "threedface", "threedhighlight",
"threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er",
"tigrinya-er-abegede", "tigrinya-et", "tigrinya-et-abegede", "to", "top",
- "trad-chinese-formal", "trad-chinese-informal",
+ "trad-chinese-formal", "trad-chinese-informal", "transform",
"translate", "translate3d", "translateX", "translateY", "translateZ",
- "transparent", "ultra-condensed", "ultra-expanded", "underline", "up",
+ "transparent", "ultra-condensed", "ultra-expanded", "underline", "unidirectional-pan", "unset", "up",
"upper-alpha", "upper-armenian", "upper-greek", "upper-hexadecimal",
"upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url",
- "var", "vertical", "vertical-text", "visible", "visibleFill", "visiblePainted",
+ "var", "vertical", "vertical-text", "view-box", "visible", "visibleFill", "visiblePainted",
"visibleStroke", "visual", "w-resize", "wait", "wave", "wider",
"window", "windowframe", "windowtext", "words", "wrap", "wrap-reverse", "x-large", "x-small", "xor",
"xx-large", "xx-small"
@@ -730,6 +765,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
valueKeywords: valueKeywords,
fontProperties: fontProperties,
allowNested: true,
+ lineComment: "//",
tokenHooks: {
"/": function(stream, state) {
if (stream.eat("/")) {
@@ -743,8 +779,8 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
}
},
":": function(stream) {
- if (stream.match(/\s*\{/))
- return [null, "{"];
+ if (stream.match(/^\s*\{/, false))
+ return [null, null]
return false;
},
"$": function(stream) {
@@ -772,6 +808,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
valueKeywords: valueKeywords,
fontProperties: fontProperties,
allowNested: true,
+ lineComment: "//",
tokenHooks: {
"/": function(stream, state) {
if (stream.eat("/")) {
@@ -786,7 +823,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
},
"@": function(stream) {
if (stream.eat("{")) return [null, "interpolation"];
- if (stream.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/, false)) return false;
+ if (stream.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/i, false)) return false;
stream.eatWhile(/[\w\\\-]/);
if (stream.match(/^\s*:/, false))
return ["variable-2", "variable-definition"];
diff --git a/src/lib/codemirror/mode/css/gss.html b/src/lib/codemirror/mode/css/gss.html
deleted file mode 100644
index 232fe8c..0000000
--- a/src/lib/codemirror/mode/css/gss.html
+++ /dev/null
@@ -1,103 +0,0 @@
-
-
-
CodeMirror: Closure Stylesheets (GSS) mode
-
-
-
-
-
-
-
-
-
-
-
-
-
-Closure Stylesheets (GSS) mode
-
-
-
- A mode for Closure Stylesheets (GSS).
- MIME type defined: text/x-gss
.
-
- Parsing/Highlighting Tests: normal, verbose.
-
-
diff --git a/src/lib/codemirror/mode/css/gss_test.js b/src/lib/codemirror/mode/css/gss_test.js
deleted file mode 100644
index d56e592..0000000
--- a/src/lib/codemirror/mode/css/gss_test.js
+++ /dev/null
@@ -1,17 +0,0 @@
-// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
-
-(function() {
- "use strict";
-
- var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-gss");
- function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), "gss"); }
-
- MT("atComponent",
- "[def @component] {",
- "[tag foo] {",
- " [property color]: [keyword black];",
- "}",
- "}");
-
-})();
diff --git a/src/lib/codemirror/mode/css/less.html b/src/lib/codemirror/mode/css/less.html
deleted file mode 100644
index adf7427..0000000
--- a/src/lib/codemirror/mode/css/less.html
+++ /dev/null
@@ -1,152 +0,0 @@
-
-
-CodeMirror: LESS mode
-
-
-
-
-
-
-
-
-
-
-
-LESS mode
-
-
-
- The LESS mode is a sub-mode of the CSS mode (defined in css.js
).
-
- Parsing/Highlighting Tests: normal, verbose.
-
diff --git a/src/lib/codemirror/mode/css/scss.html b/src/lib/codemirror/mode/css/scss.html
deleted file mode 100644
index f8e4d37..0000000
--- a/src/lib/codemirror/mode/css/scss.html
+++ /dev/null
@@ -1,157 +0,0 @@
-
-
-CodeMirror: SCSS mode
-
-
-
-
-
-
-
-
-
-
-SCSS mode
-
-
-
- The SCSS mode is a sub-mode of the CSS mode (defined in css.js
).
-
- Parsing/Highlighting Tests: normal, verbose.
-
-
diff --git a/src/lib/codemirror/mode/haml/haml.js b/src/lib/codemirror/mode/haml/haml.js
index 86def73..5e5091f 100644
--- a/src/lib/codemirror/mode/haml/haml.js
+++ b/src/lib/codemirror/mode/haml/haml.js
@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
+// Distributed under an MIT license: https://codemirror.net/5/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
@@ -72,7 +72,7 @@
}
}
- // donot handle --> as valid ruby, make it HTML close comment instead
+ // do not handle --> as valid ruby, make it HTML close comment instead
if (state.startOfLine && !stream.match("-->", false) && (ch == "=" || ch == "-" )) {
state.tokenize = ruby;
return state.tokenize(stream, state);
@@ -98,8 +98,8 @@
return {
// default to html mode
startState: function() {
- var htmlState = htmlMode.startState();
- var rubyState = rubyMode.startState();
+ var htmlState = CodeMirror.startState(htmlMode);
+ var rubyState = CodeMirror.startState(rubyMode);
return {
htmlState: htmlState,
rubyState: rubyState,
diff --git a/src/lib/codemirror/mode/htmlembedded/htmlembedded.js b/src/lib/codemirror/mode/htmlembedded/htmlembedded.js
index 464dc57..5cceeef 100644
--- a/src/lib/codemirror/mode/htmlembedded/htmlembedded.js
+++ b/src/lib/codemirror/mode/htmlembedded/htmlembedded.js
@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
+// Distributed under an MIT license: https://codemirror.net/5/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
@@ -14,7 +14,16 @@
"use strict";
CodeMirror.defineMode("htmlembedded", function(config, parserConfig) {
+ var closeComment = parserConfig.closeComment || "--%>"
return CodeMirror.multiplexingMode(CodeMirror.getMode(config, "htmlmixed"), {
+ open: parserConfig.openComment || "<%--",
+ close: closeComment,
+ delimStyle: "comment",
+ mode: {token: function(stream) {
+ stream.skipTo(closeComment) || stream.skipToEnd()
+ return "comment"
+ }}
+ }, {
open: parserConfig.open || parserConfig.scriptStartRegex || "<%",
close: parserConfig.close || parserConfig.scriptEndRegex || "%>",
mode: CodeMirror.getMode(config, parserConfig.scriptingModeSpec)
diff --git a/src/lib/codemirror/mode/htmlmixed/htmlmixed.js b/src/lib/codemirror/mode/htmlmixed/htmlmixed.js
index 6574fbd..3f6d8b7 100644
--- a/src/lib/codemirror/mode/htmlmixed/htmlmixed.js
+++ b/src/lib/codemirror/mode/htmlmixed/htmlmixed.js
@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
+// Distributed under an MIT license: https://codemirror.net/5/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
@@ -14,7 +14,7 @@
var defaultTags = {
script: [
["lang", /(javascript|babel)/i, "javascript"],
- ["type", /^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^$/i, "javascript"],
+ ["type", /^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^module$|^$/i, "javascript"],
["type", /./, "text/plain"],
[null, null, "javascript"]
],
@@ -46,11 +46,11 @@
function getAttrValue(text, attr) {
var match = text.match(getAttrRegexp(attr))
- return match ? match[2] : ""
+ return match ? /^\s*(.*?)\s*$/.exec(match[2])[1] : ""
}
function getTagRegexp(tagName, anchored) {
- return new RegExp((anchored ? "^" : "") + "<\/\s*" + tagName + "\s*>", "i");
+ return new RegExp((anchored ? "^" : "") + "<\/\\s*" + tagName + "\\s*>", "i");
}
function addTags(from, to) {
@@ -74,7 +74,8 @@
name: "xml",
htmlMode: true,
multilineTagIndentFactor: parserConfig.multilineTagIndentFactor,
- multilineTagIndentPastTag: parserConfig.multilineTagIndentPastTag
+ multilineTagIndentPastTag: parserConfig.multilineTagIndentPastTag,
+ allowMissingTagName: parserConfig.allowMissingTagName,
});
var tags = {};
@@ -105,7 +106,7 @@
return maybeBackup(stream, endTag, state.localMode.token(stream, state.localState));
};
state.localMode = mode;
- state.localState = CodeMirror.startState(mode, htmlMode.indent(state.htmlState, ""));
+ state.localState = CodeMirror.startState(mode, htmlMode.indent(state.htmlState, "", ""));
} else if (state.inTag) {
state.inTag += stream.current()
if (stream.eol()) state.inTag += " "
@@ -115,7 +116,7 @@
return {
startState: function () {
- var state = htmlMode.startState();
+ var state = CodeMirror.startState(htmlMode);
return {token: html, inTag: null, localMode: null, localState: null, htmlState: state};
},
@@ -133,11 +134,11 @@
return state.token(stream, state);
},
- indent: function (state, textAfter) {
+ indent: function (state, textAfter, line) {
if (!state.localMode || /^\s*<\//.test(textAfter))
- return htmlMode.indent(state.htmlState, textAfter);
+ return htmlMode.indent(state.htmlState, textAfter, line);
else if (state.localMode.indent)
- return state.localMode.indent(state.localState, textAfter);
+ return state.localMode.indent(state.localState, textAfter, line);
else
return CodeMirror.Pass;
},
diff --git a/src/lib/codemirror/mode/javascript/javascript.js b/src/lib/codemirror/mode/javascript/javascript.js
index fa5721d..bb735eb 100644
--- a/src/lib/codemirror/mode/javascript/javascript.js
+++ b/src/lib/codemirror/mode/javascript/javascript.js
@@ -1,7 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
-
-// TODO actually recognize syntax of TypeScript constructs
+// Distributed under an MIT license: https://codemirror.net/5/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
@@ -13,16 +11,12 @@
})(function(CodeMirror) {
"use strict";
-function expressionAllowed(stream, state, backUp) {
- return /^(?:operator|sof|keyword c|case|new|[\[{}\(,;:]|=>)$/.test(state.lastType) ||
- (state.lastType == "quasi" && /\{\s*$/.test(stream.string.slice(0, stream.pos - (backUp || 0))))
-}
-
CodeMirror.defineMode("javascript", function(config, parserConfig) {
var indentUnit = config.indentUnit;
var statementIndent = parserConfig.statementIndent;
var jsonldMode = parserConfig.jsonld;
var jsonMode = parserConfig.json || jsonldMode;
+ var trackScope = parserConfig.trackScope !== false
var isTS = parserConfig.typescript;
var wordRE = parserConfig.wordCharacters || /[\w$\xa1-\uffff]/;
@@ -30,54 +24,24 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
var keywords = function(){
function kw(type) {return {type: type, style: "keyword"};}
- var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
+ var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c"), D = kw("keyword d");
var operator = kw("operator"), atom = {type: "atom", style: "atom"};
- var jsKeywords = {
+ return {
"if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
- "return": C, "break": C, "continue": C, "new": kw("new"), "delete": C, "throw": C, "debugger": C,
- "var": kw("var"), "const": kw("var"), "let": kw("var"),
+ "return": D, "break": D, "continue": D, "new": kw("new"), "delete": C, "void": C, "throw": C,
+ "debugger": kw("debugger"), "var": kw("var"), "const": kw("var"), "let": kw("var"),
"function": kw("function"), "catch": kw("catch"),
"for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
"in": operator, "typeof": operator, "instanceof": operator,
"true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom,
"this": kw("this"), "class": kw("class"), "super": kw("atom"),
- "yield": C, "export": kw("export"), "import": kw("import"), "extends": C
+ "yield": C, "export": kw("export"), "import": kw("import"), "extends": C,
+ "await": C
};
-
- // Extend the 'normal' keywords with the TypeScript language extensions
- if (isTS) {
- var type = {type: "variable", style: "variable-3"};
- var tsKeywords = {
- // object-like things
- "interface": kw("class"),
- "implements": C,
- "namespace": C,
- "module": kw("module"),
- "enum": kw("module"),
-
- // scope modifiers
- "public": kw("modifier"),
- "private": kw("modifier"),
- "protected": kw("modifier"),
- "abstract": kw("modifier"),
-
- // operators
- "as": operator,
-
- // types
- "string": type, "number": type, "boolean": type, "any": type
- };
-
- for (var attr in tsKeywords) {
- jsKeywords[attr] = tsKeywords[attr];
- }
- }
-
- return jsKeywords;
}();
- var isOperatorChar = /[+\-*&%=<>!?|~^]/;
+ var isOperatorChar = /[+\-*&%=<>!?|~^@]/;
var isJsonldKeyword = /^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/;
function readRegexp(stream) {
@@ -104,7 +68,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (ch == '"' || ch == "'") {
state.tokenize = tokenString(ch);
return state.tokenize(stream, state);
- } else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) {
+ } else if (ch == "." && stream.match(/^\d[\d_]*(?:[eE][+\-]?[\d_]+)?/)) {
return ret("number", "number");
} else if (ch == "." && stream.match("..")) {
return ret("spread", "meta");
@@ -112,17 +76,10 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
return ret(ch);
} else if (ch == "=" && stream.eat(">")) {
return ret("=>", "operator");
- } else if (ch == "0" && stream.eat(/x/i)) {
- stream.eatWhile(/[\da-f]/i);
- return ret("number", "number");
- } else if (ch == "0" && stream.eat(/o/i)) {
- stream.eatWhile(/[0-7]/i);
- return ret("number", "number");
- } else if (ch == "0" && stream.eat(/b/i)) {
- stream.eatWhile(/[01]/i);
+ } else if (ch == "0" && stream.match(/^(?:x[\dA-Fa-f_]+|o[0-7_]+|b[01_]+)n?/)) {
return ret("number", "number");
} else if (/\d/.test(ch)) {
- stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
+ stream.match(/^[\d_]*(?:n|(?:\.[\d_]*)?(?:[eE][+\-]?[\d_]+)?)?/);
return ret("number", "number");
} else if (ch == "/") {
if (stream.eat("*")) {
@@ -133,26 +90,47 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
return ret("comment", "comment");
} else if (expressionAllowed(stream, state, 1)) {
readRegexp(stream);
- stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/);
+ stream.match(/^\b(([gimyus])(?![gimyus]*\2))+\b/);
return ret("regexp", "string-2");
} else {
- stream.eatWhile(isOperatorChar);
+ stream.eat("=");
return ret("operator", "operator", stream.current());
}
} else if (ch == "`") {
state.tokenize = tokenQuasi;
return tokenQuasi(stream, state);
- } else if (ch == "#") {
+ } else if (ch == "#" && stream.peek() == "!") {
stream.skipToEnd();
- return ret("error", "error");
+ return ret("meta", "meta");
+ } else if (ch == "#" && stream.eatWhile(wordRE)) {
+ return ret("variable", "property")
+ } else if (ch == "<" && stream.match("!--") ||
+ (ch == "-" && stream.match("->") && !/\S/.test(stream.string.slice(0, stream.start)))) {
+ stream.skipToEnd()
+ return ret("comment", "comment")
} else if (isOperatorChar.test(ch)) {
- stream.eatWhile(isOperatorChar);
+ if (ch != ">" || !state.lexical || state.lexical.type != ">") {
+ if (stream.eat("=")) {
+ if (ch == "!" || ch == "=") stream.eat("=")
+ } else if (/[<>*+\-|&?]/.test(ch)) {
+ stream.eat(ch)
+ if (ch == ">") stream.eat(ch)
+ }
+ }
+ if (ch == "?" && stream.eat(".")) return ret(".")
return ret("operator", "operator", stream.current());
} else if (wordRE.test(ch)) {
stream.eatWhile(wordRE);
- var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
- return (known && state.lastType != ".") ? ret(known.type, known.style, word) :
- ret("variable", "variable", word);
+ var word = stream.current()
+ if (state.lastType != ".") {
+ if (keywords.propertyIsEnumerable(word)) {
+ var kw = keywords[word]
+ return ret(kw.type, kw.style, word)
+ }
+ if (word == "async" && stream.match(/^(\s|\/\*([^*]|\*(?!\/))*?\*\/)*[\[\(\w]/, false))
+ return ret("async", "keyword", word)
+ }
+ return ret("variable", "variable", word)
}
}
@@ -209,19 +187,28 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
var arrow = stream.string.indexOf("=>", stream.start);
if (arrow < 0) return;
+ if (isTS) { // Try to skip TypeScript return type declarations after the arguments
+ var m = /:\s*(?:\w+(?:<[^>]*>|\[\])?|\{[^}]*\})\s*$/.exec(stream.string.slice(stream.start, arrow))
+ if (m) arrow = m.index
+ }
+
var depth = 0, sawSomething = false;
for (var pos = arrow - 1; pos >= 0; --pos) {
var ch = stream.string.charAt(pos);
var bracket = brackets.indexOf(ch);
if (bracket >= 0 && bracket < 3) {
if (!depth) { ++pos; break; }
- if (--depth == 0) break;
+ if (--depth == 0) { if (ch == "(") sawSomething = true; break; }
} else if (bracket >= 3 && bracket < 6) {
++depth;
} else if (wordRE.test(ch)) {
sawSomething = true;
- } else if (/["'\/]/.test(ch)) {
- return;
+ } else if (/["'\/`]/.test(ch)) {
+ for (;; --pos) {
+ if (pos == 0) return
+ var next = stream.string.charAt(pos - 1)
+ if (next == ch && stream.string.charAt(pos - 2) != "\\") { pos--; break }
+ }
} else if (sawSomething && !depth) {
++pos;
break;
@@ -232,7 +219,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
// Parser
- var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true, "jsonld-keyword": true};
+ var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true,
+ "regexp": true, "this": true, "import": true, "jsonld-keyword": true};
function JSLexical(indented, column, type, align, prev, info) {
this.indented = indented;
@@ -244,6 +232,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
}
function inScope(state, varname) {
+ if (!trackScope) return false
for (var v = state.localVars; v; v = v.next)
if (v.name == varname) return true;
for (var cx = state.context; cx; cx = cx.prev) {
@@ -283,35 +272,70 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
pass.apply(null, arguments);
return true;
}
+ function inList(name, list) {
+ for (var v = list; v; v = v.next) if (v.name == name) return true
+ return false;
+ }
function register(varname) {
- function inList(list) {
- for (var v = list; v; v = v.next)
- if (v.name == varname) return true;
- return false;
- }
var state = cx.state;
cx.marked = "def";
+ if (!trackScope) return
if (state.context) {
- if (inList(state.localVars)) return;
- state.localVars = {name: varname, next: state.localVars};
- } else {
- if (inList(state.globalVars)) return;
- if (parserConfig.globalVars)
- state.globalVars = {name: varname, next: state.globalVars};
+ if (state.lexical.info == "var" && state.context && state.context.block) {
+ // FIXME function decls are also not block scoped
+ var newContext = registerVarScoped(varname, state.context)
+ if (newContext != null) {
+ state.context = newContext
+ return
+ }
+ } else if (!inList(varname, state.localVars)) {
+ state.localVars = new Var(varname, state.localVars)
+ return
+ }
}
+ // Fall through means this is global
+ if (parserConfig.globalVars && !inList(varname, state.globalVars))
+ state.globalVars = new Var(varname, state.globalVars)
+ }
+ function registerVarScoped(varname, context) {
+ if (!context) {
+ return null
+ } else if (context.block) {
+ var inner = registerVarScoped(varname, context.prev)
+ if (!inner) return null
+ if (inner == context.prev) return context
+ return new Context(inner, context.vars, true)
+ } else if (inList(varname, context.vars)) {
+ return context
+ } else {
+ return new Context(context.prev, new Var(varname, context.vars), false)
+ }
+ }
+
+ function isModifier(name) {
+ return name == "public" || name == "private" || name == "protected" || name == "abstract" || name == "readonly"
}
// Combinators
- var defaultVars = {name: "this", next: {name: "arguments"}};
+ function Context(prev, vars, block) { this.prev = prev; this.vars = vars; this.block = block }
+ function Var(name, next) { this.name = name; this.next = next }
+
+ var defaultVars = new Var("this", new Var("arguments", null))
function pushcontext() {
- cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
- cx.state.localVars = defaultVars;
+ cx.state.context = new Context(cx.state.context, cx.state.localVars, false)
+ cx.state.localVars = defaultVars
}
+ function pushblockcontext() {
+ cx.state.context = new Context(cx.state.context, cx.state.localVars, true)
+ cx.state.localVars = null
+ }
+ pushcontext.lex = pushblockcontext.lex = true
function popcontext() {
- cx.state.localVars = cx.state.context.vars;
- cx.state.context = cx.state.context.prev;
+ cx.state.localVars = cx.state.context.vars
+ cx.state.context = cx.state.context.prev
}
+ popcontext.lex = true
function pushlex(type, info) {
var result = function() {
var state = cx.state, indent = state.indented;
@@ -336,56 +360,87 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
function expect(wanted) {
function exp(type) {
if (type == wanted) return cont();
- else if (wanted == ";") return pass();
+ else if (wanted == ";" || type == "}" || type == ")" || type == "]") return pass();
else return cont(exp);
};
return exp;
}
function statement(type, value) {
- if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex);
- if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex);
+ if (type == "var") return cont(pushlex("vardef", value), vardef, expect(";"), poplex);
+ if (type == "keyword a") return cont(pushlex("form"), parenExpr, statement, poplex);
if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
- if (type == "{") return cont(pushlex("}"), block, poplex);
+ if (type == "keyword d") return cx.stream.match(/^\s*$/, false) ? cont() : cont(pushlex("stat"), maybeexpression, expect(";"), poplex);
+ if (type == "debugger") return cont(expect(";"));
+ if (type == "{") return cont(pushlex("}"), pushblockcontext, block, poplex, popcontext);
if (type == ";") return cont();
if (type == "if") {
if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1] == poplex)
cx.state.cc.pop()();
- return cont(pushlex("form"), expression, statement, poplex, maybeelse);
+ return cont(pushlex("form"), parenExpr, statement, poplex, maybeelse);
}
if (type == "function") return cont(functiondef);
- if (type == "for") return cont(pushlex("form"), forspec, statement, poplex);
- if (type == "variable") return cont(pushlex("stat"), maybelabel);
- if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
- block, poplex, poplex);
+ if (type == "for") return cont(pushlex("form"), pushblockcontext, forspec, statement, popcontext, poplex);
+ if (type == "class" || (isTS && value == "interface")) {
+ cx.marked = "keyword"
+ return cont(pushlex("form", type == "class" ? type : value), className, poplex)
+ }
+ if (type == "variable") {
+ if (isTS && value == "declare") {
+ cx.marked = "keyword"
+ return cont(statement)
+ } else if (isTS && (value == "module" || value == "enum" || value == "type") && cx.stream.match(/^\s*\w/, false)) {
+ cx.marked = "keyword"
+ if (value == "enum") return cont(enumdef);
+ else if (value == "type") return cont(typename, expect("operator"), typeexpr, expect(";"));
+ else return cont(pushlex("form"), pattern, expect("{"), pushlex("}"), block, poplex, poplex)
+ } else if (isTS && value == "namespace") {
+ cx.marked = "keyword"
+ return cont(pushlex("form"), expression, statement, poplex)
+ } else if (isTS && value == "abstract") {
+ cx.marked = "keyword"
+ return cont(statement)
+ } else {
+ return cont(pushlex("stat"), maybelabel);
+ }
+ }
+ if (type == "switch") return cont(pushlex("form"), parenExpr, expect("{"), pushlex("}", "switch"), pushblockcontext,
+ block, poplex, poplex, popcontext);
if (type == "case") return cont(expression, expect(":"));
if (type == "default") return cont(expect(":"));
- if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
- statement, poplex, popcontext);
- if (type == "class") return cont(pushlex("form"), className, poplex);
+ if (type == "catch") return cont(pushlex("form"), pushcontext, maybeCatchBinding, statement, poplex, popcontext);
if (type == "export") return cont(pushlex("stat"), afterExport, poplex);
if (type == "import") return cont(pushlex("stat"), afterImport, poplex);
- if (type == "module") return cont(pushlex("form"), pattern, pushlex("}"), expect("{"), block, poplex, poplex)
+ if (type == "async") return cont(statement)
+ if (value == "@") return cont(expression, statement)
return pass(pushlex("stat"), expression, expect(";"), poplex);
}
- function expression(type) {
- return expressionInner(type, false);
+ function maybeCatchBinding(type) {
+ if (type == "(") return cont(funarg, expect(")"))
}
- function expressionNoComma(type) {
- return expressionInner(type, true);
+ function expression(type, value) {
+ return expressionInner(type, value, false);
}
- function expressionInner(type, noComma) {
+ function expressionNoComma(type, value) {
+ return expressionInner(type, value, true);
+ }
+ function parenExpr(type) {
+ if (type != "(") return pass()
+ return cont(pushlex(")"), maybeexpression, expect(")"), poplex)
+ }
+ function expressionInner(type, value, noComma) {
if (cx.state.fatArrowAt == cx.stream.start) {
var body = noComma ? arrowBodyNoComma : arrowBody;
- if (type == "(") return cont(pushcontext, pushlex(")"), commasep(pattern, ")"), poplex, expect("=>"), body, popcontext);
+ if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, expect("=>"), body, popcontext);
else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext);
}
var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;
if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
if (type == "function") return cont(functiondef, maybeop);
- if (type == "keyword c") return cont(noComma ? maybeexpressionNoComma : maybeexpression);
- if (type == "(") return cont(pushlex(")"), maybeexpression, comprehension, expect(")"), poplex, maybeop);
+ if (type == "class" || (isTS && value == "interface")) { cx.marked = "keyword"; return cont(pushlex("form"), classExpression, poplex); }
+ if (type == "keyword c" || type == "async") return cont(noComma ? expressionNoComma : expression);
+ if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeop);
if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression);
if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop);
if (type == "{") return contCommasep(objprop, "}", null, maybeop);
@@ -397,13 +452,9 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (type.match(/[;\}\)\],]/)) return pass();
return pass(expression);
}
- function maybeexpressionNoComma(type) {
- if (type.match(/[;\}\)\],]/)) return pass();
- return pass(expressionNoComma);
- }
function maybeoperatorComma(type, value) {
- if (type == ",") return cont(expression);
+ if (type == ",") return cont(maybeexpression);
return maybeoperatorNoComma(type, value, false);
}
function maybeoperatorNoComma(type, value, noComma) {
@@ -411,7 +462,9 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
var expr = noComma == false ? expression : expressionNoComma;
if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext);
if (type == "operator") {
- if (/\+\+|--/.test(value)) return cont(me);
+ if (/\+\+|--/.test(value) || isTS && value == "!") return cont(me);
+ if (isTS && value == "<" && cx.stream.match(/^([^<>]|<[^<>]*>)*>\s*\(/, false))
+ return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, me);
if (value == "?") return cont(expression, expect(":"), expr);
return cont(expr);
}
@@ -420,11 +473,17 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (type == "(") return contCommasep(expressionNoComma, ")", "call", me);
if (type == ".") return cont(property, me);
if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me);
+ if (isTS && value == "as") { cx.marked = "keyword"; return cont(typeexpr, me) }
+ if (type == "regexp") {
+ cx.state.lastType = cx.marked = "operator"
+ cx.stream.backUp(cx.stream.pos - cx.stream.start - 1)
+ return cont(expr)
+ }
}
function quasi(type, value) {
if (type != "quasi") return pass();
if (value.slice(value.length - 2) != "${") return cont(quasi);
- return cont(expression, continueQuasi);
+ return cont(maybeexpression, continueQuasi);
}
function continueQuasi(type) {
if (type == "}") {
@@ -444,6 +503,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
function maybeTarget(noComma) {
return function(type) {
if (type == ".") return cont(noComma ? targetNoComma : target);
+ else if (type == "variable" && isTS) return cont(maybeTypeArgs, noComma ? maybeoperatorNoComma : maybeoperatorComma)
else return pass(noComma ? expressionNoComma : expression);
};
}
@@ -461,21 +521,33 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (type == "variable") {cx.marked = "property"; return cont();}
}
function objprop(type, value) {
- if (type == "variable" || cx.style == "keyword") {
+ if (type == "async") {
+ cx.marked = "property";
+ return cont(objprop);
+ } else if (type == "variable" || cx.style == "keyword") {
cx.marked = "property";
if (value == "get" || value == "set") return cont(getterSetter);
+ var m // Work around fat-arrow-detection complication for detecting typescript typed arrow params
+ if (isTS && cx.state.fatArrowAt == cx.stream.start && (m = cx.stream.match(/^\s*:\s*/, false)))
+ cx.state.fatArrowAt = cx.stream.pos + m[0].length
return cont(afterprop);
} else if (type == "number" || type == "string") {
cx.marked = jsonldMode ? "property" : (cx.style + " property");
return cont(afterprop);
} else if (type == "jsonld-keyword") {
return cont(afterprop);
- } else if (type == "modifier") {
+ } else if (isTS && isModifier(value)) {
+ cx.marked = "keyword"
return cont(objprop)
} else if (type == "[") {
- return cont(expression, expect("]"), afterprop);
+ return cont(expression, maybetype, expect("]"), afterprop);
} else if (type == "spread") {
- return cont(expression);
+ return cont(expressionNoComma, afterprop);
+ } else if (value == "*") {
+ cx.marked = "keyword";
+ return cont(objprop);
+ } else if (type == ":") {
+ return pass(afterprop)
}
}
function getterSetter(type) {
@@ -487,18 +559,22 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (type == ":") return cont(expressionNoComma);
if (type == "(") return pass(functiondef);
}
- function commasep(what, end) {
- function proceed(type) {
- if (type == ",") {
+ function commasep(what, end, sep) {
+ function proceed(type, value) {
+ if (sep ? sep.indexOf(type) > -1 : type == ",") {
var lex = cx.state.lexical;
if (lex.info == "call") lex.pos = (lex.pos || 0) + 1;
- return cont(what, proceed);
+ return cont(function(type, value) {
+ if (type == end || value == end) return pass()
+ return pass(what)
+ }, proceed);
}
- if (type == end) return cont();
+ if (type == end || value == end) return cont();
+ if (sep && sep.indexOf(";") > -1) return pass(what)
return cont(expect(end));
}
- return function(type) {
- if (type == end) return cont();
+ return function(type, value) {
+ if (type == end || value == end) return cont();
return pass(what, proceed);
};
}
@@ -511,23 +587,111 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (type == "}") return cont();
return pass(statement, block);
}
- function maybetype(type) {
- if (isTS && type == ":") return cont(typedef);
+ function maybetype(type, value) {
+ if (isTS) {
+ if (type == ":") return cont(typeexpr);
+ if (value == "?") return cont(maybetype);
+ }
}
- function maybedefault(_, value) {
- if (value == "=") return cont(expressionNoComma);
+ function maybetypeOrIn(type, value) {
+ if (isTS && (type == ":" || value == "in")) return cont(typeexpr)
}
- function typedef(type) {
- if (type == "variable") {cx.marked = "variable-3"; return cont();}
+ function mayberettype(type) {
+ if (isTS && type == ":") {
+ if (cx.stream.match(/^\s*\w+\s+is\b/, false)) return cont(expression, isKW, typeexpr)
+ else return cont(typeexpr)
+ }
}
- function vardef() {
+ function isKW(_, value) {
+ if (value == "is") {
+ cx.marked = "keyword"
+ return cont()
+ }
+ }
+ function typeexpr(type, value) {
+ if (value == "keyof" || value == "typeof" || value == "infer" || value == "readonly") {
+ cx.marked = "keyword"
+ return cont(value == "typeof" ? expressionNoComma : typeexpr)
+ }
+ if (type == "variable" || value == "void") {
+ cx.marked = "type"
+ return cont(afterType)
+ }
+ if (value == "|" || value == "&") return cont(typeexpr)
+ if (type == "string" || type == "number" || type == "atom") return cont(afterType);
+ if (type == "[") return cont(pushlex("]"), commasep(typeexpr, "]", ","), poplex, afterType)
+ if (type == "{") return cont(pushlex("}"), typeprops, poplex, afterType)
+ if (type == "(") return cont(commasep(typearg, ")"), maybeReturnType, afterType)
+ if (type == "<") return cont(commasep(typeexpr, ">"), typeexpr)
+ if (type == "quasi") { return pass(quasiType, afterType); }
+ }
+ function maybeReturnType(type) {
+ if (type == "=>") return cont(typeexpr)
+ }
+ function typeprops(type) {
+ if (type.match(/[\}\)\]]/)) return cont()
+ if (type == "," || type == ";") return cont(typeprops)
+ return pass(typeprop, typeprops)
+ }
+ function typeprop(type, value) {
+ if (type == "variable" || cx.style == "keyword") {
+ cx.marked = "property"
+ return cont(typeprop)
+ } else if (value == "?" || type == "number" || type == "string") {
+ return cont(typeprop)
+ } else if (type == ":") {
+ return cont(typeexpr)
+ } else if (type == "[") {
+ return cont(expect("variable"), maybetypeOrIn, expect("]"), typeprop)
+ } else if (type == "(") {
+ return pass(functiondecl, typeprop)
+ } else if (!type.match(/[;\}\)\],]/)) {
+ return cont()
+ }
+ }
+ function quasiType(type, value) {
+ if (type != "quasi") return pass();
+ if (value.slice(value.length - 2) != "${") return cont(quasiType);
+ return cont(typeexpr, continueQuasiType);
+ }
+ function continueQuasiType(type) {
+ if (type == "}") {
+ cx.marked = "string-2";
+ cx.state.tokenize = tokenQuasi;
+ return cont(quasiType);
+ }
+ }
+ function typearg(type, value) {
+ if (type == "variable" && cx.stream.match(/^\s*[?:]/, false) || value == "?") return cont(typearg)
+ if (type == ":") return cont(typeexpr)
+ if (type == "spread") return cont(typearg)
+ return pass(typeexpr)
+ }
+ function afterType(type, value) {
+ if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, afterType)
+ if (value == "|" || type == "." || value == "&") return cont(typeexpr)
+ if (type == "[") return cont(typeexpr, expect("]"), afterType)
+ if (value == "extends" || value == "implements") { cx.marked = "keyword"; return cont(typeexpr) }
+ if (value == "?") return cont(typeexpr, expect(":"), typeexpr)
+ }
+ function maybeTypeArgs(_, value) {
+ if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, afterType)
+ }
+ function typeparam() {
+ return pass(typeexpr, maybeTypeDefault)
+ }
+ function maybeTypeDefault(_, value) {
+ if (value == "=") return cont(typeexpr)
+ }
+ function vardef(_, value) {
+ if (value == "enum") {cx.marked = "keyword"; return cont(enumdef)}
return pass(pattern, maybetype, maybeAssign, vardefCont);
}
function pattern(type, value) {
- if (type == "modifier") return cont(pattern)
+ if (isTS && isModifier(value)) { cx.marked = "keyword"; return cont(pattern) }
if (type == "variable") { register(value); return cont(); }
if (type == "spread") return cont(pattern);
- if (type == "[") return contCommasep(pattern, "]");
+ if (type == "[") return contCommasep(eltpattern, "]");
if (type == "{") return contCommasep(proppattern, "}");
}
function proppattern(type, value) {
@@ -538,8 +702,12 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (type == "variable") cx.marked = "property";
if (type == "spread") return cont(pattern);
if (type == "}") return pass();
+ if (type == "[") return cont(expression, expect(']'), expect(':'), proppattern);
return cont(expect(":"), pattern, maybeAssign);
}
+ function eltpattern() {
+ return pass(pattern, maybeAssign)
+ }
function maybeAssign(_type, value) {
if (value == "=") return cont(expressionNoComma);
}
@@ -549,73 +717,111 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
function maybeelse(type, value) {
if (type == "keyword b" && value == "else") return cont(pushlex("form", "else"), statement, poplex);
}
- function forspec(type) {
- if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex);
+ function forspec(type, value) {
+ if (value == "await") return cont(forspec);
+ if (type == "(") return cont(pushlex(")"), forspec1, poplex);
}
function forspec1(type) {
- if (type == "var") return cont(vardef, expect(";"), forspec2);
- if (type == ";") return cont(forspec2);
- if (type == "variable") return cont(formaybeinof);
- return pass(expression, expect(";"), forspec2);
- }
- function formaybeinof(_type, value) {
- if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
- return cont(maybeoperatorComma, forspec2);
+ if (type == "var") return cont(vardef, forspec2);
+ if (type == "variable") return cont(forspec2);
+ return pass(forspec2)
}
function forspec2(type, value) {
- if (type == ";") return cont(forspec3);
- if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
- return pass(expression, expect(";"), forspec3);
- }
- function forspec3(type) {
- if (type != ")") cont(expression);
+ if (type == ")") return cont()
+ if (type == ";") return cont(forspec2)
+ if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression, forspec2) }
+ return pass(expression, forspec2)
}
function functiondef(type, value) {
if (value == "*") {cx.marked = "keyword"; return cont(functiondef);}
if (type == "variable") {register(value); return cont(functiondef);}
- if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, statement, popcontext);
+ if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, mayberettype, statement, popcontext);
+ if (isTS && value == "<") return cont(pushlex(">"), commasep(typeparam, ">"), poplex, functiondef)
}
- function funarg(type) {
+ function functiondecl(type, value) {
+ if (value == "*") {cx.marked = "keyword"; return cont(functiondecl);}
+ if (type == "variable") {register(value); return cont(functiondecl);}
+ if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, mayberettype, popcontext);
+ if (isTS && value == "<") return cont(pushlex(">"), commasep(typeparam, ">"), poplex, functiondecl)
+ }
+ function typename(type, value) {
+ if (type == "keyword" || type == "variable") {
+ cx.marked = "type"
+ return cont(typename)
+ } else if (value == "<") {
+ return cont(pushlex(">"), commasep(typeparam, ">"), poplex)
+ }
+ }
+ function funarg(type, value) {
+ if (value == "@") cont(expression, funarg)
if (type == "spread") return cont(funarg);
- return pass(pattern, maybetype, maybedefault);
+ if (isTS && isModifier(value)) { cx.marked = "keyword"; return cont(funarg); }
+ if (isTS && type == "this") return cont(maybetype, maybeAssign)
+ return pass(pattern, maybetype, maybeAssign);
+ }
+ function classExpression(type, value) {
+ // Class expressions may have an optional name.
+ if (type == "variable") return className(type, value);
+ return classNameAfter(type, value);
}
function className(type, value) {
if (type == "variable") {register(value); return cont(classNameAfter);}
}
function classNameAfter(type, value) {
- if (value == "extends") return cont(expression, classNameAfter);
+ if (value == "<") return cont(pushlex(">"), commasep(typeparam, ">"), poplex, classNameAfter)
+ if (value == "extends" || value == "implements" || (isTS && type == ",")) {
+ if (value == "implements") cx.marked = "keyword";
+ return cont(isTS ? typeexpr : expression, classNameAfter);
+ }
if (type == "{") return cont(pushlex("}"), classBody, poplex);
}
function classBody(type, value) {
- if (type == "variable" || cx.style == "keyword") {
- if (value == "static") {
- cx.marked = "keyword";
- return cont(classBody);
- }
- cx.marked = "property";
- if (value == "get" || value == "set") return cont(classGetterSetter, functiondef, classBody);
- return cont(functiondef, classBody);
+ if (type == "async" ||
+ (type == "variable" &&
+ (value == "static" || value == "get" || value == "set" || (isTS && isModifier(value))) &&
+ cx.stream.match(/^\s+#?[\w$\xa1-\uffff]/, false))) {
+ cx.marked = "keyword";
+ return cont(classBody);
}
+ if (type == "variable" || cx.style == "keyword") {
+ cx.marked = "property";
+ return cont(classfield, classBody);
+ }
+ if (type == "number" || type == "string") return cont(classfield, classBody);
+ if (type == "[")
+ return cont(expression, maybetype, expect("]"), classfield, classBody)
if (value == "*") {
cx.marked = "keyword";
return cont(classBody);
}
- if (type == ";") return cont(classBody);
+ if (isTS && type == "(") return pass(functiondecl, classBody)
+ if (type == ";" || type == ",") return cont(classBody);
if (type == "}") return cont();
+ if (value == "@") return cont(expression, classBody)
}
- function classGetterSetter(type) {
- if (type != "variable") return pass();
- cx.marked = "property";
- return cont();
+ function classfield(type, value) {
+ if (value == "!") return cont(classfield)
+ if (value == "?") return cont(classfield)
+ if (type == ":") return cont(typeexpr, maybeAssign)
+ if (value == "=") return cont(expressionNoComma)
+ var context = cx.state.lexical.prev, isInterface = context && context.info == "interface"
+ return pass(isInterface ? functiondecl : functiondef)
}
- function afterExport(_type, value) {
+ function afterExport(type, value) {
if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); }
if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); }
+ if (type == "{") return cont(commasep(exportField, "}"), maybeFrom, expect(";"));
return pass(statement);
}
+ function exportField(type, value) {
+ if (value == "as") { cx.marked = "keyword"; return cont(expect("variable")); }
+ if (type == "variable") return pass(expressionNoComma, exportField);
+ }
function afterImport(type) {
if (type == "string") return cont();
- return pass(importSpec, maybeFrom);
+ if (type == "(") return pass(expression);
+ if (type == ".") return pass(maybeoperatorComma);
+ return pass(importSpec, maybeMoreImports, maybeFrom);
}
function importSpec(type, value) {
if (type == "{") return contCommasep(importSpec, "}");
@@ -623,6 +829,9 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (value == "*") cx.marked = "keyword";
return cont(maybeAs);
}
+ function maybeMoreImports(type) {
+ if (type == ",") return cont(importSpec, maybeMoreImports)
+ }
function maybeAs(_type, value) {
if (value == "as") { cx.marked = "keyword"; return cont(importSpec); }
}
@@ -631,16 +840,13 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
}
function arrayLiteral(type) {
if (type == "]") return cont();
- return pass(expressionNoComma, maybeArrayComprehension);
- }
- function maybeArrayComprehension(type) {
- if (type == "for") return pass(comprehension, expect("]"));
- if (type == ",") return cont(commasep(maybeexpressionNoComma, "]"));
return pass(commasep(expressionNoComma, "]"));
}
- function comprehension(type) {
- if (type == "for") return cont(forspec, comprehension);
- if (type == "if") return cont(expression, comprehension);
+ function enumdef() {
+ return pass(pushlex("form"), pattern, expect("{"), pushlex("}"), commasep(enummember, "}"), poplex, poplex)
+ }
+ function enummember() {
+ return pass(pattern, maybeAssign);
}
function isContinuedStatement(state, textAfter) {
@@ -649,6 +855,12 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
/[,.]/.test(textAfter.charAt(0));
}
+ function expressionAllowed(stream, state, backUp) {
+ return state.tokenize == tokenBase &&
+ /^(?:operator|sof|keyword [bcd]|case|new|export|default|spread|[\[{}\(,;:]|=>)$/.test(state.lastType) ||
+ (state.lastType == "quasi" && /\{\s*$/.test(stream.string.slice(0, stream.pos - (backUp || 0))))
+ }
+
// Interface
return {
@@ -659,7 +871,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
cc: [],
lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
localVars: parserConfig.localVars,
- context: parserConfig.localVars && {vars: parserConfig.localVars},
+ context: parserConfig.localVars && new Context(null, null, false),
indented: basecolumn || 0
};
if (parserConfig.globalVars && typeof parserConfig.globalVars == "object")
@@ -682,21 +894,25 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
},
indent: function(state, textAfter) {
- if (state.tokenize == tokenComment) return CodeMirror.Pass;
+ if (state.tokenize == tokenComment || state.tokenize == tokenQuasi) return CodeMirror.Pass;
if (state.tokenize != tokenBase) return 0;
- var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical;
+ var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical, top
// Kludge to prevent 'maybelse' from blocking lexical scope pops
if (!/^\s*else\b/.test(textAfter)) for (var i = state.cc.length - 1; i >= 0; --i) {
var c = state.cc[i];
if (c == poplex) lexical = lexical.prev;
- else if (c != maybeelse) break;
+ else if (c != maybeelse && c != popcontext) break;
}
- if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev;
+ while ((lexical.type == "stat" || lexical.type == "form") &&
+ (firstChar == "}" || ((top = state.cc[state.cc.length - 1]) &&
+ (top == maybeoperatorComma || top == maybeoperatorNoComma) &&
+ !/^[,\.=+\-*:?[\(]/.test(textAfter))))
+ lexical = lexical.prev;
if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat")
lexical = lexical.prev;
var type = lexical.type, closing = firstChar == type;
- if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info + 1 : 0);
+ if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info.length + 1 : 0);
else if (type == "form" && firstChar == "{") return lexical.indented;
else if (type == "form") return lexical.indented + indentUnit;
else if (type == "stat")
@@ -710,6 +926,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
electricInput: /^\s*(?:case .*?:|default:|\{|\})$/,
blockCommentStart: jsonMode ? null : "/*",
blockCommentEnd: jsonMode ? null : "*/",
+ blockCommentContinue: jsonMode ? null : " * ",
lineComment: jsonMode ? null : "//",
fold: "brace",
closeBrackets: "()[]{}''\"\"``",
@@ -719,9 +936,9 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
jsonMode: jsonMode,
expressionAllowed: expressionAllowed,
+
skipExpression: function(state) {
- var top = state.cc[state.cc.length - 1]
- if (top == expression || top == expressionNoComma) state.cc.pop()
+ parseJS(state, "atom", "atom", "true", new CodeMirror.StringStream("", 2, null))
}
};
});
@@ -733,9 +950,10 @@ CodeMirror.defineMIME("text/ecmascript", "javascript");
CodeMirror.defineMIME("application/javascript", "javascript");
CodeMirror.defineMIME("application/x-javascript", "javascript");
CodeMirror.defineMIME("application/ecmascript", "javascript");
-CodeMirror.defineMIME("application/json", {name: "javascript", json: true});
-CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true});
-CodeMirror.defineMIME("application/ld+json", {name: "javascript", jsonld: true});
+CodeMirror.defineMIME("application/json", { name: "javascript", json: true });
+CodeMirror.defineMIME("application/x-json", { name: "javascript", json: true });
+CodeMirror.defineMIME("application/manifest+json", { name: "javascript", json: true })
+CodeMirror.defineMIME("application/ld+json", { name: "javascript", jsonld: true });
CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true });
CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true });
diff --git a/src/lib/codemirror/mode/javascript/json-ld.html b/src/lib/codemirror/mode/javascript/json-ld.html
deleted file mode 100644
index 3a37f0b..0000000
--- a/src/lib/codemirror/mode/javascript/json-ld.html
+++ /dev/null
@@ -1,72 +0,0 @@
-
-
-CodeMirror: JSON-LD mode
-
-
-
-
-
-
-
-
-
-
-
-
-
-JSON-LD mode
-
-
-
-
-
-
- This is a specialization of the JavaScript mode.
-
diff --git a/src/lib/codemirror/mode/javascript/typescript.html b/src/lib/codemirror/mode/javascript/typescript.html
deleted file mode 100644
index 2cfc538..0000000
--- a/src/lib/codemirror/mode/javascript/typescript.html
+++ /dev/null
@@ -1,61 +0,0 @@
-
-
-CodeMirror: TypeScript mode
-
-
-
-
-
-
-
-
-
-
-TypeScript mode
-
-
-
-
-
-
- This is a specialization of the JavaScript mode.
-
diff --git a/src/lib/codemirror/mode/jsx/jsx.js b/src/lib/codemirror/mode/jsx/jsx.js
index 45c3024..35ac608 100644
--- a/src/lib/codemirror/mode/jsx/jsx.js
+++ b/src/lib/codemirror/mode/jsx/jsx.js
@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
+// Distributed under an MIT license: https://codemirror.net/5/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
@@ -26,13 +26,13 @@
}
CodeMirror.defineMode("jsx", function(config, modeConfig) {
- var xmlMode = CodeMirror.getMode(config, {name: "xml", allowMissing: true, multilineTagIndentPastTag: false})
+ var xmlMode = CodeMirror.getMode(config, {name: "xml", allowMissing: true, multilineTagIndentPastTag: false, allowMissingTagName: true})
var jsMode = CodeMirror.getMode(config, modeConfig && modeConfig.base || "javascript")
function flatXMLIndent(state) {
var tagName = state.tagName
state.tagName = null
- var result = xmlMode.indent(state, "")
+ var result = xmlMode.indent(state, "", "")
state.tagName = tagName
return result
}
@@ -103,10 +103,11 @@
}
function jsToken(stream, state, cx) {
- if (stream.peek() == "<" && jsMode.expressionAllowed(stream, cx.state)) {
- jsMode.skipExpression(cx.state)
- state.context = new Context(CodeMirror.startState(xmlMode, jsMode.indent(cx.state, "")),
+ if (stream.peek() == "<" && !stream.match(/^<([^<>]|<[^>]*>)+,\s*>/, false) &&
+ jsMode.expressionAllowed(stream, cx.state)) {
+ state.context = new Context(CodeMirror.startState(xmlMode, jsMode.indent(cx.state, "", "")),
xmlMode, 0, state.context)
+ jsMode.skipExpression(cx.state)
return null
}
diff --git a/src/lib/codemirror/mode/markdown/markdown.js b/src/lib/codemirror/mode/markdown/markdown.js
index 37329c2..6eef544 100644
--- a/src/lib/codemirror/mode/markdown/markdown.js
+++ b/src/lib/codemirror/mode/markdown/markdown.js
@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
+// Distributed under an MIT license: https://codemirror.net/5/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
@@ -35,15 +35,6 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
if (modeCfg.maxBlockquoteDepth === undefined)
modeCfg.maxBlockquoteDepth = 0;
- // Should underscores in words open/close em/strong?
- if (modeCfg.underscoresBreakWords === undefined)
- modeCfg.underscoresBreakWords = true;
-
- // Use `fencedCodeBlocks` to configure fenced code blocks. false to
- // disable, string to specify a precise regexp that the fence should
- // match, and true to allow three or more backticks or tildes (as
- // per CommonMark).
-
// Turn on task lists? ("- [ ] " and "- [x] ")
if (modeCfg.taskLists === undefined) modeCfg.taskLists = false;
@@ -51,6 +42,18 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
if (modeCfg.strikethrough === undefined)
modeCfg.strikethrough = false;
+ if (modeCfg.emoji === undefined)
+ modeCfg.emoji = false;
+
+ if (modeCfg.fencedCodeBlockHighlighting === undefined)
+ modeCfg.fencedCodeBlockHighlighting = true;
+
+ if (modeCfg.fencedCodeBlockDefaultMode === undefined)
+ modeCfg.fencedCodeBlockDefaultMode = 'text/plain';
+
+ if (modeCfg.xml === undefined)
+ modeCfg.xml = true;
+
// Allow token types to be overridden by user-provided token types.
if (modeCfg.tokenTypeOverrides === undefined)
modeCfg.tokenTypeOverrides = {};
@@ -63,7 +66,9 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
list2: "variable-3",
list3: "keyword",
hr: "hr",
- image: "tag",
+ image: "image",
+ imageAltText: "image-alt-text",
+ imageMarker: "image-marker",
formatting: "formatting",
linkInline: "link",
linkEmail: "link",
@@ -71,7 +76,8 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
linkHref: "string",
em: "em",
strong: "strong",
- strikethrough: "strikethrough"
+ strikethrough: "strikethrough",
+ emoji: "builtin"
};
for (var tokenType in tokenTypes) {
@@ -81,14 +87,15 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
}
var hrRE = /^([*\-_])(?:\s*\1){2,}\s*$/
- , ulRE = /^[*\-+]\s+/
- , olRE = /^[0-9]+([.)])\s+/
- , taskListRE = /^\[(x| )\](?=\s)/ // Must follow ulRE or olRE
+ , listRE = /^(?:[*\-+]|^[0-9]+([.)]))\s+/
+ , taskListRE = /^\[(x| )\](?=\s)/i // Must follow listRE
, atxHeaderRE = modeCfg.allowAtxHeaderWithoutSpace ? /^(#+)/ : /^(#+)(?: |$)/
- , setextHeaderRE = /^ *(?:\={1,}|-{1,})\s*$/
- , textRE = /^[^#!\[\]*_\\<>` "'(~]+/
- , fencedCodeRE = new RegExp("^(" + (modeCfg.fencedCodeBlocks === true ? "~~~+|```+" : modeCfg.fencedCodeBlocks) +
- ")[ \\t]*([\\w+#\-]*)");
+ , setextHeaderRE = /^ {0,3}(?:\={1,}|-{2,})\s*$/
+ , textRE = /^[^#!\[\]*_\\<>` "'(~:]+/
+ , fencedCodeRE = /^(~~~+|```+)[ \t]*([\w\/+#-]*)[^\n`]*$/
+ , linkDefRE = /^\s*\[[^\]]+?\]:.*$/ // naive link-definition
+ , punctuation = /[!"#$%&'()*+,\-.\/:;<=>?@\[\\\]^_`{|}~\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u0AF0\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166D\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E42\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]|\uD800[\uDD00-\uDD02\uDF9F\uDFD0]|\uD801\uDD6F|\uD802[\uDC57\uDD1F\uDD3F\uDE50-\uDE58\uDE7F\uDEF0-\uDEF6\uDF39-\uDF3F\uDF99-\uDF9C]|\uD804[\uDC47-\uDC4D\uDCBB\uDCBC\uDCBE-\uDCC1\uDD40-\uDD43\uDD74\uDD75\uDDC5-\uDDC9\uDDCD\uDDDB\uDDDD-\uDDDF\uDE38-\uDE3D\uDEA9]|\uD805[\uDCC6\uDDC1-\uDDD7\uDE41-\uDE43\uDF3C-\uDF3E]|\uD809[\uDC70-\uDC74]|\uD81A[\uDE6E\uDE6F\uDEF5\uDF37-\uDF3B\uDF44]|\uD82F\uDC9F|\uD836[\uDE87-\uDE8B]/
+ , expandedTab = " " // CommonMark specifies tab as 4 spaces
function switchInline(stream, state, f) {
state.f = state.inline = f;
@@ -109,6 +116,8 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
function blankLine(state) {
// Reset linkTitle state
state.linkTitle = false;
+ state.linkHref = false;
+ state.linkText = false;
// Reset EM state
state.em = false;
// Reset STRONG state
@@ -119,94 +128,106 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
state.quote = 0;
// Reset state.indentedCode
state.indentedCode = false;
- if (htmlModeMissing && state.f == htmlBlock) {
- state.f = inlineNormal;
- state.block = blockNormal;
+ if (state.f == htmlBlock) {
+ var exit = htmlModeMissing
+ if (!exit) {
+ var inner = CodeMirror.innerMode(htmlMode, state.htmlState)
+ exit = inner.mode.name == "xml" && inner.state.tagStart === null &&
+ (!inner.state.context && inner.state.tokenize.isInText)
+ }
+ if (exit) {
+ state.f = inlineNormal;
+ state.block = blockNormal;
+ state.htmlState = null;
+ }
}
// Reset state.trailingSpace
state.trailingSpace = 0;
state.trailingSpaceNewLine = false;
// Mark this line as blank
state.prevLine = state.thisLine
- state.thisLine = null
+ state.thisLine = {stream: null}
return null;
}
function blockNormal(stream, state) {
-
- var sol = stream.sol();
-
- var prevLineIsList = state.list !== false,
- prevLineIsIndentedCode = state.indentedCode;
+ var firstTokenOnLine = stream.column() === state.indentation;
+ var prevLineLineIsEmpty = lineIsEmpty(state.prevLine.stream);
+ var prevLineIsIndentedCode = state.indentedCode;
+ var prevLineIsHr = state.prevLine.hr;
+ var prevLineIsList = state.list !== false;
+ var maxNonCodeIndentation = (state.listStack[state.listStack.length - 1] || 0) + 3;
state.indentedCode = false;
- if (prevLineIsList) {
- if (state.indentationDiff >= 0) { // Continued list
- if (state.indentationDiff < 4) { // Only adjust indentation if *not* a code block
- state.indentation -= state.indentationDiff;
+ var lineIndentation = state.indentation;
+ // compute once per line (on first token)
+ if (state.indentationDiff === null) {
+ state.indentationDiff = state.indentation;
+ if (prevLineIsList) {
+ state.list = null;
+ // While this list item's marker's indentation is less than the deepest
+ // list item's content's indentation,pop the deepest list item
+ // indentation off the stack, and update block indentation state
+ while (lineIndentation < state.listStack[state.listStack.length - 1]) {
+ state.listStack.pop();
+ if (state.listStack.length) {
+ state.indentation = state.listStack[state.listStack.length - 1];
+ // less than the first list's indent -> the line is no longer a list
+ } else {
+ state.list = false;
+ }
+ }
+ if (state.list !== false) {
+ state.indentationDiff = lineIndentation - state.listStack[state.listStack.length - 1]
}
- state.list = null;
- } else if (state.indentation > 0) {
- state.list = null;
- } else { // No longer a list
- state.list = false;
}
}
+ // not comprehensive (currently only for setext detection purposes)
+ var allowsInlineContinuation = (
+ !prevLineLineIsEmpty && !prevLineIsHr && !state.prevLine.header &&
+ (!prevLineIsList || !prevLineIsIndentedCode) &&
+ !state.prevLine.fencedCodeEnd
+ );
+
+ var isHr = (state.list === false || prevLineIsHr || prevLineLineIsEmpty) &&
+ state.indentation <= maxNonCodeIndentation && stream.match(hrRE);
+
var match = null;
- if (state.indentationDiff >= 4) {
+ if (state.indentationDiff >= 4 && (prevLineIsIndentedCode || state.prevLine.fencedCodeEnd ||
+ state.prevLine.header || prevLineLineIsEmpty)) {
stream.skipToEnd();
- if (prevLineIsIndentedCode || lineIsEmpty(state.prevLine)) {
- state.indentation -= 4;
- state.indentedCode = true;
- return tokenTypes.code;
- } else {
- return null;
- }
+ state.indentedCode = true;
+ return tokenTypes.code;
} else if (stream.eatSpace()) {
return null;
- } else if ((match = stream.match(atxHeaderRE)) && match[1].length <= 6) {
+ } else if (firstTokenOnLine && state.indentation <= maxNonCodeIndentation && (match = stream.match(atxHeaderRE)) && match[1].length <= 6) {
+ state.quote = 0;
state.header = match[1].length;
+ state.thisLine.header = true;
if (modeCfg.highlightFormatting) state.formatting = "header";
state.f = state.inline;
return getType(state);
- } else if (!lineIsEmpty(state.prevLine) && !state.quote && !prevLineIsList &&
- !prevLineIsIndentedCode && (match = stream.match(setextHeaderRE))) {
- state.header = match[0].charAt(0) == '=' ? 1 : 2;
- if (modeCfg.highlightFormatting) state.formatting = "header";
- state.f = state.inline;
- return getType(state);
- } else if (stream.eat('>')) {
- state.quote = sol ? 1 : state.quote + 1;
+ } else if (state.indentation <= maxNonCodeIndentation && stream.eat('>')) {
+ state.quote = firstTokenOnLine ? 1 : state.quote + 1;
if (modeCfg.highlightFormatting) state.formatting = "quote";
stream.eatSpace();
return getType(state);
- } else if (stream.peek() === '[') {
- return switchInline(stream, state, footnoteLink);
- } else if (stream.match(hrRE, true)) {
- state.hr = true;
- return tokenTypes.hr;
- } else if ((lineIsEmpty(state.prevLine) || prevLineIsList) && (stream.match(ulRE, false) || stream.match(olRE, false))) {
- var listType = null;
- if (stream.match(ulRE, true)) {
- listType = 'ul';
- } else {
- stream.match(olRE, true);
- listType = 'ol';
- }
- state.indentation = stream.column() + stream.current().length;
- state.list = true;
+ } else if (!isHr && !state.setext && firstTokenOnLine && state.indentation <= maxNonCodeIndentation && (match = stream.match(listRE))) {
+ var listType = match[1] ? "ol" : "ul";
- // While this list item's marker's indentation
- // is less than the deepest list item's content's indentation,
- // pop the deepest list item indentation off the stack.
- while (state.listStack && stream.column() < state.listStack[state.listStack.length - 1]) {
- state.listStack.pop();
- }
+ state.indentation = lineIndentation + stream.current().length;
+ state.list = true;
+ state.quote = 0;
// Add this list item's content's indentation to the stack
state.listStack.push(state.indentation);
+ // Reset inline styles which shouldn't propagate across list items
+ state.em = false;
+ state.strong = false;
+ state.code = false;
+ state.strikethrough = false;
if (modeCfg.taskLists && stream.match(taskListRE, false)) {
state.taskList = true;
@@ -214,15 +235,47 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
state.f = state.inline;
if (modeCfg.highlightFormatting) state.formatting = ["list", "list-" + listType];
return getType(state);
- } else if (modeCfg.fencedCodeBlocks && (match = stream.match(fencedCodeRE, true))) {
- state.fencedChars = match[1]
+ } else if (firstTokenOnLine && state.indentation <= maxNonCodeIndentation && (match = stream.match(fencedCodeRE, true))) {
+ state.quote = 0;
+ state.fencedEndRE = new RegExp(match[1] + "+ *$");
// try switching mode
- state.localMode = getMode(match[2]);
+ state.localMode = modeCfg.fencedCodeBlockHighlighting && getMode(match[2] || modeCfg.fencedCodeBlockDefaultMode );
if (state.localMode) state.localState = CodeMirror.startState(state.localMode);
state.f = state.block = local;
if (modeCfg.highlightFormatting) state.formatting = "code-block";
state.code = -1
return getType(state);
+ // SETEXT has lowest block-scope precedence after HR, so check it after
+ // the others (code, blockquote, list...)
+ } else if (
+ // if setext set, indicates line after ---/===
+ state.setext || (
+ // line before ---/===
+ (!allowsInlineContinuation || !prevLineIsList) && !state.quote && state.list === false &&
+ !state.code && !isHr && !linkDefRE.test(stream.string) &&
+ (match = stream.lookAhead(1)) && (match = match.match(setextHeaderRE))
+ )
+ ) {
+ if ( !state.setext ) {
+ state.header = match[0].charAt(0) == '=' ? 1 : 2;
+ state.setext = state.header;
+ } else {
+ state.header = state.setext;
+ // has no effect on type so we can reset it now
+ state.setext = 0;
+ stream.skipToEnd();
+ if (modeCfg.highlightFormatting) state.formatting = "header";
+ }
+ state.thisLine.header = true;
+ state.f = state.inline;
+ return getType(state);
+ } else if (isHr) {
+ stream.skipToEnd();
+ state.hr = true;
+ state.thisLine.hr = true;
+ return tokenTypes.hr;
+ } else if (stream.peek() === '[') {
+ return switchInline(stream, state, footnoteLink);
}
return switchInline(stream, state, state.inline);
@@ -244,10 +297,21 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
}
function local(stream, state) {
- if (state.fencedChars && stream.match(state.fencedChars, false)) {
+ var currListInd = state.listStack[state.listStack.length - 1] || 0;
+ var hasExitedList = state.indentation < currListInd;
+ var maxFencedEndInd = currListInd + 3;
+ if (state.fencedEndRE && state.indentation <= maxFencedEndInd && (hasExitedList || stream.match(state.fencedEndRE))) {
+ if (modeCfg.highlightFormatting) state.formatting = "code-block";
+ var returnType;
+ if (!hasExitedList) returnType = getType(state)
state.localMode = state.localState = null;
- state.f = state.block = leavingLocal;
- return null;
+ state.block = blockNormal;
+ state.f = inlineNormal;
+ state.fencedEndRE = null;
+ state.code = 0
+ state.thisLine.fencedCodeEnd = true;
+ if (hasExitedList) return switchBlock(stream, state, state.block);
+ return returnType;
} else if (state.localMode) {
return state.localMode.token(stream, state.localState);
} else {
@@ -256,18 +320,6 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
}
}
- function leavingLocal(stream, state) {
- stream.match(state.fencedChars);
- state.block = blockNormal;
- state.f = inlineNormal;
- state.fencedChars = null;
- if (modeCfg.highlightFormatting) state.formatting = "code-block";
- state.code = 1
- var returnType = getType(state);
- state.code = 0
- return returnType;
- }
-
// Inline
function getType(state) {
var styles = [];
@@ -311,8 +363,12 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
if (state.strong) { styles.push(tokenTypes.strong); }
if (state.em) { styles.push(tokenTypes.em); }
if (state.strikethrough) { styles.push(tokenTypes.strikethrough); }
+ if (state.emoji) { styles.push(tokenTypes.emoji); }
if (state.linkText) { styles.push(tokenTypes.linkText); }
if (state.code) { styles.push(tokenTypes.code); }
+ if (state.image) { styles.push(tokenTypes.image); }
+ if (state.imageAltText) { styles.push(tokenTypes.imageAltText, "link"); }
+ if (state.imageMarker) { styles.push(tokenTypes.imageMarker); }
}
if (state.header) { styles.push(tokenTypes.header, tokenTypes.header + "-" + state.header); }
@@ -366,7 +422,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
}
if (state.taskList) {
- var taskOpen = stream.match(taskListRE, true)[1] !== "x";
+ var taskOpen = stream.match(taskListRE, true)[1] === " ";
if (taskOpen) state.taskOpen = true;
else state.taskClosed = true;
if (modeCfg.highlightFormatting) state.formatting = "task";
@@ -382,9 +438,6 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
return getType(state);
}
- // Get sol() value now, before character is consumed
- var sol = stream.sol();
-
var ch = stream.next();
// Matches link titles present on next line
@@ -394,7 +447,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
if (ch === '(') {
matchCh = ')';
}
- matchCh = (matchCh+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
+ matchCh = (matchCh+'').replace(/([.?*+^\[\]\\(){}|-])/g, "\\$1");
var regex = '^\\s*(?:[^' + matchCh + '\\\\]+|\\\\\\\\|\\\\.)' + matchCh;
if (stream.match(new RegExp(regex), true)) {
return tokenTypes.linkHref;
@@ -407,7 +460,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
if (modeCfg.highlightFormatting) state.formatting = "code";
stream.eatWhile('`');
var count = stream.current().length
- if (state.code == 0) {
+ if (state.code == 0 && (!state.quote || count == 1)) {
state.code = count
return getType(state)
} else if (count == state.code) { // Must be exact
@@ -432,22 +485,40 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
}
if (ch === '!' && stream.match(/\[[^\]]*\] ?(?:\(|\[)/, false)) {
- stream.match(/\[[^\]]*\]/);
- state.inline = state.f = linkHref;
- return tokenTypes.image;
+ state.imageMarker = true;
+ state.image = true;
+ if (modeCfg.highlightFormatting) state.formatting = "image";
+ return getType(state);
}
- if (ch === '[' && stream.match(/[^\]]*\](\(.*\)| ?\[.*?\])/, false)) {
+ if (ch === '[' && state.imageMarker && stream.match(/[^\]]*\](\(.*?\)| ?\[.*?\])/, false)) {
+ state.imageMarker = false;
+ state.imageAltText = true
+ if (modeCfg.highlightFormatting) state.formatting = "image";
+ return getType(state);
+ }
+
+ if (ch === ']' && state.imageAltText) {
+ if (modeCfg.highlightFormatting) state.formatting = "image";
+ var type = getType(state);
+ state.imageAltText = false;
+ state.image = false;
+ state.inline = state.f = linkHref;
+ return type;
+ }
+
+ if (ch === '[' && !state.image) {
+ if (state.linkText && stream.match(/^.*?\]/)) return getType(state)
state.linkText = true;
if (modeCfg.highlightFormatting) state.formatting = "link";
return getType(state);
}
- if (ch === ']' && state.linkText && stream.match(/\(.*?\)| ?\[.*?\]/, false)) {
+ if (ch === ']' && state.linkText) {
if (modeCfg.highlightFormatting) state.formatting = "link";
var type = getType(state);
state.linkText = false;
- state.inline = state.f = linkHref;
+ state.inline = state.f = stream.match(/\(.*?\)| ?\[.*?\]/, false) ? linkHref : inlineNormal
return type;
}
@@ -475,7 +546,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
return type + tokenTypes.linkEmail;
}
- if (ch === '<' && stream.match(/^(!--|\w)/, false)) {
+ if (modeCfg.xml && ch === '<' && stream.match(/^(!--|\?|!\[CDATA\[|[a-z][a-z0-9-]*(?:\s+[a-z_:.\-]+(?:\s*=\s*[^>]+)?)*\s*(?:>|$))/i, false)) {
var end = stream.string.indexOf(">", stream.pos);
if (end != -1) {
var atts = stream.string.substring(stream.start, end);
@@ -486,44 +557,37 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
return switchBlock(stream, state, htmlBlock);
}
- if (ch === '<' && stream.match(/^\/\w*?>/)) {
+ if (modeCfg.xml && ch === '<' && stream.match(/^\/\w*?>/)) {
state.md_inside = false;
return "tag";
- }
-
- var ignoreUnderscore = false;
- if (!modeCfg.underscoresBreakWords) {
- if (ch === '_' && stream.peek() !== '_' && stream.match(/(\w)/, false)) {
- var prevPos = stream.pos - 2;
- if (prevPos >= 0) {
- var prevCh = stream.string.charAt(prevPos);
- if (prevCh !== '_' && prevCh.match(/(\w)/, false)) {
- ignoreUnderscore = true;
- }
- }
+ } else if (ch === "*" || ch === "_") {
+ var len = 1, before = stream.pos == 1 ? " " : stream.string.charAt(stream.pos - 2)
+ while (len < 3 && stream.eat(ch)) len++
+ var after = stream.peek() || " "
+ // See http://spec.commonmark.org/0.27/#emphasis-and-strong-emphasis
+ var leftFlanking = !/\s/.test(after) && (!punctuation.test(after) || /\s/.test(before) || punctuation.test(before))
+ var rightFlanking = !/\s/.test(before) && (!punctuation.test(before) || /\s/.test(after) || punctuation.test(after))
+ var setEm = null, setStrong = null
+ if (len % 2) { // Em
+ if (!state.em && leftFlanking && (ch === "*" || !rightFlanking || punctuation.test(before)))
+ setEm = true
+ else if (state.em == ch && rightFlanking && (ch === "*" || !leftFlanking || punctuation.test(after)))
+ setEm = false
}
- }
- if (ch === '*' || (ch === '_' && !ignoreUnderscore)) {
- if (sol && stream.peek() === ' ') {
- // Do nothing, surrounded by newline and space
- } else if (state.strong === ch && stream.eat(ch)) { // Remove STRONG
- if (modeCfg.highlightFormatting) state.formatting = "strong";
- var t = getType(state);
- state.strong = false;
- return t;
- } else if (!state.strong && stream.eat(ch)) { // Add STRONG
- state.strong = ch;
- if (modeCfg.highlightFormatting) state.formatting = "strong";
- return getType(state);
- } else if (state.em === ch) { // Remove EM
- if (modeCfg.highlightFormatting) state.formatting = "em";
- var t = getType(state);
- state.em = false;
- return t;
- } else if (!state.em) { // Add EM
- state.em = ch;
- if (modeCfg.highlightFormatting) state.formatting = "em";
- return getType(state);
+ if (len > 1) { // Strong
+ if (!state.strong && leftFlanking && (ch === "*" || !rightFlanking || punctuation.test(before)))
+ setStrong = true
+ else if (state.strong == ch && rightFlanking && (ch === "*" || !leftFlanking || punctuation.test(after)))
+ setStrong = false
+ }
+ if (setStrong != null || setEm != null) {
+ if (modeCfg.highlightFormatting) state.formatting = setEm == null ? "strong" : setStrong == null ? "em" : "strong em"
+ if (setEm === true) state.em = ch
+ if (setStrong === true) state.strong = ch
+ var t = getType(state)
+ if (setEm === false) state.em = false
+ if (setStrong === false) state.strong = false
+ return t
}
} else if (ch === ' ') {
if (stream.eat('*') || stream.eat('_')) { // Probably surrounded by spaces
@@ -548,7 +612,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
return getType(state);
}
} else if (ch === ' ') {
- if (stream.match(/^~~/, true)) { // Probably surrounded by space
+ if (stream.match('~~', true)) { // Probably surrounded by space
if (stream.peek() === ' ') { // Surrounded by spaces, ignore
return getType(state);
} else { // Not surrounded by spaces, back up pointer
@@ -558,8 +622,16 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
}
}
+ if (modeCfg.emoji && ch === ":" && stream.match(/^(?:[a-z_\d+][a-z_\d+-]*|\-[a-z_\d+][a-z_\d+-]*):/)) {
+ state.emoji = true;
+ if (modeCfg.highlightFormatting) state.formatting = "emoji";
+ var retType = getType(state);
+ state.emoji = false;
+ return retType;
+ }
+
if (ch === ' ') {
- if (stream.match(/ +$/, false)) {
+ if (stream.match(/^ +$/, false)) {
state.trailingSpace++;
} else if (state.trailingSpace) {
state.trailingSpaceNewLine = true;
@@ -596,7 +668,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
}
var ch = stream.next();
if (ch === '(' || ch === '[') {
- state.f = state.inline = getLinkHrefInside(ch === "(" ? ")" : "]", 0);
+ state.f = state.inline = getLinkHrefInside(ch === "(" ? ")" : "]");
if (modeCfg.highlightFormatting) state.formatting = "link-string";
state.linkHref = true;
return getType(state);
@@ -606,7 +678,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
var linkRE = {
")": /^(?:[^\\\(\)]|\\.|\((?:[^\\\(\)]|\\.)*\))*?(?=\))/,
- "]": /^(?:[^\\\[\]]|\\.|\[(?:[^\\\[\\]]|\\.)*\])*?(?=\])/
+ "]": /^(?:[^\\\[\]]|\\.|\[(?:[^\\\[\]]|\\.)*\])*?(?=\])/
}
function getLinkHrefInside(endChar) {
@@ -639,7 +711,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
}
function footnoteLinkInside(stream, state) {
- if (stream.match(/^\]:/, true)) {
+ if (stream.match(']:', true)) {
state.f = state.inline = footnoteUrl;
if (modeCfg.highlightFormatting) state.formatting = "link";
var returnType = getType(state);
@@ -663,7 +735,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
if (stream.peek() === undefined) { // End of line, set flag to check next line
state.linkTitle = true;
} else { // More content on line, check if link title
- stream.match(/^(?:\s+(?:"(?:[^"\\]|\\\\|\\.)+"|'(?:[^'\\]|\\\\|\\.)+'|\((?:[^)\\]|\\\\|\\.)+\)))?/, true);
+ stream.match(/^(?:\s+(?:"(?:[^"\\]|\\.)+"|'(?:[^'\\]|\\.)+'|\((?:[^)\\]|\\.)+\)))?/, true);
}
state.f = state.inline = inlineNormal;
return tokenTypes.linkHref + " url";
@@ -674,8 +746,8 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
return {
f: blockNormal,
- prevLine: null,
- thisLine: null,
+ prevLine: {stream: null},
+ thisLine: {stream: null},
block: blockNormal,
htmlState: null,
@@ -692,6 +764,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
em: false,
strong: false,
header: 0,
+ setext: 0,
hr: false,
taskList: false,
list: false,
@@ -700,7 +773,8 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
trailingSpace: 0,
trailingSpaceNewLine: false,
strikethrough: false,
- fencedChars: null
+ emoji: false,
+ fencedEndRE: null
};
},
@@ -721,12 +795,16 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
inline: s.inline,
text: s.text,
formatting: false,
+ linkText: s.linkText,
linkTitle: s.linkTitle,
+ linkHref: s.linkHref,
code: s.code,
em: s.em,
strong: s.strong,
strikethrough: s.strikethrough,
+ emoji: s.emoji,
header: s.header,
+ setext: s.setext,
hr: s.hr,
taskList: s.taskList,
list: s.list,
@@ -736,7 +814,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
trailingSpace: s.trailingSpace,
trailingSpaceNewLine: s.trailingSpaceNewLine,
md_inside: s.md_inside,
- fencedChars: s.fencedChars
+ fencedEndRE: s.fencedEndRE
};
},
@@ -745,21 +823,17 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
// Reset state.formatting
state.formatting = false;
- if (stream != state.thisLine) {
- var forceBlankLine = state.header || state.hr;
-
- // Reset state.header and state.hr
+ if (stream != state.thisLine.stream) {
state.header = 0;
state.hr = false;
- if (stream.match(/^\s*$/, true) || forceBlankLine) {
+ if (stream.match(/^\s*$/, true)) {
blankLine(state);
- if (!forceBlankLine) return null
- state.prevLine = null
+ return null;
}
state.prevLine = state.thisLine
- state.thisLine = stream
+ state.thisLine = {stream: stream}
// Reset state.taskList
state.taskList = false;
@@ -768,11 +842,15 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
state.trailingSpace = 0;
state.trailingSpaceNewLine = false;
- state.f = state.block;
- var indentation = stream.match(/^\s*/, true)[0].replace(/\t/g, ' ').length;
- state.indentationDiff = Math.min(indentation - state.indentation, 4);
- state.indentation = state.indentation + state.indentationDiff;
- if (indentation > 0) return null;
+ if (!state.localState) {
+ state.f = state.block;
+ if (state.f != htmlBlock) {
+ var indentation = stream.match(/^\s*/, true)[0].replace(/\t/g, expandedTab).length;
+ state.indentation = indentation;
+ state.indentationDiff = null;
+ if (indentation > 0) return null;
+ }
+ }
}
return state.f(stream, state);
},
@@ -783,15 +861,26 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
return {state: state, mode: mode};
},
+ indent: function(state, textAfter, line) {
+ if (state.block == htmlBlock && htmlMode.indent) return htmlMode.indent(state.htmlState, textAfter, line)
+ if (state.localState && state.localMode.indent) return state.localMode.indent(state.localState, textAfter, line)
+ return CodeMirror.Pass
+ },
+
blankLine: blankLine,
getType: getType,
+ blockCommentStart: "",
+ closeBrackets: "()[]{}''\"\"``",
fold: "markdown"
};
return mode;
}, "xml");
+CodeMirror.defineMIME("text/markdown", "markdown");
+
CodeMirror.defineMIME("text/x-markdown", "markdown");
});
diff --git a/src/lib/codemirror/mode/pug/pug.js b/src/lib/codemirror/mode/pug/pug.js
index 4018233..64f5430 100644
--- a/src/lib/codemirror/mode/pug/pug.js
+++ b/src/lib/codemirror/mode/pug/pug.js
@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
+// Distributed under an MIT license: https://codemirror.net/5/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
@@ -261,7 +261,7 @@ CodeMirror.defineMode("pug", function (config) {
}
return 'variable';
}
- if (stream.match(/^\+#{/, false)) {
+ if (stream.match('+#{', false)) {
stream.next();
state.mixinCallAfter = true;
return interpolation(stream, state);
@@ -545,12 +545,12 @@ CodeMirror.defineMode("pug", function (config) {
|| javaScriptArguments(stream, state)
|| callArguments(stream, state)
- || yieldStatement(stream, state)
- || doctype(stream, state)
+ || yieldStatement(stream)
+ || doctype(stream)
|| interpolation(stream, state)
|| caseStatement(stream, state)
|| when(stream, state)
- || defaultStatement(stream, state)
+ || defaultStatement(stream)
|| extendsStatement(stream, state)
|| append(stream, state)
|| prepend(stream, state)
@@ -565,16 +565,16 @@ CodeMirror.defineMode("pug", function (config) {
|| tag(stream, state)
|| filter(stream, state)
|| code(stream, state)
- || id(stream, state)
- || className(stream, state)
+ || id(stream)
+ || className(stream)
|| attrs(stream, state)
|| attributesBlock(stream, state)
- || indent(stream, state)
+ || indent(stream)
|| text(stream, state)
|| comment(stream, state)
- || colon(stream, state)
+ || colon(stream)
|| dot(stream, state)
- || fail(stream, state);
+ || fail(stream);
return tok === true ? null : tok;
}
diff --git a/src/lib/codemirror/mode/sass/sass.js b/src/lib/codemirror/mode/sass/sass.js
index 6973ece..3cfac0a 100644
--- a/src/lib/codemirror/mode/sass/sass.js
+++ b/src/lib/codemirror/mode/sass/sass.js
@@ -1,17 +1,23 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
+// Distributed under an MIT license: https://codemirror.net/5/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
- mod(require("../../lib/codemirror"));
+ mod(require("../../lib/codemirror"), require("../css/css"));
else if (typeof define == "function" && define.amd) // AMD
- define(["../../lib/codemirror"], mod);
+ define(["../../lib/codemirror", "../css/css"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.defineMode("sass", function(config) {
+ var cssMode = CodeMirror.mimeModes["text/css"];
+ var propertyKeywords = cssMode.propertyKeywords || {},
+ colorKeywords = cssMode.colorKeywords || {},
+ valueKeywords = cssMode.valueKeywords || {},
+ fontProperties = cssMode.fontProperties || {};
+
function tokenRegexp(words) {
return new RegExp("^" + words.join("|"));
}
@@ -25,6 +31,12 @@ CodeMirror.defineMode("sass", function(config) {
var pseudoElementsRegexp = /^::?[a-zA-Z_][\w\-]*/;
+ var word;
+
+ function isEndLine(stream) {
+ return !stream.peek() || stream.match(/\s+$/, false);
+ }
+
function urlTokens(stream, state) {
var ch = stream.peek();
@@ -76,6 +88,9 @@ CodeMirror.defineMode("sass", function(config) {
if (endingString) {
if (nextChar !== quote && greedy) { stream.next(); }
+ if (isEndLine(stream)) {
+ state.cursorHalf = 0;
+ }
state.tokenizer = tokenBase;
return "string";
} else if (nextChar === "#" && peekChar === "{") {
@@ -147,14 +162,20 @@ CodeMirror.defineMode("sass", function(config) {
// first half i.e. before : for key-value pairs
// including selectors
+ if (ch === "-") {
+ if (stream.match(/^-\w+-/)) {
+ return "meta";
+ }
+ }
+
if (ch === ".") {
stream.next();
if (stream.match(/^[\w-]+/)) {
indent(state);
- return "atom";
+ return "qualifier";
} else if (stream.peek() === "#") {
indent(state);
- return "atom";
+ return "tag";
}
}
@@ -163,11 +184,11 @@ CodeMirror.defineMode("sass", function(config) {
// ID selectors
if (stream.match(/^[\w-]+/)) {
indent(state);
- return "atom";
+ return "builtin";
}
if (stream.peek() === "#") {
indent(state);
- return "atom";
+ return "tag";
}
}
@@ -210,7 +231,7 @@ CodeMirror.defineMode("sass", function(config) {
}
if(ch === "@"){
- if(stream.match(/@extend/)){
+ if(stream.match('@extend')){
if(!stream.match(/\s*[\w]/))
dedent(state);
}
@@ -220,37 +241,48 @@ CodeMirror.defineMode("sass", function(config) {
// Indent Directives
if (stream.match(/^@(else if|if|media|else|for|each|while|mixin|function)/)) {
indent(state);
- return "meta";
+ return "def";
}
// Other Directives
if (ch === "@") {
stream.next();
stream.eatWhile(/[\w-]/);
- return "meta";
+ return "def";
}
if (stream.eatWhile(/[\w-]/)){
if(stream.match(/ *: *[\w-\+\$#!\("']/,false)){
- return "property";
+ word = stream.current().toLowerCase();
+ var prop = state.prevProp + "-" + word;
+ if (propertyKeywords.hasOwnProperty(prop)) {
+ return "property";
+ } else if (propertyKeywords.hasOwnProperty(word)) {
+ state.prevProp = word;
+ return "property";
+ } else if (fontProperties.hasOwnProperty(word)) {
+ return "property";
+ }
+ return "tag";
}
else if(stream.match(/ *:/,false)){
indent(state);
state.cursorHalf = 1;
- return "atom";
+ state.prevProp = stream.current().toLowerCase();
+ return "property";
}
else if(stream.match(/ *,/,false)){
- return "atom";
+ return "tag";
}
else{
indent(state);
- return "atom";
+ return "tag";
}
}
if(ch === ":"){
if (stream.match(pseudoElementsRegexp)){ // could be a pseudo-element
- return "keyword";
+ return "variable-3";
}
stream.next();
state.cursorHalf=1;
@@ -264,7 +296,7 @@ CodeMirror.defineMode("sass", function(config) {
stream.next();
// Hex numbers
if (stream.match(/[0-9a-fA-F]{6}|[0-9a-fA-F]{3}/)){
- if(!stream.peek()){
+ if (isEndLine(stream)) {
state.cursorHalf = 0;
}
return "number";
@@ -273,7 +305,7 @@ CodeMirror.defineMode("sass", function(config) {
// Numbers
if (stream.match(/^-?[0-9\.]+/)){
- if(!stream.peek()){
+ if (isEndLine(stream)) {
state.cursorHalf = 0;
}
return "number";
@@ -281,14 +313,14 @@ CodeMirror.defineMode("sass", function(config) {
// Units
if (stream.match(/^(px|em|in)\b/)){
- if(!stream.peek()){
+ if (isEndLine(stream)) {
state.cursorHalf = 0;
}
return "unit";
}
if (stream.match(keywordsRegexp)){
- if(!stream.peek()){
+ if (isEndLine(stream)) {
state.cursorHalf = 0;
}
return "keyword";
@@ -296,7 +328,7 @@ CodeMirror.defineMode("sass", function(config) {
if (stream.match(/^url/) && stream.peek() === "(") {
state.tokenizer = urlTokens;
- if(!stream.peek()){
+ if (isEndLine(stream)) {
state.cursorHalf = 0;
}
return "atom";
@@ -306,23 +338,21 @@ CodeMirror.defineMode("sass", function(config) {
if (ch === "$") {
stream.next();
stream.eatWhile(/[\w-]/);
- if(!stream.peek()){
+ if (isEndLine(stream)) {
state.cursorHalf = 0;
}
- return "variable-3";
+ return "variable-2";
}
// bang character for !important, !default, etc.
if (ch === "!") {
stream.next();
- if(!stream.peek()){
- state.cursorHalf = 0;
- }
+ state.cursorHalf = 0;
return stream.match(/^[\w]+/) ? "keyword": "operator";
}
if (stream.match(opRegexp)){
- if(!stream.peek()){
+ if (isEndLine(stream)) {
state.cursorHalf = 0;
}
return "operator";
@@ -330,14 +360,24 @@ CodeMirror.defineMode("sass", function(config) {
// attributes
if (stream.eatWhile(/[\w-]/)) {
- if(!stream.peek()){
+ if (isEndLine(stream)) {
state.cursorHalf = 0;
}
- return "attribute";
+ word = stream.current().toLowerCase();
+ if (valueKeywords.hasOwnProperty(word)) {
+ return "atom";
+ } else if (colorKeywords.hasOwnProperty(word)) {
+ return "keyword";
+ } else if (propertyKeywords.hasOwnProperty(word)) {
+ state.prevProp = stream.current().toLowerCase();
+ return "property";
+ } else {
+ return "tag";
+ }
}
//stream.eatSpace();
- if(!stream.peek()){
+ if (isEndLine(stream)) {
state.cursorHalf = 0;
return null;
}
@@ -405,9 +445,14 @@ CodeMirror.defineMode("sass", function(config) {
indent: function(state) {
return state.scopes[0].offset;
- }
+ },
+
+ blockCommentStart: "/*",
+ blockCommentEnd: "*/",
+ lineComment: "//",
+ fold: "indent"
};
-});
+}, "css");
CodeMirror.defineMIME("text/x-sass", "sass");
diff --git a/src/lib/codemirror/mode/stylus/stylus.js b/src/lib/codemirror/mode/stylus/stylus.js
index 8d83a01..dae99e5 100644
--- a/src/lib/codemirror/mode/stylus/stylus.js
+++ b/src/lib/codemirror/mode/stylus/stylus.js
@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
+// Distributed under an MIT license: https://codemirror.net/5/LICENSE
// Stylus mode created by Dmitry Kiselyov http://git.io/AaRB
@@ -15,6 +15,7 @@
CodeMirror.defineMode("stylus", function(config) {
var indentUnit = config.indentUnit,
+ indentUnitString = '',
tagKeywords = keySet(tagKeywords_),
tagVariablesRegexp = /^(a|b|i|s|col|em)$/i,
propertyKeywords = keySet(propertyKeywords_),
@@ -38,6 +39,8 @@
type,
override;
+ while (indentUnitString.length < indentUnit) indentUnitString += ' ';
+
/**
* Tokenizers
*/
@@ -73,7 +76,7 @@
if (ch == "#") {
stream.next();
// Hex color
- if (stream.match(/^[0-9a-f]{6}|[0-9a-f]{3}/i)) {
+ if (stream.match(/^[0-9a-f]{3}([0-9a-f]([0-9a-f]{2}){0,2})?\b(?!-)/i)) {
return ["atom", "atom"];
}
// ID selector
@@ -135,7 +138,7 @@
// Variable
if (stream.match(/^(\.|\[)[\w-\'\"\]]+/i, false)) {
if (!wordIsTag(stream.current())) {
- stream.match(/\./);
+ stream.match('.');
return ["variable-2", "variable-name"];
}
}
@@ -313,7 +316,7 @@
return pushContext(state, stream, "block", 0);
}
}
- if (typeIsBlock(type, stream, state)) {
+ if (typeIsBlock(type, stream)) {
return pushContext(state, stream, "block");
}
if (type == "}" && endOfLine(stream)) {
@@ -513,7 +516,7 @@
*/
states.atBlock = function(type, stream, state) {
if (type == "(") return pushContext(state, stream, "atBlock_parens");
- if (typeIsBlock(type, stream, state)) {
+ if (typeIsBlock(type, stream)) {
return pushContext(state, stream, "block");
}
if (typeIsInterpolation(type, stream)) {
@@ -672,7 +675,7 @@
ch = textAfter && textAfter.charAt(0),
indent = cx.indent,
lineFirstWord = firstWordOfLine(textAfter),
- lineIndent = line.length - line.replace(/^\s*/, "").length,
+ lineIndent = line.match(/^\s*/)[0].replace(/\t/g, indentUnitString).length,
prevLineFirstWord = state.context.prev ? state.context.prev.line.firstWord : "",
prevLineIndent = state.context.prev ? state.context.prev.line.indent : lineIndent;
@@ -681,7 +684,6 @@
ch == ")" && (cx.type == "parens" || cx.type == "atBlock_parens") ||
ch == "{" && (cx.type == "at"))) {
indent = cx.indent - indentUnit;
- cx = cx.prev;
} else if (!(/(\})/.test(ch))) {
if (/@|\$|\d/.test(ch) ||
/^\{/.test(textAfter) ||
@@ -720,6 +722,9 @@
return indent;
},
electricChars: "}",
+ blockCommentStart: "/*",
+ blockCommentEnd: "*/",
+ blockCommentContinue: " * ",
lineComment: "//",
fold: "indent"
};
@@ -729,14 +734,15 @@
var tagKeywords_ = ["a","abbr","address","area","article","aside","audio", "b", "base","bdi", "bdo","bgsound","blockquote","body","br","button","canvas","caption","cite", "code","col","colgroup","data","datalist","dd","del","details","dfn","div", "dl","dt","em","embed","fieldset","figcaption","figure","footer","form","h1", "h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","iframe", "img","input","ins","kbd","keygen","label","legend","li","link","main","map", "mark","marquee","menu","menuitem","meta","meter","nav","nobr","noframes", "noscript","object","ol","optgroup","option","output","p","param","pre", "progress","q","rp","rt","ruby","s","samp","script","section","select", "small","source","span","strong","style","sub","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","tr","track", "u","ul","var","video"];
// github.com/codemirror/CodeMirror/blob/master/mode/css/css.js
- var documentTypes_ = ["domain", "regexp", "url", "url-prefix"];
+ // Note, "url-prefix" should precede "url" in order to match correctly in documentTypesRegexp
+ var documentTypes_ = ["domain", "regexp", "url-prefix", "url"];
var mediaTypes_ = ["all","aural","braille","handheld","print","projection","screen","tty","tv","embossed"];
- var mediaFeatures_ = ["width","min-width","max-width","height","min-height","max-height","device-width","min-device-width","max-device-width","device-height","min-device-height","max-device-height","aspect-ratio","min-aspect-ratio","max-aspect-ratio","device-aspect-ratio","min-device-aspect-ratio","max-device-aspect-ratio","color","min-color","max-color","color-index","min-color-index","max-color-index","monochrome","min-monochrome","max-monochrome","resolution","min-resolution","max-resolution","scan","grid"];
+ var mediaFeatures_ = ["width","min-width","max-width","height","min-height","max-height","device-width","min-device-width","max-device-width","device-height","min-device-height","max-device-height","aspect-ratio","min-aspect-ratio","max-aspect-ratio","device-aspect-ratio","min-device-aspect-ratio","max-device-aspect-ratio","color","min-color","max-color","color-index","min-color-index","max-color-index","monochrome","min-monochrome","max-monochrome","resolution","min-resolution","max-resolution","scan","grid","dynamic-range","video-dynamic-range"];
var propertyKeywords_ = ["align-content","align-items","align-self","alignment-adjust","alignment-baseline","anchor-point","animation","animation-delay","animation-direction","animation-duration","animation-fill-mode","animation-iteration-count","animation-name","animation-play-state","animation-timing-function","appearance","azimuth","backface-visibility","background","background-attachment","background-clip","background-color","background-image","background-origin","background-position","background-repeat","background-size","baseline-shift","binding","bleed","bookmark-label","bookmark-level","bookmark-state","bookmark-target","border","border-bottom","border-bottom-color","border-bottom-left-radius","border-bottom-right-radius","border-bottom-style","border-bottom-width","border-collapse","border-color","border-image","border-image-outset","border-image-repeat","border-image-slice","border-image-source","border-image-width","border-left","border-left-color","border-left-style","border-left-width","border-radius","border-right","border-right-color","border-right-style","border-right-width","border-spacing","border-style","border-top","border-top-color","border-top-left-radius","border-top-right-radius","border-top-style","border-top-width","border-width","bottom","box-decoration-break","box-shadow","box-sizing","break-after","break-before","break-inside","caption-side","clear","clip","color","color-profile","column-count","column-fill","column-gap","column-rule","column-rule-color","column-rule-style","column-rule-width","column-span","column-width","columns","content","counter-increment","counter-reset","crop","cue","cue-after","cue-before","cursor","direction","display","dominant-baseline","drop-initial-after-adjust","drop-initial-after-align","drop-initial-before-adjust","drop-initial-before-align","drop-initial-size","drop-initial-value","elevation","empty-cells","fit","fit-position","flex","flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","flex-wrap","float","float-offset","flow-from","flow-into","font","font-feature-settings","font-family","font-kerning","font-language-override","font-size","font-size-adjust","font-stretch","font-style","font-synthesis","font-variant","font-variant-alternates","font-variant-caps","font-variant-east-asian","font-variant-ligatures","font-variant-numeric","font-variant-position","font-weight","grid","grid-area","grid-auto-columns","grid-auto-flow","grid-auto-position","grid-auto-rows","grid-column","grid-column-end","grid-column-start","grid-row","grid-row-end","grid-row-start","grid-template","grid-template-areas","grid-template-columns","grid-template-rows","hanging-punctuation","height","hyphens","icon","image-orientation","image-rendering","image-resolution","inline-box-align","justify-content","left","letter-spacing","line-break","line-height","line-stacking","line-stacking-ruby","line-stacking-shift","line-stacking-strategy","list-style","list-style-image","list-style-position","list-style-type","margin","margin-bottom","margin-left","margin-right","margin-top","marker-offset","marks","marquee-direction","marquee-loop","marquee-play-count","marquee-speed","marquee-style","max-height","max-width","min-height","min-width","move-to","nav-down","nav-index","nav-left","nav-right","nav-up","object-fit","object-position","opacity","order","orphans","outline","outline-color","outline-offset","outline-style","outline-width","overflow","overflow-style","overflow-wrap","overflow-x","overflow-y","padding","padding-bottom","padding-left","padding-right","padding-top","page","page-break-after","page-break-before","page-break-inside","page-policy","pause","pause-after","pause-before","perspective","perspective-origin","pitch","pitch-range","play-during","position","presentation-level","punctuation-trim","quotes","region-break-after","region-break-before","region-break-inside","region-fragment","rendering-intent","resize","rest","rest-after","rest-before","richness","right","rotation","rotation-point","ruby-align","ruby-overhang","ruby-position","ruby-span","shape-image-threshold","shape-inside","shape-margin","shape-outside","size","speak","speak-as","speak-header","speak-numeral","speak-punctuation","speech-rate","stress","string-set","tab-size","table-layout","target","target-name","target-new","target-position","text-align","text-align-last","text-decoration","text-decoration-color","text-decoration-line","text-decoration-skip","text-decoration-style","text-emphasis","text-emphasis-color","text-emphasis-position","text-emphasis-style","text-height","text-indent","text-justify","text-outline","text-overflow","text-shadow","text-size-adjust","text-space-collapse","text-transform","text-underline-position","text-wrap","top","transform","transform-origin","transform-style","transition","transition-delay","transition-duration","transition-property","transition-timing-function","unicode-bidi","vertical-align","visibility","voice-balance","voice-duration","voice-family","voice-pitch","voice-range","voice-rate","voice-stress","voice-volume","volume","white-space","widows","width","will-change","word-break","word-spacing","word-wrap","z-index","clip-path","clip-rule","mask","enable-background","filter","flood-color","flood-opacity","lighting-color","stop-color","stop-opacity","pointer-events","color-interpolation","color-interpolation-filters","color-rendering","fill","fill-opacity","fill-rule","image-rendering","marker","marker-end","marker-mid","marker-start","shape-rendering","stroke","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke-width","text-rendering","baseline-shift","dominant-baseline","glyph-orientation-horizontal","glyph-orientation-vertical","text-anchor","writing-mode","font-smoothing","osx-font-smoothing"];
var nonStandardPropertyKeywords_ = ["scrollbar-arrow-color","scrollbar-base-color","scrollbar-dark-shadow-color","scrollbar-face-color","scrollbar-highlight-color","scrollbar-shadow-color","scrollbar-3d-light-color","scrollbar-track-color","shape-inside","searchfield-cancel-button","searchfield-decoration","searchfield-results-button","searchfield-results-decoration","zoom"];
var fontProperties_ = ["font-family","src","unicode-range","font-variant","font-feature-settings","font-stretch","font-weight","font-style"];
var colorKeywords_ = ["aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgreen","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","grey","green","greenyellow","honeydew","hotpink","indianred","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgray","lightgreen","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","rebeccapurple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","snow","springgreen","steelblue","tan","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen"];
- var valueKeywords_ = ["above","absolute","activeborder","additive","activecaption","afar","after-white-space","ahead","alias","all","all-scroll","alphabetic","alternate","always","amharic","amharic-abegede","antialiased","appworkspace","arabic-indic","armenian","asterisks","attr","auto","avoid","avoid-column","avoid-page","avoid-region","background","backwards","baseline","below","bidi-override","binary","bengali","blink","block","block-axis","bold","bolder","border","border-box","both","bottom","break","break-all","break-word","bullets","button","button-bevel","buttonface","buttonhighlight","buttonshadow","buttontext","calc","cambodian","capitalize","caps-lock-indicator","caption","captiontext","caret","cell","center","checkbox","circle","cjk-decimal","cjk-earthly-branch","cjk-heavenly-stem","cjk-ideographic","clear","clip","close-quote","col-resize","collapse","column","compact","condensed","contain","content","contents","content-box","context-menu","continuous","copy","counter","counters","cover","crop","cross","crosshair","currentcolor","cursive","cyclic","dashed","decimal","decimal-leading-zero","default","default-button","destination-atop","destination-in","destination-out","destination-over","devanagari","disc","discard","disclosure-closed","disclosure-open","document","dot-dash","dot-dot-dash","dotted","double","down","e-resize","ease","ease-in","ease-in-out","ease-out","element","ellipse","ellipsis","embed","end","ethiopic","ethiopic-abegede","ethiopic-abegede-am-et","ethiopic-abegede-gez","ethiopic-abegede-ti-er","ethiopic-abegede-ti-et","ethiopic-halehame-aa-er","ethiopic-halehame-aa-et","ethiopic-halehame-am-et","ethiopic-halehame-gez","ethiopic-halehame-om-et","ethiopic-halehame-sid-et","ethiopic-halehame-so-et","ethiopic-halehame-ti-er","ethiopic-halehame-ti-et","ethiopic-halehame-tig","ethiopic-numeric","ew-resize","expanded","extends","extra-condensed","extra-expanded","fantasy","fast","fill","fixed","flat","flex","footnotes","forwards","from","geometricPrecision","georgian","graytext","groove","gujarati","gurmukhi","hand","hangul","hangul-consonant","hebrew","help","hidden","hide","higher","highlight","highlighttext","hiragana","hiragana-iroha","horizontal","hsl","hsla","icon","ignore","inactiveborder","inactivecaption","inactivecaptiontext","infinite","infobackground","infotext","inherit","initial","inline","inline-axis","inline-block","inline-flex","inline-table","inset","inside","intrinsic","invert","italic","japanese-formal","japanese-informal","justify","kannada","katakana","katakana-iroha","keep-all","khmer","korean-hangul-formal","korean-hanja-formal","korean-hanja-informal","landscape","lao","large","larger","left","level","lighter","line-through","linear","linear-gradient","lines","list-item","listbox","listitem","local","logical","loud","lower","lower-alpha","lower-armenian","lower-greek","lower-hexadecimal","lower-latin","lower-norwegian","lower-roman","lowercase","ltr","malayalam","match","matrix","matrix3d","media-controls-background","media-current-time-display","media-fullscreen-button","media-mute-button","media-play-button","media-return-to-realtime-button","media-rewind-button","media-seek-back-button","media-seek-forward-button","media-slider","media-sliderthumb","media-time-remaining-display","media-volume-slider","media-volume-slider-container","media-volume-sliderthumb","medium","menu","menulist","menulist-button","menulist-text","menulist-textfield","menutext","message-box","middle","min-intrinsic","mix","mongolian","monospace","move","multiple","myanmar","n-resize","narrower","ne-resize","nesw-resize","no-close-quote","no-drop","no-open-quote","no-repeat","none","normal","not-allowed","nowrap","ns-resize","numbers","numeric","nw-resize","nwse-resize","oblique","octal","open-quote","optimizeLegibility","optimizeSpeed","oriya","oromo","outset","outside","outside-shape","overlay","overline","padding","padding-box","painted","page","paused","persian","perspective","plus-darker","plus-lighter","pointer","polygon","portrait","pre","pre-line","pre-wrap","preserve-3d","progress","push-button","radial-gradient","radio","read-only","read-write","read-write-plaintext-only","rectangle","region","relative","repeat","repeating-linear-gradient","repeating-radial-gradient","repeat-x","repeat-y","reset","reverse","rgb","rgba","ridge","right","rotate","rotate3d","rotateX","rotateY","rotateZ","round","row-resize","rtl","run-in","running","s-resize","sans-serif","scale","scale3d","scaleX","scaleY","scaleZ","scroll","scrollbar","scroll-position","se-resize","searchfield","searchfield-cancel-button","searchfield-decoration","searchfield-results-button","searchfield-results-decoration","semi-condensed","semi-expanded","separate","serif","show","sidama","simp-chinese-formal","simp-chinese-informal","single","skew","skewX","skewY","skip-white-space","slide","slider-horizontal","slider-vertical","sliderthumb-horizontal","sliderthumb-vertical","slow","small","small-caps","small-caption","smaller","solid","somali","source-atop","source-in","source-out","source-over","space","spell-out","square","square-button","start","static","status-bar","stretch","stroke","sub","subpixel-antialiased","super","sw-resize","symbolic","symbols","table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row","table-row-group","tamil","telugu","text","text-bottom","text-top","textarea","textfield","thai","thick","thin","threeddarkshadow","threedface","threedhighlight","threedlightshadow","threedshadow","tibetan","tigre","tigrinya-er","tigrinya-er-abegede","tigrinya-et","tigrinya-et-abegede","to","top","trad-chinese-formal","trad-chinese-informal","translate","translate3d","translateX","translateY","translateZ","transparent","ultra-condensed","ultra-expanded","underline","up","upper-alpha","upper-armenian","upper-greek","upper-hexadecimal","upper-latin","upper-norwegian","upper-roman","uppercase","urdu","url","var","vertical","vertical-text","visible","visibleFill","visiblePainted","visibleStroke","visual","w-resize","wait","wave","wider","window","windowframe","windowtext","words","x-large","x-small","xor","xx-large","xx-small","bicubic","optimizespeed","grayscale","row","row-reverse","wrap","wrap-reverse","column-reverse","flex-start","flex-end","space-between","space-around", "unset"];
+ var valueKeywords_ = ["above","absolute","activeborder","additive","activecaption","afar","after-white-space","ahead","alias","all","all-scroll","alphabetic","alternate","always","amharic","amharic-abegede","antialiased","appworkspace","arabic-indic","armenian","asterisks","attr","auto","avoid","avoid-column","avoid-page","avoid-region","background","backwards","baseline","below","bidi-override","binary","bengali","blink","block","block-axis","bold","bolder","border","border-box","both","bottom","break","break-all","break-word","bullets","button","buttonface","buttonhighlight","buttonshadow","buttontext","calc","cambodian","capitalize","caps-lock-indicator","caption","captiontext","caret","cell","center","checkbox","circle","cjk-decimal","cjk-earthly-branch","cjk-heavenly-stem","cjk-ideographic","clear","clip","close-quote","col-resize","collapse","column","compact","condensed","conic-gradient","contain","content","contents","content-box","context-menu","continuous","copy","counter","counters","cover","crop","cross","crosshair","currentcolor","cursive","cyclic","dashed","decimal","decimal-leading-zero","default","default-button","destination-atop","destination-in","destination-out","destination-over","devanagari","disc","discard","disclosure-closed","disclosure-open","document","dot-dash","dot-dot-dash","dotted","double","down","e-resize","ease","ease-in","ease-in-out","ease-out","element","ellipse","ellipsis","embed","end","ethiopic","ethiopic-abegede","ethiopic-abegede-am-et","ethiopic-abegede-gez","ethiopic-abegede-ti-er","ethiopic-abegede-ti-et","ethiopic-halehame-aa-er","ethiopic-halehame-aa-et","ethiopic-halehame-am-et","ethiopic-halehame-gez","ethiopic-halehame-om-et","ethiopic-halehame-sid-et","ethiopic-halehame-so-et","ethiopic-halehame-ti-er","ethiopic-halehame-ti-et","ethiopic-halehame-tig","ethiopic-numeric","ew-resize","expanded","extends","extra-condensed","extra-expanded","fantasy","fast","fill","fixed","flat","flex","footnotes","forwards","from","geometricPrecision","georgian","graytext","groove","gujarati","gurmukhi","hand","hangul","hangul-consonant","hebrew","help","hidden","hide","high","higher","highlight","highlighttext","hiragana","hiragana-iroha","horizontal","hsl","hsla","icon","ignore","inactiveborder","inactivecaption","inactivecaptiontext","infinite","infobackground","infotext","inherit","initial","inline","inline-axis","inline-block","inline-flex","inline-table","inset","inside","intrinsic","invert","italic","japanese-formal","japanese-informal","justify","kannada","katakana","katakana-iroha","keep-all","khmer","korean-hangul-formal","korean-hanja-formal","korean-hanja-informal","landscape","lao","large","larger","left","level","lighter","line-through","linear","linear-gradient","lines","list-item","listbox","listitem","local","logical","loud","lower","lower-alpha","lower-armenian","lower-greek","lower-hexadecimal","lower-latin","lower-norwegian","lower-roman","lowercase","ltr","malayalam","match","matrix","matrix3d","media-play-button","media-slider","media-sliderthumb","media-volume-slider","media-volume-sliderthumb","medium","menu","menulist","menulist-button","menutext","message-box","middle","min-intrinsic","mix","mongolian","monospace","move","multiple","myanmar","n-resize","narrower","ne-resize","nesw-resize","no-close-quote","no-drop","no-open-quote","no-repeat","none","normal","not-allowed","nowrap","ns-resize","numbers","numeric","nw-resize","nwse-resize","oblique","octal","open-quote","optimizeLegibility","optimizeSpeed","oriya","oromo","outset","outside","outside-shape","overlay","overline","padding","padding-box","painted","page","paused","persian","perspective","plus-darker","plus-lighter","pointer","polygon","portrait","pre","pre-line","pre-wrap","preserve-3d","progress","push-button","radial-gradient","radio","read-only","read-write","read-write-plaintext-only","rectangle","region","relative","repeat","repeating-linear-gradient","repeating-radial-gradient","repeating-conic-gradient","repeat-x","repeat-y","reset","reverse","rgb","rgba","ridge","right","rotate","rotate3d","rotateX","rotateY","rotateZ","round","row-resize","rtl","run-in","running","s-resize","sans-serif","scale","scale3d","scaleX","scaleY","scaleZ","scroll","scrollbar","scroll-position","se-resize","searchfield","searchfield-cancel-button","searchfield-decoration","searchfield-results-button","searchfield-results-decoration","semi-condensed","semi-expanded","separate","serif","show","sidama","simp-chinese-formal","simp-chinese-informal","single","skew","skewX","skewY","skip-white-space","slide","slider-horizontal","slider-vertical","sliderthumb-horizontal","sliderthumb-vertical","slow","small","small-caps","small-caption","smaller","solid","somali","source-atop","source-in","source-out","source-over","space","spell-out","square","square-button","standard","start","static","status-bar","stretch","stroke","sub","subpixel-antialiased","super","sw-resize","symbolic","symbols","table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row","table-row-group","tamil","telugu","text","text-bottom","text-top","textarea","textfield","thai","thick","thin","threeddarkshadow","threedface","threedhighlight","threedlightshadow","threedshadow","tibetan","tigre","tigrinya-er","tigrinya-er-abegede","tigrinya-et","tigrinya-et-abegede","to","top","trad-chinese-formal","trad-chinese-informal","translate","translate3d","translateX","translateY","translateZ","transparent","ultra-condensed","ultra-expanded","underline","up","upper-alpha","upper-armenian","upper-greek","upper-hexadecimal","upper-latin","upper-norwegian","upper-roman","uppercase","urdu","url","var","vertical","vertical-text","visible","visibleFill","visiblePainted","visibleStroke","visual","w-resize","wait","wave","wider","window","windowframe","windowtext","words","x-large","x-small","xor","xx-large","xx-small","bicubic","optimizespeed","grayscale","row","row-reverse","wrap","wrap-reverse","column-reverse","flex-start","flex-end","space-between","space-around", "unset"];
var wordOperatorKeywords_ = ["in","and","or","not","is not","is a","is","isnt","defined","if unless"],
blockKeywords_ = ["for","if","else","unless", "from", "to"],
diff --git a/src/lib/codemirror/mode/xml/xml.js b/src/lib/codemirror/mode/xml/xml.js
index f987a3a..701e151 100644
--- a/src/lib/codemirror/mode/xml/xml.js
+++ b/src/lib/codemirror/mode/xml/xml.js
@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
+// Distributed under an MIT license: https://codemirror.net/5/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
@@ -52,6 +52,7 @@ var xmlConfig = {
doNotIndent: {},
allowUnquoted: false,
allowMissing: false,
+ allowMissingTagName: false,
caseFold: false
}
@@ -162,8 +163,9 @@ CodeMirror.defineMode("xml", function(editorConf, config_) {
stream.next();
}
return style;
- };
+ }
}
+
function doctype(depth) {
return function(stream, state) {
var ch;
@@ -185,9 +187,13 @@ CodeMirror.defineMode("xml", function(editorConf, config_) {
};
}
+ function lower(tagName) {
+ return tagName && tagName.toLowerCase();
+ }
+
function Context(state, tagName, startOfLine) {
this.prev = state.context;
- this.tagName = tagName;
+ this.tagName = tagName || "";
this.indent = state.indented;
this.startOfLine = startOfLine;
if (config.doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.noIndent))
@@ -203,8 +209,8 @@ CodeMirror.defineMode("xml", function(editorConf, config_) {
return;
}
parentTagName = state.context.tagName;
- if (!config.contextGrabbers.hasOwnProperty(parentTagName) ||
- !config.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) {
+ if (!config.contextGrabbers.hasOwnProperty(lower(parentTagName)) ||
+ !config.contextGrabbers[lower(parentTagName)].hasOwnProperty(lower(nextTagName))) {
return;
}
popContext(state);
@@ -226,6 +232,9 @@ CodeMirror.defineMode("xml", function(editorConf, config_) {
state.tagName = stream.current();
setStyle = "tag";
return attrState;
+ } else if (config.allowMissingTagName && type == "endTag") {
+ setStyle = "tag bracket";
+ return attrState(type, stream, state);
} else {
setStyle = "error";
return tagNameState;
@@ -235,7 +244,7 @@ CodeMirror.defineMode("xml", function(editorConf, config_) {
if (type == "word") {
var tagName = stream.current();
if (state.context && state.context.tagName != tagName &&
- config.implicitlyClosed.hasOwnProperty(state.context.tagName))
+ config.implicitlyClosed.hasOwnProperty(lower(state.context.tagName)))
popContext(state);
if ((state.context && state.context.tagName == tagName) || config.matchClosing === false) {
setStyle = "tag";
@@ -244,6 +253,9 @@ CodeMirror.defineMode("xml", function(editorConf, config_) {
setStyle = "tag error";
return closeStateErr;
}
+ } else if (config.allowMissingTagName && type == "endTag") {
+ setStyle = "tag bracket";
+ return closeState(type, stream, state);
} else {
setStyle = "error";
return closeStateErr;
@@ -271,7 +283,7 @@ CodeMirror.defineMode("xml", function(editorConf, config_) {
var tagName = state.tagName, tagStart = state.tagStart;
state.tagName = state.tagStart = null;
if (type == "selfcloseTag" ||
- config.autoSelfClosers.hasOwnProperty(tagName)) {
+ config.autoSelfClosers.hasOwnProperty(lower(tagName))) {
maybePopContext(state, tagName);
} else {
maybePopContext(state, tagName);
@@ -351,7 +363,7 @@ CodeMirror.defineMode("xml", function(editorConf, config_) {
if (context.tagName == tagAfter[2]) {
context = context.prev;
break;
- } else if (config.implicitlyClosed.hasOwnProperty(context.tagName)) {
+ } else if (config.implicitlyClosed.hasOwnProperty(lower(context.tagName))) {
context = context.prev;
} else {
break;
@@ -359,8 +371,8 @@ CodeMirror.defineMode("xml", function(editorConf, config_) {
}
} else if (tagAfter) { // Opening tag spotted
while (context) {
- var grabbers = config.contextGrabbers[context.tagName];
- if (grabbers && grabbers.hasOwnProperty(tagAfter[2]))
+ var grabbers = config.contextGrabbers[lower(context.tagName)];
+ if (grabbers && grabbers.hasOwnProperty(lower(tagAfter[2])))
context = context.prev;
else
break;
@@ -382,6 +394,17 @@ CodeMirror.defineMode("xml", function(editorConf, config_) {
skipAttribute: function(state) {
if (state.state == attrValueState)
state.state = attrState
+ },
+
+ xmlCurrentTag: function(state) {
+ return state.tagName ? {name: state.tagName, close: state.type == "closeTag"} : null
+ },
+
+ xmlCurrentContext: function(state) {
+ var context = []
+ for (var cx = state.context; cx; cx = cx.prev)
+ context.push(cx.tagName)
+ return context.reverse()
}
};
});