reorganize language mode support

This commit is contained in:
Fabian Jakobs 2010-04-14 11:39:42 +02:00
commit 29435328f3
13 changed files with 287 additions and 233 deletions

View file

@ -1,9 +1,12 @@
ace.provide("ace.Editor");
ace.Editor = function(doc, renderer) {
ace.Editor = function(renderer, doc, mode) {
var container = renderer.getContainerElement();
this.renderer = renderer;
this.setDocument(doc || new ace.TextDocument(""));
this.setMode(mode || new ace.mode.Text());
this.textInput = new ace.TextInput(container, this);
new ace.KeyBinding(container, this);
@ -15,16 +18,6 @@ ace.Editor = function(doc, renderer) {
ace.addTripleClickListener(container, ace.bind(this.selectLine,
this));
this.doc = doc;
doc.addChangeListener(ace.bind(this.onDocumentChange, this));
renderer.setDocument(doc);
this.tokenizer = new ace.BackgroundTokenizer(new ace.Tokenizer(
ace.JavaScript.RULES), ace.bind(this.onTokenizerUpdate, this));
this.tokenizer.setLines(doc.lines);
renderer.setTokenizer(this.tokenizer);
this.cursor = {
row : 0,
column : 0
@ -37,6 +30,31 @@ ace.Editor = function(doc, renderer) {
this.renderer.draw();
};
ace.Editor.prototype.setDocument = function(doc) {
// TODO: document change is not yet supported
if (this.doc) {
throw new Error("TODO: document change is not yet supported");
}
this.doc = doc;
doc.addChangeListener(ace.bind(this.onDocumentChange, this));
this.renderer.setDocument(doc);
};
ace.Editor.prototype.setMode = function(mode) {
// TODO: mode change is not yet supported
if (this.mode) {
throw new Error("TODO: mode change is not yet supported");
}
this.mode = mode;
this.tokenizer = new ace.BackgroundTokenizer(mode.getTokenizer(), ace.bind(this.onTokenizerUpdate, this));
this.tokenizer.setLines(this.doc.lines);
this.renderer.setTokenizer(this.tokenizer);
};
ace.Editor.prototype.resize = function()
{
this.renderer.scrollToY(this.renderer.getScrollTop());

View file

@ -1,111 +0,0 @@
ace.provide("ace.JavaScript");
(function() {
var keywords = {
"break" : 1,
"case" : 1,
"catch" : 1,
"continue" : 1,
"default" : 1,
"delete" : 1,
"do" : 1,
"else" : 1,
"finally" : 1,
"for" : 1,
"function" : 1,
"if" : 1,
"in" : 1,
"instanceof" : 1,
"new" : 1,
"return" : 1,
"switch" : 1,
"throw" : 1,
"try" : 1,
"typeof" : 1,
"var" : 1,
"while" : 1,
"with" : 1
};
// regexp must not have capturing parentheses
// regexps are ordered -> the first match is used
ace.JavaScript.RULES = {
start : [ {
token : "comment",
regex : "\\/\\/.*$"
}, {
token : "comment", // multi line comment in one line
regex : "\\/\\*.*?\\*\\/"
}, {
token : "comment", // multi line comment start
regex : "\\/\\*.*$",
next : "comment"
}, {
token : "string", // single line
regex : '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'
}, {
token : "string", // multi line string start
regex : '["].*\\\\$',
next : "qqstring"
}, {
token : "string", // single line
regex : "['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"
}, {
token : "string", // multi line string start
regex : "['].*\\\\$",
next : "qstring"
}, {
token : "number", // hex
regex : "0[xX][0-9a-fA-F]+\\b"
}, {
token : "number", // float
regex : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"
}, {
token : function(value) {
if (keywords[value]) {
return "keyword";
}
else {
return "identifier";
}
},
regex : "[a-zA-Z_][a-zA-Z0-9_]*\\b"
}, {
token : function(value) {
// return parens[value];
return "text";
},
regex : "[\\[\\]\\(\\)\\{\\}]"
}, {
token : "text",
regex : "\\s+"
} ],
"comment" : [ {
token : "comment", // closing comment
regex : ".*?\\*\\/",
next : "start"
}, {
token : "comment", // comment spanning whole line
regex : ".+"
} ],
"qqstring" : [ {
token : "string",
regex : '(?:(?:\\\\.)|(?:[^"\\\\]))*?"',
next : "start"
}, {
token : "string",
regex : '.+'
} ],
"qstring" : [ {
token : "string",
regex : "(?:(?:\\\\.)|(?:[^'\\\\]))*?'",
next : "start"
}, {
token : "string",
regex : '.+'
} ]
};
})();

View file

@ -1,72 +0,0 @@
ace.provide("ace.XML");
(function() {
// regexp must not have capturing parentheses
// regexps are ordered -> the first match is used
ace.XML.RULES = {
start : [ {
token : "text",
regex : "<\\!\\[CDATA\\[",
next : "cdata"
}, {
token : "xml_pe",
regex : "<\\?.*?\\?>"
}, {
token : "comment",
regex : "<\\!--",
next : "comment"
}, {
token : "text", // opening tag
regex : "<",
next : "tag"
}, {
token : "text",
regex : "\\s+"
}, {
token : "text",
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 : ".+"
} ]
};
})();

View file

@ -13,6 +13,14 @@ ace.provide = function(namespace) {
}
};
ace.inherits = function(ctor, superCtor) {
var tempCtor = function() {};
tempCtor.prototype = superCtor.prototype;
ctor.super_ = superCtor.prototype;
ctor.prototype = new tempCtor();
ctor.prototype.constructor = ctor;
};
ace.addListener = function(elem, type, callback) {
if (elem.addEventListener) {
return elem.addEventListener(type, callback, false);
@ -64,14 +72,6 @@ ace.preventDefault = function(e) {
e.returnValue = false;
};
ace.inherits = function(ctor, superCtor) {
var tempCtor = function() {};
tempCtor.prototype = superCtor.prototype;
ctor.super_ = superCtor.prototype;
ctor.prototype = new tempCtor();
ctor.prototype.constructor = ctor;
};
ace.getInnerWidth = function(element) {
return (parseInt(ace.computedStyle(element, "paddingLeft"))
+ parseInt(ace.computedStyle(element, "paddingRight")) + element.clientWidth);

7
src/mode/JavaScript.js Normal file
View file

@ -0,0 +1,7 @@
ace.provide("ace.mode.JavaScript");
ace.mode.JavaScript = function() {
this.$tokenizer = new ace.Tokenizer(new ace.mode.JavaScriptHighlightRules().getRules());
};
ace.inherits(ace.mode.JavaScript, ace.mode.Text);

View file

@ -0,0 +1,114 @@
ace.provide("ace.mode.JavaScriptHighlightRules");
ace.mode.JavaScriptHighlightRules = function() {
var keywords = {
"break" : 1,
"case" : 1,
"catch" : 1,
"continue" : 1,
"default" : 1,
"delete" : 1,
"do" : 1,
"else" : 1,
"finally" : 1,
"for" : 1,
"function" : 1,
"if" : 1,
"in" : 1,
"instanceof" : 1,
"new" : 1,
"return" : 1,
"switch" : 1,
"throw" : 1,
"try" : 1,
"typeof" : 1,
"var" : 1,
"while" : 1,
"with" : 1
};
// regexp must not have capturing parentheses. Use (?:) instead.
// regexps are ordered -> the first match is used
this._rules = {
start : [ {
token : "comment",
regex : "\\/\\/.*$"
}, {
token : "comment", // multi line comment in one line
regex : "\\/\\*.*?\\*\\/"
}, {
token : "comment", // multi line comment start
regex : "\\/\\*.*$",
next : "comment"
}, {
token : "string", // single line
regex : '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'
}, {
token : "string", // multi line string start
regex : '["].*\\\\$',
next : "qqstring"
}, {
token : "string", // single line
regex : "['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"
}, {
token : "string", // multi line string start
regex : "['].*\\\\$",
next : "qstring"
}, {
token : "number", // hex
regex : "0[xX][0-9a-fA-F]+\\b"
}, {
token : "number", // float
regex : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"
}, {
token : function(value) {
if (keywords[value]) {
return "keyword";
}
else {
return "identifier";
}
},
regex : "[a-zA-Z_][a-zA-Z0-9_]*\\b"
}, {
token : function(value) {
// return parens[value];
return "text";
},
regex : "[\\[\\]\\(\\)\\{\\}]"
}, {
token : "text",
regex : "\\s+"
} ],
"comment" : [ {
token : "comment", // closing comment
regex : ".*?\\*\\/",
next : "start"
}, {
token : "comment", // comment spanning whole line
regex : ".+"
} ],
"qqstring" : [ {
token : "string",
regex : '(?:(?:\\\\.)|(?:[^"\\\\]))*?"',
next : "start"
}, {
token : "string",
regex : '.+'
} ],
"qstring" : [ {
token : "string",
regex : "(?:(?:\\\\.)|(?:[^'\\\\]))*?'",
next : "start"
}, {
token : "string",
regex : '.+'
} ]
};
};
ace.mode.JavaScriptHighlightRules.prototype.getRules = function() {
return this._rules;
};

9
src/mode/Text.js Normal file
View file

@ -0,0 +1,9 @@
ace.provide("ace.mode.Text");
ace.mode.Text = function() {
this.$tokenizer = new ace.Tokenizer({});
};
ace.mode.Text.prototype.getTokenizer = function() {
return this.$tokenizer;
};

6
src/mode/Xml.js Normal file
View file

@ -0,0 +1,6 @@
ace.provide("ace.mode.Xml");
ace.mode.Xml = function() {
this.$tokenizer = new Tokenizer(new ace.mode.XmlHighlightRules().getRules());
};
ace.inherits(ace.mode.Xml, ace.mode.Text);

View file

@ -0,0 +1,75 @@
ace.provide("ace.mode.XmlHighlightRules");
ace.mode.XmlHighlightRules = 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", // opening tag
regex : "<",
next : "tag"
}, {
token : "text",
regex : "\\s+"
}, {
token : "text",
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 : ".+"
} ]
};
};
ace.mode.XmlHighlightRules.prototype.getRules = function() {
return this._rules;
};