310 lines
10 KiB
JavaScript
310 lines
10 KiB
JavaScript
|
/* ***** BEGIN LICENSE BLOCK *****
|
||
|
* Distributed under the BSD license:
|
||
|
*
|
||
|
* Copyright (c) 2014, Ajax.org B.V.
|
||
|
* All rights reserved.
|
||
|
*
|
||
|
* Redistribution and use in source and binary forms, with or without
|
||
|
* modification, are permitted provided that the following conditions are met:
|
||
|
* * Redistributions of source code must retain the above copyright
|
||
|
* notice, this list of conditions and the following disclaimer.
|
||
|
* * Redistributions in binary form must reproduce the above copyright
|
||
|
* notice, this list of conditions and the following disclaimer in the
|
||
|
* documentation and/or other materials provided with the distribution.
|
||
|
* * Neither the name of Ajax.org B.V. nor the
|
||
|
* names of its contributors may be used to endorse or promote products
|
||
|
* derived from this software without specific prior written permission.
|
||
|
*
|
||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||
|
* DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
|
||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
|
*
|
||
|
* ***** END LICENSE BLOCK ***** */
|
||
|
|
||
|
define(function(require, exports, module) {
|
||
|
"use strict";
|
||
|
|
||
|
exports.MaskHighlightRules = MaskHighlightRules;
|
||
|
|
||
|
var oop = require("../lib/oop");
|
||
|
var lang = require("../lib/lang");
|
||
|
var TextRules = require("./text_highlight_rules").TextHighlightRules;
|
||
|
var JSRules = require("./javascript_highlight_rules").JavaScriptHighlightRules;
|
||
|
var CssRules = require("./css_highlight_rules").CssHighlightRules;
|
||
|
var MDRules = require("./markdown_highlight_rules").MarkdownHighlightRules;
|
||
|
var HTMLRules = require("./html_highlight_rules").HtmlHighlightRules;
|
||
|
|
||
|
var token_TAG = "keyword.support.constant.language",
|
||
|
token_COMPO = "support.function.markup.bold",
|
||
|
token_KEYWORD = "keyword",
|
||
|
token_LANG = "constant.language",
|
||
|
token_UTIL = "keyword.control.markup.italic",
|
||
|
token_ATTR = "support.variable.class",
|
||
|
token_PUNKT = "keyword.operator",
|
||
|
token_ITALIC = "markup.italic",
|
||
|
token_BOLD = "markup.bold",
|
||
|
token_LPARE = "paren.lparen",
|
||
|
token_RPARE = "paren.rparen";
|
||
|
|
||
|
var const_FUNCTIONS,
|
||
|
const_KEYWORDS,
|
||
|
const_CONST,
|
||
|
const_TAGS;
|
||
|
(function(){
|
||
|
const_FUNCTIONS = lang.arrayToMap(
|
||
|
("log").split("|")
|
||
|
);
|
||
|
const_CONST = lang.arrayToMap(
|
||
|
(":dualbind|:bind|:import|slot|event|style|html|markdown|md").split("|")
|
||
|
);
|
||
|
const_KEYWORDS = lang.arrayToMap(
|
||
|
("debugger|define|var|if|each|for|of|else|switch|case|with|visible|+if|+each|+for|+switch|+with|+visible|include|import").split("|")
|
||
|
);
|
||
|
const_TAGS = lang.arrayToMap(
|
||
|
("a|abbr|acronym|address|applet|area|article|aside|audio|b|base|basefont|bdo|" +
|
||
|
"big|blockquote|body|br|button|canvas|caption|center|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|tt|u|ul|var|video|wbr|xmp").split("|")
|
||
|
);
|
||
|
}());
|
||
|
|
||
|
function MaskHighlightRules () {
|
||
|
|
||
|
this.$rules = {
|
||
|
"start" : [
|
||
|
Token("comment", "\\/\\/.*$"),
|
||
|
Token("comment", "\\/\\*", [
|
||
|
Token("comment", ".*?\\*\\/", "start"),
|
||
|
Token("comment", ".+")
|
||
|
]),
|
||
|
|
||
|
Blocks.string("'''"),
|
||
|
Blocks.string('"""'),
|
||
|
Blocks.string('"'),
|
||
|
Blocks.string("'"),
|
||
|
|
||
|
Blocks.syntax(/(markdown|md)\b/, "md-multiline", "multiline"),
|
||
|
Blocks.syntax(/html\b/, "html-multiline", "multiline"),
|
||
|
Blocks.syntax(/(slot|event)\b/, "js-block", "block"),
|
||
|
Blocks.syntax(/style\b/, "css-block", "block"),
|
||
|
Blocks.syntax(/var\b/, "js-statement", "attr"),
|
||
|
|
||
|
Blocks.tag(),
|
||
|
|
||
|
Token(token_LPARE, "[[({>]"),
|
||
|
Token(token_RPARE, "[\\])};]", "start"),
|
||
|
{
|
||
|
caseInsensitive: true
|
||
|
}
|
||
|
]
|
||
|
};
|
||
|
var rules = this;
|
||
|
|
||
|
addJavaScript("interpolation", /\]/, token_RPARE + "." + token_ITALIC);
|
||
|
addJavaScript("statement", /\)|}|;/);
|
||
|
addJavaScript("block", /\}/);
|
||
|
addCss();
|
||
|
addMarkdown();
|
||
|
addHtml();
|
||
|
|
||
|
function addJavaScript(name, escape, closeType) {
|
||
|
var prfx = "js-" + name + "-",
|
||
|
rootTokens = name === "block" ? ["start"] : ["start", "no_regex"];
|
||
|
add(
|
||
|
JSRules
|
||
|
, prfx
|
||
|
, escape
|
||
|
, rootTokens
|
||
|
, closeType
|
||
|
);
|
||
|
}
|
||
|
function addCss() {
|
||
|
add(CssRules, "css-block-", /\}/);
|
||
|
}
|
||
|
function addMarkdown() {
|
||
|
add(MDRules, "md-multiline-", /("""|''')/, []);
|
||
|
}
|
||
|
function addHtml() {
|
||
|
add(HTMLRules, "html-multiline-", /("""|''')/);
|
||
|
}
|
||
|
function add(Rules, strPrfx, rgxEnd, rootTokens, closeType) {
|
||
|
var next = "pop";
|
||
|
var tokens = rootTokens || [ "start" ];
|
||
|
if (tokens.length === 0) {
|
||
|
tokens = null;
|
||
|
}
|
||
|
if (/block|multiline/.test(strPrfx)) {
|
||
|
next = strPrfx + "end";
|
||
|
rules.$rules[next] = [
|
||
|
Token("empty", "", "start")
|
||
|
];
|
||
|
}
|
||
|
rules.embedRules(
|
||
|
Rules
|
||
|
, strPrfx
|
||
|
, [ Token(closeType || token_RPARE, rgxEnd, next) ]
|
||
|
, tokens
|
||
|
, tokens == null ? true : false
|
||
|
);
|
||
|
}
|
||
|
|
||
|
this.normalizeRules();
|
||
|
}
|
||
|
oop.inherits(MaskHighlightRules, TextRules);
|
||
|
|
||
|
var Blocks = {
|
||
|
string: function(str, next){
|
||
|
var token = Token(
|
||
|
"string.start"
|
||
|
, str
|
||
|
, [
|
||
|
Token(token_LPARE + "." + token_ITALIC, /~\[/, Blocks.interpolation()),
|
||
|
Token("string.end", str, "pop"),
|
||
|
{
|
||
|
defaultToken: "string"
|
||
|
}
|
||
|
]
|
||
|
, next
|
||
|
);
|
||
|
if (str.length === 1){
|
||
|
var escaped = Token("string.escape", "\\\\" + str);
|
||
|
token.push.unshift(escaped);
|
||
|
}
|
||
|
return token;
|
||
|
},
|
||
|
interpolation: function(){
|
||
|
return [
|
||
|
Token(token_UTIL, /\s*\w*\s*:/),
|
||
|
"js-interpolation-start"
|
||
|
];
|
||
|
},
|
||
|
tagHead: function (rgx) {
|
||
|
return Token(token_ATTR, rgx, [
|
||
|
Token(token_ATTR, /[\w\-_]+/),
|
||
|
Token(token_LPARE + "." + token_ITALIC, /~\[/, Blocks.interpolation()),
|
||
|
Blocks.goUp()
|
||
|
]);
|
||
|
},
|
||
|
tag: function () {
|
||
|
return {
|
||
|
token: 'tag',
|
||
|
onMatch : function(value) {
|
||
|
if (void 0 !== const_KEYWORDS[value])
|
||
|
return token_KEYWORD;
|
||
|
if (void 0 !== const_CONST[value])
|
||
|
return token_LANG;
|
||
|
if (void 0 !== const_FUNCTIONS[value])
|
||
|
return "support.function";
|
||
|
if (void 0 !== const_TAGS[value.toLowerCase()])
|
||
|
return token_TAG;
|
||
|
|
||
|
return token_COMPO;
|
||
|
},
|
||
|
regex : /([@\w\-_:+]+)|((^|\s)(?=\s*(\.|#)))/,
|
||
|
push: [
|
||
|
Blocks.tagHead(/\./) ,
|
||
|
Blocks.tagHead(/#/) ,
|
||
|
Blocks.expression(),
|
||
|
Blocks.attribute(),
|
||
|
|
||
|
Token(token_LPARE, /[;>{]/, "pop")
|
||
|
]
|
||
|
};
|
||
|
},
|
||
|
syntax: function(rgx, next, type){
|
||
|
return {
|
||
|
token: token_LANG,
|
||
|
regex : rgx,
|
||
|
push: ({
|
||
|
"attr": [
|
||
|
next + "-start",
|
||
|
Token(token_PUNKT, /;/, "start")
|
||
|
],
|
||
|
"multiline": [
|
||
|
Blocks.tagHead(/\./) ,
|
||
|
Blocks.tagHead(/#/) ,
|
||
|
Blocks.attribute(),
|
||
|
Blocks.expression(),
|
||
|
Token(token_LPARE, /[>\{]/),
|
||
|
Token(token_PUNKT, /;/, "start"),
|
||
|
Token(token_LPARE, /'''|"""/, [ next + "-start" ])
|
||
|
],
|
||
|
"block": [
|
||
|
Blocks.tagHead(/\./) ,
|
||
|
Blocks.tagHead(/#/) ,
|
||
|
Blocks.attribute(),
|
||
|
Blocks.expression(),
|
||
|
Token(token_LPARE, /\{/, [ next + "-start" ])
|
||
|
]
|
||
|
})[type]
|
||
|
};
|
||
|
},
|
||
|
attribute: function(){
|
||
|
return Token(function(value){
|
||
|
return /^x\-/.test(value)
|
||
|
? token_ATTR + "." + token_BOLD
|
||
|
: token_ATTR;
|
||
|
}, /[\w_-]+/, [
|
||
|
Token(token_PUNKT, /\s*=\s*/, [
|
||
|
Blocks.string('"'),
|
||
|
Blocks.string("'"),
|
||
|
Blocks.word(),
|
||
|
Blocks.goUp()
|
||
|
]),
|
||
|
Blocks.goUp()
|
||
|
]);
|
||
|
},
|
||
|
expression: function(){
|
||
|
return Token(token_LPARE, /\(/, [ "js-statement-start" ]);
|
||
|
},
|
||
|
word: function(){
|
||
|
return Token("string", /[\w-_]+/);
|
||
|
},
|
||
|
goUp: function(){
|
||
|
return Token("text", "", "pop");
|
||
|
},
|
||
|
goStart: function(){
|
||
|
return Token("text", "", "start");
|
||
|
}
|
||
|
};
|
||
|
|
||
|
|
||
|
function Token(token, rgx, mix) {
|
||
|
var push, next, onMatch;
|
||
|
if (arguments.length === 4) {
|
||
|
push = mix;
|
||
|
next = arguments[3];
|
||
|
}
|
||
|
else if (typeof mix === "string") {
|
||
|
next = mix;
|
||
|
}
|
||
|
else {
|
||
|
push = mix;
|
||
|
}
|
||
|
if (typeof token === "function") {
|
||
|
onMatch = token;
|
||
|
token = "empty";
|
||
|
}
|
||
|
return {
|
||
|
token: token,
|
||
|
regex: rgx,
|
||
|
push: push,
|
||
|
next: next,
|
||
|
onMatch: onMatch
|
||
|
};
|
||
|
}
|
||
|
|
||
|
});
|