diff options
Diffstat (limited to 'imports/codemirror/mode/less/less.js')
-rw-r--r-- | imports/codemirror/mode/less/less.js | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/imports/codemirror/mode/less/less.js b/imports/codemirror/mode/less/less.js new file mode 100644 index 00000000..dc584f02 --- /dev/null +++ b/imports/codemirror/mode/less/less.js | |||
@@ -0,0 +1,189 @@ | |||
1 | CodeMirror.defineMode("less", function(config) { | ||
2 | var indentUnit = config.indentUnit, type; | ||
3 | function ret(style, tp) {type = tp; return style;} | ||
4 | //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"]; | ||
6 | |||
7 | function inTagsArray(val){ | ||
8 | for(var i=0; i<tags.length; i++){ | ||
9 | if(val === tags[i]){ | ||
10 | return true; | ||
11 | } | ||
12 | } | ||
13 | } | ||
14 | |||
15 | function tokenBase(stream, state) { | ||
16 | var ch = stream.next(); | ||
17 | |||
18 | if (ch == "@") {stream.eatWhile(/[\w\-]/); return ret("meta", stream.current());} | ||
19 | else if (ch == "/" && stream.eat("*")) { | ||
20 | state.tokenize = tokenCComment; | ||
21 | return tokenCComment(stream, state); | ||
22 | } | ||
23 | else if (ch == "<" && stream.eat("!")) { | ||
24 | state.tokenize = tokenSGMLComment; | ||
25 | return tokenSGMLComment(stream, state); | ||
26 | } | ||
27 | else if (ch == "=") ret(null, "compare"); | ||
28 | else if ((ch == "~" || ch == "|") && stream.eat("=")) return ret(null, "compare"); | ||
29 | else if (ch == "\"" || ch == "'") { | ||
30 | state.tokenize = tokenString(ch); | ||
31 | return state.tokenize(stream, state); | ||
32 | } | ||
33 | else if (ch == "/") { // lesscss e.g.: .png will not be parsed as a class | ||
34 | if(stream.eat("/")){ | ||
35 | state.tokenize = tokenSComment | ||
36 | return tokenSComment(stream, state); | ||
37 | }else{ | ||
38 | stream.eatWhile(/[\a-zA-Z0-9\-_.]/); | ||
39 | if(stream.peek() == ")" || stream.peek() == "/")return ret("string", "string");//let url(/images/logo.png) without quotes return as string | ||
40 | return ret("number", "unit"); | ||
41 | } | ||
42 | } | ||
43 | else if (ch == "!") { | ||
44 | stream.match(/^\s*\w*/); | ||
45 | return ret("keyword", "important"); | ||
46 | } | ||
47 | else if (/\d/.test(ch)) { | ||
48 | stream.eatWhile(/[\w.%]/); | ||
49 | return ret("number", "unit"); | ||
50 | } | ||
51 | else if (/[,+>*\/]/.test(ch)) {//removed . dot character original was [,.+>*\/] | ||
52 | return ret(null, "select-op"); | ||
53 | } | ||
54 | else if (/[;{}:\[\]()]/.test(ch)) { //added () char for lesscss original was [;{}:\[\]] | ||
55 | if(ch == ":"){ | ||
56 | stream.eatWhile(/[active|hover|link|visited]/); | ||
57 | if( stream.current().match(/active|hover|link|visited/)){ | ||
58 | return ret("tag", "tag"); | ||
59 | }else{ | ||
60 | return ret(null, ch); | ||
61 | } | ||
62 | }else{ | ||
63 | return ret(null, ch); | ||
64 | } | ||
65 | } | ||
66 | else if (ch == ".") { // lesscss | ||
67 | stream.eatWhile(/[\a-zA-Z0-9\-_]/); | ||
68 | return ret("tag", "tag"); | ||
69 | } | ||
70 | else if (ch == "#") { // lesscss | ||
71 | stream.match(/([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/); | ||
72 | if(stream.current().length >1){ | ||
73 | if(stream.current().match(/([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/) != null){ | ||
74 | return ret("number", "unit"); | ||
75 | }else{ | ||
76 | stream.eatWhile(/[\w\-]/); | ||
77 | return ret("atom", "tag"); | ||
78 | } | ||
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 { | ||
89 | stream.eatWhile(/[\w\\\-_.%]/); | ||
90 | if( stream.eat("(") ){ // lesscss | ||
91 | return ret(null, ch); | ||
92 | }else if( stream.current().match(/\-\d|\-.\d/) ){ // lesscss match e.g.: -5px -0.4 etc... | ||
93 | return ret("number", "unit"); | ||
94 | }else if( inTagsArray(stream.current()) ){ // lesscss match html tags | ||
95 | return ret("tag", "tag"); | ||
96 | }else if( (stream.peek() == ")" || stream.peek() == "/") && stream.current().indexOf('.') !== -1){ | ||
97 | return ret("string", "string");//let url(logo.png) without quotes and froward slash return as string | ||
98 | }else{ | ||
99 | return ret("variable", "variable"); | ||
100 | } | ||
101 | } | ||
102 | |||
103 | } | ||
104 | |||
105 | function tokenSComment(stream, state) {// SComment = Slash comment | ||
106 | stream.skipToEnd(); | ||
107 | state.tokenize = tokenBase; | ||
108 | return ret("comment", "comment"); | ||
109 | } | ||
110 | |||
111 | function tokenCComment(stream, state) { | ||
112 | var maybeEnd = false, ch; | ||
113 | while ((ch = stream.next()) != null) { | ||
114 | if (maybeEnd && ch == "/") { | ||
115 | state.tokenize = tokenBase; | ||
116 | break; | ||
117 | } | ||
118 | maybeEnd = (ch == "*"); | ||
119 | } | ||
120 | return ret("comment", "comment"); | ||
121 | } | ||
122 | |||
123 | function tokenSGMLComment(stream, state) { | ||
124 | var dashes = 0, ch; | ||
125 | while ((ch = stream.next()) != null) { | ||
126 | if (dashes >= 2 && ch == ">") { | ||
127 | state.tokenize = tokenBase; | ||
128 | break; | ||
129 | } | ||
130 | dashes = (ch == "-") ? dashes + 1 : 0; | ||
131 | } | ||
132 | return ret("comment", "comment"); | ||
133 | } | ||
134 | |||
135 | function tokenString(quote) { | ||
136 | return function(stream, state) { | ||
137 | var escaped = false, ch; | ||
138 | while ((ch = stream.next()) != null) { | ||
139 | if (ch == quote && !escaped) | ||
140 | break; | ||
141 | escaped = !escaped && ch == "\\"; | ||
142 | } | ||
143 | if (!escaped) state.tokenize = tokenBase; | ||
144 | return ret("string", "string"); | ||
145 | }; | ||
146 | } | ||
147 | |||
148 | return { | ||
149 | startState: function(base) { | ||
150 | return {tokenize: tokenBase, | ||
151 | baseIndent: base || 0, | ||
152 | stack: []}; | ||
153 | }, | ||
154 | |||
155 | token: function(stream, state) { | ||
156 | if (stream.eatSpace()) return null; | ||
157 | var style = state.tokenize(stream, state); | ||
158 | |||
159 | var context = state.stack[state.stack.length-1]; | ||
160 | if (type == "hash" && context == "rule") style = "atom"; | ||
161 | else if (style == "variable") { | ||
162 | if (context == "rule") style = null; //"tag" | ||
163 | else if (!context || context == "@media{") style = "tag"; | ||
164 | } | ||
165 | |||
166 | if (context == "rule" && /^[\{\};]$/.test(type)) | ||
167 | state.stack.pop(); | ||
168 | if (type == "{") { | ||
169 | if (context == "@media") state.stack[state.stack.length-1] = "@media{"; | ||
170 | else state.stack.push("{"); | ||
171 | } | ||
172 | else if (type == "}") state.stack.pop(); | ||
173 | else if (type == "@media") state.stack.push("@media"); | ||
174 | else if (context == "{" && type != "comment") state.stack.push("rule"); | ||
175 | return style; | ||
176 | }, | ||
177 | |||
178 | indent: function(state, textAfter) { | ||
179 | var n = state.stack.length; | ||
180 | if (/^\}/.test(textAfter)) | ||
181 | n -= state.stack[state.stack.length-1] == "rule" ? 2 : 1; | ||
182 | return state.baseIndent + n * indentUnit; | ||
183 | }, | ||
184 | |||
185 | electricChars: "}" | ||
186 | }; | ||
187 | }); | ||
188 | |||
189 | CodeMirror.defineMIME("text/less", "less"); | ||