Path: blob/master/web-gui/buildyourownbotnet/assets/js/codemirror/mode/less/less.js
1294 views
/*1LESS mode - http://www.lesscss.org/2Ported to CodeMirror by Peter Kroon <[email protected]>3Report bugs/issues here: https://github.com/marijnh/CodeMirror/issues4GitHub: @peterkroon5*/67CodeMirror.defineMode("less", function(config) {8var indentUnit = config.indentUnit, type;9function ret(style, tp) {type = tp; return style;}1011var selectors = /(^\:root$|^\:nth\-child$|^\:nth\-last\-child$|^\:nth\-of\-type$|^\:nth\-last\-of\-type$|^\:first\-child$|^\:last\-child$|^\:first\-of\-type$|^\:last\-of\-type$|^\:only\-child$|^\:only\-of\-type$|^\:empty$|^\:link|^\:visited$|^\:active$|^\:hover$|^\:focus$|^\:target$|^\:lang$|^\:enabled^\:disabled$|^\:checked$|^\:first\-line$|^\:first\-letter$|^\:before$|^\:after$|^\:not$|^\:required$|^\:invalid$)/;1213function tokenBase(stream, state) {14var ch = stream.next();1516if (ch == "@") {stream.eatWhile(/[\w\-]/); return ret("meta", stream.current());}17else if (ch == "/" && stream.eat("*")) {18state.tokenize = tokenCComment;19return tokenCComment(stream, state);20} else if (ch == "<" && stream.eat("!")) {21state.tokenize = tokenSGMLComment;22return tokenSGMLComment(stream, state);23} else if (ch == "=") ret(null, "compare");24else if (ch == "|" && stream.eat("=")) return ret(null, "compare");25else if (ch == "\"" || ch == "'") {26state.tokenize = tokenString(ch);27return state.tokenize(stream, state);28} else if (ch == "/") { // e.g.: .png will not be parsed as a class29if(stream.eat("/")){30state.tokenize = tokenSComment;31return tokenSComment(stream, state);32} else {33if(type == "string" || type == "(") return ret("string", "string");34if(state.stack[state.stack.length-1] !== undefined) return ret(null, ch);35stream.eatWhile(/[\a-zA-Z0-9\-_.\s]/);36if( /\/|\)|#/.test(stream.peek() || (stream.eatSpace() && stream.peek() === ")")) || stream.eol() )return ret("string", "string"); // let url(/images/logo.png) without quotes return as string37}38} else if (ch == "!") {39stream.match(/^\s*\w*/);40return ret("keyword", "important");41} else if (/\d/.test(ch)) {42stream.eatWhile(/[\w.%]/);43return ret("number", "unit");44} else if (/[,+<>*\/]/.test(ch)) {45if(stream.peek() == "=" || type == "a")return ret("string", "string");46if(ch === ",")return ret(null, ch);47return ret(null, "select-op");48} else if (/[;{}:\[\]()~\|]/.test(ch)) {49if(ch == ":"){50stream.eatWhile(/[a-z\\\-]/);51if( selectors.test(stream.current()) ){52return ret("tag", "tag");53} else if(stream.peek() == ":"){//::-webkit-search-decoration54stream.next();55stream.eatWhile(/[a-z\\\-]/);56if(stream.current().match(/\:\:\-(o|ms|moz|webkit)\-/))return ret("string", "string");57if( selectors.test(stream.current().substring(1)) )return ret("tag", "tag");58return ret(null, ch);59} else {60return ret(null, ch);61}62} else if(ch == "~"){63if(type == "r")return ret("string", "string");64} else {65return ret(null, ch);66}67} else if (ch == ".") {68if(type == "(")return ret("string", "string"); // allow url(../image.png)69stream.eatWhile(/[\a-zA-Z0-9\-_]/);70if(stream.peek() === " ")stream.eatSpace();71if(stream.peek() === ")" || type === ":")return ret("number", "unit");//rgba(0,0,0,.25);72else if(stream.current().length >1){73if(state.stack[state.stack.length-1] === "rule" && !stream.match(/^[{,+(]/, false)) return ret("number", "unit");74}75return ret("tag", "tag");76} else if (ch == "#") {77//we don't eat white-space, we want the hex color and or id only78stream.eatWhile(/[A-Za-z0-9]/);79//check if there is a proper hex color length e.g. #eee || #eeeEEE80if(stream.current().length == 4 || stream.current().length == 7){81if(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 stream82//when not a valid hex value, parse as id83if(stream.current().substring(1) != stream.current().match(/[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3}/,false))return ret("atom", "tag");84//eat white-space85stream.eatSpace();86//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[;,]87if( /[\/<>.(){!$%^&*_\-\\?=+\|#'~`]/.test(stream.peek()) ){88if(type === "select-op")return ret("number", "unit"); else return ret("atom", "tag");89}90//#time { color: #aaa }91else if(stream.peek() == "}" )return ret("number", "unit");92//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 .aaa93else if( /[a-zA-Z\\]/.test(stream.peek()) )return ret("atom", "tag");94//when a hex value is on the end of a line, parse as id95else if(stream.eol())return ret("atom", "tag");96//default97else return ret("number", "unit");98} else {//when not a valid hexvalue in the current stream e.g. #footer99stream.eatWhile(/[\w\\\-]/);100return ret("atom", stream.current());101}102} else {//when not a valid hexvalue length103stream.eatWhile(/[\w\\\-]/);104if(state.stack[state.stack.length-1] === "rule")return ret("atom", stream.current());return ret("atom", stream.current());105return ret("atom", "tag");106}107} else if (ch == "&") {108stream.eatWhile(/[\w\-]/);109return ret(null, ch);110} else {111stream.eatWhile(/[\w\\\-_%.{]/);112if(stream.current().match(/\\/) !== null){113if(stream.current().charAt(stream.current().length-1) === "\\"){114stream.eat(/\'|\"|\)|\(/);115while(stream.eatWhile(/[\w\\\-_%.{]/)){116stream.eat(/\'|\"|\)|\(/);117}118return ret("string", stream.current());119}120} //else if(type === "tag")return ret("tag", "tag");121else if(type == "string"){122if(state.stack[state.stack.length-1] === "{" && stream.peek() === ":")return ret("variable", "variable");123if(stream.peek() === "/")stream.eatWhile(/[\w\\\-_%.{:\/]/);124return ret(type, stream.current());125} else if(stream.current().match(/(^http$|^https$)/) != null){126stream.eatWhile(/[\w\\\-_%.{:\/]/);127if(stream.peek() === "/")stream.eatWhile(/[\w\\\-_%.{:\/]/);128return ret("string", "string");129} else if(stream.peek() == "<" || stream.peek() == ">" || stream.peek() == "+"){130if(type === "(" && (stream.current() === "n" || stream.current() === "-n"))return ret("string", stream.current());131return ret("tag", "tag");132} else if( /\(/.test(stream.peek()) ){133if(stream.current() === "when")return ret("variable","variable");134else if(state.stack[state.stack.length-1] === "@media" && stream.current() === "and")return ret("variable",stream.current());135return ret(null, ch);136} else if (stream.peek() == "/" && state.stack[state.stack.length-1] !== undefined){ // url(dir/center/image.png)137if(stream.peek() === "/")stream.eatWhile(/[\w\\\-_%.{:\/]/);138return ret("string", stream.current());139} else if( stream.current().match(/\-\d|\-.\d/) ){ // match e.g.: -5px -0.4 etc... only colorize the minus sign140//commment out these 2 comment if you want the minus sign to be parsed as null -500px141//stream.backUp(stream.current().length-1);142//return ret(null, ch);143return ret("number", "unit");144} else if( /\/|[\s\)]/.test(stream.peek() || stream.eol() || (stream.eatSpace() && stream.peek() == "/")) && stream.current().indexOf(".") !== -1){145if(stream.current().substring(stream.current().length-1,stream.current().length) == "{"){146stream.backUp(1);147return ret("tag", "tag");148}//end if149stream.eatSpace();150if( /[{<>.a-zA-Z\/]/.test(stream.peek()) || stream.eol() )return ret("tag", "tag"); // e.g. button.icon-plus151return ret("string", "string"); // let url(/images/logo.png) without quotes return as string152} else if( stream.eol() || stream.peek() == "[" || stream.peek() == "#" || type == "tag" ){153154if(stream.current().substring(stream.current().length-1,stream.current().length) == "{")stream.backUp(1);155else if(state.stack[state.stack.length-1] === "border-color" || state.stack[state.stack.length-1] === "background-position" || state.stack[state.stack.length-1] === "font-family")return ret(null, stream.current());156else if(type === "tag")return ret("tag", "tag");157else if((type === ":" || type === "unit") && state.stack[state.stack.length-1] === "rule")return ret(null, stream.current());158else if(state.stack[state.stack.length-1] === "rule" && type === "tag")return ret("string", stream.current());159else if(state.stack[state.stack.length-1] === ";" && type === ":")return ret(null, stream.current());160//else if(state.stack[state.stack.length-1] === ";" || type === "")return ret("variable", stream.current());161else if(stream.peek() === "#" && type !== undefined && type.match(/\+|,|tag|select\-op|}|{|;/g) === null)return ret("string", stream.current());162else if(type === "variable")return ret(null, stream.current());163else if(state.stack[state.stack.length-1] === "{" && type === "comment")return ret("variable", stream.current());164else if(state.stack.length === 0 && (type === ";" || type === "comment"))return ret("tag", stream.current());165else if((state.stack[state.stack.length-1] === "{" || type === ";") && state.stack[state.stack.length-1] !== "@media{")return ret("variable", stream.current());166else if(state.stack[state.stack.length-2] === "{" && state.stack[state.stack.length-1] === ";")return ret("variable", stream.current());167168return ret("tag", "tag");169} else if(type == "compare" || type == "a" || type == "("){170return ret("string", "string");171} else if(type == "|" || stream.current() == "-" || type == "["){172if (type == "|" && stream.match(/^[\]=~]/, false)) return ret("number", stream.current());173else if(type == "|" )return ret("tag", "tag");174else if(type == "["){175stream.eatWhile(/\w\-/);176return ret("number", stream.current());177}178return ret(null, ch);179} else if((stream.peek() == ":") || ( stream.eatSpace() && stream.peek() == ":")) {180stream.next();181var t_v = stream.peek() == ":" ? true : false;182if(!t_v){183var old_pos = stream.pos;184var sc = stream.current().length;185stream.eatWhile(/[a-z\\\-]/);186var new_pos = stream.pos;187if(stream.current().substring(sc-1).match(selectors) != null){188stream.backUp(new_pos-(old_pos-1));189return ret("tag", "tag");190} else stream.backUp(new_pos-(old_pos-1));191} else {192stream.backUp(1);193}194if(t_v)return ret("tag", "tag"); else return ret("variable", "variable");195} else if(state.stack[state.stack.length-1] === "font-family" || state.stack[state.stack.length-1] === "background-position" || state.stack[state.stack.length-1] === "border-color"){196return ret(null, null);197} else {198199if(state.stack[state.stack.length-1] === null && type === ":")return ret(null, stream.current());200201//else if((type === ")" && state.stack[state.stack.length-1] === "rule") || (state.stack[state.stack.length-2] === "{" && state.stack[state.stack.length-1] === "rule" && type === "variable"))return ret(null, stream.current());202203else if (/\^|\$/.test(stream.current()) && stream.match(/^[~=]/, false)) return ret("string", "string");//att^=val204205else if(type === "unit" && state.stack[state.stack.length-1] === "rule")return ret(null, "unit");206else if(type === "unit" && state.stack[state.stack.length-1] === ";")return ret(null, "unit");207else if(type === ")" && state.stack[state.stack.length-1] === "rule")return ret(null, "unit");208else if(type && type.match("@") !== null && state.stack[state.stack.length-1] === "rule")return ret(null, "unit");209//else if(type === "unit" && state.stack[state.stack.length-1] === "rule")return ret(null, stream.current());210211else if((type === ";" || type === "}" || type === ",") && state.stack[state.stack.length-1] === ";")return ret("tag", stream.current());212else if((type === ";" && stream.peek() !== undefined && !stream.match(/^[{\.]/, false)) ||213(type === ";" && stream.eatSpace() && !stream.match(/^[{\.]/))) return ret("variable", stream.current());214else if((type === "@media" && state.stack[state.stack.length-1] === "@media") || type === "@namespace")return ret("tag", stream.current());215216else if(type === "{" && state.stack[state.stack.length-1] === ";" && stream.peek() === "{")return ret("tag", "tag");217else if((type === "{" || type === ":") && state.stack[state.stack.length-1] === ";")return ret(null, stream.current());218else if((state.stack[state.stack.length-1] === "{" && stream.eatSpace() && !stream.match(/^[\.#]/)) || type === "select-op" || (state.stack[state.stack.length-1] === "rule" && type === ",") )return ret("tag", "tag");219else if(type === "variable" && state.stack[state.stack.length-1] === "rule")return ret("tag", "tag");220else if((stream.eatSpace() && stream.peek() === "{") || stream.eol() || stream.peek() === "{")return ret("tag", "tag");221//this one messes up indentation222//else if((type === "}" && stream.peek() !== ":") || (type === "}" && stream.eatSpace() && stream.peek() !== ":"))return(type, "tag");223224else if(type === ")" && (stream.current() == "and" || stream.current() == "and "))return ret("variable", "variable");225else if(type === ")" && (stream.current() == "when" || stream.current() == "when "))return ret("variable", "variable");226else if(type === ")" || type === "comment" || type === "{")return ret("tag", "tag");227else if(stream.sol())return ret("tag", "tag");228else if((stream.eatSpace() && stream.peek() === "#") || stream.peek() === "#")return ret("tag", "tag");229else if(state.stack.length === 0)return ret("tag", "tag");230else if(type === ";" && stream.peek() !== undefined && stream.match(/^[\.|#]/g)) return ret("tag", "tag");231232else if(type === ":"){stream.eatSpace();return ret(null, stream.current());}233234else if(stream.current() === "and " || stream.current() === "and")return ret("variable", stream.current());235else if(type === ";" && state.stack[state.stack.length-1] === "{")return ret("variable", stream.current());236237else if(state.stack[state.stack.length-1] === "rule")return ret(null, stream.current());238239return ret("tag", stream.current());240}241}242}243244function tokenSComment(stream, state) { // SComment = Slash comment245stream.skipToEnd();246state.tokenize = tokenBase;247return ret("comment", "comment");248}249250function tokenCComment(stream, state) {251var maybeEnd = false, ch;252while ((ch = stream.next()) != null) {253if (maybeEnd && ch == "/") {254state.tokenize = tokenBase;255break;256}257maybeEnd = (ch == "*");258}259return ret("comment", "comment");260}261262function tokenSGMLComment(stream, state) {263var dashes = 0, ch;264while ((ch = stream.next()) != null) {265if (dashes >= 2 && ch == ">") {266state.tokenize = tokenBase;267break;268}269dashes = (ch == "-") ? dashes + 1 : 0;270}271return ret("comment", "comment");272}273274function tokenString(quote) {275return function(stream, state) {276var escaped = false, ch;277while ((ch = stream.next()) != null) {278if (ch == quote && !escaped)279break;280escaped = !escaped && ch == "\\";281}282if (!escaped) state.tokenize = tokenBase;283return ret("string", "string");284};285}286287return {288startState: function(base) {289return {tokenize: tokenBase,290baseIndent: base || 0,291stack: []};292},293294token: function(stream, state) {295if (stream.eatSpace()) return null;296var style = state.tokenize(stream, state);297298var context = state.stack[state.stack.length-1];299if (type == "hash" && context == "rule") style = "atom";300else if (style == "variable") {301if (context == "rule") style = null; //"tag"302else if (!context || context == "@media{") {303style = stream.current() == "when" ? "variable" :304/[\s,|\s\)|\s]/.test(stream.peek()) ? "tag" : type;305}306}307308if (context == "rule" && /^[\{\};]$/.test(type))309state.stack.pop();310if (type == "{") {311if (context == "@media") state.stack[state.stack.length-1] = "@media{";312else state.stack.push("{");313}314else if (type == "}") state.stack.pop();315else if (type == "@media") state.stack.push("@media");316else if (stream.current() === "font-family") state.stack[state.stack.length-1] = "font-family";317else if (stream.current() === "background-position") state.stack[state.stack.length-1] = "background-position";318else if (stream.current() === "border-color") state.stack[state.stack.length-1] = "border-color";319else if (context == "{" && type != "comment" && type !== "tag") state.stack.push("rule");320else if (stream.peek() === ":" && stream.current().match(/@|#/) === null) style = type;321if(type === ";" && (state.stack[state.stack.length-1] == "font-family" || state.stack[state.stack.length-1] == "background-position" || state.stack[state.stack.length-1] == "border-color"))state.stack[state.stack.length-1] = stream.current();322else if(type === "tag" && stream.peek() === ")" && stream.current().match(/\:/) === null){type = null; style = null;}323// ????324else if((type === "variable" && stream.peek() === ")") || (type === "variable" && stream.eatSpace() && stream.peek() === ")"))return ret(null,stream.current());325return style;326},327328indent: function(state, textAfter) {329var n = state.stack.length;330if (/^\}/.test(textAfter))331n -= state.stack[state.stack.length-1] === "rule" ? 2 : 1;332else if (state.stack[state.stack.length-2] === "{")333n -= state.stack[state.stack.length-1] === "rule" ? 1 : 0;334return state.baseIndent + n * indentUnit;335},336337electricChars: "}",338blockCommentStart: "/*",339blockCommentEnd: "*/",340lineComment: "//"341};342});343344CodeMirror.defineMIME("text/x-less", "less");345if (!CodeMirror.mimeModes.hasOwnProperty("text/css"))346CodeMirror.defineMIME("text/css", "less");347348349