Mercurial Hosting > nabble
diff src/nabble/view/web/util/codemirror/js/parsecss.js @ 0:7ecd1a4ef557
add content
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Thu, 21 Mar 2019 19:15:52 -0600 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nabble/view/web/util/codemirror/js/parsecss.js Thu Mar 21 19:15:52 2019 -0600 @@ -0,0 +1,161 @@ +/* Simple parser for CSS */ + +var CSSParser = Editor.Parser = (function() { + var tokenizeCSS = (function() { + function normal(source, setState) { + var ch = source.next(); + if (ch == "@") { + source.nextWhileMatches(/\w/); + return "css-at"; + } + else if (ch == "/" && source.equals("*")) { + setState(inCComment); + return null; + } + else if (ch == "<" && source.equals("!")) { + setState(inSGMLComment); + return null; + } + else if (ch == "=") { + return "css-compare"; + } + else if (source.equals("=") && (ch == "~" || ch == "|")) { + source.next(); + return "css-compare"; + } + else if (ch == "\"" || ch == "'") { + setState(inString(ch)); + return null; + } + else if (ch == "#") { + source.nextWhileMatches(/\w/); + return "css-hash"; + } + else if (ch == "!") { + source.nextWhileMatches(/[ \t]/); + source.nextWhileMatches(/\w/); + return "css-important"; + } + else if (/\d/.test(ch)) { + source.nextWhileMatches(/[\w.%]/); + return "css-unit"; + } + else if (/[,.+>*\/]/.test(ch)) { + return "css-select-op"; + } + else if (/[;{}:\[\]]/.test(ch)) { + return "css-punctuation"; + } + else { + source.nextWhileMatches(/[\w\\\-_]/); + return "css-identifier"; + } + } + + function inCComment(source, setState) { + var maybeEnd = false; + while (!source.endOfLine()) { + var ch = source.next(); + if (maybeEnd && ch == "/") { + setState(normal); + break; + } + maybeEnd = (ch == "*"); + } + return "css-comment"; + } + + function inSGMLComment(source, setState) { + var dashes = 0; + while (!source.endOfLine()) { + var ch = source.next(); + if (dashes >= 2 && ch == ">") { + setState(normal); + break; + } + dashes = (ch == "-") ? dashes + 1 : 0; + } + return "css-comment"; + } + + function inString(quote) { + return function(source, setState) { + var escaped = false; + while (!source.endOfLine()) { + var ch = source.next(); + if (ch == quote && !escaped) + break; + escaped = !escaped && ch == "\\"; + } + if (!escaped) + setState(normal); + return "css-string"; + }; + } + + return function(source, startState) { + return tokenizer(source, startState || normal); + }; + })(); + + function indentCSS(inBraces, inRule, base) { + return function(nextChars) { + if (!inBraces || /^\}/.test(nextChars)) return base; + else if (inRule) return base + indentUnit * 2; + else return base + indentUnit; + }; + } + + // This is a very simplistic parser -- since CSS does not really + // nest, it works acceptably well, but some nicer colouroing could + // be provided with a more complicated parser. + function parseCSS(source, basecolumn) { + basecolumn = basecolumn || 0; + var tokens = tokenizeCSS(source); + var inBraces = false, inRule = false, inDecl = false;; + + var iter = { + next: function() { + var token = tokens.next(), style = token.style, content = token.content; + + if (style == "css-hash") + style = token.style = inRule ? "css-colorcode" : "css-identifier"; + if (style == "css-identifier") { + if (inRule) token.style = "css-value"; + else if (!inBraces && !inDecl) token.style = "css-selector"; + } + + if (content == "\n") + token.indentation = indentCSS(inBraces, inRule, basecolumn); + + if (content == "{" && inDecl == "@media") + inDecl = false; + else if (content == "{") + inBraces = true; + else if (content == "}") + inBraces = inRule = inDecl = false; + else if (content == ";") + inRule = inDecl = false; + else if (inBraces && style != "css-comment" && style != "whitespace") + inRule = true; + else if (!inBraces && style == "css-at") + inDecl = content; + + return token; + }, + + copy: function() { + var _inBraces = inBraces, _inRule = inRule, _tokenState = tokens.state; + return function(source) { + tokens = tokenizeCSS(source, _tokenState); + inBraces = _inBraces; + inRule = _inRule; + return iter; + }; + } + }; + return iter; + } + + return {make: parseCSS, electricChars: "}"}; +})();