1
0
mirror of https://github.com/chinchang/web-maker.git synced 2025-07-25 07:51:12 +02:00

update cm modes

This commit is contained in:
Kushagra Gour
2024-04-29 16:52:20 +05:30
parent 6093614bbb
commit b059769f94
18 changed files with 1012 additions and 1141 deletions

View File

@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others // 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: * Link to the project's GitHub page:
@@ -349,6 +349,10 @@ CodeMirror.defineMode("coffeescript", function(conf, parserConf) {
return external; 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/x-coffeescript", "coffeescript");
CodeMirror.defineMIME("text/coffeescript", "coffeescript"); CodeMirror.defineMIME("text/coffeescript", "coffeescript");

View File

@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others // 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) { (function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS if (typeof exports == "object" && typeof module == "object") // CommonJS
@@ -28,7 +28,9 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
colorKeywords = parserConfig.colorKeywords || {}, colorKeywords = parserConfig.colorKeywords || {},
valueKeywords = parserConfig.valueKeywords || {}, valueKeywords = parserConfig.valueKeywords || {},
allowNested = parserConfig.allowNested, allowNested = parserConfig.allowNested,
supportsAtComponent = parserConfig.supportsAtComponent === true; lineComment = parserConfig.lineComment,
supportsAtComponent = parserConfig.supportsAtComponent === true,
highlightNonStandardPropertyKeywords = config.highlightNonStandardPropertyKeywords !== false;
var type, override; var type, override;
function ret(style, tp) { type = tp; return style; } function ret(style, tp) { type = tp; return style; }
@@ -62,7 +64,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
if (/[\d.]/.test(stream.peek())) { if (/[\d.]/.test(stream.peek())) {
stream.eatWhile(/[\w.%]/); stream.eatWhile(/[\w.%]/);
return ret("number", "unit"); return ret("number", "unit");
} else if (stream.match(/^-[\w\\\-]+/)) { } else if (stream.match(/^-[\w\\\-]*/)) {
stream.eatWhile(/[\w\\\-]/); stream.eatWhile(/[\w\\\-]/);
if (stream.match(/^\s*:/, false)) if (stream.match(/^\s*:/, false))
return ret("variable-2", "variable-definition"); return ret("variable-2", "variable-definition");
@@ -76,12 +78,11 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
return ret("qualifier", "qualifier"); return ret("qualifier", "qualifier");
} else if (/[:;{}\[\]\(\)]/.test(ch)) { } else if (/[:;{}\[\]\(\)]/.test(ch)) {
return ret(null, ch); return ret(null, ch);
} else if ((ch == "u" && stream.match(/rl(-prefix)?\(/)) || } else if (stream.match(/^[\w-.]+(?=\()/)) {
(ch == "d" && stream.match("omain(")) || if (/^(url(-prefix)?|domain|regexp)$/i.test(stream.current())) {
(ch == "r" && stream.match("egexp("))) { state.tokenize = tokenParenthesized;
stream.backUp(1); }
state.tokenize = tokenParenthesized; return ret("variable callee", "variable");
return ret("property", "word");
} else if (/[\w\\\-]/.test(ch)) { } else if (/[\w\\\-]/.test(ch)) {
stream.eatWhile(/[\w\\\-]/); stream.eatWhile(/[\w\\\-]/);
return ret("property", "word"); return ret("property", "word");
@@ -107,7 +108,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
function tokenParenthesized(stream, state) { function tokenParenthesized(stream, state) {
stream.next(); // Must be '(' stream.next(); // Must be '('
if (!stream.match(/\s*[\"\')]/, false)) if (!stream.match(/^\s*[\"\')]/, false))
state.tokenize = tokenString(")"); state.tokenize = tokenString(")");
else else
state.tokenize = null; state.tokenize = null;
@@ -161,16 +162,16 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
return pushContext(state, stream, "block"); return pushContext(state, stream, "block");
} else if (type == "}" && state.context.prev) { } else if (type == "}" && state.context.prev) {
return popContext(state); return popContext(state);
} else if (supportsAtComponent && /@component/.test(type)) { } else if (supportsAtComponent && /@component/i.test(type)) {
return pushContext(state, stream, "atComponentBlock"); return pushContext(state, stream, "atComponentBlock");
} else if (/^@(-moz-)?document$/.test(type)) { } else if (/^@(-moz-)?document$/i.test(type)) {
return pushContext(state, stream, "documentTypes"); 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"); 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; state.stateArg = type;
return "restricted_atBlock_before"; 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"; return "keyframes";
} else if (type && type.charAt(0) == "@") { } else if (type && type.charAt(0) == "@") {
return pushContext(state, stream, "at"); return pushContext(state, stream, "at");
@@ -197,7 +198,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
override = "property"; override = "property";
return "maybeprop"; return "maybeprop";
} else if (nonStandardPropertyKeywords.hasOwnProperty(word)) { } else if (nonStandardPropertyKeywords.hasOwnProperty(word)) {
override = "string-2"; override = highlightNonStandardPropertyKeywords ? "string-2" : "property";
return "maybeprop"; return "maybeprop";
} else if (allowNested) { } else if (allowNested) {
override = stream.match(/^\s*:(?:\s|$)/, false) ? "property" : "tag"; 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 == "}" || type == "{") return popAndPass(type, stream, state);
if (type == "(") return pushContext(state, stream, "parens"); 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"; override += " error";
} else if (type == "word") { } else if (type == "word") {
wordAsValue(stream); wordAsValue(stream);
@@ -253,6 +254,8 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
}; };
states.pseudo = function(type, stream, state) { states.pseudo = function(type, stream, state) {
if (type == "meta") return "pseudo";
if (type == "word") { if (type == "word") {
override = "variable-3"; override = "variable-3";
return state.context.type; return state.context.type;
@@ -289,7 +292,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
else if (propertyKeywords.hasOwnProperty(word)) else if (propertyKeywords.hasOwnProperty(word))
override = "property"; override = "property";
else if (nonStandardPropertyKeywords.hasOwnProperty(word)) else if (nonStandardPropertyKeywords.hasOwnProperty(word))
override = "string-2"; override = highlightNonStandardPropertyKeywords ? "string-2" : "property";
else if (valueKeywords.hasOwnProperty(word)) else if (valueKeywords.hasOwnProperty(word))
override = "atom"; override = "atom";
else if (colorKeywords.hasOwnProperty(word)) else if (colorKeywords.hasOwnProperty(word))
@@ -380,7 +383,8 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
style = style[0]; style = style[0];
} }
override = style; override = style;
state.state = states[state.state](type, stream, state); if (type != "comment")
state.state = states[state.state](type, stream, state);
return override; return override;
}, },
@@ -398,7 +402,6 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
ch == "{" && (cx.type == "at" || cx.type == "atBlock")) { ch == "{" && (cx.type == "at" || cx.type == "atBlock")) {
// Dedent relative to current context. // Dedent relative to current context.
indent = Math.max(0, cx.indent - indentUnit); indent = Math.max(0, cx.indent - indentUnit);
cx = cx.prev;
} }
} }
return indent; return indent;
@@ -407,6 +410,8 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
electricChars: "}", electricChars: "}",
blockCommentStart: "/*", blockCommentStart: "/*",
blockCommentEnd: "*/", blockCommentEnd: "*/",
blockCommentContinue: " * ",
lineComment: lineComment,
fold: "brace" fold: "brace"
}; };
}); });
@@ -414,7 +419,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
function keySet(array) { function keySet(array) {
var keys = {}; var keys = {};
for (var i = 0; i < array.length; ++i) { for (var i = 0; i < array.length; ++i) {
keys[array[i]] = true; keys[array[i].toLowerCase()] = true;
} }
return keys; return keys;
} }
@@ -438,117 +443,151 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"monochrome", "min-monochrome", "max-monochrome", "resolution", "monochrome", "min-monochrome", "max-monochrome", "resolution",
"min-resolution", "max-resolution", "scan", "grid", "orientation", "min-resolution", "max-resolution", "scan", "grid", "orientation",
"device-pixel-ratio", "min-device-pixel-ratio", "max-device-pixel-ratio", "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_); ], mediaFeatures = keySet(mediaFeatures_);
var mediaValueKeywords_ = [ var mediaValueKeywords_ = [
"landscape", "portrait", "none", "coarse", "fine", "on-demand", "hover", "landscape", "portrait", "none", "coarse", "fine", "on-demand", "hover",
"interlace", "progressive" "interlace", "progressive",
"dark", "light",
"standard", "high"
], mediaValueKeywords = keySet(mediaValueKeywords_); ], mediaValueKeywords = keySet(mediaValueKeywords_);
var propertyKeywords_ = [ var propertyKeywords_ = [
"align-content", "align-items", "align-self", "alignment-adjust", "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-direction", "animation-duration", "animation-fill-mode",
"animation-iteration-count", "animation-name", "animation-play-state", "animation-iteration-count", "animation-name", "animation-play-state",
"animation-timing-function", "appearance", "azimuth", "backface-visibility", "animation-timing-function", "appearance", "azimuth", "backdrop-filter",
"background", "background-attachment", "background-blend-mode", "background-clip", "backface-visibility", "background", "background-attachment",
"background-color", "background-image", "background-origin", "background-position", "background-blend-mode", "background-clip", "background-color",
"background-repeat", "background-size", "baseline-shift", "binding", "background-image", "background-origin", "background-position",
"bleed", "bookmark-label", "bookmark-level", "bookmark-state", "background-position-x", "background-position-y", "background-repeat",
"bookmark-target", "border", "border-bottom", "border-bottom-color", "background-size", "baseline-shift", "binding", "bleed", "block-size",
"border-bottom-left-radius", "border-bottom-right-radius", "bookmark-label", "bookmark-level", "bookmark-state", "bookmark-target",
"border-bottom-style", "border-bottom-width", "border-collapse", "border", "border-bottom", "border-bottom-color", "border-bottom-left-radius",
"border-color", "border-image", "border-image-outset", "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-repeat", "border-image-slice", "border-image-source",
"border-image-width", "border-left", "border-left-color", "border-image-width", "border-left", "border-left-color", "border-left-style",
"border-left-style", "border-left-width", "border-radius", "border-right", "border-left-width", "border-radius", "border-right", "border-right-color",
"border-right-color", "border-right-style", "border-right-width", "border-right-style", "border-right-width", "border-spacing", "border-style",
"border-spacing", "border-style", "border-top", "border-top-color", "border-top", "border-top-color", "border-top-left-radius",
"border-top-left-radius", "border-top-right-radius", "border-top-style", "border-top-right-radius", "border-top-style", "border-top-width",
"border-top-width", "border-width", "bottom", "box-decoration-break", "border-width", "bottom", "box-decoration-break", "box-shadow", "box-sizing",
"box-shadow", "box-sizing", "break-after", "break-before", "break-inside", "break-after", "break-before", "break-inside", "caption-side", "caret-color",
"caption-side", "clear", "clip", "color", "color-profile", "column-count", "clear", "clip", "color", "color-profile", "column-count", "column-fill",
"column-fill", "column-gap", "column-rule", "column-rule-color", "column-gap", "column-rule", "column-rule-color", "column-rule-style",
"column-rule-style", "column-rule-width", "column-span", "column-width", "column-rule-width", "column-span", "column-width", "columns", "contain",
"columns", "content", "counter-increment", "counter-reset", "crop", "cue", "content", "counter-increment", "counter-reset", "crop", "cue", "cue-after",
"cue-after", "cue-before", "cursor", "direction", "display", "cue-before", "cursor", "direction", "display", "dominant-baseline",
"dominant-baseline", "drop-initial-after-adjust", "drop-initial-after-adjust", "drop-initial-after-align",
"drop-initial-after-align", "drop-initial-before-adjust", "drop-initial-before-adjust", "drop-initial-before-align", "drop-initial-size",
"drop-initial-before-align", "drop-initial-size", "drop-initial-value", "drop-initial-value", "elevation", "empty-cells", "fit", "fit-content", "fit-position",
"elevation", "empty-cells", "fit", "fit-position", "flex", "flex-basis", "flex", "flex-basis", "flex-direction", "flex-flow", "flex-grow",
"flex-direction", "flex-flow", "flex-grow", "flex-shrink", "flex-wrap", "flex-shrink", "flex-wrap", "float", "float-offset", "flow-from", "flow-into",
"float", "float-offset", "flow-from", "flow-into", "font", "font-feature-settings", "font", "font-family", "font-feature-settings", "font-kerning",
"font-family", "font-kerning", "font-language-override", "font-size", "font-size-adjust", "font-language-override", "font-optical-sizing", "font-size",
"font-stretch", "font-style", "font-synthesis", "font-variant", "font-size-adjust", "font-stretch", "font-style", "font-synthesis",
"font-variant-alternates", "font-variant-caps", "font-variant-east-asian", "font-variant", "font-variant-alternates", "font-variant-caps",
"font-variant-ligatures", "font-variant-numeric", "font-variant-position", "font-variant-east-asian", "font-variant-ligatures", "font-variant-numeric",
"font-weight", "grid", "grid-area", "grid-auto-columns", "grid-auto-flow", "font-variant-position", "font-variation-settings", "font-weight", "gap",
"grid-auto-position", "grid-auto-rows", "grid-column", "grid-column-end", "grid", "grid-area", "grid-auto-columns", "grid-auto-flow", "grid-auto-rows",
"grid-column-start", "grid-row", "grid-row-end", "grid-row-start", "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", "grid-template-areas", "grid-template-columns",
"grid-template-rows", "hanging-punctuation", "height", "hyphens", "grid-template-rows", "hanging-punctuation", "height", "hyphens", "icon",
"icon", "image-orientation", "image-rendering", "image-resolution", "image-orientation", "image-rendering", "image-resolution", "inline-box-align",
"inline-box-align", "justify-content", "left", "letter-spacing", "inset", "inset-block", "inset-block-end", "inset-block-start", "inset-inline",
"line-break", "line-height", "line-stacking", "line-stacking-ruby", "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", "line-stacking-shift", "line-stacking-strategy", "list-style",
"list-style-image", "list-style-position", "list-style-type", "margin", "list-style-image", "list-style-position", "list-style-type", "margin",
"margin-bottom", "margin-left", "margin-right", "margin-top", "margin-bottom", "margin-left", "margin-right", "margin-top", "marks",
"marker-offset", "marks", "marquee-direction", "marquee-loop", "marquee-direction", "marquee-loop", "marquee-play-count", "marquee-speed",
"marquee-play-count", "marquee-speed", "marquee-style", "max-height", "marquee-style", "mask-clip", "mask-composite", "mask-image", "mask-mode",
"max-width", "min-height", "min-width", "move-to", "nav-down", "nav-index", "mask-origin", "mask-position", "mask-repeat", "mask-size","mask-type",
"nav-left", "nav-right", "nav-up", "object-fit", "object-position", "max-block-size", "max-height", "max-inline-size",
"opacity", "order", "orphans", "outline", "max-width", "min-block-size", "min-height", "min-inline-size", "min-width",
"outline-color", "outline-offset", "outline-style", "outline-width", "mix-blend-mode", "move-to", "nav-down", "nav-index", "nav-left", "nav-right",
"overflow", "overflow-style", "overflow-wrap", "overflow-x", "overflow-y", "nav-up", "object-fit", "object-position", "offset", "offset-anchor",
"padding", "padding-bottom", "padding-left", "padding-right", "padding-top", "offset-distance", "offset-path", "offset-position", "offset-rotate",
"page", "page-break-after", "page-break-before", "page-break-inside", "opacity", "order", "orphans", "outline", "outline-color", "outline-offset",
"page-policy", "pause", "pause-after", "pause-before", "perspective", "outline-style", "outline-width", "overflow", "overflow-style",
"perspective-origin", "pitch", "pitch-range", "play-during", "position", "overflow-wrap", "overflow-x", "overflow-y", "padding", "padding-bottom",
"presentation-level", "punctuation-trim", "quotes", "region-break-after", "padding-left", "padding-right", "padding-top", "page", "page-break-after",
"region-break-before", "region-break-inside", "region-fragment", "page-break-before", "page-break-inside", "page-policy", "pause",
"rendering-intent", "resize", "rest", "rest-after", "rest-before", "richness", "pause-after", "pause-before", "perspective", "perspective-origin", "pitch",
"right", "rotation", "rotation-point", "ruby-align", "ruby-overhang", "pitch-range", "place-content", "place-items", "place-self", "play-during",
"ruby-position", "ruby-span", "shape-image-threshold", "shape-inside", "shape-margin", "position", "presentation-level", "punctuation-trim", "quotes",
"shape-outside", "size", "speak", "speak-as", "speak-header", "region-break-after", "region-break-before", "region-break-inside",
"speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set", "region-fragment", "rendering-intent", "resize", "rest", "rest-after",
"tab-size", "table-layout", "target", "target-name", "target-new", "rest-before", "richness", "right", "rotate", "rotation", "rotation-point",
"target-position", "text-align", "text-align-last", "text-decoration", "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-color", "text-decoration-line", "text-decoration-skip",
"text-decoration-style", "text-emphasis", "text-emphasis-color", "text-decoration-skip-ink", "text-decoration-style", "text-emphasis",
"text-emphasis-position", "text-emphasis-style", "text-height", "text-emphasis-color", "text-emphasis-position", "text-emphasis-style",
"text-indent", "text-justify", "text-outline", "text-overflow", "text-shadow", "text-height", "text-indent", "text-justify", "text-orientation",
"text-size-adjust", "text-space-collapse", "text-transform", "text-underline-position", "text-outline", "text-overflow", "text-rendering", "text-shadow",
"text-wrap", "top", "transform", "transform-origin", "transform-style", "text-size-adjust", "text-space-collapse", "text-transform",
"transition", "transition-delay", "transition-duration", "text-underline-position", "text-wrap", "top", "touch-action", "transform", "transform-origin",
"transition-property", "transition-timing-function", "unicode-bidi", "transform-style", "transition", "transition-delay", "transition-duration",
"vertical-align", "visibility", "voice-balance", "voice-duration", "transition-property", "transition-timing-function", "translate",
"voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress", "unicode-bidi", "user-select", "vertical-align", "visibility", "voice-balance",
"voice-volume", "volume", "white-space", "widows", "width", "word-break", "voice-duration", "voice-family", "voice-pitch", "voice-range", "voice-rate",
"word-spacing", "word-wrap", "z-index", "voice-stress", "voice-volume", "volume", "white-space", "widows", "width",
"will-change", "word-break", "word-spacing", "word-wrap", "writing-mode", "z-index",
// SVG-specific // SVG-specific
"clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color", "clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color",
"flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events", "flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events",
"color-interpolation", "color-interpolation-filters", "color-interpolation", "color-interpolation-filters",
"color-rendering", "fill", "fill-opacity", "fill-rule", "image-rendering", "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-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin",
"stroke-miterlimit", "stroke-opacity", "stroke-width", "text-rendering", "stroke-miterlimit", "stroke-opacity", "stroke-width", "text-rendering",
"baseline-shift", "dominant-baseline", "glyph-orientation-horizontal", "baseline-shift", "dominant-baseline", "glyph-orientation-horizontal",
"glyph-orientation-vertical", "text-anchor", "writing-mode" "glyph-orientation-vertical", "text-anchor", "writing-mode",
], propertyKeywords = keySet(propertyKeywords_); ], propertyKeywords = keySet(propertyKeywords_);
var nonStandardPropertyKeywords_ = [ 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-arrow-color", "scrollbar-base-color", "scrollbar-dark-shadow-color",
"scrollbar-face-color", "scrollbar-highlight-color", "scrollbar-shadow-color", "scrollbar-face-color", "scrollbar-highlight-color", "scrollbar-shadow-color",
"scrollbar-3d-light-color", "scrollbar-track-color", "shape-inside", "scrollbar-track-color", "searchfield-cancel-button", "searchfield-decoration",
"searchfield-cancel-button", "searchfield-decoration", "searchfield-results-button", "searchfield-results-button", "searchfield-results-decoration", "shape-inside", "zoom"
"searchfield-results-decoration", "zoom"
], nonStandardPropertyKeywords = keySet(nonStandardPropertyKeywords_); ], nonStandardPropertyKeywords = keySet(nonStandardPropertyKeywords_);
var fontProperties_ = [ var fontProperties_ = [
"font-family", "src", "unicode-range", "font-variant", "font-feature-settings", "font-display", "font-family", "src", "unicode-range", "font-variant",
"font-stretch", "font-weight", "font-style" "font-feature-settings", "font-stretch", "font-weight", "font-style"
], fontProperties = keySet(fontProperties_); ], fontProperties = keySet(fontProperties_);
var counterDescriptors_ = [ var counterDescriptors_ = [
@@ -561,16 +600,16 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown",
"burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue",
"cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod",
"darkgray", "darkgreen", "darkkhaki", "darkmagenta", "darkolivegreen", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen",
"darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen",
"darkslateblue", "darkslategray", "darkturquoise", "darkviolet", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet",
"deeppink", "deepskyblue", "dimgray", "dodgerblue", "firebrick", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick",
"floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite",
"gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew",
"hotpink", "indianred", "indigo", "ivory", "khaki", "lavender", "hotpink", "indianred", "indigo", "ivory", "khaki", "lavender",
"lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral",
"lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightpink", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink",
"lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey",
"lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta",
"maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple",
"mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise",
@@ -580,7 +619,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue",
"purple", "rebeccapurple", "red", "rosybrown", "royalblue", "saddlebrown", "purple", "rebeccapurple", "red", "rosybrown", "royalblue", "saddlebrown",
"salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "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", "teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white",
"whitesmoke", "yellow", "yellowgreen" "whitesmoke", "yellow", "yellowgreen"
], colorKeywords = keySet(colorKeywords_); ], colorKeywords = keySet(colorKeywords_);
@@ -589,23 +628,23 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"above", "absolute", "activeborder", "additive", "activecaption", "afar", "above", "absolute", "activeborder", "additive", "activecaption", "afar",
"after-white-space", "ahead", "alias", "all", "all-scroll", "alphabetic", "alternate", "after-white-space", "ahead", "alias", "all", "all-scroll", "alphabetic", "alternate",
"always", "amharic", "amharic-abegede", "antialiased", "appworkspace", "always", "amharic", "amharic-abegede", "antialiased", "appworkspace",
"arabic-indic", "armenian", "asterisks", "attr", "auto", "avoid", "avoid-column", "avoid-page", "arabic-indic", "armenian", "asterisks", "attr", "auto", "auto-flow", "avoid", "avoid-column", "avoid-page",
"avoid-region", "background", "backwards", "baseline", "below", "bidi-override", "binary", "avoid-region", "axis-pan", "background", "backwards", "baseline", "below", "bidi-override", "binary",
"bengali", "blink", "block", "block-axis", "bold", "bolder", "border", "border-box", "bengali", "blink", "block", "block-axis", "blur", "bold", "bolder", "border", "border-box",
"both", "bottom", "break", "break-all", "break-word", "bullets", "button", "button-bevel", "both", "bottom", "break", "break-all", "break-word", "brightness", "bullets", "button",
"buttonface", "buttonhighlight", "buttonshadow", "buttontext", "calc", "cambodian", "buttonface", "buttonhighlight", "buttonshadow", "buttontext", "calc", "cambodian",
"capitalize", "caps-lock-indicator", "caption", "captiontext", "caret", "capitalize", "caps-lock-indicator", "caption", "captiontext", "caret",
"cell", "center", "checkbox", "circle", "cjk-decimal", "cjk-earthly-branch", "cell", "center", "checkbox", "circle", "cjk-decimal", "cjk-earthly-branch",
"cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote", "cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote",
"col-resize", "collapse", "color", "color-burn", "color-dodge", "column", "column-reverse", "col-resize", "collapse", "color", "color-burn", "color-dodge", "column", "column-reverse",
"compact", "condensed", "contain", "content", "compact", "condensed", "conic-gradient", "contain", "content", "contents",
"content-box", "context-menu", "continuous", "copy", "counter", "counters", "cover", "crop", "content-box", "context-menu", "continuous", "contrast", "copy", "counter", "counters", "cover", "crop",
"cross", "crosshair", "currentcolor", "cursive", "cyclic", "darken", "dashed", "decimal", "cross", "crosshair", "cubic-bezier", "currentcolor", "cursive", "cyclic", "darken", "dashed", "decimal",
"decimal-leading-zero", "default", "default-button", "destination-atop", "decimal-leading-zero", "default", "default-button", "dense", "destination-atop",
"destination-in", "destination-out", "destination-over", "devanagari", "difference", "destination-in", "destination-out", "destination-over", "devanagari", "difference",
"disc", "discard", "disclosure-closed", "disclosure-open", "document", "disc", "discard", "disclosure-closed", "disclosure-open", "document",
"dot-dash", "dot-dot-dash", "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", "element", "ellipse", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede",
"ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er", "ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er",
"ethiopic-abegede-ti-et", "ethiopic-halehame-aa-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-sid-et", "ethiopic-halehame-so-et",
"ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et", "ethiopic-halehame-tig", "ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et", "ethiopic-halehame-tig",
"ethiopic-numeric", "ew-resize", "exclusion", "expanded", "extends", "extra-condensed", "ethiopic-numeric", "ew-resize", "exclusion", "expanded", "extends", "extra-condensed",
"extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "flex", "flex-end", "flex-start", "footnotes", "extra-expanded", "fantasy", "fast", "fill", "fill-box", "fixed", "flat", "flex", "flex-end", "flex-start", "footnotes",
"forwards", "from", "geometricPrecision", "georgian", "graytext", "groove", "forwards", "from", "geometricPrecision", "georgian", "grayscale", "graytext", "grid", "groove",
"gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hard-light", "hebrew", "gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hard-light", "hebrew",
"help", "hidden", "hide", "higher", "highlight", "highlighttext", "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", "inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite",
"infobackground", "infotext", "inherit", "initial", "inline", "inline-axis", "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", "italic", "japanese-formal", "japanese-informal", "justify", "kannada",
"katakana", "katakana-iroha", "keep-all", "khmer", "katakana", "katakana-iroha", "keep-all", "khmer",
"korean-hangul-formal", "korean-hanja-formal", "korean-hanja-informal", "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", "line-through", "linear", "linear-gradient", "lines", "list-item", "listbox", "listitem",
"local", "logical", "loud", "lower", "lower-alpha", "lower-armenian", "local", "logical", "loud", "lower", "lower-alpha", "lower-armenian",
"lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian", "lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian",
"lower-roman", "lowercase", "ltr", "luminosity", "malayalam", "match", "matrix", "matrix3d", "lower-roman", "lowercase", "ltr", "luminosity", "malayalam", "manipulation", "match", "matrix", "matrix3d",
"media-controls-background", "media-current-time-display", "media-play-button", "media-slider", "media-sliderthumb",
"media-fullscreen-button", "media-mute-button", "media-play-button", "media-volume-slider", "media-volume-sliderthumb", "medium",
"media-return-to-realtime-button", "media-rewind-button", "menu", "menulist", "menulist-button",
"media-seek-back-button", "media-seek-forward-button", "media-slider", "menutext", "message-box", "middle", "min-intrinsic",
"media-sliderthumb", "media-time-remaining-display", "media-volume-slider", "mix", "mongolian", "monospace", "move", "multiple", "multiple_mask_images", "multiply", "myanmar", "n-resize",
"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",
"narrower", "ne-resize", "nesw-resize", "no-close-quote", "no-drop", "narrower", "ne-resize", "nesw-resize", "no-close-quote", "no-drop",
"no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap", "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", "optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset",
"outside", "outside-shape", "overlay", "overline", "padding", "padding-box", "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", "pointer", "polygon", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d",
"progress", "push-button", "radial-gradient", "radio", "read-only", "progress", "push-button", "radial-gradient", "radio", "read-only",
"read-write", "read-write-plaintext-only", "rectangle", "region", "read-write", "read-write-plaintext-only", "rectangle", "region",
"relative", "repeat", "repeating-linear-gradient", "relative", "repeat", "repeating-linear-gradient", "repeating-radial-gradient",
"repeating-radial-gradient", "repeat-x", "repeat-y", "reset", "reverse", "repeating-conic-gradient", "repeat-x", "repeat-y", "reset", "reverse",
"rgb", "rgba", "ridge", "right", "rotate", "rotate3d", "rotateX", "rotateY", "rgb", "rgba", "ridge", "right", "rotate", "rotate3d", "rotateX", "rotateY",
"rotateZ", "round", "row", "row-resize", "row-reverse", "rtl", "run-in", "running", "rotateZ", "round", "row", "row-resize", "row-reverse", "rtl", "run-in", "running",
"s-resize", "sans-serif", "saturation", "scale", "scale3d", "scaleX", "scaleY", "scaleZ", "screen", "s-resize", "sans-serif", "saturate", "saturation", "scale", "scale3d", "scaleX", "scaleY", "scaleZ", "screen",
"scroll", "scrollbar", "se-resize", "searchfield", "scroll", "scrollbar", "scroll-position", "se-resize", "searchfield",
"searchfield-cancel-button", "searchfield-decoration", "searchfield-cancel-button", "searchfield-decoration",
"searchfield-results-button", "searchfield-results-decoration", "searchfield-results-button", "searchfield-results-decoration", "self-start", "self-end",
"semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama", "semi-condensed", "semi-expanded", "separate", "sepia", "serif", "show", "sidama",
"simp-chinese-formal", "simp-chinese-informal", "single", "simp-chinese-formal", "simp-chinese-informal", "single",
"skew", "skewX", "skewY", "skip-white-space", "slide", "slider-horizontal", "skew", "skewX", "skewY", "skip-white-space", "slide", "slider-horizontal",
"slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow", "slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow",
"small", "small-caps", "small-caption", "smaller", "soft-light", "solid", "somali", "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", "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", "sub", "square-button", "start", "static", "status-bar", "stretch", "stroke", "stroke-box", "sub",
"subpixel-antialiased", "super", "sw-resize", "symbolic", "symbols", "table", "subpixel-antialiased", "svg_masks", "super", "sw-resize", "symbolic", "symbols", "system-ui", "table",
"table-caption", "table-cell", "table-column", "table-column-group", "table-caption", "table-cell", "table-column", "table-column-group",
"table-footer-group", "table-header-group", "table-row", "table-row-group", "table-footer-group", "table-header-group", "table-row", "table-row-group",
"tamil", "tamil",
@@ -671,12 +706,12 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"thick", "thin", "threeddarkshadow", "threedface", "threedhighlight", "thick", "thin", "threeddarkshadow", "threedface", "threedhighlight",
"threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er", "threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er",
"tigrinya-er-abegede", "tigrinya-et", "tigrinya-et-abegede", "to", "top", "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", "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-alpha", "upper-armenian", "upper-greek", "upper-hexadecimal",
"upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url", "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", "visibleStroke", "visual", "w-resize", "wait", "wave", "wider",
"window", "windowframe", "windowtext", "words", "wrap", "wrap-reverse", "x-large", "x-small", "xor", "window", "windowframe", "windowtext", "words", "wrap", "wrap-reverse", "x-large", "x-small", "xor",
"xx-large", "xx-small" "xx-large", "xx-small"
@@ -730,6 +765,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
valueKeywords: valueKeywords, valueKeywords: valueKeywords,
fontProperties: fontProperties, fontProperties: fontProperties,
allowNested: true, allowNested: true,
lineComment: "//",
tokenHooks: { tokenHooks: {
"/": function(stream, state) { "/": function(stream, state) {
if (stream.eat("/")) { if (stream.eat("/")) {
@@ -743,8 +779,8 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
} }
}, },
":": function(stream) { ":": function(stream) {
if (stream.match(/\s*\{/)) if (stream.match(/^\s*\{/, false))
return [null, "{"]; return [null, null]
return false; return false;
}, },
"$": function(stream) { "$": function(stream) {
@@ -772,6 +808,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
valueKeywords: valueKeywords, valueKeywords: valueKeywords,
fontProperties: fontProperties, fontProperties: fontProperties,
allowNested: true, allowNested: true,
lineComment: "//",
tokenHooks: { tokenHooks: {
"/": function(stream, state) { "/": function(stream, state) {
if (stream.eat("/")) { if (stream.eat("/")) {
@@ -786,7 +823,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
}, },
"@": function(stream) { "@": function(stream) {
if (stream.eat("{")) return [null, "interpolation"]; 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\\\-]/); stream.eatWhile(/[\w\\\-]/);
if (stream.match(/^\s*:/, false)) if (stream.match(/^\s*:/, false))
return ["variable-2", "variable-definition"]; return ["variable-2", "variable-definition"];

View File

@@ -1,103 +0,0 @@
<!doctype html>
<title>CodeMirror: Closure Stylesheets (GSS) mode</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
<link rel="stylesheet" href="../../addon/hint/show-hint.css">
<script src="../../lib/codemirror.js"></script>
<script src="css.js"></script>
<script src="../../addon/hint/show-hint.js"></script>
<script src="../../addon/hint/css-hint.js"></script>
<style>.CodeMirror {background: #f8f8f8;}</style>
<div id=nav>
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<ul>
<li><a href="../../index.html">Home</a>
<li><a href="../../doc/manual.html">Manual</a>
<li><a href="https://github.com/codemirror/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">Closure Stylesheets (GSS)</a>
</ul>
</div>
<article>
<h2>Closure Stylesheets (GSS) mode</h2>
<form><textarea id="code" name="code">
/* Some example Closure Stylesheets */
@provide 'some.styles';
@require 'other.styles';
@component {
@def FONT_FAMILY "Times New Roman", Georgia, Serif;
@def FONT_SIZE_NORMAL 15px;
@def FONT_NORMAL normal FONT_SIZE_NORMAL FONT_FAMILY;
@def BG_COLOR rgb(235, 239, 249);
@def DIALOG_BORDER_COLOR rgb(107, 144, 218);
@def DIALOG_BG_COLOR BG_COLOR;
@def LEFT_HAND_NAV_WIDTH 180px;
@def LEFT_HAND_NAV_PADDING 3px;
@defmixin size(WIDTH, HEIGHT) {
width: WIDTH;
height: HEIGHT;
}
body {
background-color: BG_COLOR;
margin: 0;
padding: 3em 6em;
font: FONT_NORMAL;
color: #000;
}
#navigation a {
font-weight: bold;
text-decoration: none !important;
}
.dialog {
background-color: DIALOG_BG_COLOR;
border: 1px solid DIALOG_BORDER_COLOR;
}
.content {
position: absolute;
margin-left: add(LEFT_HAND_NAV_PADDING, /* padding left */
LEFT_HAND_NAV_WIDTH,
LEFT_HAND_NAV_PADDING); /* padding right */
}
.logo {
@mixin size(150px, 55px);
background-image: url('http://www.google.com/images/logo_sm.gif');
}
}
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
extraKeys: {"Ctrl-Space": "autocomplete"},
lineNumbers: true,
matchBrackets: "text/x-less",
mode: "text/x-gss"
});
</script>
<p>A mode for <a href="https://github.com/google/closure-stylesheets">Closure Stylesheets</a> (GSS).</p>
<p><strong>MIME type defined:</strong> <code>text/x-gss</code>.</p>
<p><strong>Parsing/Highlighting Tests:</strong> <a href="../../test/index.html#gss_*">normal</a>, <a href="../../test/index.html#verbose,gss_*">verbose</a>.</p>
</article>

View File

@@ -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];",
"}",
"}");
})();

View File

@@ -1,152 +0,0 @@
<!doctype html>
<title>CodeMirror: LESS mode</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="../../addon/edit/matchbrackets.js"></script>
<script src="css.js"></script>
<style>.CodeMirror {border: 1px solid #ddd; line-height: 1.2;}</style>
<div id=nav>
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<ul>
<li><a href="../../index.html">Home</a>
<li><a href="../../doc/manual.html">Manual</a>
<li><a href="https://github.com/codemirror/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">LESS</a>
</ul>
</div>
<article>
<h2>LESS mode</h2>
<form><textarea id="code" name="code">@media screen and (device-aspect-ratio: 16/9) { … }
@media screen and (device-aspect-ratio: 1280/720) { … }
@media screen and (device-aspect-ratio: 2560/1440) { … }
html:lang(fr-be)
tr:nth-child(2n+1) /* represents every odd row of an HTML table */
img:nth-of-type(2n+1) { float: right; }
img:nth-of-type(2n) { float: left; }
body > h2:not(:first-of-type):not(:last-of-type)
html|*:not(:link):not(:visited)
*|*:not(:hover)
p::first-line { text-transform: uppercase }
@namespace foo url(http://www.example.com);
foo|h1 { color: blue } /* first rule */
span[hello="Ocean"][goodbye="Land"]
E[foo]{
padding:65px;
}
input[type="search"]::-webkit-search-decoration,
input[type="search"]::-webkit-search-cancel-button {
-webkit-appearance: none; // Inner-padding issues in Chrome OSX, Safari 5
}
button::-moz-focus-inner,
input::-moz-focus-inner { // Inner padding and border oddities in FF3/4
padding: 0;
border: 0;
}
.btn {
// reset here as of 2.0.3 due to Recess property order
border-color: #ccc;
border-color: rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.25);
}
fieldset span button, fieldset span input[type="file"] {
font-size:12px;
font-family:Arial, Helvetica, sans-serif;
}
.rounded-corners (@radius: 5px) {
border-radius: @radius;
-webkit-border-radius: @radius;
-moz-border-radius: @radius;
}
@import url("something.css");
@light-blue: hsl(190, 50%, 65%);
#menu {
position: absolute;
width: 100%;
z-index: 3;
clear: both;
display: block;
background-color: @blue;
height: 42px;
border-top: 2px solid lighten(@alpha-blue, 20%);
border-bottom: 2px solid darken(@alpha-blue, 25%);
.box-shadow(0, 1px, 8px, 0.6);
-moz-box-shadow: 0 0 0 #000; // Because firefox sucks.
&.docked {
background-color: hsla(210, 60%, 40%, 0.4);
}
&:hover {
background-color: @blue;
}
#dropdown {
margin: 0 0 0 117px;
padding: 0;
padding-top: 5px;
display: none;
width: 190px;
border-top: 2px solid @medium;
color: @highlight;
border: 2px solid darken(@medium, 25%);
border-left-color: darken(@medium, 15%);
border-right-color: darken(@medium, 15%);
border-top-width: 0;
background-color: darken(@medium, 10%);
ul {
padding: 0px;
}
li {
font-size: 14px;
display: block;
text-align: left;
padding: 0;
border: 0;
a {
display: block;
padding: 0px 15px;
text-decoration: none;
color: white;
&:hover {
background-color: darken(@medium, 15%);
text-decoration: none;
}
}
}
.border-radius(5px, bottom);
.box-shadow(0, 6px, 8px, 0.5);
}
}
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers : true,
matchBrackets : true,
mode: "text/x-less"
});
</script>
<p>The LESS mode is a sub-mode of the <a href="index.html">CSS mode</a> (defined in <code>css.js</code>).</p>
<p><strong>Parsing/Highlighting Tests:</strong> <a href="../../test/index.html#less_*">normal</a>, <a href="../../test/index.html#verbose,less_*">verbose</a>.</p>
</article>

View File

@@ -1,157 +0,0 @@
<!doctype html>
<title>CodeMirror: SCSS mode</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="css.js"></script>
<style>.CodeMirror {background: #f8f8f8;}</style>
<div id=nav>
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<ul>
<li><a href="../../index.html">Home</a>
<li><a href="../../doc/manual.html">Manual</a>
<li><a href="https://github.com/codemirror/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">SCSS</a>
</ul>
</div>
<article>
<h2>SCSS mode</h2>
<form><textarea id="code" name="code">
/* Some example SCSS */
@import "compass/css3";
$variable: #333;
$blue: #3bbfce;
$margin: 16px;
.content-navigation {
#nested {
background-color: black;
}
border-color: $blue;
color:
darken($blue, 9%);
}
.border {
padding: $margin / 2;
margin: $margin / 2;
border-color: $blue;
}
@mixin table-base {
th {
text-align: center;
font-weight: bold;
}
td, th {padding: 2px}
}
table.hl {
margin: 2em 0;
td.ln {
text-align: right;
}
}
li {
font: {
family: serif;
weight: bold;
size: 1.2em;
}
}
@mixin left($dist) {
float: left;
margin-left: $dist;
}
#data {
@include left(10px);
@include table-base;
}
.source {
@include flow-into(target);
border: 10px solid green;
margin: 20px;
width: 200px; }
.new-container {
@include flow-from(target);
border: 10px solid red;
margin: 20px;
width: 200px; }
body {
margin: 0;
padding: 3em 6em;
font-family: tahoma, arial, sans-serif;
color: #000;
}
@mixin yellow() {
background: yellow;
}
.big {
font-size: 14px;
}
.nested {
@include border-radius(3px);
@extend .big;
p {
background: whitesmoke;
a {
color: red;
}
}
}
#navigation a {
font-weight: bold;
text-decoration: none !important;
}
h1 {
font-size: 2.5em;
}
h2 {
font-size: 1.7em;
}
h1:before, h2:before {
content: "::";
}
code {
font-family: courier, monospace;
font-size: 80%;
color: #418A8A;
}
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
matchBrackets: true,
mode: "text/x-scss"
});
</script>
<p>The SCSS mode is a sub-mode of the <a href="index.html">CSS mode</a> (defined in <code>css.js</code>).</p>
<p><strong>Parsing/Highlighting Tests:</strong> <a href="../../test/index.html#scss_*">normal</a>, <a href="../../test/index.html#verbose,scss_*">verbose</a>.</p>
</article>

View File

@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others // 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) { (function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS 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 == "-" )) { if (state.startOfLine && !stream.match("-->", false) && (ch == "=" || ch == "-" )) {
state.tokenize = ruby; state.tokenize = ruby;
return state.tokenize(stream, state); return state.tokenize(stream, state);
@@ -98,8 +98,8 @@
return { return {
// default to html mode // default to html mode
startState: function() { startState: function() {
var htmlState = htmlMode.startState(); var htmlState = CodeMirror.startState(htmlMode);
var rubyState = rubyMode.startState(); var rubyState = CodeMirror.startState(rubyMode);
return { return {
htmlState: htmlState, htmlState: htmlState,
rubyState: rubyState, rubyState: rubyState,

View File

@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others // 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) { (function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS if (typeof exports == "object" && typeof module == "object") // CommonJS
@@ -14,7 +14,16 @@
"use strict"; "use strict";
CodeMirror.defineMode("htmlembedded", function(config, parserConfig) { CodeMirror.defineMode("htmlembedded", function(config, parserConfig) {
var closeComment = parserConfig.closeComment || "--%>"
return CodeMirror.multiplexingMode(CodeMirror.getMode(config, "htmlmixed"), { 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 || "<%", open: parserConfig.open || parserConfig.scriptStartRegex || "<%",
close: parserConfig.close || parserConfig.scriptEndRegex || "%>", close: parserConfig.close || parserConfig.scriptEndRegex || "%>",
mode: CodeMirror.getMode(config, parserConfig.scriptingModeSpec) mode: CodeMirror.getMode(config, parserConfig.scriptingModeSpec)

View File

@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others // 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) { (function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS if (typeof exports == "object" && typeof module == "object") // CommonJS
@@ -14,7 +14,7 @@
var defaultTags = { var defaultTags = {
script: [ script: [
["lang", /(javascript|babel)/i, "javascript"], ["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"], ["type", /./, "text/plain"],
[null, null, "javascript"] [null, null, "javascript"]
], ],
@@ -46,11 +46,11 @@
function getAttrValue(text, attr) { function getAttrValue(text, attr) {
var match = text.match(getAttrRegexp(attr)) var match = text.match(getAttrRegexp(attr))
return match ? match[2] : "" return match ? /^\s*(.*?)\s*$/.exec(match[2])[1] : ""
} }
function getTagRegexp(tagName, anchored) { function getTagRegexp(tagName, anchored) {
return new RegExp((anchored ? "^" : "") + "<\/\s*" + tagName + "\s*>", "i"); return new RegExp((anchored ? "^" : "") + "<\/\\s*" + tagName + "\\s*>", "i");
} }
function addTags(from, to) { function addTags(from, to) {
@@ -74,7 +74,8 @@
name: "xml", name: "xml",
htmlMode: true, htmlMode: true,
multilineTagIndentFactor: parserConfig.multilineTagIndentFactor, multilineTagIndentFactor: parserConfig.multilineTagIndentFactor,
multilineTagIndentPastTag: parserConfig.multilineTagIndentPastTag multilineTagIndentPastTag: parserConfig.multilineTagIndentPastTag,
allowMissingTagName: parserConfig.allowMissingTagName,
}); });
var tags = {}; var tags = {};
@@ -105,7 +106,7 @@
return maybeBackup(stream, endTag, state.localMode.token(stream, state.localState)); return maybeBackup(stream, endTag, state.localMode.token(stream, state.localState));
}; };
state.localMode = mode; 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) { } else if (state.inTag) {
state.inTag += stream.current() state.inTag += stream.current()
if (stream.eol()) state.inTag += " " if (stream.eol()) state.inTag += " "
@@ -115,7 +116,7 @@
return { return {
startState: function () { startState: function () {
var state = htmlMode.startState(); var state = CodeMirror.startState(htmlMode);
return {token: html, inTag: null, localMode: null, localState: null, htmlState: state}; return {token: html, inTag: null, localMode: null, localState: null, htmlState: state};
}, },
@@ -133,11 +134,11 @@
return state.token(stream, state); return state.token(stream, state);
}, },
indent: function (state, textAfter) { indent: function (state, textAfter, line) {
if (!state.localMode || /^\s*<\//.test(textAfter)) if (!state.localMode || /^\s*<\//.test(textAfter))
return htmlMode.indent(state.htmlState, textAfter); return htmlMode.indent(state.htmlState, textAfter, line);
else if (state.localMode.indent) else if (state.localMode.indent)
return state.localMode.indent(state.localState, textAfter); return state.localMode.indent(state.localState, textAfter, line);
else else
return CodeMirror.Pass; return CodeMirror.Pass;
}, },

View File

@@ -1,7 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others // 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
// TODO actually recognize syntax of TypeScript constructs
(function(mod) { (function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS if (typeof exports == "object" && typeof module == "object") // CommonJS
@@ -13,16 +11,12 @@
})(function(CodeMirror) { })(function(CodeMirror) {
"use strict"; "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) { CodeMirror.defineMode("javascript", function(config, parserConfig) {
var indentUnit = config.indentUnit; var indentUnit = config.indentUnit;
var statementIndent = parserConfig.statementIndent; var statementIndent = parserConfig.statementIndent;
var jsonldMode = parserConfig.jsonld; var jsonldMode = parserConfig.jsonld;
var jsonMode = parserConfig.json || jsonldMode; var jsonMode = parserConfig.json || jsonldMode;
var trackScope = parserConfig.trackScope !== false
var isTS = parserConfig.typescript; var isTS = parserConfig.typescript;
var wordRE = parserConfig.wordCharacters || /[\w$\xa1-\uffff]/; var wordRE = parserConfig.wordCharacters || /[\w$\xa1-\uffff]/;
@@ -30,54 +24,24 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
var keywords = function(){ var keywords = function(){
function kw(type) {return {type: type, style: "keyword"};} 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 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, "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, "return": D, "break": D, "continue": D, "new": kw("new"), "delete": C, "void": C, "throw": C,
"var": kw("var"), "const": kw("var"), "let": kw("var"), "debugger": kw("debugger"), "var": kw("var"), "const": kw("var"), "let": kw("var"),
"function": kw("function"), "catch": kw("catch"), "function": kw("function"), "catch": kw("catch"),
"for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"), "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
"in": operator, "typeof": operator, "instanceof": operator, "in": operator, "typeof": operator, "instanceof": operator,
"true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom, "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom,
"this": kw("this"), "class": kw("class"), "super": kw("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)"/; var isJsonldKeyword = /^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/;
function readRegexp(stream) { function readRegexp(stream) {
@@ -104,7 +68,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (ch == '"' || ch == "'") { if (ch == '"' || ch == "'") {
state.tokenize = tokenString(ch); state.tokenize = tokenString(ch);
return state.tokenize(stream, state); 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"); return ret("number", "number");
} else if (ch == "." && stream.match("..")) { } else if (ch == "." && stream.match("..")) {
return ret("spread", "meta"); return ret("spread", "meta");
@@ -112,17 +76,10 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
return ret(ch); return ret(ch);
} else if (ch == "=" && stream.eat(">")) { } else if (ch == "=" && stream.eat(">")) {
return ret("=>", "operator"); return ret("=>", "operator");
} else if (ch == "0" && stream.eat(/x/i)) { } else if (ch == "0" && stream.match(/^(?:x[\dA-Fa-f_]+|o[0-7_]+|b[01_]+)n?/)) {
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);
return ret("number", "number"); return ret("number", "number");
} else if (/\d/.test(ch)) { } else if (/\d/.test(ch)) {
stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/); stream.match(/^[\d_]*(?:n|(?:\.[\d_]*)?(?:[eE][+\-]?[\d_]+)?)?/);
return ret("number", "number"); return ret("number", "number");
} else if (ch == "/") { } else if (ch == "/") {
if (stream.eat("*")) { if (stream.eat("*")) {
@@ -133,26 +90,47 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
return ret("comment", "comment"); return ret("comment", "comment");
} else if (expressionAllowed(stream, state, 1)) { } else if (expressionAllowed(stream, state, 1)) {
readRegexp(stream); readRegexp(stream);
stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/); stream.match(/^\b(([gimyus])(?![gimyus]*\2))+\b/);
return ret("regexp", "string-2"); return ret("regexp", "string-2");
} else { } else {
stream.eatWhile(isOperatorChar); stream.eat("=");
return ret("operator", "operator", stream.current()); return ret("operator", "operator", stream.current());
} }
} else if (ch == "`") { } else if (ch == "`") {
state.tokenize = tokenQuasi; state.tokenize = tokenQuasi;
return tokenQuasi(stream, state); return tokenQuasi(stream, state);
} else if (ch == "#") { } else if (ch == "#" && stream.peek() == "!") {
stream.skipToEnd(); 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)) { } 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()); return ret("operator", "operator", stream.current());
} else if (wordRE.test(ch)) { } else if (wordRE.test(ch)) {
stream.eatWhile(wordRE); stream.eatWhile(wordRE);
var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word]; var word = stream.current()
return (known && state.lastType != ".") ? ret(known.type, known.style, word) : if (state.lastType != ".") {
ret("variable", "variable", word); 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); var arrow = stream.string.indexOf("=>", stream.start);
if (arrow < 0) return; 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; var depth = 0, sawSomething = false;
for (var pos = arrow - 1; pos >= 0; --pos) { for (var pos = arrow - 1; pos >= 0; --pos) {
var ch = stream.string.charAt(pos); var ch = stream.string.charAt(pos);
var bracket = brackets.indexOf(ch); var bracket = brackets.indexOf(ch);
if (bracket >= 0 && bracket < 3) { if (bracket >= 0 && bracket < 3) {
if (!depth) { ++pos; break; } if (!depth) { ++pos; break; }
if (--depth == 0) break; if (--depth == 0) { if (ch == "(") sawSomething = true; break; }
} else if (bracket >= 3 && bracket < 6) { } else if (bracket >= 3 && bracket < 6) {
++depth; ++depth;
} else if (wordRE.test(ch)) { } else if (wordRE.test(ch)) {
sawSomething = true; sawSomething = true;
} else if (/["'\/]/.test(ch)) { } else if (/["'\/`]/.test(ch)) {
return; 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) { } else if (sawSomething && !depth) {
++pos; ++pos;
break; break;
@@ -232,7 +219,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
// Parser // 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) { function JSLexical(indented, column, type, align, prev, info) {
this.indented = indented; this.indented = indented;
@@ -244,6 +232,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
} }
function inScope(state, varname) { function inScope(state, varname) {
if (!trackScope) return false
for (var v = state.localVars; v; v = v.next) for (var v = state.localVars; v; v = v.next)
if (v.name == varname) return true; if (v.name == varname) return true;
for (var cx = state.context; cx; cx = cx.prev) { for (var cx = state.context; cx; cx = cx.prev) {
@@ -283,35 +272,70 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
pass.apply(null, arguments); pass.apply(null, arguments);
return true; 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 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; var state = cx.state;
cx.marked = "def"; cx.marked = "def";
if (!trackScope) return
if (state.context) { if (state.context) {
if (inList(state.localVars)) return; if (state.lexical.info == "var" && state.context && state.context.block) {
state.localVars = {name: varname, next: state.localVars}; // FIXME function decls are also not block scoped
} else { var newContext = registerVarScoped(varname, state.context)
if (inList(state.globalVars)) return; if (newContext != null) {
if (parserConfig.globalVars) state.context = newContext
state.globalVars = {name: varname, next: state.globalVars}; 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 // 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() { function pushcontext() {
cx.state.context = {prev: cx.state.context, vars: cx.state.localVars}; cx.state.context = new Context(cx.state.context, cx.state.localVars, false)
cx.state.localVars = defaultVars; 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() { function popcontext() {
cx.state.localVars = cx.state.context.vars; cx.state.localVars = cx.state.context.vars
cx.state.context = cx.state.context.prev; cx.state.context = cx.state.context.prev
} }
popcontext.lex = true
function pushlex(type, info) { function pushlex(type, info) {
var result = function() { var result = function() {
var state = cx.state, indent = state.indented; var state = cx.state, indent = state.indented;
@@ -336,56 +360,87 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
function expect(wanted) { function expect(wanted) {
function exp(type) { function exp(type) {
if (type == wanted) return cont(); if (type == wanted) return cont();
else if (wanted == ";") return pass(); else if (wanted == ";" || type == "}" || type == ")" || type == "]") return pass();
else return cont(exp); else return cont(exp);
}; };
return exp; return exp;
} }
function statement(type, value) { function statement(type, value) {
if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex); if (type == "var") return cont(pushlex("vardef", value), vardef, expect(";"), poplex);
if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex); if (type == "keyword a") return cont(pushlex("form"), parenExpr, statement, poplex);
if (type == "keyword b") return cont(pushlex("form"), 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 == ";") return cont();
if (type == "if") { if (type == "if") {
if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1] == poplex) if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1] == poplex)
cx.state.cc.pop()(); 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 == "function") return cont(functiondef);
if (type == "for") return cont(pushlex("form"), forspec, statement, poplex); if (type == "for") return cont(pushlex("form"), pushblockcontext, forspec, statement, popcontext, poplex);
if (type == "variable") return cont(pushlex("stat"), maybelabel); if (type == "class" || (isTS && value == "interface")) {
if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"), cx.marked = "keyword"
block, poplex, poplex); 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 == "case") return cont(expression, expect(":"));
if (type == "default") return cont(expect(":")); if (type == "default") return cont(expect(":"));
if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"), if (type == "catch") return cont(pushlex("form"), pushcontext, maybeCatchBinding, statement, poplex, popcontext);
statement, poplex, popcontext);
if (type == "class") return cont(pushlex("form"), className, poplex);
if (type == "export") return cont(pushlex("stat"), afterExport, poplex); if (type == "export") return cont(pushlex("stat"), afterExport, poplex);
if (type == "import") return cont(pushlex("stat"), afterImport, 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); return pass(pushlex("stat"), expression, expect(";"), poplex);
} }
function expression(type) { function maybeCatchBinding(type) {
return expressionInner(type, false); if (type == "(") return cont(funarg, expect(")"))
} }
function expressionNoComma(type) { function expression(type, value) {
return expressionInner(type, true); 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) { if (cx.state.fatArrowAt == cx.stream.start) {
var body = noComma ? arrowBodyNoComma : arrowBody; 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); else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext);
} }
var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma; var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;
if (atomicTypes.hasOwnProperty(type)) return cont(maybeop); if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
if (type == "function") return cont(functiondef, maybeop); if (type == "function") return cont(functiondef, maybeop);
if (type == "keyword c") return cont(noComma ? maybeexpressionNoComma : maybeexpression); if (type == "class" || (isTS && value == "interface")) { cx.marked = "keyword"; return cont(pushlex("form"), classExpression, poplex); }
if (type == "(") return cont(pushlex(")"), maybeexpression, comprehension, expect(")"), poplex, maybeop); 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 == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression);
if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop); if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop);
if (type == "{") return contCommasep(objprop, "}", null, maybeop); if (type == "{") return contCommasep(objprop, "}", null, maybeop);
@@ -397,13 +452,9 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (type.match(/[;\}\)\],]/)) return pass(); if (type.match(/[;\}\)\],]/)) return pass();
return pass(expression); return pass(expression);
} }
function maybeexpressionNoComma(type) {
if (type.match(/[;\}\)\],]/)) return pass();
return pass(expressionNoComma);
}
function maybeoperatorComma(type, value) { function maybeoperatorComma(type, value) {
if (type == ",") return cont(expression); if (type == ",") return cont(maybeexpression);
return maybeoperatorNoComma(type, value, false); return maybeoperatorNoComma(type, value, false);
} }
function maybeoperatorNoComma(type, value, noComma) { function maybeoperatorNoComma(type, value, noComma) {
@@ -411,7 +462,9 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
var expr = noComma == false ? expression : expressionNoComma; var expr = noComma == false ? expression : expressionNoComma;
if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext); if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext);
if (type == "operator") { 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); if (value == "?") return cont(expression, expect(":"), expr);
return cont(expr); return cont(expr);
} }
@@ -420,11 +473,17 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (type == "(") return contCommasep(expressionNoComma, ")", "call", me); if (type == "(") return contCommasep(expressionNoComma, ")", "call", me);
if (type == ".") return cont(property, me); if (type == ".") return cont(property, me);
if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, 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) { function quasi(type, value) {
if (type != "quasi") return pass(); if (type != "quasi") return pass();
if (value.slice(value.length - 2) != "${") return cont(quasi); if (value.slice(value.length - 2) != "${") return cont(quasi);
return cont(expression, continueQuasi); return cont(maybeexpression, continueQuasi);
} }
function continueQuasi(type) { function continueQuasi(type) {
if (type == "}") { if (type == "}") {
@@ -444,6 +503,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
function maybeTarget(noComma) { function maybeTarget(noComma) {
return function(type) { return function(type) {
if (type == ".") return cont(noComma ? targetNoComma : target); if (type == ".") return cont(noComma ? targetNoComma : target);
else if (type == "variable" && isTS) return cont(maybeTypeArgs, noComma ? maybeoperatorNoComma : maybeoperatorComma)
else return pass(noComma ? expressionNoComma : expression); else return pass(noComma ? expressionNoComma : expression);
}; };
} }
@@ -461,21 +521,33 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (type == "variable") {cx.marked = "property"; return cont();} if (type == "variable") {cx.marked = "property"; return cont();}
} }
function objprop(type, value) { 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"; cx.marked = "property";
if (value == "get" || value == "set") return cont(getterSetter); 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); return cont(afterprop);
} else if (type == "number" || type == "string") { } else if (type == "number" || type == "string") {
cx.marked = jsonldMode ? "property" : (cx.style + " property"); cx.marked = jsonldMode ? "property" : (cx.style + " property");
return cont(afterprop); return cont(afterprop);
} else if (type == "jsonld-keyword") { } else if (type == "jsonld-keyword") {
return cont(afterprop); return cont(afterprop);
} else if (type == "modifier") { } else if (isTS && isModifier(value)) {
cx.marked = "keyword"
return cont(objprop) return cont(objprop)
} else if (type == "[") { } else if (type == "[") {
return cont(expression, expect("]"), afterprop); return cont(expression, maybetype, expect("]"), afterprop);
} else if (type == "spread") { } 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) { function getterSetter(type) {
@@ -487,18 +559,22 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (type == ":") return cont(expressionNoComma); if (type == ":") return cont(expressionNoComma);
if (type == "(") return pass(functiondef); if (type == "(") return pass(functiondef);
} }
function commasep(what, end) { function commasep(what, end, sep) {
function proceed(type) { function proceed(type, value) {
if (type == ",") { if (sep ? sep.indexOf(type) > -1 : type == ",") {
var lex = cx.state.lexical; var lex = cx.state.lexical;
if (lex.info == "call") lex.pos = (lex.pos || 0) + 1; 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 cont(expect(end));
} }
return function(type) { return function(type, value) {
if (type == end) return cont(); if (type == end || value == end) return cont();
return pass(what, proceed); return pass(what, proceed);
}; };
} }
@@ -511,23 +587,111 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (type == "}") return cont(); if (type == "}") return cont();
return pass(statement, block); return pass(statement, block);
} }
function maybetype(type) { function maybetype(type, value) {
if (isTS && type == ":") return cont(typedef); if (isTS) {
if (type == ":") return cont(typeexpr);
if (value == "?") return cont(maybetype);
}
} }
function maybedefault(_, value) { function maybetypeOrIn(type, value) {
if (value == "=") return cont(expressionNoComma); if (isTS && (type == ":" || value == "in")) return cont(typeexpr)
} }
function typedef(type) { function mayberettype(type) {
if (type == "variable") {cx.marked = "variable-3"; return cont();} 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); return pass(pattern, maybetype, maybeAssign, vardefCont);
} }
function pattern(type, value) { 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 == "variable") { register(value); return cont(); }
if (type == "spread") return cont(pattern); if (type == "spread") return cont(pattern);
if (type == "[") return contCommasep(pattern, "]"); if (type == "[") return contCommasep(eltpattern, "]");
if (type == "{") return contCommasep(proppattern, "}"); if (type == "{") return contCommasep(proppattern, "}");
} }
function proppattern(type, value) { function proppattern(type, value) {
@@ -538,8 +702,12 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (type == "variable") cx.marked = "property"; if (type == "variable") cx.marked = "property";
if (type == "spread") return cont(pattern); if (type == "spread") return cont(pattern);
if (type == "}") return pass(); if (type == "}") return pass();
if (type == "[") return cont(expression, expect(']'), expect(':'), proppattern);
return cont(expect(":"), pattern, maybeAssign); return cont(expect(":"), pattern, maybeAssign);
} }
function eltpattern() {
return pass(pattern, maybeAssign)
}
function maybeAssign(_type, value) { function maybeAssign(_type, value) {
if (value == "=") return cont(expressionNoComma); if (value == "=") return cont(expressionNoComma);
} }
@@ -549,73 +717,111 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
function maybeelse(type, value) { function maybeelse(type, value) {
if (type == "keyword b" && value == "else") return cont(pushlex("form", "else"), statement, poplex); if (type == "keyword b" && value == "else") return cont(pushlex("form", "else"), statement, poplex);
} }
function forspec(type) { function forspec(type, value) {
if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex); if (value == "await") return cont(forspec);
if (type == "(") return cont(pushlex(")"), forspec1, poplex);
} }
function forspec1(type) { function forspec1(type) {
if (type == "var") return cont(vardef, expect(";"), forspec2); if (type == "var") return cont(vardef, forspec2);
if (type == ";") return cont(forspec2); if (type == "variable") return cont(forspec2);
if (type == "variable") return cont(formaybeinof); return pass(forspec2)
return pass(expression, expect(";"), forspec2);
}
function formaybeinof(_type, value) {
if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
return cont(maybeoperatorComma, forspec2);
} }
function forspec2(type, value) { function forspec2(type, value) {
if (type == ";") return cont(forspec3); if (type == ")") return cont()
if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); } if (type == ";") return cont(forspec2)
return pass(expression, expect(";"), forspec3); if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression, forspec2) }
} return pass(expression, forspec2)
function forspec3(type) {
if (type != ")") cont(expression);
} }
function functiondef(type, value) { function functiondef(type, value) {
if (value == "*") {cx.marked = "keyword"; return cont(functiondef);} if (value == "*") {cx.marked = "keyword"; return cont(functiondef);}
if (type == "variable") {register(value); 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); 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) { function className(type, value) {
if (type == "variable") {register(value); return cont(classNameAfter);} if (type == "variable") {register(value); return cont(classNameAfter);}
} }
function classNameAfter(type, value) { 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); if (type == "{") return cont(pushlex("}"), classBody, poplex);
} }
function classBody(type, value) { function classBody(type, value) {
if (type == "variable" || cx.style == "keyword") { if (type == "async" ||
if (value == "static") { (type == "variable" &&
cx.marked = "keyword"; (value == "static" || value == "get" || value == "set" || (isTS && isModifier(value))) &&
return cont(classBody); cx.stream.match(/^\s+#?[\w$\xa1-\uffff]/, false))) {
} cx.marked = "keyword";
cx.marked = "property"; return cont(classBody);
if (value == "get" || value == "set") return cont(classGetterSetter, functiondef, classBody);
return cont(functiondef, 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 == "*") { if (value == "*") {
cx.marked = "keyword"; cx.marked = "keyword";
return cont(classBody); 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 (type == "}") return cont();
if (value == "@") return cont(expression, classBody)
} }
function classGetterSetter(type) { function classfield(type, value) {
if (type != "variable") return pass(); if (value == "!") return cont(classfield)
cx.marked = "property"; if (value == "?") return cont(classfield)
return cont(); 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 == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); }
if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); } if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); }
if (type == "{") return cont(commasep(exportField, "}"), maybeFrom, expect(";"));
return pass(statement); 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) { function afterImport(type) {
if (type == "string") return cont(); 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) { function importSpec(type, value) {
if (type == "{") return contCommasep(importSpec, "}"); if (type == "{") return contCommasep(importSpec, "}");
@@ -623,6 +829,9 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (value == "*") cx.marked = "keyword"; if (value == "*") cx.marked = "keyword";
return cont(maybeAs); return cont(maybeAs);
} }
function maybeMoreImports(type) {
if (type == ",") return cont(importSpec, maybeMoreImports)
}
function maybeAs(_type, value) { function maybeAs(_type, value) {
if (value == "as") { cx.marked = "keyword"; return cont(importSpec); } if (value == "as") { cx.marked = "keyword"; return cont(importSpec); }
} }
@@ -631,16 +840,13 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
} }
function arrayLiteral(type) { function arrayLiteral(type) {
if (type == "]") return cont(); 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, "]")); return pass(commasep(expressionNoComma, "]"));
} }
function comprehension(type) { function enumdef() {
if (type == "for") return cont(forspec, comprehension); return pass(pushlex("form"), pattern, expect("{"), pushlex("}"), commasep(enummember, "}"), poplex, poplex)
if (type == "if") return cont(expression, comprehension); }
function enummember() {
return pass(pattern, maybeAssign);
} }
function isContinuedStatement(state, textAfter) { function isContinuedStatement(state, textAfter) {
@@ -649,6 +855,12 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
/[,.]/.test(textAfter.charAt(0)); /[,.]/.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 // Interface
return { return {
@@ -659,7 +871,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
cc: [], cc: [],
lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false), lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
localVars: parserConfig.localVars, localVars: parserConfig.localVars,
context: parserConfig.localVars && {vars: parserConfig.localVars}, context: parserConfig.localVars && new Context(null, null, false),
indented: basecolumn || 0 indented: basecolumn || 0
}; };
if (parserConfig.globalVars && typeof parserConfig.globalVars == "object") if (parserConfig.globalVars && typeof parserConfig.globalVars == "object")
@@ -682,21 +894,25 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
}, },
indent: function(state, textAfter) { 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; 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 // 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) { if (!/^\s*else\b/.test(textAfter)) for (var i = state.cc.length - 1; i >= 0; --i) {
var c = state.cc[i]; var c = state.cc[i];
if (c == poplex) lexical = lexical.prev; 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") if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat")
lexical = lexical.prev; lexical = lexical.prev;
var type = lexical.type, closing = firstChar == type; 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" && firstChar == "{") return lexical.indented;
else if (type == "form") return lexical.indented + indentUnit; else if (type == "form") return lexical.indented + indentUnit;
else if (type == "stat") else if (type == "stat")
@@ -710,6 +926,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
electricInput: /^\s*(?:case .*?:|default:|\{|\})$/, electricInput: /^\s*(?:case .*?:|default:|\{|\})$/,
blockCommentStart: jsonMode ? null : "/*", blockCommentStart: jsonMode ? null : "/*",
blockCommentEnd: jsonMode ? null : "*/", blockCommentEnd: jsonMode ? null : "*/",
blockCommentContinue: jsonMode ? null : " * ",
lineComment: jsonMode ? null : "//", lineComment: jsonMode ? null : "//",
fold: "brace", fold: "brace",
closeBrackets: "()[]{}''\"\"``", closeBrackets: "()[]{}''\"\"``",
@@ -719,9 +936,9 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
jsonMode: jsonMode, jsonMode: jsonMode,
expressionAllowed: expressionAllowed, expressionAllowed: expressionAllowed,
skipExpression: function(state) { skipExpression: function(state) {
var top = state.cc[state.cc.length - 1] parseJS(state, "atom", "atom", "true", new CodeMirror.StringStream("", 2, null))
if (top == expression || top == expressionNoComma) state.cc.pop()
} }
}; };
}); });
@@ -733,9 +950,10 @@ CodeMirror.defineMIME("text/ecmascript", "javascript");
CodeMirror.defineMIME("application/javascript", "javascript"); CodeMirror.defineMIME("application/javascript", "javascript");
CodeMirror.defineMIME("application/x-javascript", "javascript"); CodeMirror.defineMIME("application/x-javascript", "javascript");
CodeMirror.defineMIME("application/ecmascript", "javascript"); CodeMirror.defineMIME("application/ecmascript", "javascript");
CodeMirror.defineMIME("application/json", {name: "javascript", json: true}); CodeMirror.defineMIME("application/json", { name: "javascript", json: true });
CodeMirror.defineMIME("application/x-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/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("text/typescript", { name: "javascript", typescript: true });
CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true }); CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true });

View File

@@ -1,72 +0,0 @@
<!doctype html>
<title>CodeMirror: JSON-LD mode</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="../../addon/edit/matchbrackets.js"></script>
<script src="../../addon/comment/continuecomment.js"></script>
<script src="../../addon/comment/comment.js"></script>
<script src="javascript.js"></script>
<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id="nav">
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"/></a>
<ul>
<li><a href="../../index.html">Home</a>
<li><a href="../../doc/manual.html">Manual</a>
<li><a href="https://github.com/codemirror/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">JSON-LD</a>
</ul>
</div>
<article>
<h2>JSON-LD mode</h2>
<div><textarea id="code" name="code">
{
"@context": {
"name": "http://schema.org/name",
"description": "http://schema.org/description",
"image": {
"@id": "http://schema.org/image",
"@type": "@id"
},
"geo": "http://schema.org/geo",
"latitude": {
"@id": "http://schema.org/latitude",
"@type": "xsd:float"
},
"longitude": {
"@id": "http://schema.org/longitude",
"@type": "xsd:float"
},
"xsd": "http://www.w3.org/2001/XMLSchema#"
},
"name": "The Empire State Building",
"description": "The Empire State Building is a 102-story landmark in New York City.",
"image": "http://www.civil.usherbrooke.ca/cours/gci215a/empire-state-building.jpg",
"geo": {
"latitude": "40.75",
"longitude": "73.98"
}
}
</textarea></div>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
matchBrackets: true,
autoCloseBrackets: true,
mode: "application/ld+json",
lineWrapping: true
});
</script>
<p>This is a specialization of the <a href="index.html">JavaScript mode</a>.</p>
</article>

View File

@@ -1,61 +0,0 @@
<!doctype html>
<title>CodeMirror: TypeScript mode</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="javascript.js"></script>
<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<ul>
<li><a href="../../index.html">Home</a>
<li><a href="../../doc/manual.html">Manual</a>
<li><a href="https://github.com/codemirror/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">TypeScript</a>
</ul>
</div>
<article>
<h2>TypeScript mode</h2>
<div><textarea id="code" name="code">
class Greeter {
greeting: string;
constructor (message: string) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting;
}
}
var greeter = new Greeter("world");
var button = document.createElement('button')
button.innerText = "Say Hello"
button.onclick = function() {
alert(greeter.greet())
}
document.body.appendChild(button)
</textarea></div>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
matchBrackets: true,
mode: "text/typescript"
});
</script>
<p>This is a specialization of the <a href="index.html">JavaScript mode</a>.</p>
</article>

View File

@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others // 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) { (function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS if (typeof exports == "object" && typeof module == "object") // CommonJS
@@ -26,13 +26,13 @@
} }
CodeMirror.defineMode("jsx", function(config, modeConfig) { 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") var jsMode = CodeMirror.getMode(config, modeConfig && modeConfig.base || "javascript")
function flatXMLIndent(state) { function flatXMLIndent(state) {
var tagName = state.tagName var tagName = state.tagName
state.tagName = null state.tagName = null
var result = xmlMode.indent(state, "") var result = xmlMode.indent(state, "", "")
state.tagName = tagName state.tagName = tagName
return result return result
} }
@@ -103,10 +103,11 @@
} }
function jsToken(stream, state, cx) { function jsToken(stream, state, cx) {
if (stream.peek() == "<" && jsMode.expressionAllowed(stream, cx.state)) { if (stream.peek() == "<" && !stream.match(/^<([^<>]|<[^>]*>)+,\s*>/, false) &&
jsMode.skipExpression(cx.state) jsMode.expressionAllowed(stream, cx.state)) {
state.context = new Context(CodeMirror.startState(xmlMode, jsMode.indent(cx.state, "")), state.context = new Context(CodeMirror.startState(xmlMode, jsMode.indent(cx.state, "", "")),
xmlMode, 0, state.context) xmlMode, 0, state.context)
jsMode.skipExpression(cx.state)
return null return null
} }

View File

@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others // 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) { (function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS if (typeof exports == "object" && typeof module == "object") // CommonJS
@@ -35,15 +35,6 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
if (modeCfg.maxBlockquoteDepth === undefined) if (modeCfg.maxBlockquoteDepth === undefined)
modeCfg.maxBlockquoteDepth = 0; 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] ") // Turn on task lists? ("- [ ] " and "- [x] ")
if (modeCfg.taskLists === undefined) modeCfg.taskLists = false; if (modeCfg.taskLists === undefined) modeCfg.taskLists = false;
@@ -51,6 +42,18 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
if (modeCfg.strikethrough === undefined) if (modeCfg.strikethrough === undefined)
modeCfg.strikethrough = false; 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. // Allow token types to be overridden by user-provided token types.
if (modeCfg.tokenTypeOverrides === undefined) if (modeCfg.tokenTypeOverrides === undefined)
modeCfg.tokenTypeOverrides = {}; modeCfg.tokenTypeOverrides = {};
@@ -63,7 +66,9 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
list2: "variable-3", list2: "variable-3",
list3: "keyword", list3: "keyword",
hr: "hr", hr: "hr",
image: "tag", image: "image",
imageAltText: "image-alt-text",
imageMarker: "image-marker",
formatting: "formatting", formatting: "formatting",
linkInline: "link", linkInline: "link",
linkEmail: "link", linkEmail: "link",
@@ -71,7 +76,8 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
linkHref: "string", linkHref: "string",
em: "em", em: "em",
strong: "strong", strong: "strong",
strikethrough: "strikethrough" strikethrough: "strikethrough",
emoji: "builtin"
}; };
for (var tokenType in tokenTypes) { for (var tokenType in tokenTypes) {
@@ -81,14 +87,15 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
} }
var hrRE = /^([*\-_])(?:\s*\1){2,}\s*$/ var hrRE = /^([*\-_])(?:\s*\1){2,}\s*$/
, ulRE = /^[*\-+]\s+/ , listRE = /^(?:[*\-+]|^[0-9]+([.)]))\s+/
, olRE = /^[0-9]+([.)])\s+/ , taskListRE = /^\[(x| )\](?=\s)/i // Must follow listRE
, taskListRE = /^\[(x| )\](?=\s)/ // Must follow ulRE or olRE
, atxHeaderRE = modeCfg.allowAtxHeaderWithoutSpace ? /^(#+)/ : /^(#+)(?: |$)/ , atxHeaderRE = modeCfg.allowAtxHeaderWithoutSpace ? /^(#+)/ : /^(#+)(?: |$)/
, setextHeaderRE = /^ *(?:\={1,}|-{1,})\s*$/ , setextHeaderRE = /^ {0,3}(?:\={1,}|-{2,})\s*$/
, textRE = /^[^#!\[\]*_\\<>` "'(~]+/ , textRE = /^[^#!\[\]*_\\<>` "'(~:]+/
, fencedCodeRE = new RegExp("^(" + (modeCfg.fencedCodeBlocks === true ? "~~~+|```+" : modeCfg.fencedCodeBlocks) + , fencedCodeRE = /^(~~~+|```+)[ \t]*([\w\/+#-]*)[^\n`]*$/
")[ \\t]*([\\w+#\-]*)"); , 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) { function switchInline(stream, state, f) {
state.f = state.inline = f; state.f = state.inline = f;
@@ -109,6 +116,8 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
function blankLine(state) { function blankLine(state) {
// Reset linkTitle state // Reset linkTitle state
state.linkTitle = false; state.linkTitle = false;
state.linkHref = false;
state.linkText = false;
// Reset EM state // Reset EM state
state.em = false; state.em = false;
// Reset STRONG state // Reset STRONG state
@@ -119,94 +128,106 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
state.quote = 0; state.quote = 0;
// Reset state.indentedCode // Reset state.indentedCode
state.indentedCode = false; state.indentedCode = false;
if (htmlModeMissing && state.f == htmlBlock) { if (state.f == htmlBlock) {
state.f = inlineNormal; var exit = htmlModeMissing
state.block = blockNormal; 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 // Reset state.trailingSpace
state.trailingSpace = 0; state.trailingSpace = 0;
state.trailingSpaceNewLine = false; state.trailingSpaceNewLine = false;
// Mark this line as blank // Mark this line as blank
state.prevLine = state.thisLine state.prevLine = state.thisLine
state.thisLine = null state.thisLine = {stream: null}
return null; return null;
} }
function blockNormal(stream, state) { function blockNormal(stream, state) {
var firstTokenOnLine = stream.column() === state.indentation;
var sol = stream.sol(); var prevLineLineIsEmpty = lineIsEmpty(state.prevLine.stream);
var prevLineIsIndentedCode = state.indentedCode;
var prevLineIsList = state.list !== false, var prevLineIsHr = state.prevLine.hr;
prevLineIsIndentedCode = state.indentedCode; var prevLineIsList = state.list !== false;
var maxNonCodeIndentation = (state.listStack[state.listStack.length - 1] || 0) + 3;
state.indentedCode = false; state.indentedCode = false;
if (prevLineIsList) { var lineIndentation = state.indentation;
if (state.indentationDiff >= 0) { // Continued list // compute once per line (on first token)
if (state.indentationDiff < 4) { // Only adjust indentation if *not* a code block if (state.indentationDiff === null) {
state.indentation -= state.indentationDiff; 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; var match = null;
if (state.indentationDiff >= 4) { if (state.indentationDiff >= 4 && (prevLineIsIndentedCode || state.prevLine.fencedCodeEnd ||
state.prevLine.header || prevLineLineIsEmpty)) {
stream.skipToEnd(); stream.skipToEnd();
if (prevLineIsIndentedCode || lineIsEmpty(state.prevLine)) { state.indentedCode = true;
state.indentation -= 4; return tokenTypes.code;
state.indentedCode = true;
return tokenTypes.code;
} else {
return null;
}
} else if (stream.eatSpace()) { } else if (stream.eatSpace()) {
return null; 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.header = match[1].length;
state.thisLine.header = true;
if (modeCfg.highlightFormatting) state.formatting = "header"; if (modeCfg.highlightFormatting) state.formatting = "header";
state.f = state.inline; state.f = state.inline;
return getType(state); return getType(state);
} else if (!lineIsEmpty(state.prevLine) && !state.quote && !prevLineIsList && } else if (state.indentation <= maxNonCodeIndentation && stream.eat('>')) {
!prevLineIsIndentedCode && (match = stream.match(setextHeaderRE))) { state.quote = firstTokenOnLine ? 1 : state.quote + 1;
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;
if (modeCfg.highlightFormatting) state.formatting = "quote"; if (modeCfg.highlightFormatting) state.formatting = "quote";
stream.eatSpace(); stream.eatSpace();
return getType(state); return getType(state);
} else if (stream.peek() === '[') { } else if (!isHr && !state.setext && firstTokenOnLine && state.indentation <= maxNonCodeIndentation && (match = stream.match(listRE))) {
return switchInline(stream, state, footnoteLink); var listType = match[1] ? "ol" : "ul";
} 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;
// While this list item's marker's indentation state.indentation = lineIndentation + stream.current().length;
// is less than the deepest list item's content's indentation, state.list = true;
// pop the deepest list item indentation off the stack. state.quote = 0;
while (state.listStack && stream.column() < state.listStack[state.listStack.length - 1]) {
state.listStack.pop();
}
// Add this list item's content's indentation to the stack // Add this list item's content's indentation to the stack
state.listStack.push(state.indentation); 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)) { if (modeCfg.taskLists && stream.match(taskListRE, false)) {
state.taskList = true; state.taskList = true;
@@ -214,15 +235,47 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
state.f = state.inline; state.f = state.inline;
if (modeCfg.highlightFormatting) state.formatting = ["list", "list-" + listType]; if (modeCfg.highlightFormatting) state.formatting = ["list", "list-" + listType];
return getType(state); return getType(state);
} else if (modeCfg.fencedCodeBlocks && (match = stream.match(fencedCodeRE, true))) { } else if (firstTokenOnLine && state.indentation <= maxNonCodeIndentation && (match = stream.match(fencedCodeRE, true))) {
state.fencedChars = match[1] state.quote = 0;
state.fencedEndRE = new RegExp(match[1] + "+ *$");
// try switching mode // 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); if (state.localMode) state.localState = CodeMirror.startState(state.localMode);
state.f = state.block = local; state.f = state.block = local;
if (modeCfg.highlightFormatting) state.formatting = "code-block"; if (modeCfg.highlightFormatting) state.formatting = "code-block";
state.code = -1 state.code = -1
return getType(state); 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); return switchInline(stream, state, state.inline);
@@ -244,10 +297,21 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
} }
function local(stream, state) { 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.localMode = state.localState = null;
state.f = state.block = leavingLocal; state.block = blockNormal;
return null; 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) { } else if (state.localMode) {
return state.localMode.token(stream, state.localState); return state.localMode.token(stream, state.localState);
} else { } 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 // Inline
function getType(state) { function getType(state) {
var styles = []; var styles = [];
@@ -311,8 +363,12 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
if (state.strong) { styles.push(tokenTypes.strong); } if (state.strong) { styles.push(tokenTypes.strong); }
if (state.em) { styles.push(tokenTypes.em); } if (state.em) { styles.push(tokenTypes.em); }
if (state.strikethrough) { styles.push(tokenTypes.strikethrough); } if (state.strikethrough) { styles.push(tokenTypes.strikethrough); }
if (state.emoji) { styles.push(tokenTypes.emoji); }
if (state.linkText) { styles.push(tokenTypes.linkText); } if (state.linkText) { styles.push(tokenTypes.linkText); }
if (state.code) { styles.push(tokenTypes.code); } 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); } if (state.header) { styles.push(tokenTypes.header, tokenTypes.header + "-" + state.header); }
@@ -366,7 +422,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
} }
if (state.taskList) { if (state.taskList) {
var taskOpen = stream.match(taskListRE, true)[1] !== "x"; var taskOpen = stream.match(taskListRE, true)[1] === " ";
if (taskOpen) state.taskOpen = true; if (taskOpen) state.taskOpen = true;
else state.taskClosed = true; else state.taskClosed = true;
if (modeCfg.highlightFormatting) state.formatting = "task"; if (modeCfg.highlightFormatting) state.formatting = "task";
@@ -382,9 +438,6 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
return getType(state); return getType(state);
} }
// Get sol() value now, before character is consumed
var sol = stream.sol();
var ch = stream.next(); var ch = stream.next();
// Matches link titles present on next line // Matches link titles present on next line
@@ -394,7 +447,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
if (ch === '(') { if (ch === '(') {
matchCh = ')'; matchCh = ')';
} }
matchCh = (matchCh+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1"); matchCh = (matchCh+'').replace(/([.?*+^\[\]\\(){}|-])/g, "\\$1");
var regex = '^\\s*(?:[^' + matchCh + '\\\\]+|\\\\\\\\|\\\\.)' + matchCh; var regex = '^\\s*(?:[^' + matchCh + '\\\\]+|\\\\\\\\|\\\\.)' + matchCh;
if (stream.match(new RegExp(regex), true)) { if (stream.match(new RegExp(regex), true)) {
return tokenTypes.linkHref; return tokenTypes.linkHref;
@@ -407,7 +460,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
if (modeCfg.highlightFormatting) state.formatting = "code"; if (modeCfg.highlightFormatting) state.formatting = "code";
stream.eatWhile('`'); stream.eatWhile('`');
var count = stream.current().length var count = stream.current().length
if (state.code == 0) { if (state.code == 0 && (!state.quote || count == 1)) {
state.code = count state.code = count
return getType(state) return getType(state)
} else if (count == state.code) { // Must be exact } else if (count == state.code) { // Must be exact
@@ -432,22 +485,40 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
} }
if (ch === '!' && stream.match(/\[[^\]]*\] ?(?:\(|\[)/, false)) { if (ch === '!' && stream.match(/\[[^\]]*\] ?(?:\(|\[)/, false)) {
stream.match(/\[[^\]]*\]/); state.imageMarker = true;
state.inline = state.f = linkHref; state.image = true;
return tokenTypes.image; 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; state.linkText = true;
if (modeCfg.highlightFormatting) state.formatting = "link"; if (modeCfg.highlightFormatting) state.formatting = "link";
return getType(state); return getType(state);
} }
if (ch === ']' && state.linkText && stream.match(/\(.*?\)| ?\[.*?\]/, false)) { if (ch === ']' && state.linkText) {
if (modeCfg.highlightFormatting) state.formatting = "link"; if (modeCfg.highlightFormatting) state.formatting = "link";
var type = getType(state); var type = getType(state);
state.linkText = false; state.linkText = false;
state.inline = state.f = linkHref; state.inline = state.f = stream.match(/\(.*?\)| ?\[.*?\]/, false) ? linkHref : inlineNormal
return type; return type;
} }
@@ -475,7 +546,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
return type + tokenTypes.linkEmail; 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); var end = stream.string.indexOf(">", stream.pos);
if (end != -1) { if (end != -1) {
var atts = stream.string.substring(stream.start, end); var atts = stream.string.substring(stream.start, end);
@@ -486,44 +557,37 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
return switchBlock(stream, state, htmlBlock); return switchBlock(stream, state, htmlBlock);
} }
if (ch === '<' && stream.match(/^\/\w*?>/)) { if (modeCfg.xml && ch === '<' && stream.match(/^\/\w*?>/)) {
state.md_inside = false; state.md_inside = false;
return "tag"; return "tag";
} } else if (ch === "*" || ch === "_") {
var len = 1, before = stream.pos == 1 ? " " : stream.string.charAt(stream.pos - 2)
var ignoreUnderscore = false; while (len < 3 && stream.eat(ch)) len++
if (!modeCfg.underscoresBreakWords) { var after = stream.peek() || " "
if (ch === '_' && stream.peek() !== '_' && stream.match(/(\w)/, false)) { // See http://spec.commonmark.org/0.27/#emphasis-and-strong-emphasis
var prevPos = stream.pos - 2; var leftFlanking = !/\s/.test(after) && (!punctuation.test(after) || /\s/.test(before) || punctuation.test(before))
if (prevPos >= 0) { var rightFlanking = !/\s/.test(before) && (!punctuation.test(before) || /\s/.test(after) || punctuation.test(after))
var prevCh = stream.string.charAt(prevPos); var setEm = null, setStrong = null
if (prevCh !== '_' && prevCh.match(/(\w)/, false)) { if (len % 2) { // Em
ignoreUnderscore = true; 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 (len > 1) { // Strong
if (ch === '*' || (ch === '_' && !ignoreUnderscore)) { if (!state.strong && leftFlanking && (ch === "*" || !rightFlanking || punctuation.test(before)))
if (sol && stream.peek() === ' ') { setStrong = true
// Do nothing, surrounded by newline and space else if (state.strong == ch && rightFlanking && (ch === "*" || !leftFlanking || punctuation.test(after)))
} else if (state.strong === ch && stream.eat(ch)) { // Remove STRONG setStrong = false
if (modeCfg.highlightFormatting) state.formatting = "strong"; }
var t = getType(state); if (setStrong != null || setEm != null) {
state.strong = false; if (modeCfg.highlightFormatting) state.formatting = setEm == null ? "strong" : setStrong == null ? "em" : "strong em"
return t; if (setEm === true) state.em = ch
} else if (!state.strong && stream.eat(ch)) { // Add STRONG if (setStrong === true) state.strong = ch
state.strong = ch; var t = getType(state)
if (modeCfg.highlightFormatting) state.formatting = "strong"; if (setEm === false) state.em = false
return getType(state); if (setStrong === false) state.strong = false
} else if (state.em === ch) { // Remove EM return t
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);
} }
} else if (ch === ' ') { } else if (ch === ' ') {
if (stream.eat('*') || stream.eat('_')) { // Probably surrounded by spaces if (stream.eat('*') || stream.eat('_')) { // Probably surrounded by spaces
@@ -548,7 +612,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
return getType(state); return getType(state);
} }
} else if (ch === ' ') { } 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 if (stream.peek() === ' ') { // Surrounded by spaces, ignore
return getType(state); return getType(state);
} else { // Not surrounded by spaces, back up pointer } 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 (ch === ' ') {
if (stream.match(/ +$/, false)) { if (stream.match(/^ +$/, false)) {
state.trailingSpace++; state.trailingSpace++;
} else if (state.trailingSpace) { } else if (state.trailingSpace) {
state.trailingSpaceNewLine = true; state.trailingSpaceNewLine = true;
@@ -596,7 +668,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
} }
var ch = stream.next(); var ch = stream.next();
if (ch === '(' || ch === '[') { if (ch === '(' || ch === '[') {
state.f = state.inline = getLinkHrefInside(ch === "(" ? ")" : "]", 0); state.f = state.inline = getLinkHrefInside(ch === "(" ? ")" : "]");
if (modeCfg.highlightFormatting) state.formatting = "link-string"; if (modeCfg.highlightFormatting) state.formatting = "link-string";
state.linkHref = true; state.linkHref = true;
return getType(state); return getType(state);
@@ -606,7 +678,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
var linkRE = { var linkRE = {
")": /^(?:[^\\\(\)]|\\.|\((?:[^\\\(\)]|\\.)*\))*?(?=\))/, ")": /^(?:[^\\\(\)]|\\.|\((?:[^\\\(\)]|\\.)*\))*?(?=\))/,
"]": /^(?:[^\\\[\]]|\\.|\[(?:[^\\\[\\]]|\\.)*\])*?(?=\])/ "]": /^(?:[^\\\[\]]|\\.|\[(?:[^\\\[\]]|\\.)*\])*?(?=\])/
} }
function getLinkHrefInside(endChar) { function getLinkHrefInside(endChar) {
@@ -639,7 +711,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
} }
function footnoteLinkInside(stream, state) { function footnoteLinkInside(stream, state) {
if (stream.match(/^\]:/, true)) { if (stream.match(']:', true)) {
state.f = state.inline = footnoteUrl; state.f = state.inline = footnoteUrl;
if (modeCfg.highlightFormatting) state.formatting = "link"; if (modeCfg.highlightFormatting) state.formatting = "link";
var returnType = getType(state); 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 if (stream.peek() === undefined) { // End of line, set flag to check next line
state.linkTitle = true; state.linkTitle = true;
} else { // More content on line, check if link title } else { // More content on line, check if link title
stream.match(/^(?:\s+(?:"(?:[^"\\]|\\\\|\\.)+"|'(?:[^'\\]|\\\\|\\.)+'|\((?:[^)\\]|\\\\|\\.)+\)))?/, true); stream.match(/^(?:\s+(?:"(?:[^"\\]|\\.)+"|'(?:[^'\\]|\\.)+'|\((?:[^)\\]|\\.)+\)))?/, true);
} }
state.f = state.inline = inlineNormal; state.f = state.inline = inlineNormal;
return tokenTypes.linkHref + " url"; return tokenTypes.linkHref + " url";
@@ -674,8 +746,8 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
return { return {
f: blockNormal, f: blockNormal,
prevLine: null, prevLine: {stream: null},
thisLine: null, thisLine: {stream: null},
block: blockNormal, block: blockNormal,
htmlState: null, htmlState: null,
@@ -692,6 +764,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
em: false, em: false,
strong: false, strong: false,
header: 0, header: 0,
setext: 0,
hr: false, hr: false,
taskList: false, taskList: false,
list: false, list: false,
@@ -700,7 +773,8 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
trailingSpace: 0, trailingSpace: 0,
trailingSpaceNewLine: false, trailingSpaceNewLine: false,
strikethrough: false, strikethrough: false,
fencedChars: null emoji: false,
fencedEndRE: null
}; };
}, },
@@ -721,12 +795,16 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
inline: s.inline, inline: s.inline,
text: s.text, text: s.text,
formatting: false, formatting: false,
linkText: s.linkText,
linkTitle: s.linkTitle, linkTitle: s.linkTitle,
linkHref: s.linkHref,
code: s.code, code: s.code,
em: s.em, em: s.em,
strong: s.strong, strong: s.strong,
strikethrough: s.strikethrough, strikethrough: s.strikethrough,
emoji: s.emoji,
header: s.header, header: s.header,
setext: s.setext,
hr: s.hr, hr: s.hr,
taskList: s.taskList, taskList: s.taskList,
list: s.list, list: s.list,
@@ -736,7 +814,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
trailingSpace: s.trailingSpace, trailingSpace: s.trailingSpace,
trailingSpaceNewLine: s.trailingSpaceNewLine, trailingSpaceNewLine: s.trailingSpaceNewLine,
md_inside: s.md_inside, md_inside: s.md_inside,
fencedChars: s.fencedChars fencedEndRE: s.fencedEndRE
}; };
}, },
@@ -745,21 +823,17 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
// Reset state.formatting // Reset state.formatting
state.formatting = false; state.formatting = false;
if (stream != state.thisLine) { if (stream != state.thisLine.stream) {
var forceBlankLine = state.header || state.hr;
// Reset state.header and state.hr
state.header = 0; state.header = 0;
state.hr = false; state.hr = false;
if (stream.match(/^\s*$/, true) || forceBlankLine) { if (stream.match(/^\s*$/, true)) {
blankLine(state); blankLine(state);
if (!forceBlankLine) return null return null;
state.prevLine = null
} }
state.prevLine = state.thisLine state.prevLine = state.thisLine
state.thisLine = stream state.thisLine = {stream: stream}
// Reset state.taskList // Reset state.taskList
state.taskList = false; state.taskList = false;
@@ -768,11 +842,15 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
state.trailingSpace = 0; state.trailingSpace = 0;
state.trailingSpaceNewLine = false; state.trailingSpaceNewLine = false;
state.f = state.block; if (!state.localState) {
var indentation = stream.match(/^\s*/, true)[0].replace(/\t/g, ' ').length; state.f = state.block;
state.indentationDiff = Math.min(indentation - state.indentation, 4); if (state.f != htmlBlock) {
state.indentation = state.indentation + state.indentationDiff; var indentation = stream.match(/^\s*/, true)[0].replace(/\t/g, expandedTab).length;
if (indentation > 0) return null; state.indentation = indentation;
state.indentationDiff = null;
if (indentation > 0) return null;
}
}
} }
return state.f(stream, state); return state.f(stream, state);
}, },
@@ -783,15 +861,26 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
return {state: state, mode: mode}; 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, blankLine: blankLine,
getType: getType, getType: getType,
blockCommentStart: "<!--",
blockCommentEnd: "-->",
closeBrackets: "()[]{}''\"\"``",
fold: "markdown" fold: "markdown"
}; };
return mode; return mode;
}, "xml"); }, "xml");
CodeMirror.defineMIME("text/markdown", "markdown");
CodeMirror.defineMIME("text/x-markdown", "markdown"); CodeMirror.defineMIME("text/x-markdown", "markdown");
}); });

View File

@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others // 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) { (function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS if (typeof exports == "object" && typeof module == "object") // CommonJS
@@ -261,7 +261,7 @@ CodeMirror.defineMode("pug", function (config) {
} }
return 'variable'; return 'variable';
} }
if (stream.match(/^\+#{/, false)) { if (stream.match('+#{', false)) {
stream.next(); stream.next();
state.mixinCallAfter = true; state.mixinCallAfter = true;
return interpolation(stream, state); return interpolation(stream, state);
@@ -545,12 +545,12 @@ CodeMirror.defineMode("pug", function (config) {
|| javaScriptArguments(stream, state) || javaScriptArguments(stream, state)
|| callArguments(stream, state) || callArguments(stream, state)
|| yieldStatement(stream, state) || yieldStatement(stream)
|| doctype(stream, state) || doctype(stream)
|| interpolation(stream, state) || interpolation(stream, state)
|| caseStatement(stream, state) || caseStatement(stream, state)
|| when(stream, state) || when(stream, state)
|| defaultStatement(stream, state) || defaultStatement(stream)
|| extendsStatement(stream, state) || extendsStatement(stream, state)
|| append(stream, state) || append(stream, state)
|| prepend(stream, state) || prepend(stream, state)
@@ -565,16 +565,16 @@ CodeMirror.defineMode("pug", function (config) {
|| tag(stream, state) || tag(stream, state)
|| filter(stream, state) || filter(stream, state)
|| code(stream, state) || code(stream, state)
|| id(stream, state) || id(stream)
|| className(stream, state) || className(stream)
|| attrs(stream, state) || attrs(stream, state)
|| attributesBlock(stream, state) || attributesBlock(stream, state)
|| indent(stream, state) || indent(stream)
|| text(stream, state) || text(stream, state)
|| comment(stream, state) || comment(stream, state)
|| colon(stream, state) || colon(stream)
|| dot(stream, state) || dot(stream, state)
|| fail(stream, state); || fail(stream);
return tok === true ? null : tok; return tok === true ? null : tok;
} }

View File

@@ -1,17 +1,23 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others // 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) { (function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS 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 else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod); define(["../../lib/codemirror", "../css/css"], mod);
else // Plain browser env else // Plain browser env
mod(CodeMirror); mod(CodeMirror);
})(function(CodeMirror) { })(function(CodeMirror) {
"use strict"; "use strict";
CodeMirror.defineMode("sass", function(config) { 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) { function tokenRegexp(words) {
return new RegExp("^" + words.join("|")); return new RegExp("^" + words.join("|"));
} }
@@ -25,6 +31,12 @@ CodeMirror.defineMode("sass", function(config) {
var pseudoElementsRegexp = /^::?[a-zA-Z_][\w\-]*/; var pseudoElementsRegexp = /^::?[a-zA-Z_][\w\-]*/;
var word;
function isEndLine(stream) {
return !stream.peek() || stream.match(/\s+$/, false);
}
function urlTokens(stream, state) { function urlTokens(stream, state) {
var ch = stream.peek(); var ch = stream.peek();
@@ -76,6 +88,9 @@ CodeMirror.defineMode("sass", function(config) {
if (endingString) { if (endingString) {
if (nextChar !== quote && greedy) { stream.next(); } if (nextChar !== quote && greedy) { stream.next(); }
if (isEndLine(stream)) {
state.cursorHalf = 0;
}
state.tokenizer = tokenBase; state.tokenizer = tokenBase;
return "string"; return "string";
} else if (nextChar === "#" && peekChar === "{") { } else if (nextChar === "#" && peekChar === "{") {
@@ -147,14 +162,20 @@ CodeMirror.defineMode("sass", function(config) {
// first half i.e. before : for key-value pairs // first half i.e. before : for key-value pairs
// including selectors // including selectors
if (ch === "-") {
if (stream.match(/^-\w+-/)) {
return "meta";
}
}
if (ch === ".") { if (ch === ".") {
stream.next(); stream.next();
if (stream.match(/^[\w-]+/)) { if (stream.match(/^[\w-]+/)) {
indent(state); indent(state);
return "atom"; return "qualifier";
} else if (stream.peek() === "#") { } else if (stream.peek() === "#") {
indent(state); indent(state);
return "atom"; return "tag";
} }
} }
@@ -163,11 +184,11 @@ CodeMirror.defineMode("sass", function(config) {
// ID selectors // ID selectors
if (stream.match(/^[\w-]+/)) { if (stream.match(/^[\w-]+/)) {
indent(state); indent(state);
return "atom"; return "builtin";
} }
if (stream.peek() === "#") { if (stream.peek() === "#") {
indent(state); indent(state);
return "atom"; return "tag";
} }
} }
@@ -210,7 +231,7 @@ CodeMirror.defineMode("sass", function(config) {
} }
if(ch === "@"){ if(ch === "@"){
if(stream.match(/@extend/)){ if(stream.match('@extend')){
if(!stream.match(/\s*[\w]/)) if(!stream.match(/\s*[\w]/))
dedent(state); dedent(state);
} }
@@ -220,37 +241,48 @@ CodeMirror.defineMode("sass", function(config) {
// Indent Directives // Indent Directives
if (stream.match(/^@(else if|if|media|else|for|each|while|mixin|function)/)) { if (stream.match(/^@(else if|if|media|else|for|each|while|mixin|function)/)) {
indent(state); indent(state);
return "meta"; return "def";
} }
// Other Directives // Other Directives
if (ch === "@") { if (ch === "@") {
stream.next(); stream.next();
stream.eatWhile(/[\w-]/); stream.eatWhile(/[\w-]/);
return "meta"; return "def";
} }
if (stream.eatWhile(/[\w-]/)){ if (stream.eatWhile(/[\w-]/)){
if(stream.match(/ *: *[\w-\+\$#!\("']/,false)){ 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)){ else if(stream.match(/ *:/,false)){
indent(state); indent(state);
state.cursorHalf = 1; state.cursorHalf = 1;
return "atom"; state.prevProp = stream.current().toLowerCase();
return "property";
} }
else if(stream.match(/ *,/,false)){ else if(stream.match(/ *,/,false)){
return "atom"; return "tag";
} }
else{ else{
indent(state); indent(state);
return "atom"; return "tag";
} }
} }
if(ch === ":"){ if(ch === ":"){
if (stream.match(pseudoElementsRegexp)){ // could be a pseudo-element if (stream.match(pseudoElementsRegexp)){ // could be a pseudo-element
return "keyword"; return "variable-3";
} }
stream.next(); stream.next();
state.cursorHalf=1; state.cursorHalf=1;
@@ -264,7 +296,7 @@ CodeMirror.defineMode("sass", function(config) {
stream.next(); stream.next();
// Hex numbers // Hex numbers
if (stream.match(/[0-9a-fA-F]{6}|[0-9a-fA-F]{3}/)){ if (stream.match(/[0-9a-fA-F]{6}|[0-9a-fA-F]{3}/)){
if(!stream.peek()){ if (isEndLine(stream)) {
state.cursorHalf = 0; state.cursorHalf = 0;
} }
return "number"; return "number";
@@ -273,7 +305,7 @@ CodeMirror.defineMode("sass", function(config) {
// Numbers // Numbers
if (stream.match(/^-?[0-9\.]+/)){ if (stream.match(/^-?[0-9\.]+/)){
if(!stream.peek()){ if (isEndLine(stream)) {
state.cursorHalf = 0; state.cursorHalf = 0;
} }
return "number"; return "number";
@@ -281,14 +313,14 @@ CodeMirror.defineMode("sass", function(config) {
// Units // Units
if (stream.match(/^(px|em|in)\b/)){ if (stream.match(/^(px|em|in)\b/)){
if(!stream.peek()){ if (isEndLine(stream)) {
state.cursorHalf = 0; state.cursorHalf = 0;
} }
return "unit"; return "unit";
} }
if (stream.match(keywordsRegexp)){ if (stream.match(keywordsRegexp)){
if(!stream.peek()){ if (isEndLine(stream)) {
state.cursorHalf = 0; state.cursorHalf = 0;
} }
return "keyword"; return "keyword";
@@ -296,7 +328,7 @@ CodeMirror.defineMode("sass", function(config) {
if (stream.match(/^url/) && stream.peek() === "(") { if (stream.match(/^url/) && stream.peek() === "(") {
state.tokenizer = urlTokens; state.tokenizer = urlTokens;
if(!stream.peek()){ if (isEndLine(stream)) {
state.cursorHalf = 0; state.cursorHalf = 0;
} }
return "atom"; return "atom";
@@ -306,23 +338,21 @@ CodeMirror.defineMode("sass", function(config) {
if (ch === "$") { if (ch === "$") {
stream.next(); stream.next();
stream.eatWhile(/[\w-]/); stream.eatWhile(/[\w-]/);
if(!stream.peek()){ if (isEndLine(stream)) {
state.cursorHalf = 0; state.cursorHalf = 0;
} }
return "variable-3"; return "variable-2";
} }
// bang character for !important, !default, etc. // bang character for !important, !default, etc.
if (ch === "!") { if (ch === "!") {
stream.next(); stream.next();
if(!stream.peek()){ state.cursorHalf = 0;
state.cursorHalf = 0;
}
return stream.match(/^[\w]+/) ? "keyword": "operator"; return stream.match(/^[\w]+/) ? "keyword": "operator";
} }
if (stream.match(opRegexp)){ if (stream.match(opRegexp)){
if(!stream.peek()){ if (isEndLine(stream)) {
state.cursorHalf = 0; state.cursorHalf = 0;
} }
return "operator"; return "operator";
@@ -330,14 +360,24 @@ CodeMirror.defineMode("sass", function(config) {
// attributes // attributes
if (stream.eatWhile(/[\w-]/)) { if (stream.eatWhile(/[\w-]/)) {
if(!stream.peek()){ if (isEndLine(stream)) {
state.cursorHalf = 0; 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(); //stream.eatSpace();
if(!stream.peek()){ if (isEndLine(stream)) {
state.cursorHalf = 0; state.cursorHalf = 0;
return null; return null;
} }
@@ -405,9 +445,14 @@ CodeMirror.defineMode("sass", function(config) {
indent: function(state) { indent: function(state) {
return state.scopes[0].offset; return state.scopes[0].offset;
} },
blockCommentStart: "/*",
blockCommentEnd: "*/",
lineComment: "//",
fold: "indent"
}; };
}); }, "css");
CodeMirror.defineMIME("text/x-sass", "sass"); CodeMirror.defineMIME("text/x-sass", "sass");

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others // 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) { (function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS if (typeof exports == "object" && typeof module == "object") // CommonJS
@@ -52,6 +52,7 @@ var xmlConfig = {
doNotIndent: {}, doNotIndent: {},
allowUnquoted: false, allowUnquoted: false,
allowMissing: false, allowMissing: false,
allowMissingTagName: false,
caseFold: false caseFold: false
} }
@@ -162,8 +163,9 @@ CodeMirror.defineMode("xml", function(editorConf, config_) {
stream.next(); stream.next();
} }
return style; return style;
}; }
} }
function doctype(depth) { function doctype(depth) {
return function(stream, state) { return function(stream, state) {
var ch; var ch;
@@ -185,9 +187,13 @@ CodeMirror.defineMode("xml", function(editorConf, config_) {
}; };
} }
function lower(tagName) {
return tagName && tagName.toLowerCase();
}
function Context(state, tagName, startOfLine) { function Context(state, tagName, startOfLine) {
this.prev = state.context; this.prev = state.context;
this.tagName = tagName; this.tagName = tagName || "";
this.indent = state.indented; this.indent = state.indented;
this.startOfLine = startOfLine; this.startOfLine = startOfLine;
if (config.doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.noIndent)) if (config.doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.noIndent))
@@ -203,8 +209,8 @@ CodeMirror.defineMode("xml", function(editorConf, config_) {
return; return;
} }
parentTagName = state.context.tagName; parentTagName = state.context.tagName;
if (!config.contextGrabbers.hasOwnProperty(parentTagName) || if (!config.contextGrabbers.hasOwnProperty(lower(parentTagName)) ||
!config.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) { !config.contextGrabbers[lower(parentTagName)].hasOwnProperty(lower(nextTagName))) {
return; return;
} }
popContext(state); popContext(state);
@@ -226,6 +232,9 @@ CodeMirror.defineMode("xml", function(editorConf, config_) {
state.tagName = stream.current(); state.tagName = stream.current();
setStyle = "tag"; setStyle = "tag";
return attrState; return attrState;
} else if (config.allowMissingTagName && type == "endTag") {
setStyle = "tag bracket";
return attrState(type, stream, state);
} else { } else {
setStyle = "error"; setStyle = "error";
return tagNameState; return tagNameState;
@@ -235,7 +244,7 @@ CodeMirror.defineMode("xml", function(editorConf, config_) {
if (type == "word") { if (type == "word") {
var tagName = stream.current(); var tagName = stream.current();
if (state.context && state.context.tagName != tagName && if (state.context && state.context.tagName != tagName &&
config.implicitlyClosed.hasOwnProperty(state.context.tagName)) config.implicitlyClosed.hasOwnProperty(lower(state.context.tagName)))
popContext(state); popContext(state);
if ((state.context && state.context.tagName == tagName) || config.matchClosing === false) { if ((state.context && state.context.tagName == tagName) || config.matchClosing === false) {
setStyle = "tag"; setStyle = "tag";
@@ -244,6 +253,9 @@ CodeMirror.defineMode("xml", function(editorConf, config_) {
setStyle = "tag error"; setStyle = "tag error";
return closeStateErr; return closeStateErr;
} }
} else if (config.allowMissingTagName && type == "endTag") {
setStyle = "tag bracket";
return closeState(type, stream, state);
} else { } else {
setStyle = "error"; setStyle = "error";
return closeStateErr; return closeStateErr;
@@ -271,7 +283,7 @@ CodeMirror.defineMode("xml", function(editorConf, config_) {
var tagName = state.tagName, tagStart = state.tagStart; var tagName = state.tagName, tagStart = state.tagStart;
state.tagName = state.tagStart = null; state.tagName = state.tagStart = null;
if (type == "selfcloseTag" || if (type == "selfcloseTag" ||
config.autoSelfClosers.hasOwnProperty(tagName)) { config.autoSelfClosers.hasOwnProperty(lower(tagName))) {
maybePopContext(state, tagName); maybePopContext(state, tagName);
} else { } else {
maybePopContext(state, tagName); maybePopContext(state, tagName);
@@ -351,7 +363,7 @@ CodeMirror.defineMode("xml", function(editorConf, config_) {
if (context.tagName == tagAfter[2]) { if (context.tagName == tagAfter[2]) {
context = context.prev; context = context.prev;
break; break;
} else if (config.implicitlyClosed.hasOwnProperty(context.tagName)) { } else if (config.implicitlyClosed.hasOwnProperty(lower(context.tagName))) {
context = context.prev; context = context.prev;
} else { } else {
break; break;
@@ -359,8 +371,8 @@ CodeMirror.defineMode("xml", function(editorConf, config_) {
} }
} else if (tagAfter) { // Opening tag spotted } else if (tagAfter) { // Opening tag spotted
while (context) { while (context) {
var grabbers = config.contextGrabbers[context.tagName]; var grabbers = config.contextGrabbers[lower(context.tagName)];
if (grabbers && grabbers.hasOwnProperty(tagAfter[2])) if (grabbers && grabbers.hasOwnProperty(lower(tagAfter[2])))
context = context.prev; context = context.prev;
else else
break; break;
@@ -382,6 +394,17 @@ CodeMirror.defineMode("xml", function(editorConf, config_) {
skipAttribute: function(state) { skipAttribute: function(state) {
if (state.state == attrValueState) if (state.state == attrValueState)
state.state = attrState 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()
} }
}; };
}); });