diff options
Diffstat (limited to 'imports/codemirror/mode/less/less.js')
-rw-r--r-- | imports/codemirror/mode/less/less.js | 143 |
1 files changed, 86 insertions, 57 deletions
diff --git a/imports/codemirror/mode/less/less.js b/imports/codemirror/mode/less/less.js index dc584f02..1c20bd81 100644 --- a/imports/codemirror/mode/less/less.js +++ b/imports/codemirror/mode/less/less.js | |||
@@ -1,21 +1,26 @@ | |||
1 | CodeMirror.defineMode("less", function(config) { | 1 | /* |
2 | LESS mode - http://www.lesscss.org/ | ||
3 | Ported to CodeMirror by Peter Kroon | ||
4 | */ | ||
5 | |||
6 | CodeMirror.defineMode("css", function(config) { | ||
2 | var indentUnit = config.indentUnit, type; | 7 | var indentUnit = config.indentUnit, type; |
3 | function ret(style, tp) {type = tp; return style;} | 8 | function ret(style, tp) {type = tp; return style;} |
4 | //html5 tags | 9 | //html5 tags |
5 | var tags = ["a","abbr","acronym","address","applet","area","article","aside","audio","b","base","basefont","bdi","bdo","big","blockquote","body","br","button","canvas","caption","cite","code","col","colgroup","command","datalist","dd","del","details","dfn","dir","div","dl","dt","em","embed","fieldset","figcaption","figure","font","footer","form","frame","frameset","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","iframe","img","input","ins","keygen","kbd","label","legend","li","link","map","mark","menu","meta","meter","nav","noframes","noscript","object","ol","optgroup","option","output","p","param","pre","progress","q","rp","rt","ruby","s","samp","script","section","select","small","source","span","strike","strong","style","sub","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","title","tr","track","tt","u","ul","var","video","wbr"]; | 10 | var tags = ["a","abbr","acronym","address","applet","area","article","aside","audio","b","base","basefont","bdi","bdo","big","blockquote","body","br","button","canvas","caption","cite","code","col","colgroup","command","datalist","dd","del","details","dfn","dir","div","dl","dt","em","embed","fieldset","figcaption","figure","font","footer","form","frame","frameset","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","iframe","img","input","ins","keygen","kbd","label","legend","li","link","map","mark","menu","meta","meter","nav","noframes","noscript","object","ol","optgroup","option","output","p","param","pre","progress","q","rp","rt","ruby","s","samp","script","section","select","small","source","span","strike","strong","style","sub","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","title","tr","track","tt","u","ul","var","video","wbr"]; |
6 | 11 | ||
7 | function inTagsArray(val){ | 12 | function inTagsArray(val){ |
8 | for(var i=0; i<tags.length; i++){ | 13 | for(var i=0; i<tags.length; i++){ |
9 | if(val === tags[i]){ | 14 | if(val === tags[i]){ |
10 | return true; | 15 | return true; |
11 | } | 16 | } |
12 | } | 17 | } |
13 | } | 18 | } |
14 | 19 | ||
15 | function tokenBase(stream, state) { | 20 | function tokenBase(stream, state) { |
16 | var ch = stream.next(); | 21 | var ch = stream.next(); |
17 | 22 | ||
18 | if (ch == "@") {stream.eatWhile(/[\w\-]/); return ret("meta", stream.current());} | 23 | if (ch == "@") {stream.eatWhile(/[\w\-]/); return ret("meta", stream.current());} |
19 | else if (ch == "/" && stream.eat("*")) { | 24 | else if (ch == "/" && stream.eat("*")) { |
20 | state.tokenize = tokenCComment; | 25 | state.tokenize = tokenCComment; |
21 | return tokenCComment(stream, state); | 26 | return tokenCComment(stream, state); |
@@ -30,15 +35,15 @@ CodeMirror.defineMode("less", function(config) { | |||
30 | state.tokenize = tokenString(ch); | 35 | state.tokenize = tokenString(ch); |
31 | return state.tokenize(stream, state); | 36 | return state.tokenize(stream, state); |
32 | } | 37 | } |
33 | else if (ch == "/") { // lesscss e.g.: .png will not be parsed as a class | 38 | else if (ch == "/") { // lesscss e.g.: .png will not be parsed as a class |
34 | if(stream.eat("/")){ | 39 | if(stream.eat("/")){ |
35 | state.tokenize = tokenSComment | 40 | state.tokenize = tokenSComment |
36 | return tokenSComment(stream, state); | 41 | return tokenSComment(stream, state); |
37 | }else{ | 42 | }else{ |
38 | stream.eatWhile(/[\a-zA-Z0-9\-_.]/); | 43 | stream.eatWhile(/[\a-zA-Z0-9\-_.\s]/); |
39 | if(stream.peek() == ")" || stream.peek() == "/")return ret("string", "string");//let url(/images/logo.png) without quotes return as string | 44 | if(/\/|\)/.test(stream.peek() || stream.eol() || (stream.eatSpace() && stream.peek() == ")")))return ret("string", "string");//let url(/images/logo.png) without quotes return as string |
40 | return ret("number", "unit"); | 45 | return ret("number", "unit"); |
41 | } | 46 | } |
42 | } | 47 | } |
43 | else if (ch == "!") { | 48 | else if (ch == "!") { |
44 | stream.match(/^\s*\w*/); | 49 | stream.match(/^\s*\w*/); |
@@ -48,66 +53,86 @@ CodeMirror.defineMode("less", function(config) { | |||
48 | stream.eatWhile(/[\w.%]/); | 53 | stream.eatWhile(/[\w.%]/); |
49 | return ret("number", "unit"); | 54 | return ret("number", "unit"); |
50 | } | 55 | } |
51 | else if (/[,+>*\/]/.test(ch)) {//removed . dot character original was [,.+>*\/] | 56 | else if (/[,+<>*\/]/.test(ch)) {//removed . dot character original was [,.+>*\/] |
52 | return ret(null, "select-op"); | 57 | return ret(null, "select-op"); |
53 | } | 58 | } |
54 | else if (/[;{}:\[\]()]/.test(ch)) { //added () char for lesscss original was [;{}:\[\]] | 59 | else if (/[;{}:\[\]()]/.test(ch)) { //added () char for lesscss original was [;{}:\[\]] |
55 | if(ch == ":"){ | 60 | if(ch == ":"){ |
56 | stream.eatWhile(/[active|hover|link|visited]/); | 61 | stream.eatWhile(/[active|hover|link|visited]/); |
57 | if( stream.current().match(/active|hover|link|visited/)){ | 62 | if( stream.current().match(/active|hover|link|visited/)){ |
58 | return ret("tag", "tag"); | 63 | return ret("tag", "tag"); |
59 | }else{ | 64 | }else{ |
60 | return ret(null, ch); | 65 | return ret(null, ch); |
61 | } | 66 | } |
62 | }else{ | 67 | }else{ |
63 | return ret(null, ch); | 68 | return ret(null, ch); |
64 | } | 69 | } |
65 | } | 70 | } |
66 | else if (ch == ".") { // lesscss | 71 | else if (ch == ".") { // lesscss |
67 | stream.eatWhile(/[\a-zA-Z0-9\-_]/); | 72 | stream.eatWhile(/[\a-zA-Z0-9\-_]/); |
68 | return ret("tag", "tag"); | 73 | return ret("tag", "tag"); |
69 | } | 74 | } |
70 | else if (ch == "#") { // lesscss | 75 | else if (ch == "#") { // lesscss |
71 | stream.match(/([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/); | 76 | //we don't eat white-space, we want the hex color and or id only |
72 | if(stream.current().length >1){ | 77 | stream.eatWhile(/[A-Za-z0-9]/); |
73 | if(stream.current().match(/([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/) != null){ | 78 | //check if there is a proper hex color length e.g. #eee || #eeeEEE |
74 | return ret("number", "unit"); | 79 | if(stream.current().length ===4 || stream.current().length ===7){ |
75 | }else{ | 80 | if(stream.current().match(/[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3}/,false) != null){//is there a valid hex color value present in the current stream |
81 | //when not a valid hex value, parse as id | ||
82 | if(stream.current().substring(1) != stream.current().match(/[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3}/,false))return ret("atom", "tag"); | ||
83 | //eat white-space | ||
84 | stream.eatSpace(); | ||
85 | //when hex value declaration doesn't end with [;,] but is does with a slash/cc comment treat it as an id, just like the other hex values that don't end with[;,] | ||
86 | if( /[\/<>.(){!$%^&*_\-\\?=+\|#'~`]/.test(stream.peek()) )return ret("atom", "tag"); | ||
87 | //#time { color: #aaa } | ||
88 | else if(stream.peek() == "}" )return ret("number", "unit"); | ||
89 | //we have a valid hex color value, parse as id whenever an element/class is defined after the hex(id) value e.g. #eee aaa || #eee .aaa | ||
90 | else if( /[a-zA-Z\\]/.test(stream.peek()) )return ret("atom", "tag"); | ||
91 | //when a hex value is on the end of a line, parse as id | ||
92 | else if(stream.eol())return ret("atom", "tag"); | ||
93 | //default | ||
94 | else return ret("number", "unit"); | ||
95 | }else{//when not a valid hexvalue in the current stream e.g. #footer | ||
96 | stream.eatWhile(/[\w\\\-]/); | ||
97 | return ret("atom", "tag"); | ||
98 | } | ||
99 | }else{ | ||
100 | stream.eatWhile(/[\w\\\-]/); | ||
101 | return ret("atom", "tag"); | ||
102 | } | ||
103 | } | ||
104 | else if (ch == "&") { | ||
76 | stream.eatWhile(/[\w\-]/); | 105 | stream.eatWhile(/[\w\-]/); |
77 | return ret("atom", "tag"); | 106 | return ret(null, ch); |
107 | } | ||
108 | else if (ch == "&") { | ||
109 | stream.eatWhile(/[\w\-]/); | ||
110 | return ret(null, ch); | ||
78 | } | 111 | } |
79 | }else{ | ||
80 | stream.eatWhile(/[\w\-]/); | ||
81 | return ret("atom", "tag"); | ||
82 | } | ||
83 | } | ||
84 | else if (ch == "&") { | ||
85 | stream.eatWhile(/[\w\-]/); | ||
86 | return ret(null, ch); | ||
87 | } | ||
88 | else { | 112 | else { |
89 | stream.eatWhile(/[\w\\\-_.%]/); | 113 | stream.eatWhile(/[\w\\\-_.%]/); |
90 | if( stream.eat("(") ){ // lesscss | 114 | if( stream.peek().match(/\(/) != null ){// lesscss |
91 | return ret(null, ch); | 115 | stream.eatWhile(/[a-zA-Z\s]/); |
92 | }else if( stream.current().match(/\-\d|\-.\d/) ){ // lesscss match e.g.: -5px -0.4 etc... | 116 | if(stream.peek() == "(")return ret(null, ch); |
93 | return ret("number", "unit"); | 117 | }else if( stream.current().match(/\-\d|\-.\d/) ){ // lesscss match e.g.: -5px -0.4 etc... |
94 | }else if( inTagsArray(stream.current()) ){ // lesscss match html tags | 118 | return ret("number", "unit"); |
95 | return ret("tag", "tag"); | 119 | }else if( inTagsArray(stream.current()) ){ // lesscss match html tags |
96 | }else if( (stream.peek() == ")" || stream.peek() == "/") && stream.current().indexOf('.') !== -1){ | 120 | return ret("tag", "tag"); |
97 | return ret("string", "string");//let url(logo.png) without quotes and froward slash return as string | 121 | }else if( /\/|\)/.test(stream.peek() || stream.eol() || (stream.eatSpace() && stream.peek() == ")")) && stream.current().indexOf(".") !== -1){ |
98 | }else{ | 122 | return ret("string", "string");//let url(/images/logo.png) without quotes return as string |
123 | }else{ | ||
99 | return ret("variable", "variable"); | 124 | return ret("variable", "variable"); |
100 | } | 125 | } |
101 | } | 126 | } |
102 | 127 | ||
103 | } | 128 | } |
104 | 129 | ||
105 | function tokenSComment(stream, state) {// SComment = Slash comment | 130 | function tokenSComment(stream, state) {// SComment = Slash comment |
106 | stream.skipToEnd(); | 131 | stream.skipToEnd(); |
107 | state.tokenize = tokenBase; | 132 | state.tokenize = tokenBase; |
108 | return ret("comment", "comment"); | 133 | return ret("comment", "comment"); |
109 | } | 134 | } |
110 | 135 | ||
111 | function tokenCComment(stream, state) { | 136 | function tokenCComment(stream, state) { |
112 | var maybeEnd = false, ch; | 137 | var maybeEnd = false, ch; |
113 | while ((ch = stream.next()) != null) { | 138 | while ((ch = stream.next()) != null) { |
@@ -146,7 +171,7 @@ CodeMirror.defineMode("less", function(config) { | |||
146 | } | 171 | } |
147 | 172 | ||
148 | return { | 173 | return { |
149 | startState: function(base) { | 174 | startState: function(base) { |
150 | return {tokenize: tokenBase, | 175 | return {tokenize: tokenBase, |
151 | baseIndent: base || 0, | 176 | baseIndent: base || 0, |
152 | stack: []}; | 177 | stack: []}; |
@@ -160,7 +185,11 @@ CodeMirror.defineMode("less", function(config) { | |||
160 | if (type == "hash" && context == "rule") style = "atom"; | 185 | if (type == "hash" && context == "rule") style = "atom"; |
161 | else if (style == "variable") { | 186 | else if (style == "variable") { |
162 | if (context == "rule") style = null; //"tag" | 187 | if (context == "rule") style = null; //"tag" |
163 | else if (!context || context == "@media{") style = "tag"; | 188 | else if (!context || context == "@media{"){ |
189 | style = stream.current() == "when" ? "variable" : | ||
190 | stream.string.match(/#/g) != undefined ? null : | ||
191 | /[\s,|\s\)]/.test(stream.peek()) ? "tag" : null; | ||
192 | } | ||
164 | } | 193 | } |
165 | 194 | ||
166 | if (context == "rule" && /^[\{\};]$/.test(type)) | 195 | if (context == "rule" & |