| Index: Source/devtools/front_end/cm/css.js
|
| diff --git a/Source/devtools/front_end/cm/css.js b/Source/devtools/front_end/cm/css.js
|
| index d8c30cf33d6fe1b5b452f39e6faa0aae9a361af4..2678c57d59adf10d728b402c4692a1f965a6b234 100644
|
| --- a/Source/devtools/front_end/cm/css.js
|
| +++ b/Source/devtools/front_end/cm/css.js
|
| @@ -1,308 +1,341 @@
|
| -CodeMirror.defineMode("css", function(config, parserConfig) {
|
| - "use strict";
|
| +// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
| +// Distributed under an MIT license: http://codemirror.net/LICENSE
|
| +
|
| +(function(mod) {
|
| + if (typeof exports == "object" && typeof module == "object") // CommonJS
|
| + mod(require("../../lib/codemirror"));
|
| + else if (typeof define == "function" && define.amd) // AMD
|
| + define(["../../lib/codemirror"], mod);
|
| + else // Plain browser env
|
| + mod(CodeMirror);
|
| +})(function(CodeMirror) {
|
| +"use strict";
|
|
|
| +CodeMirror.defineMode("css", function(config, parserConfig) {
|
| if (!parserConfig.propertyKeywords) parserConfig = CodeMirror.resolveMode("text/css");
|
|
|
| - var indentUnit = config.indentUnit || config.tabSize || 2,
|
| - hooks = parserConfig.hooks || {},
|
| - atMediaTypes = parserConfig.atMediaTypes || {},
|
| - atMediaFeatures = parserConfig.atMediaFeatures || {},
|
| + var indentUnit = config.indentUnit,
|
| + tokenHooks = parserConfig.tokenHooks,
|
| + mediaTypes = parserConfig.mediaTypes || {},
|
| + mediaFeatures = parserConfig.mediaFeatures || {},
|
| propertyKeywords = parserConfig.propertyKeywords || {},
|
| + nonStandardPropertyKeywords = parserConfig.nonStandardPropertyKeywords || {},
|
| colorKeywords = parserConfig.colorKeywords || {},
|
| valueKeywords = parserConfig.valueKeywords || {},
|
| - allowNested = !!parserConfig.allowNested,
|
| - type = null;
|
| + fontProperties = parserConfig.fontProperties || {},
|
| + allowNested = parserConfig.allowNested;
|
|
|
| + var type, override;
|
| function ret(style, tp) { type = tp; return style; }
|
|
|
| + // Tokenizers
|
| +
|
| function tokenBase(stream, state) {
|
| var ch = stream.next();
|
| - if (hooks[ch]) {
|
| - // result[0] is style and result[1] is type
|
| - var result = hooks[ch](stream, state);
|
| + if (tokenHooks[ch]) {
|
| + var result = tokenHooks[ch](stream, state);
|
| if (result !== false) return result;
|
| }
|
| - if (ch == "@") {stream.eatWhile(/[\w\\\-]/); return ret("def", stream.current());}
|
| - else if (ch == "=") ret(null, "compare");
|
| - else if ((ch == "~" || ch == "|") && stream.eat("=")) return ret(null, "compare");
|
| - else if (ch == "\"" || ch == "'") {
|
| + if (ch == "@") {
|
| + stream.eatWhile(/[\w\\\-]/);
|
| + return ret("def", stream.current());
|
| + } else if (ch == "=" || (ch == "~" || ch == "|") && stream.eat("=")) {
|
| + return ret(null, "compare");
|
| + } else if (ch == "\"" || ch == "'") {
|
| state.tokenize = tokenString(ch);
|
| return state.tokenize(stream, state);
|
| - }
|
| - else if (ch == "#") {
|
| + } else if (ch == "#") {
|
| stream.eatWhile(/[\w\\\-]/);
|
| return ret("atom", "hash");
|
| - }
|
| - else if (ch == "!") {
|
| + } else if (ch == "!") {
|
| stream.match(/^\s*\w*/);
|
| return ret("keyword", "important");
|
| - }
|
| - else if (/\d/.test(ch) || ch == "." && stream.eat(/\d/)) {
|
| + } else if (/\d/.test(ch) || ch == "." && stream.eat(/\d/)) {
|
| stream.eatWhile(/[\w.%]/);
|
| return ret("number", "unit");
|
| - }
|
| - else if (ch === "-") {
|
| - if (/\d/.test(stream.peek())) {
|
| + } else if (ch === "-") {
|
| + if (/[\d.]/.test(stream.peek())) {
|
| stream.eatWhile(/[\w.%]/);
|
| return ret("number", "unit");
|
| - } else if (stream.match(/^[^-]+-/)) {
|
| + } else if (stream.match(/^\w+-/)) {
|
| return ret("meta", "meta");
|
| }
|
| - }
|
| - else if (/[,+>*\/]/.test(ch)) {
|
| + } else if (/[,+>*\/]/.test(ch)) {
|
| return ret(null, "select-op");
|
| - }
|
| - else if (ch == "." && stream.match(/^-?[_a-z][_a-z0-9-]*/i)) {
|
| + } else if (ch == "." && stream.match(/^-?[_a-z][_a-z0-9-]*/i)) {
|
| return ret("qualifier", "qualifier");
|
| - }
|
| - else if (ch == ":") {
|
| - return ret("operator", ch);
|
| - }
|
| - else if (/[;{}\[\]\(\)]/.test(ch)) {
|
| + } else if (/[:;{}\[\]\(\)]/.test(ch)) {
|
| return ret(null, ch);
|
| - }
|
| - else if (ch == "u" && stream.match("rl(")) {
|
| + } else if (ch == "u" && stream.match("rl(")) {
|
| stream.backUp(1);
|
| state.tokenize = tokenParenthesized;
|
| - return ret("property", "variable");
|
| - }
|
| - else {
|
| + return ret("property", "word");
|
| + } else if (/[\w\\\-]/.test(ch)) {
|
| stream.eatWhile(/[\w\\\-]/);
|
| - return ret("property", "variable");
|
| + return ret("property", "word");
|
| + } else {
|
| + return ret(null, null);
|
| }
|
| }
|
|
|
| - function tokenString(quote, nonInclusive) {
|
| + function tokenString(quote) {
|
| return function(stream, state) {
|
| var escaped = false, ch;
|
| while ((ch = stream.next()) != null) {
|
| - if (ch == quote && !escaped)
|
| + if (ch == quote && !escaped) {
|
| + if (quote == ")") stream.backUp(1);
|
| break;
|
| + }
|
| escaped = !escaped && ch == "\\";
|
| }
|
| - if (!escaped) {
|
| - if (nonInclusive) stream.backUp(1);
|
| - state.tokenize = tokenBase;
|
| - }
|
| + if (ch == quote || !escaped && quote != ")") state.tokenize = null;
|
| return ret("string", "string");
|
| };
|
| }
|
|
|
| function tokenParenthesized(stream, state) {
|
| stream.next(); // Must be '('
|
| - if (!stream.match(/\s*[\"\']/, false))
|
| - state.tokenize = tokenString(")", true);
|
| + if (!stream.match(/\s*[\"\')]/, false))
|
| + state.tokenize = tokenString(")");
|
| else
|
| - state.tokenize = tokenBase;
|
| + state.tokenize = null;
|
| return ret(null, "(");
|
| }
|
|
|
| + // Context management
|
| +
|
| + function Context(type, indent, prev) {
|
| + this.type = type;
|
| + this.indent = indent;
|
| + this.prev = prev;
|
| + }
|
| +
|
| + function pushContext(state, stream, type) {
|
| + state.context = new Context(type, stream.indentation() + indentUnit, state.context);
|
| + return type;
|
| + }
|
| +
|
| + function popContext(state) {
|
| + state.context = state.context.prev;
|
| + return state.context.type;
|
| + }
|
| +
|
| + function pass(type, stream, state) {
|
| + return states[state.context.type](type, stream, state);
|
| + }
|
| + function popAndPass(type, stream, state, n) {
|
| + for (var i = n || 1; i > 0; i--)
|
| + state.context = state.context.prev;
|
| + return pass(type, stream, state);
|
| + }
|
| +
|
| + // Parser
|
| +
|
| + function wordAsValue(stream) {
|
| + var word = stream.current().toLowerCase();
|
| + if (valueKeywords.hasOwnProperty(word))
|
| + override = "atom";
|
| + else if (colorKeywords.hasOwnProperty(word))
|
| + override = "keyword";
|
| + else
|
| + override = "variable";
|
| + }
|
| +
|
| + var states = {};
|
| +
|
| + states.top = function(type, stream, state) {
|
| + if (type == "{") {
|
| + return pushContext(state, stream, "block");
|
| + } else if (type == "}" && state.context.prev) {
|
| + return popContext(state);
|
| + } else if (type == "@media") {
|
| + return pushContext(state, stream, "media");
|
| + } else if (type == "@font-face") {
|
| + return "font_face_before";
|
| + } else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/.test(type)) {
|
| + return "keyframes";
|
| + } else if (type && type.charAt(0) == "@") {
|
| + return pushContext(state, stream, "at");
|
| + } else if (type == "hash") {
|
| + override = "builtin";
|
| + } else if (type == "word") {
|
| + override = "tag";
|
| + } else if (type == "variable-definition") {
|
| + return "maybeprop";
|
| + } else if (type == "interpolation") {
|
| + return pushContext(state, stream, "interpolation");
|
| + } else if (type == ":") {
|
| + return "pseudo";
|
| + } else if (allowNested && type == "(") {
|
| + return pushContext(state, stream, "parens");
|
| + }
|
| + return state.context.type;
|
| + };
|
| +
|
| + states.block = function(type, stream, state) {
|
| + if (type == "word") {
|
| + var word = stream.current().toLowerCase();
|
| + if (propertyKeywords.hasOwnProperty(word)) {
|
| + override = "property";
|
| + return "maybeprop";
|
| + } else if (nonStandardPropertyKeywords.hasOwnProperty(word)) {
|
| + override = "string-2";
|
| + return "maybeprop";
|
| + } else if (allowNested) {
|
| + override = stream.match(/^\s*:/, false) ? "property" : "tag";
|
| + return "block";
|
| + } else {
|
| + override += " error";
|
| + return "maybeprop";
|
| + }
|
| + } else if (type == "meta") {
|
| + return "block";
|
| + } else if (!allowNested && (type == "hash" || type == "qualifier")) {
|
| + override = "error";
|
| + return "block";
|
| + } else {
|
| + return states.top(type, stream, state);
|
| + }
|
| + };
|
| +
|
| + states.maybeprop = function(type, stream, state) {
|
| + if (type == ":") return pushContext(state, stream, "prop");
|
| + return pass(type, stream, state);
|
| + };
|
| +
|
| + states.prop = function(type, stream, state) {
|
| + if (type == ";") return popContext(state);
|
| + if (type == "{" && allowNested) return pushContext(state, stream, "propBlock");
|
| + if (type == "}" || type == "{") return popAndPass(type, stream, state);
|
| + if (type == "(") return pushContext(state, stream, "parens");
|
| +
|
| + if (type == "hash" && !/^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/.test(stream.current())) {
|
| + override += " error";
|
| + } else if (type == "word") {
|
| + wordAsValue(stream);
|
| + } else if (type == "interpolation") {
|
| + return pushContext(state, stream, "interpolation");
|
| + }
|
| + return "prop";
|
| + };
|
| +
|
| + states.propBlock = function(type, _stream, state) {
|
| + if (type == "}") return popContext(state);
|
| + if (type == "word") { override = "property"; return "maybeprop"; }
|
| + return state.context.type;
|
| + };
|
| +
|
| + states.parens = function(type, stream, state) {
|
| + if (type == "{" || type == "}") return popAndPass(type, stream, state);
|
| + if (type == ")") return popContext(state);
|
| + if (type == "(") return pushContext(state, stream, "parens");
|
| + if (type == "word") wordAsValue(stream);
|
| + return "parens";
|
| + };
|
| +
|
| + states.pseudo = function(type, stream, state) {
|
| + if (type == "word") {
|
| + override = "variable-3";
|
| + return state.context.type;
|
| + }
|
| + return pass(type, stream, state);
|
| + };
|
| +
|
| + states.media = function(type, stream, state) {
|
| + if (type == "(") return pushContext(state, stream, "media_parens");
|
| + if (type == "}") return popAndPass(type, stream, state);
|
| + if (type == "{") return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top");
|
| +
|
| + if (type == "word") {
|
| + var word = stream.current().toLowerCase();
|
| + if (word == "only" || word == "not" || word == "and")
|
| + override = "keyword";
|
| + else if (mediaTypes.hasOwnProperty(word))
|
| + override = "attribute";
|
| + else if (mediaFeatures.hasOwnProperty(word))
|
| + override = "property";
|
| + else
|
| + override = "error";
|
| + }
|
| + return state.context.type;
|
| + };
|
| +
|
| + states.media_parens = function(type, stream, state) {
|
| + if (type == ")") return popContext(state);
|
| + if (type == "{" || type == "}") return popAndPass(type, stream, state, 2);
|
| + return states.media(type, stream, state);
|
| + };
|
| +
|
| + states.font_face_before = function(type, stream, state) {
|
| + if (type == "{")
|
| + return pushContext(state, stream, "font_face");
|
| + return pass(type, stream, state);
|
| + };
|
| +
|
| + states.font_face = function(type, stream, state) {
|
| + if (type == "}") return popContext(state);
|
| + if (type == "word") {
|
| + if (!fontProperties.hasOwnProperty(stream.current().toLowerCase()))
|
| + override = "error";
|
| + else
|
| + override = "property";
|
| + return "maybeprop";
|
| + }
|
| + return "font_face";
|
| + };
|
| +
|
| + states.keyframes = function(type, stream, state) {
|
| + if (type == "word") { override = "variable"; return "keyframes"; }
|
| + if (type == "{") return pushContext(state, stream, "top");
|
| + return pass(type, stream, state);
|
| + };
|
| +
|
| + states.at = function(type, stream, state) {
|
| + if (type == ";") return popContext(state);
|
| + if (type == "{" || type == "}") return popAndPass(type, stream, state);
|
| + if (type == "word") override = "tag";
|
| + else if (type == "hash") override = "builtin";
|
| + return "at";
|
| + };
|
| +
|
| + states.interpolation = function(type, stream, state) {
|
| + if (type == "}") return popContext(state);
|
| + if (type == "{" || type == ";") return popAndPass(type, stream, state);
|
| + if (type != "variable") override = "error";
|
| + return "interpolation";
|
| + };
|
| +
|
| return {
|
| startState: function(base) {
|
| - return {tokenize: tokenBase,
|
| - baseIndent: base || 0,
|
| - stack: [],
|
| - lastToken: null};
|
| + return {tokenize: null,
|
| + state: "top",
|
| + context: new Context("top", base || 0, null)};
|
| },
|
|
|
| token: function(stream, state) {
|
| -
|
| - // Use these terms when applicable (see http://www.xanthir.com/blog/b4E50)
|
| - //
|
| - // rule** or **ruleset:
|
| - // A selector + braces combo, or an at-rule.
|
| - //
|
| - // declaration block:
|
| - // A sequence of declarations.
|
| - //
|
| - // declaration:
|
| - // A property + colon + value combo.
|
| - //
|
| - // property value:
|
| - // The entire value of a property.
|
| - //
|
| - // component value:
|
| - // A single piece of a property value. Like the 5px in
|
| - // text-shadow: 0 0 5px blue;. Can also refer to things that are
|
| - // multiple terms, like the 1-4 terms that make up the background-size
|
| - // portion of the background shorthand.
|
| - //
|
| - // term:
|
| - // The basic unit of author-facing CSS, like a single number (5),
|
| - // dimension (5px), string ("foo"), or function. Officially defined
|
| - // by the CSS 2.1 grammar (look for the 'term' production)
|
| - //
|
| - //
|
| - // simple selector:
|
| - // A single atomic selector, like a type selector, an attr selector, a
|
| - // class selector, etc.
|
| - //
|
| - // compound selector:
|
| - // One or more simple selectors without a combinator. div.example is
|
| - // compound, div > .example is not.
|
| - //
|
| - // complex selector:
|
| - // One or more compound selectors chained with combinators.
|
| - //
|
| - // combinator:
|
| - // The parts of selectors that express relationships. There are four
|
| - // currently - the space (descendant combinator), the greater-than
|
| - // bracket (child combinator), the plus sign (next sibling combinator),
|
| - // and the tilda (following sibling combinator).
|
| - //
|
| - // sequence of selectors:
|
| - // One or more of the named type of selector chained with commas.
|
| -
|
| - state.tokenize = state.tokenize || tokenBase;
|
| - if (state.tokenize == tokenBase && stream.eatSpace()) return null;
|
| - var style = state.tokenize(stream, state);
|
| - if (style && typeof style != "string") style = ret(style[0], style[1]);
|
| -
|
| - // Changing style returned based on context
|
| - var context = state.stack[state.stack.length-1];
|
| - if (style == "variable") {
|
| - if (type == "variable-definition") state.stack.push("propertyValue");
|
| - return state.lastToken = "variable-2";
|
| - } else if (style == "property") {
|
| - var word = stream.current().toLowerCase();
|
| - if (context == "propertyValue") {
|
| - if (valueKeywords.hasOwnProperty(word)) {
|
| - style = "string-2";
|
| - } else if (colorKeywords.hasOwnProperty(word)) {
|
| - style = "keyword";
|
| - } else {
|
| - style = "variable-2";
|
| - }
|
| - } else if (context == "rule") {
|
| - if (!propertyKeywords.hasOwnProperty(word)) {
|
| - style += " error";
|
| - }
|
| - } else if (context == "block") {
|
| - // if a value is present in both property, value, or color, the order
|
| - // of preference is property -> color -> value
|
| - if (propertyKeywords.hasOwnProperty(word)) {
|
| - style = "property";
|
| - } else if (colorKeywords.hasOwnProperty(word)) {
|
| - style = "keyword";
|
| - } else if (valueKeywords.hasOwnProperty(word)) {
|
| - style = "string-2";
|
| - } else {
|
| - style = "tag";
|
| - }
|
| - } else if (!context || context == "@media{") {
|
| - style = "tag";
|
| - } else if (context == "@media") {
|
| - if (atMediaTypes[stream.current()]) {
|
| - style = "attribute"; // Known attribute
|
| - } else if (/^(only|not)$/.test(word)) {
|
| - style = "keyword";
|
| - } else if (word == "and") {
|
| - style = "error"; // "and" is only allowed in @mediaType
|
| - } else if (atMediaFeatures.hasOwnProperty(word)) {
|
| - style = "error"; // Known property, should be in @mediaType(
|
| - } else {
|
| - // Unknown, expecting keyword or attribute, assuming attribute
|
| - style = "attribute error";
|
| - }
|
| - } else if (context == "@mediaType") {
|
| - if (atMediaTypes.hasOwnProperty(word)) {
|
| - style = "attribute";
|
| - } else if (word == "and") {
|
| - style = "operator";
|
| - } else if (/^(only|not)$/.test(word)) {
|
| - style = "error"; // Only allowed in @media
|
| - } else {
|
| - // Unknown attribute or property, but expecting property (preceded
|
| - // by "and"). Should be in parentheses
|
| - style = "error";
|
| - }
|
| - } else if (context == "@mediaType(") {
|
| - if (propertyKeywords.hasOwnProperty(word)) {
|
| - // do nothing, remains "property"
|
| - } else if (atMediaTypes.hasOwnProperty(word)) {
|
| - style = "error"; // Known property, should be in parentheses
|
| - } else if (word == "and") {
|
| - style = "operator";
|
| - } else if (/^(only|not)$/.test(word)) {
|
| - style = "error"; // Only allowed in @media
|
| - } else {
|
| - style += " error";
|
| - }
|
| - } else if (context == "@import") {
|
| - style = "tag";
|
| - } else {
|
| - style = "error";
|
| - }
|
| - } else if (style == "atom") {
|
| - if(!context || context == "@media{" || context == "block") {
|
| - style = "builtin";
|
| - } else if (context == "propertyValue") {
|
| - if (!/^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/.test(stream.current())) {
|
| - style += " error";
|
| - }
|
| - } else {
|
| - style = "error";
|
| - }
|
| - } else if (context == "@media" && type == "{") {
|
| - style = "error";
|
| + if (!state.tokenize && stream.eatSpace()) return null;
|
| + var style = (state.tokenize || tokenBase)(stream, state);
|
| + if (style && typeof style == "object") {
|
| + type = style[1];
|
| + style = style[0];
|
| }
|
| -
|
| - // Push/pop context stack
|
| - if (type == "{") {
|
| - if (context == "@media" || context == "@mediaType") {
|
| - state.stack[state.stack.length-1] = "@media{";
|
| - }
|
| - else {
|
| - var newContext = allowNested ? "block" : "rule";
|
| - state.stack.push(newContext);
|
| - }
|
| - }
|
| - else if (type == "}") {
|
| - if (context == "interpolation") style = "operator";
|
| - // Pop off end of array until { is reached
|
| - while(state.stack.length){
|
| - var removed = state.stack.pop();
|
| - if(removed.indexOf("{") > -1 || removed == "block" || removed == "rule"){
|
| - break;
|
| - }
|
| - }
|
| - }
|
| - else if (type == "interpolation") state.stack.push("interpolation");
|
| - else if (type == "@media") state.stack.push("@media");
|
| - else if (type == "@import") state.stack.push("@import");
|
| - else if (context == "@media" && /\b(keyword|attribute)\b/.test(style))
|
| - state.stack[state.stack.length-1] = "@mediaType";
|
| - else if (context == "@mediaType" && stream.current() == ",")
|
| - state.stack[state.stack.length-1] = "@media";
|
| - else if (type == "(") {
|
| - if (context == "@media" || context == "@mediaType") {
|
| - // Make sure @mediaType is used to avoid error on {
|
| - state.stack[state.stack.length-1] = "@mediaType";
|
| - state.stack.push("@mediaType(");
|
| - }
|
| - else state.stack.push("(");
|
| - }
|
| - else if (type == ")") {
|
| - // Pop off end of array until ( is reached
|
| - while(state.stack.length){
|
| - var removed = state.stack.pop();
|
| - if(removed.indexOf("(") > -1){
|
| - break;
|
| - }
|
| - }
|
| - }
|
| - else if (type == ":" && state.lastToken == "property") state.stack.push("propertyValue");
|
| - else if (context == "propertyValue" && type == ";") state.stack.pop();
|
| - else if (context == "@import" && type == ";") state.stack.pop();
|
| -
|
| - return state.lastToken = style;
|
| + override = style;
|
| + state.state = states[state.state](type, stream, state);
|
| + return override;
|
| },
|
|
|
| indent: function(state, textAfter) {
|
| - var n = state.stack.length;
|
| - if (/^\}/.test(textAfter))
|
| - n -= state.stack[n-1] == "propertyValue" ? 2 : 1;
|
| - return state.baseIndent + n * indentUnit;
|
| + var cx = state.context, ch = textAfter && textAfter.charAt(0);
|
| + var indent = cx.indent;
|
| + if (cx.type == "prop" && (ch == "}" || ch == ")")) cx = cx.prev;
|
| + if (cx.prev &&
|
| + (ch == "}" && (cx.type == "block" || cx.type == "top" || cx.type == "interpolation" || cx.type == "font_face") ||
|
| + ch == ")" && (cx.type == "parens" || cx.type == "media_parens") ||
|
| + ch == "{" && (cx.type == "at" || cx.type == "media"))) {
|
| + indent = cx.indent - indentUnit;
|
| + cx = cx.prev;
|
| + }
|
| + return indent;
|
| },
|
|
|
| electricChars: "}",
|
| @@ -312,7 +345,6 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
| };
|
| });
|
|
|
| -(function() {
|
| function keySet(array) {
|
| var keys = {};
|
| for (var i = 0; i < array.length; ++i) {
|
| @@ -321,12 +353,12 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
| return keys;
|
| }
|
|
|
| - var atMediaTypes = keySet([
|
| + var mediaTypes_ = [
|
| "all", "aural", "braille", "handheld", "print", "projection", "screen",
|
| "tty", "tv", "embossed"
|
| - ]);
|
| + ], mediaTypes = keySet(mediaTypes_);
|
|
|
| - var atMediaFeatures = keySet([
|
| + var mediaFeatures_ = [
|
| "width", "min-width", "max-width", "height", "min-height", "max-height",
|
| "device-width", "min-device-width", "max-device-width", "device-height",
|
| "min-device-height", "max-device-height", "aspect-ratio",
|
| @@ -335,15 +367,15 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
| "max-color", "color-index", "min-color-index", "max-color-index",
|
| "monochrome", "min-monochrome", "max-monochrome", "resolution",
|
| "min-resolution", "max-resolution", "scan", "grid"
|
| - ]);
|
| + ], mediaFeatures = keySet(mediaFeatures_);
|
|
|
| - var propertyKeywords = keySet([
|
| + var propertyKeywords_ = [
|
| "align-content", "align-items", "align-self", "alignment-adjust",
|
| "alignment-baseline", "anchor-point", "animation", "animation-delay",
|
| - "animation-direction", "animation-duration", "animation-iteration-count",
|
| - "animation-name", "animation-play-state", "animation-timing-function",
|
| - "appearance", "azimuth", "backface-visibility", "background",
|
| - "background-attachment", "background-clip", "background-color",
|
| + "animation-direction", "animation-duration", "animation-fill-mode",
|
| + "animation-iteration-count", "animation-name", "animation-play-state",
|
| + "animation-timing-function", "appearance", "azimuth", "backface-visibility",
|
| + "background", "background-attachment", "background-clip", "background-color",
|
| "background-image", "background-origin", "background-position",
|
| "background-repeat", "background-size", "baseline-shift", "binding",
|
| "bleed", "bookmark-label", "bookmark-level", "bookmark-state",
|
| @@ -374,10 +406,11 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
| "font-stretch", "font-style", "font-synthesis", "font-variant",
|
| "font-variant-alternates", "font-variant-caps", "font-variant-east-asian",
|
| "font-variant-ligatures", "font-variant-numeric", "font-variant-position",
|
| - "font-weight", "grid-cell", "grid-column", "grid-column-align",
|
| - "grid-column-sizing", "grid-column-span", "grid-columns", "grid-flow",
|
| - "grid-row", "grid-row-align", "grid-row-sizing", "grid-row-span",
|
| - "grid-rows", "grid-template", "hanging-punctuation", "height", "hyphens",
|
| + "font-weight", "grid", "grid-area", "grid-auto-columns", "grid-auto-flow",
|
| + "grid-auto-position", "grid-auto-rows", "grid-column", "grid-column-end",
|
| + "grid-column-start", "grid-row", "grid-row-end", "grid-row-start",
|
| + "grid-template", "grid-template-areas", "grid-template-columns",
|
| + "grid-template-rows", "hanging-punctuation", "height", "hyphens",
|
| "icon", "image-orientation", "image-rendering", "image-resolution",
|
| "inline-box-align", "justify-content", "left", "letter-spacing",
|
| "line-break", "line-height", "line-stacking", "line-stacking-ruby",
|
| @@ -387,7 +420,8 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
| "marker-offset", "marks", "marquee-direction", "marquee-loop",
|
| "marquee-play-count", "marquee-speed", "marquee-style", "max-height",
|
| "max-width", "min-height", "min-width", "move-to", "nav-down", "nav-index",
|
| - "nav-left", "nav-right", "nav-up", "opacity", "order", "orphans", "outline",
|
| + "nav-left", "nav-right", "nav-up", "object-fit", "object-position",
|
| + "opacity", "order", "orphans", "outline",
|
| "outline-color", "outline-offset", "outline-style", "outline-width",
|
| "overflow", "overflow-style", "overflow-wrap", "overflow-x", "overflow-y",
|
| "padding", "padding-bottom", "padding-left", "padding-right", "padding-top",
|
| @@ -398,8 +432,8 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
| "region-break-before", "region-break-inside", "region-fragment",
|
| "rendering-intent", "resize", "rest", "rest-after", "rest-before", "richness",
|
| "right", "rotation", "rotation-point", "ruby-align", "ruby-overhang",
|
| - "ruby-position", "ruby-span", "shape-inside", "shape-outside", "size",
|
| - "speak", "speak-as", "speak-header",
|
| + "ruby-position", "ruby-span", "shape-image-threshold", "shape-inside", "shape-margin",
|
| + "shape-outside", "size", "speak", "speak-as", "speak-header",
|
| "speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set",
|
| "tab-size", "table-layout", "target", "target-name", "target-new",
|
| "target-position", "text-align", "text-align-last", "text-decoration",
|
| @@ -414,20 +448,28 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
| "vertical-align", "visibility", "voice-balance", "voice-duration",
|
| "voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress",
|
| "voice-volume", "volume", "white-space", "widows", "width", "word-break",
|
| - "word-spacing", "word-wrap", "z-index", "zoom",
|
| + "word-spacing", "word-wrap", "z-index",
|
| // SVG-specific
|
| "clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color",
|
| "flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events",
|
| - "color-interpolation", "color-interpolation-filters", "color-profile",
|
| + "color-interpolation", "color-interpolation-filters",
|
| "color-rendering", "fill", "fill-opacity", "fill-rule", "image-rendering",
|
| "marker", "marker-end", "marker-mid", "marker-start", "shape-rendering", "stroke",
|
| "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin",
|
| "stroke-miterlimit", "stroke-opacity", "stroke-width", "text-rendering",
|
| "baseline-shift", "dominant-baseline", "glyph-orientation-horizontal",
|
| - "glyph-orientation-vertical", "kerning", "text-anchor", "writing-mode"
|
| - ]);
|
| + "glyph-orientation-vertical", "text-anchor", "writing-mode"
|
| + ], propertyKeywords = keySet(propertyKeywords_);
|
| +
|
| + var nonStandardPropertyKeywords = [
|
| + "scrollbar-arrow-color", "scrollbar-base-color", "scrollbar-dark-shadow-color",
|
| + "scrollbar-face-color", "scrollbar-highlight-color", "scrollbar-shadow-color",
|
| + "scrollbar-3d-light-color", "scrollbar-track-color", "shape-inside",
|
| + "searchfield-cancel-button", "searchfield-decoration", "searchfield-results-button",
|
| + "searchfield-results-decoration", "zoom"
|
| + ], nonStandardPropertyKeywords = keySet(nonStandardPropertyKeywords);
|
|
|
| - var colorKeywords = keySet([
|
| + var colorKeywords_ = [
|
| "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige",
|
| "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown",
|
| "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue",
|
| @@ -449,14 +491,14 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
| "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered",
|
| "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred",
|
| "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue",
|
| - "purple", "red", "rosybrown", "royalblue", "saddlebrown", "salmon",
|
| - "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue",
|
| + "purple", "rebeccapurple", "red", "rosybrown", "royalblue", "saddlebrown",
|
| + "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue",
|
| "slateblue", "slategray", "snow", "springgreen", "steelblue", "tan",
|
| "teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white",
|
| "whitesmoke", "yellow", "yellowgreen"
|
| - ]);
|
| + ], colorKeywords = keySet(colorKeywords_);
|
|
|
| - var valueKeywords = keySet([
|
| + var valueKeywords_ = [
|
| "above", "absolute", "activeborder", "activecaption", "afar",
|
| "after-white-space", "ahead", "alias", "all", "all-scroll", "alternate",
|
| "always", "amharic", "amharic-abegede", "antialiased", "appworkspace",
|
| @@ -539,7 +581,16 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
| "visibleStroke", "visual", "w-resize", "wait", "wave", "wider",
|
| "window", "windowframe", "windowtext", "x-large", "x-small", "xor",
|
| "xx-large", "xx-small"
|
| - ]);
|
| + ], valueKeywords = keySet(valueKeywords_);
|
| +
|
| + var fontProperties_ = [
|
| + "font-family", "src", "unicode-range", "font-variant", "font-feature-settings",
|
| + "font-stretch", "font-weight", "font-style"
|
| + ], fontProperties = keySet(fontProperties_);
|
| +
|
| + var allWords = mediaTypes_.concat(mediaFeatures_).concat(propertyKeywords_)
|
| + .concat(nonStandardPropertyKeywords).concat(colorKeywords_).concat(valueKeywords_);
|
| + CodeMirror.registerHelper("hintWords", "css", allWords);
|
|
|
| function tokenCComment(stream, state) {
|
| var maybeEnd = false, ch;
|
| @@ -553,67 +604,90 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
| return ["comment", "comment"];
|
| }
|
|
|
| + function tokenSGMLComment(stream, state) {
|
| + if (stream.skipTo("-->")) {
|
| + stream.match("-->");
|
| + state.tokenize = null;
|
| + } else {
|
| + stream.skipToEnd();
|
| + }
|
| + return ["comment", "comment"];
|
| + }
|
| +
|
| CodeMirror.defineMIME("text/css", {
|
| - atMediaTypes: atMediaTypes,
|
| - atMediaFeatures: atMediaFeatures,
|
| + mediaTypes: mediaTypes,
|
| + mediaFeatures: mediaFeatures,
|
| propertyKeywords: propertyKeywords,
|
| + nonStandardPropertyKeywords: nonStandardPropertyKeywords,
|
| colorKeywords: colorKeywords,
|
| valueKeywords: valueKeywords,
|
| - hooks: {
|
| + fontProperties: fontProperties,
|
| + tokenHooks: {
|
| "<": function(stream, state) {
|
| - function tokenSGMLComment(stream, state) {
|
| - var dashes = 0, ch;
|
| - while ((ch = stream.next()) != null) {
|
| - if (dashes >= 2 && ch == ">") {
|
| - state.tokenize = null;
|
| - break;
|
| - }
|
| - dashes = (ch == "-") ? dashes + 1 : 0;
|
| - }
|
| - return ["comment", "comment"];
|
| - }
|
| - if (stream.eat("!")) {
|
| - state.tokenize = tokenSGMLComment;
|
| - return tokenSGMLComment(stream, state);
|
| - }
|
| + if (!stream.match("!--")) return false;
|
| + state.tokenize = tokenSGMLComment;
|
| + return tokenSGMLComment(stream, state);
|
| },
|
| "/": function(stream, state) {
|
| - if (stream.eat("*")) {
|
| - state.tokenize = tokenCComment;
|
| - return tokenCComment(stream, state);
|
| - }
|
| - return false;
|
| + if (!stream.eat("*")) return false;
|
| + state.tokenize = tokenCComment;
|
| + return tokenCComment(stream, state);
|
| }
|
| },
|
| name: "css"
|
| });
|
|
|
| CodeMirror.defineMIME("text/x-scss", {
|
| - atMediaTypes: atMediaTypes,
|
| - atMediaFeatures: atMediaFeatures,
|
| + mediaTypes: mediaTypes,
|
| + mediaFeatures: mediaFeatures,
|
| propertyKeywords: propertyKeywords,
|
| + nonStandardPropertyKeywords: nonStandardPropertyKeywords,
|
| colorKeywords: colorKeywords,
|
| valueKeywords: valueKeywords,
|
| + fontProperties: fontProperties,
|
| allowNested: true,
|
| - hooks: {
|
| + tokenHooks: {
|
| + "/": function(stream, state) {
|
| + if (stream.eat("/")) {
|
| + stream.skipToEnd();
|
| + return ["comment", "comment"];
|
| + } else if (stream.eat("*")) {
|
| + state.tokenize = tokenCComment;
|
| + return tokenCComment(stream, state);
|
| + } else {
|
| + return ["operator", "operator"];
|
| + }
|
| + },
|
| ":": function(stream) {
|
| - if (stream.match(/\s*{/)) {
|
| + if (stream.match(/\s*\{/))
|
| return [null, "{"];
|
| - }
|
| return false;
|
| },
|
| "$": function(stream) {
|
| stream.match(/^[\w-]+/);
|
| - if (stream.peek() == ":") {
|
| - return ["variable", "variable-definition"];
|
| - }
|
| - return ["variable", "variable"];
|
| - },
|
| - ",": function(stream, state) {
|
| - if (state.stack[state.stack.length - 1] == "propertyValue" && stream.match(/^ *\$/, false)) {
|
| - return ["operator", ";"];
|
| - }
|
| + if (stream.match(/^\s*:/, false))
|
| + return ["variable-2", "variable-definition"];
|
| + return ["variable-2", "variable"];
|
| },
|
| + "#": function(stream) {
|
| + if (!stream.eat("{")) return false;
|
| + return [null, "interpolation"];
|
| + }
|
| + },
|
| + name: "css",
|
| + helperType: "scss"
|
| + });
|
| +
|
| + CodeMirror.defineMIME("text/x-less", {
|
| + mediaTypes: mediaTypes,
|
| + mediaFeatures: mediaFeatures,
|
| + propertyKeywords: propertyKeywords,
|
| + nonStandardPropertyKeywords: nonStandardPropertyKeywords,
|
| + colorKeywords: colorKeywords,
|
| + valueKeywords: valueKeywords,
|
| + fontProperties: fontProperties,
|
| + allowNested: true,
|
| + tokenHooks: {
|
| "/": function(stream, state) {
|
| if (stream.eat("/")) {
|
| stream.skipToEnd();
|
| @@ -625,15 +699,19 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
| return ["operator", "operator"];
|
| }
|
| },
|
| - "#": function(stream) {
|
| - if (stream.eat("{")) {
|
| - return ["operator", "interpolation"];
|
| - } else {
|
| - stream.eatWhile(/[\w\\\-]/);
|
| - return ["atom", "hash"];
|
| - }
|
| + "@": function(stream) {
|
| + if (stream.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/, false)) return false;
|
| + stream.eatWhile(/[\w\\\-]/);
|
| + if (stream.match(/^\s*:/, false))
|
| + return ["variable-2", "variable-definition"];
|
| + return ["variable-2", "variable"];
|
| + },
|
| + "&": function() {
|
| + return ["atom", "atom"];
|
| }
|
| },
|
| - name: "css"
|
| + name: "css",
|
| + helperType: "less"
|
| });
|
| -})();
|
| +
|
| +});
|
|
|