aboutsummaryrefslogtreecommitdiff
path: root/imports/codemirror/mode/less/less.js
diff options
context:
space:
mode:
Diffstat (limited to 'imports/codemirror/mode/less/less.js')
-rw-r--r--imports/codemirror/mode/less/less.js143
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 @@
1CodeMirror.defineMode("less", function(config) { 1/*
2LESS mode - http://www.lesscss.org/
3Ported to CodeMirror by Peter Kroon
4*/
5
6CodeMirror.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" && /^[\{\};]$/.test(type))