first CSS tokenizer
This commit is contained in:
parent
b1a902b196
commit
8b110a3e70
7 changed files with 233 additions and 6 deletions
|
|
@ -74,6 +74,18 @@
|
||||||
color: blue;
|
color: blue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.line .buildin-constant {
|
||||||
|
color: rgb(88, 72, 246);
|
||||||
|
}
|
||||||
|
|
||||||
|
.line .library-constant {
|
||||||
|
color: rgb(6, 150, 14);
|
||||||
|
}
|
||||||
|
|
||||||
|
.line .buildin-function {
|
||||||
|
color: rgb(60, 76, 114);
|
||||||
|
}
|
||||||
|
|
||||||
.line .string {
|
.line .string {
|
||||||
color: rgb(3, 106, 7);
|
color: rgb(3, 106, 7);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,8 @@
|
||||||
<script src="../src/mode/JavaScriptHighlightRules.js" type="text/javascript" charset="utf-8"></script>
|
<script src="../src/mode/JavaScriptHighlightRules.js" type="text/javascript" charset="utf-8"></script>
|
||||||
<script src="../src/mode/Html.js" type="text/javascript" charset="utf-8"></script>
|
<script src="../src/mode/Html.js" type="text/javascript" charset="utf-8"></script>
|
||||||
<script src="../src/mode/HtmlHighlightRules.js" type="text/javascript" charset="utf-8"></script>
|
<script src="../src/mode/HtmlHighlightRules.js" type="text/javascript" charset="utf-8"></script>
|
||||||
|
<script src="../src/mode/Css.js" type="text/javascript" charset="utf-8"></script>
|
||||||
|
<script src="../src/mode/CssHighlightRules.js" type="text/javascript" charset="utf-8"></script>
|
||||||
<script src="../src/mode/Xml.js" type="text/javascript" charset="utf-8"></script>
|
<script src="../src/mode/Xml.js" type="text/javascript" charset="utf-8"></script>
|
||||||
<script src="../src/mode/XmlHighlightRules.js" type="text/javascript" charset="utf-8"></script>
|
<script src="../src/mode/XmlHighlightRules.js" type="text/javascript" charset="utf-8"></script>
|
||||||
<script src="../src/MEventEmitter.js" type="text/javascript" charset="utf-8"></script>
|
<script src="../src/MEventEmitter.js" type="text/javascript" charset="utf-8"></script>
|
||||||
|
|
@ -65,6 +67,7 @@
|
||||||
<option value="javascript">JavaScript</option>
|
<option value="javascript">JavaScript</option>
|
||||||
<option value="xml">XML</option>
|
<option value="xml">XML</option>
|
||||||
<option value="html">HTML</option>
|
<option value="html">HTML</option>
|
||||||
|
<option value="css">CSS</option>
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
@ -92,6 +95,7 @@ var modes = {
|
||||||
text: new ace.mode.Text(),
|
text: new ace.mode.Text(),
|
||||||
xml: new ace.mode.Xml(),
|
xml: new ace.mode.Xml(),
|
||||||
html: new ace.mode.Html(),
|
html: new ace.mode.Html(),
|
||||||
|
css: new ace.mode.Css(),
|
||||||
javascript: new ace.mode.JavaScript()
|
javascript: new ace.mode.JavaScript()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -138,15 +142,17 @@ ace.addListener(container, "drop", function(e) {
|
||||||
if (window.FileReader) {
|
if (window.FileReader) {
|
||||||
var reader = new FileReader();
|
var reader = new FileReader();
|
||||||
reader.onload = function(e) {
|
reader.onload = function(e) {
|
||||||
editor.clearSelection();
|
editor.getSelection().selectAll();
|
||||||
editor.moveCursorTo(0, 0);
|
|
||||||
editor.selectFileEnd();
|
|
||||||
|
|
||||||
var mode = "text";
|
var mode = "text";
|
||||||
if (/^.*\.js$/i.test(file.name)) {
|
if (/^.*\.js$/i.test(file.name)) {
|
||||||
mode = "javascript";
|
mode = "javascript";
|
||||||
} else if (/^.*\.xml$/i.test(file.name)) {
|
} else if (/^.*\.xml$/i.test(file.name)) {
|
||||||
mode = "xml";
|
mode = "xml";
|
||||||
|
} else if (/^.*\.html$/i.test(file.name)) {
|
||||||
|
mode = "html";
|
||||||
|
} else if (/^.*\.css$/i.test(file.name)) {
|
||||||
|
mode = "css";
|
||||||
}
|
}
|
||||||
|
|
||||||
editor.onTextInput(reader.result);
|
editor.onTextInput(reader.result);
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ server: http://localhost:4224
|
||||||
|
|
||||||
load:
|
load:
|
||||||
- src/ace.js
|
- src/ace.js
|
||||||
|
- src/MEventEmitter.js
|
||||||
- src/mode/Text.js
|
- src/mode/Text.js
|
||||||
- src/mode/*.js
|
- src/mode/*.js
|
||||||
- src/*.js
|
- src/*.js
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ ace.Tokenizer.prototype.getLineTokens = function(line, startState) {
|
||||||
if (re.lastIndex == lastIndex) { throw new Error("tokenizer error"); }
|
if (re.lastIndex == lastIndex) { throw new Error("tokenizer error"); }
|
||||||
lastIndex = re.lastIndex;
|
lastIndex = re.lastIndex;
|
||||||
|
|
||||||
// window.LOG && jstestdriver.console.log(currentState, match);
|
window.LOG && jstestdriver.console.log(currentState, match);
|
||||||
|
|
||||||
for ( var i = 0; i < state.length; i++) {
|
for ( var i = 0; i < state.length; i++) {
|
||||||
if (match[i + 1]) {
|
if (match[i + 1]) {
|
||||||
|
|
@ -79,7 +79,7 @@ ace.Tokenizer.prototype.getLineTokens = function(line, startState) {
|
||||||
tokens.push(token);
|
tokens.push(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
// window.LOG && jstestdriver.console.log(tokens, currentState);
|
window.LOG && jstestdriver.console.log(tokens, currentState);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
tokens : tokens,
|
tokens : tokens,
|
||||||
|
|
|
||||||
6
src/mode/Css.js
Normal file
6
src/mode/Css.js
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
ace.provide("ace.mode.Css");
|
||||||
|
|
||||||
|
ace.mode.Css = function() {
|
||||||
|
this.$tokenizer = new ace.Tokenizer(new ace.mode.CssHighlightRules().getRules());
|
||||||
|
};
|
||||||
|
ace.inherits(ace.mode.Css, ace.mode.Text);
|
||||||
174
src/mode/CssHighlightRules.js
Normal file
174
src/mode/CssHighlightRules.js
Normal file
|
|
@ -0,0 +1,174 @@
|
||||||
|
ace.provide("ace.mode.CssHighlightRules");
|
||||||
|
|
||||||
|
ace.mode.CssHighlightRules = function() {
|
||||||
|
|
||||||
|
var properties = {
|
||||||
|
"width": 1,
|
||||||
|
"height": 1,
|
||||||
|
"top": 1,
|
||||||
|
"left": 1,
|
||||||
|
"right": 1,
|
||||||
|
"bottom": 1,
|
||||||
|
"overflow": 1,
|
||||||
|
"overflow-x": 1,
|
||||||
|
"overflow-y": 1,
|
||||||
|
"background": 1,
|
||||||
|
"font": 1,
|
||||||
|
"font-style": 1,
|
||||||
|
"font-family": 1,
|
||||||
|
"font-size": 1,
|
||||||
|
"text-align": 1,
|
||||||
|
"white-space": 1,
|
||||||
|
"color": 1,
|
||||||
|
"z-index": 1,
|
||||||
|
"position": 1,
|
||||||
|
"cursor": 1,
|
||||||
|
"box-sizing": 1,
|
||||||
|
"-webkit-box-sizing": 1,
|
||||||
|
"-moz-box-sizing": 1,
|
||||||
|
"margin": 1,
|
||||||
|
"padding": 1,
|
||||||
|
"padding-top": 1,
|
||||||
|
"padding-right": 1,
|
||||||
|
"padding-bottom": 1,
|
||||||
|
"padding-left": 1,
|
||||||
|
"border": 1,
|
||||||
|
"border-top": 1,
|
||||||
|
"border-right": 1,
|
||||||
|
"border-left": 1,
|
||||||
|
"border-bottom": 1
|
||||||
|
};
|
||||||
|
|
||||||
|
var functions = {
|
||||||
|
"rgb": 1,
|
||||||
|
"rgba": 1
|
||||||
|
};
|
||||||
|
|
||||||
|
var constants = {
|
||||||
|
"absolute": 1,
|
||||||
|
"relative": 1,
|
||||||
|
"fixed": 1,
|
||||||
|
"solid": 1,
|
||||||
|
"hidden": 1,
|
||||||
|
"scroll": 1,
|
||||||
|
"no-wrap": 1
|
||||||
|
};
|
||||||
|
|
||||||
|
// regexp must not have capturing parentheses. Use (?:) instead.
|
||||||
|
// regexps are ordered -> the first match is used
|
||||||
|
|
||||||
|
var numRe = "\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))";
|
||||||
|
|
||||||
|
function ic(str) {
|
||||||
|
var re = [];
|
||||||
|
var chars = str.split("");
|
||||||
|
for (var i=0; i<chars.length; i++) {
|
||||||
|
re.push(
|
||||||
|
"[",
|
||||||
|
chars[i].toLowerCase(),
|
||||||
|
chars[i].toUpperCase(),
|
||||||
|
"]"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return re.join("");
|
||||||
|
}
|
||||||
|
|
||||||
|
this._rules = {
|
||||||
|
"start" : [ {
|
||||||
|
token : "comment", // multi line comment
|
||||||
|
regex : "\\/\\*",
|
||||||
|
next : "comment"
|
||||||
|
}, {
|
||||||
|
token : "string", // single line
|
||||||
|
regex : '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'
|
||||||
|
}, {
|
||||||
|
token : "string", // single line
|
||||||
|
regex : "['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"
|
||||||
|
}, {
|
||||||
|
token : "number",
|
||||||
|
regex : numRe + ic("em")
|
||||||
|
}, {
|
||||||
|
token : "number",
|
||||||
|
regex : numRe + ic("ex")
|
||||||
|
}, {
|
||||||
|
token : "number",
|
||||||
|
regex : numRe + ic("px")
|
||||||
|
}, {
|
||||||
|
token : "number",
|
||||||
|
regex : numRe + ic("cm")
|
||||||
|
}, {
|
||||||
|
token : "number",
|
||||||
|
regex : numRe + ic("mm")
|
||||||
|
}, {
|
||||||
|
token : "number",
|
||||||
|
regex : numRe + ic("in")
|
||||||
|
}, {
|
||||||
|
token : "number",
|
||||||
|
regex : numRe + ic("pt")
|
||||||
|
}, {
|
||||||
|
token : "number",
|
||||||
|
regex : numRe + ic("pc")
|
||||||
|
}, {
|
||||||
|
token : "number",
|
||||||
|
regex : numRe + ic("deg")
|
||||||
|
}, {
|
||||||
|
token : "number",
|
||||||
|
regex : numRe + ic("rad")
|
||||||
|
}, {
|
||||||
|
token : "number",
|
||||||
|
regex : numRe + ic("grad")
|
||||||
|
}, {
|
||||||
|
token : "number",
|
||||||
|
regex : numRe + ic("ms")
|
||||||
|
}, {
|
||||||
|
token : "number",
|
||||||
|
regex : numRe + ic("s")
|
||||||
|
}, {
|
||||||
|
token : "number",
|
||||||
|
regex : numRe + ic("hz")
|
||||||
|
}, {
|
||||||
|
token : "number",
|
||||||
|
regex : numRe + ic("khz")
|
||||||
|
}, {
|
||||||
|
token : "number",
|
||||||
|
regex : numRe + "%"
|
||||||
|
}, {
|
||||||
|
token : "number",
|
||||||
|
regex : numRe
|
||||||
|
}, {
|
||||||
|
token : "number", // hex6 color
|
||||||
|
regex : "#[a-fA-F0-9]{6}"
|
||||||
|
}, {
|
||||||
|
token : "number", // hex3 color
|
||||||
|
regex : "#[a-fA-F0-9]{3}"
|
||||||
|
}, {
|
||||||
|
token : function(value) {
|
||||||
|
if (properties[value.toLowerCase()]) {
|
||||||
|
return "buildin-constant";
|
||||||
|
}
|
||||||
|
else if (functions[value.toLowerCase()]) {
|
||||||
|
return "buildin-function";
|
||||||
|
}
|
||||||
|
else if (constants[value.toLowerCase()]) {
|
||||||
|
return "library-constant";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return "identifier";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
regex : "\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"
|
||||||
|
}],
|
||||||
|
"comment" : [{
|
||||||
|
token : "comment", // closing comment
|
||||||
|
regex : ".*?\\*\\/",
|
||||||
|
next : "start"
|
||||||
|
}, {
|
||||||
|
token : "comment", // comment spanning whole line
|
||||||
|
regex : ".+"
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
ace.mode.CssHighlightRules.prototype.getRules = function() {
|
||||||
|
return this._rules;
|
||||||
|
};
|
||||||
28
test/mode/CssTokenizerTest.js
Normal file
28
test/mode/CssTokenizerTest.js
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
var CssTest = new TestCase("mode.CssTest", {
|
||||||
|
|
||||||
|
setUp : function() {
|
||||||
|
this.tokenizer = new ace.mode.Css().getTokenizer();
|
||||||
|
},
|
||||||
|
|
||||||
|
"test: tokenize pixel number" : function() {
|
||||||
|
var line = "-12px";
|
||||||
|
var tokens = this.tokenizer.getLineTokens(line, "start").tokens;
|
||||||
|
|
||||||
|
assertEquals(1, tokens.length);
|
||||||
|
assertEquals("number", tokens[0].type);
|
||||||
|
},
|
||||||
|
|
||||||
|
"test: tokenize hex3 color" : function() {
|
||||||
|
var tokens = this.tokenizer.getLineTokens("#abc", "start").tokens;
|
||||||
|
|
||||||
|
assertEquals(1, tokens.length);
|
||||||
|
assertEquals("number", tokens[0].type);
|
||||||
|
},
|
||||||
|
|
||||||
|
"test: tokenize hex6 color" : function() {
|
||||||
|
var tokens = this.tokenizer.getLineTokens("#abc012", "start").tokens;
|
||||||
|
|
||||||
|
assertEquals(1, tokens.length);
|
||||||
|
assertEquals("number", tokens[0].type);
|
||||||
|
}
|
||||||
|
});
|
||||||
Loading…
Add table
Add a link
Reference in a new issue