add html mode with mixed XML and JS highlighting
This commit is contained in:
parent
257d80f379
commit
980fee2e99
11 changed files with 187 additions and 14 deletions
|
|
@ -36,6 +36,8 @@
|
|||
<script src="../src/mode/Text.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="../src/mode/JavaScript.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/HtmlHighlightRules.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/MEventEmitter.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
|
@ -61,7 +63,8 @@
|
|||
<select id="mode" size="1">
|
||||
<option value="text">Plain Text</option>
|
||||
<option value="javascript">JavaScript</option>
|
||||
<option value="xml">XML</option>
|
||||
<option value="xml">XML</option>
|
||||
<option value="html">HTML</option>
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
|
|
@ -88,6 +91,7 @@ modeEl.onchange = function() {
|
|||
var modes = {
|
||||
text: new ace.mode.Text(),
|
||||
xml: new ace.mode.Xml(),
|
||||
html: new ace.mode.Html(),
|
||||
javascript: new ace.mode.JavaScript()
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -344,7 +344,8 @@ ace.Editor.prototype.toggleCommentLines = function() {
|
|||
if (this.selection.isEmpty()) return;
|
||||
|
||||
var range = this.getSelectionRange();
|
||||
var addedColumns = this.mode.toggleCommentLines(this.doc, range);
|
||||
var state = this.bgTokenizer.getState(this.getCursorPosition().row);
|
||||
var addedColumns = this.mode.toggleCommentLines(this.doc, range, state);
|
||||
|
||||
this.selection.shiftSelection(addedColumns);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ ace.Tokenizer.prototype.getLineTokens = function(line, startState) {
|
|||
if (re.lastIndex == lastIndex) { throw new Error("tokenizer error"); }
|
||||
lastIndex = re.lastIndex;
|
||||
|
||||
// window.LOG && console.log(match);
|
||||
// window.LOG && jstestdriver.console.log(currentState, match);
|
||||
|
||||
for ( var i = 0; i < state.length; i++) {
|
||||
if (match[i + 1]) {
|
||||
|
|
@ -79,7 +79,7 @@ ace.Tokenizer.prototype.getLineTokens = function(line, startState) {
|
|||
tokens.push(token);
|
||||
}
|
||||
|
||||
// window.LOG && console.log(tokens, currentState);
|
||||
// window.LOG && jstestdriver.console.log(tokens, currentState);
|
||||
|
||||
return {
|
||||
tokens : tokens,
|
||||
|
|
|
|||
26
src/mode/Html.js
Normal file
26
src/mode/Html.js
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
ace.provide("ace.mode.Html");
|
||||
|
||||
ace.mode.Html = function() {
|
||||
this.$tokenizer = new ace.Tokenizer(new ace.mode.HtmlHighlightRules().getRules());
|
||||
|
||||
this._js = new ace.mode.JavaScript();
|
||||
};
|
||||
ace.inherits(ace.mode.Html, ace.mode.Text);
|
||||
|
||||
ace.mode.Html.prototype.toggleCommentLines = function(doc, range, state) {
|
||||
var split = state.split("js-");
|
||||
if (!split[0] && split[1]) {
|
||||
return this._js.toggleCommentLines(doc, range, state);
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
ace.mode.Html.prototype.getNextLineIndent = function(line, state, tab) {
|
||||
var split = state.split("js-");
|
||||
if (!split[0] && split[1]) {
|
||||
return this._js.getNextLineIndent(line, split[1], tab);
|
||||
}
|
||||
|
||||
return "";
|
||||
};
|
||||
119
src/mode/HtmlHighlightRules.js
Normal file
119
src/mode/HtmlHighlightRules.js
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
ace.provide("ace.mode.HtmlHighlightRules");
|
||||
|
||||
ace.mode.HtmlHighlightRules = function() {
|
||||
|
||||
// regexp must not have capturing parentheses
|
||||
// regexps are ordered -> the first match is used
|
||||
|
||||
this._rules = {
|
||||
start : [ {
|
||||
token : "text",
|
||||
regex : "<\\!\\[CDATA\\[",
|
||||
next : "cdata"
|
||||
}, {
|
||||
token : "xml_pe",
|
||||
regex : "<\\?.*?\\?>"
|
||||
}, {
|
||||
token : "comment",
|
||||
regex : "<\\!--",
|
||||
next : "comment"
|
||||
}, {
|
||||
token : "text",
|
||||
regex : "<(?=\s*script)",
|
||||
next : "script"
|
||||
}, {
|
||||
token : "text", // opening tag
|
||||
regex : "<\\/?",
|
||||
next : "tag"
|
||||
}, {
|
||||
token : "text",
|
||||
regex : "\\s+"
|
||||
}, {
|
||||
token : "text",
|
||||
regex : "[^<]+"
|
||||
} ],
|
||||
|
||||
script : [ {
|
||||
token : "text",
|
||||
regex : ">",
|
||||
next : "js-start"
|
||||
}, {
|
||||
token : "keyword",
|
||||
regex : "[-_a-zA-Z0-9:]+"
|
||||
}, {
|
||||
token : "text",
|
||||
regex : "\\s+"
|
||||
}, {
|
||||
token : "string",
|
||||
regex : '".*?"'
|
||||
}, {
|
||||
token : "string",
|
||||
regex : "'.*?'"
|
||||
} ],
|
||||
|
||||
tag : [ {
|
||||
token : "text",
|
||||
regex : ">",
|
||||
next : "start"
|
||||
}, {
|
||||
token : "keyword",
|
||||
regex : "[-_a-zA-Z0-9:]+"
|
||||
}, {
|
||||
token : "text",
|
||||
regex : "\\s+"
|
||||
}, {
|
||||
token : "string",
|
||||
regex : '".*?"'
|
||||
}, {
|
||||
token : "string",
|
||||
regex : "'.*?'"
|
||||
} ],
|
||||
|
||||
cdata : [ {
|
||||
token : "text",
|
||||
regex : "\\]\\]>",
|
||||
next : "start"
|
||||
}, {
|
||||
token : "text",
|
||||
regex : "\\s+"
|
||||
}, {
|
||||
token : "text",
|
||||
regex : ".+"
|
||||
} ],
|
||||
|
||||
comment : [ {
|
||||
token : "comment",
|
||||
regex : ".*?-->",
|
||||
next : "start"
|
||||
}, {
|
||||
token : "comment",
|
||||
regex : ".+"
|
||||
} ]
|
||||
};
|
||||
|
||||
var jsRules = new ace.mode.JavaScriptHighlightRules().getRules();
|
||||
this._addRules(jsRules, "js-");
|
||||
this._rules["js-start"].unshift({
|
||||
token: "text",
|
||||
regex: "<\\/(?=script)",
|
||||
next: "tag"
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
ace.mode.HtmlHighlightRules.prototype._addRules = function(rules, prefix) {
|
||||
for (var key in rules) {
|
||||
var state = rules[key];
|
||||
for (var i=0; i<state.length; i++) {
|
||||
var rule = state[i];
|
||||
if (rule.next) {
|
||||
rule.next = prefix + rule.next;
|
||||
}
|
||||
}
|
||||
this._rules[prefix + key] = state;
|
||||
}
|
||||
};
|
||||
|
||||
ace.mode.HtmlHighlightRules.prototype.getRules = function() {
|
||||
return this._rules;
|
||||
};
|
||||
|
|
@ -5,7 +5,7 @@ ace.mode.JavaScript = function() {
|
|||
};
|
||||
ace.inherits(ace.mode.JavaScript, ace.mode.Text);
|
||||
|
||||
ace.mode.JavaScript.prototype.toggleCommentLines = function(doc, range) {
|
||||
ace.mode.JavaScript.prototype.toggleCommentLines = function(doc, range, state) {
|
||||
var addedRows = doc.outdentRows(range, "//");
|
||||
if (addedRows == 0) {
|
||||
var addedRows = doc.indentRows(range, "//");
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ ace.mode.Text.prototype.getTokenizer = function() {
|
|||
return this.$tokenizer;
|
||||
};
|
||||
|
||||
ace.mode.Text.prototype.toggleCommentLines = function(doc, range) {
|
||||
ace.mode.Text.prototype.toggleCommentLines = function(doc, range, state) {
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
|
|
|||
25
test/mode/HtmlTokenizerTest.js
Normal file
25
test/mode/HtmlTokenizerTest.js
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
var HtmlTest = new TestCase("mode.HtmlTest", {
|
||||
|
||||
setUp : function() {
|
||||
this.tokenizer = new ace.mode.Html().getTokenizer();
|
||||
},
|
||||
|
||||
"test: tokenize embedded script" : function() {
|
||||
|
||||
var line = "<script a='a'>var</script>'123'";
|
||||
var tokens = this.tokenizer.getLineTokens(line, "start").tokens;
|
||||
|
||||
//assertEquals(10, tokens.length);
|
||||
assertEquals("text", tokens[0].type);
|
||||
assertEquals("keyword", tokens[1].type);
|
||||
assertEquals("text", tokens[2].type);
|
||||
assertEquals("keyword", tokens[3].type);
|
||||
assertEquals("text", tokens[4].type);
|
||||
assertEquals("string", tokens[5].type);
|
||||
assertEquals("text", tokens[6].type);
|
||||
assertEquals("keyword", tokens[7].type);
|
||||
assertEquals("text", tokens[8].type);
|
||||
assertEquals("keyword", tokens[9].type);
|
||||
assertEquals("text", tokens[10].type);
|
||||
}
|
||||
});
|
||||
|
|
@ -21,7 +21,7 @@ var JavaScriptTest = new TestCase("mode.JavaScriptTest", {
|
|||
end: {row: 1, column: 1}
|
||||
};
|
||||
|
||||
var comment = this.mode.toggleCommentLines(doc, range);
|
||||
var comment = this.mode.toggleCommentLines(doc, range, "start");
|
||||
assertEquals(["// abc", "//cde", "fg"].join("\n"), doc.toString());
|
||||
},
|
||||
|
||||
|
|
@ -33,7 +33,7 @@ var JavaScriptTest = new TestCase("mode.JavaScriptTest", {
|
|||
end: {row: 1, column: 1}
|
||||
};
|
||||
|
||||
var comment = this.mode.toggleCommentLines(doc, range);
|
||||
var comment = this.mode.toggleCommentLines(doc, range, "start");
|
||||
assertEquals([" abc", "cde", "fg"].join("\n"), doc.toString());
|
||||
},
|
||||
|
||||
|
|
@ -45,7 +45,7 @@ var JavaScriptTest = new TestCase("mode.JavaScriptTest", {
|
|||
end: {row: 2, column: 1}
|
||||
};
|
||||
|
||||
var comment = this.mode.toggleCommentLines(doc, range);
|
||||
var comment = this.mode.toggleCommentLines(doc, range, "start");
|
||||
assertEquals(["//// abc", "////cde", "//fg"].join("\n"), doc.toString());
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ var XmlTest = new TestCase("mode.XmlTest", {
|
|||
end: {row: 1, column: 1}
|
||||
};
|
||||
|
||||
var comment = this.mode.toggleCommentLines(doc, range);
|
||||
var comment = this.mode.toggleCommentLines(doc, range, "start");
|
||||
assertEquals([" abc", "cde", "fg"].join("\n"), doc.toString());
|
||||
}
|
||||
});
|
||||
|
|
@ -9,13 +9,11 @@ var XmlTest = new TestCase("mode.XmlTest", {
|
|||
var line = "<Juhu>//Juhu Kinners</Kinners>";
|
||||
var tokens = this.tokenizer.getLineTokens(line, "start").tokens;
|
||||
|
||||
assertEquals(7, tokens.length);
|
||||
assertEquals(5, tokens.length);
|
||||
assertEquals("text", tokens[0].type);
|
||||
assertEquals("keyword", tokens[1].type);
|
||||
assertEquals("text", tokens[2].type);
|
||||
assertEquals("text", tokens[3].type);
|
||||
assertEquals("keyword", tokens[3].type);
|
||||
assertEquals("text", tokens[4].type);
|
||||
assertEquals("keyword", tokens[5].type);
|
||||
assertEquals("text", tokens[6].type);
|
||||
}
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue