diff --git a/lib/ace/editor.js b/lib/ace/editor.js index 20330582..4d12d431 100644 --- a/lib/ace/editor.js +++ b/lib/ace/editor.js @@ -421,6 +421,14 @@ var Editor =function(renderer, session) { var mode = session.getMode(); var cursor = this.getCursorPosition(); + + if (this.getBehavioursEnabled()) { + // Get a transform if the current mode wants one. + var transform = mode.transformAction(session.getState(cursor.row), 'insertion', this, session, text); + if (transform) + text = transform.text; + } + text = text.replace("\t", this.session.getTabString()); // remove selected text @@ -436,12 +444,27 @@ var Editor =function(renderer, session) { this.clearSelection(); + var start = cursor.column; var lineState = session.getState(cursor.row); var shouldOutdent = mode.checkOutdent(lineState, session.getLine(cursor.row), text); var line = session.getLine(cursor.row); var lineIndent = mode.getNextLineIndent(lineState, line.slice(0, cursor.column), session.getTabString()); var end = session.insert(cursor, text); - + + if (transform && transform.selection) { + if (transform.selection.length == 2) { // Transform relative to the current column + this.selection.setSelectionRange( + new Range(cursor.row, start + transform.selection[0], + cursor.row, start + transform.selection[1])); + } else { // Transform relative to the current row. + this.selection.setSelectionRange( + new Range(cursor.row + transform.selection[0], + transform.selection[1], + cursor.row + transform.selection[2], + transform.selection[3])); + } + } + var lineState = session.getState(cursor.row); // TODO disabled multiline auto indent @@ -591,6 +614,15 @@ var Editor =function(renderer, session) { this.getReadOnly = function() { return this.$readOnly; }; + + this.$modeBehaviours = false; + this.setBehavioursEnabled = function (enabled) { + this.$modeBehaviours = enabled; + } + + this.getBehavioursEnabled = function () { + return this.$modeBehaviours; + } this.removeRight = function() { if (this.$readOnly) @@ -609,8 +641,18 @@ var Editor =function(renderer, session) { if (this.selection.isEmpty()) this.selection.selectLeft(); + + var range = this.getSelectionRange(); + if (this.getBehavioursEnabled()) { + var session = this.session; + var state = session.getState(range.start.row); + var new_range = session.getMode().transformAction(state, 'deletion', this, session, range); + if (new_range !== false) { + range = new_range; + } + } - this.session.remove(this.getSelectionRange()); + this.session.remove(range); this.clearSelection(); }; diff --git a/lib/ace/mode/behaviour.js b/lib/ace/mode/behaviour.js new file mode 100644 index 00000000..c30afbad --- /dev/null +++ b/lib/ace/mode/behaviour.js @@ -0,0 +1,97 @@ +/* vim:ts=4:sts=4:sw=4: + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Ajax.org Code Editor (ACE). + * + * The Initial Developer of the Original Code is + * Ajax.org B.V. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Chris Spencer + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +var Behaviour = function() { + this.$behaviours = {}; +}; + +(function () { + + this.add = function (name, action, callback) { + switch (undefined) { + case this.$behaviours: + this.$behaviours = {}; + case this.$behaviours[name]: + this.$behaviours[name] = {}; + } + this.$behaviours[name][action] = callback; + } + + this.addBehaviours = function (behaviours) { + for (var key in behaviours) { + for (var action in behaviours[key]) { + this.add(key, action, behaviours[key][action]); + } + } + } + + this.remove = function (name) { + if (this.$behaviours && this.$behaviours[name]) { + delete this.$behaviours[name]; + } + } + + this.inherit = function (mode, filter) { + if (typeof mode === "function") { + var behaviours = new mode().getBehaviours(filter); + } else { + var behaviours = mode.getBehaviours(filter); + } + this.addBehaviours(behaviours); + } + + this.getBehaviours = function (filter) { + if (!filter) { + return this.$behaviours; + } else { + var ret = {} + for (var i = 0; i < filter.length; i++) { + if (this.$behaviours[filter[i]]) { + ret[filter[i]] = this.$behaviours[filter[i]]; + } + } + return ret; + } + } + +}).call(Behaviour.prototype); + +exports.Behaviour = Behaviour; +}); \ No newline at end of file diff --git a/lib/ace/mode/behaviour/cstyle.js b/lib/ace/mode/behaviour/cstyle.js new file mode 100644 index 00000000..d685ad06 --- /dev/null +++ b/lib/ace/mode/behaviour/cstyle.js @@ -0,0 +1,226 @@ +/* vim:ts=4:sts=4:sw=4: + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Ajax.org Code Editor (ACE). + * + * The Initial Developer of the Original Code is + * Ajax.org B.V. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Chris Spencer + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +var oop = require("pilot/oop"); +var Behaviour = require('ace/mode/behaviour').Behaviour; + +var CstyleBehaviour = function () { + + this.add("braces", "insertion", function (state, action, editor, session, text) { + if (text == '{') { + var selection = editor.getSelectionRange(); + var selected = session.doc.getTextRange(selection); + if (selected !== "") { + return { + text: '{' + selected + '}', + selection: false + } + } else { + return { + text: '{}', + selection: [1, 1] + } + } + } else if (text == '}') { + var cursor = editor.getCursorPosition(); + var line = session.doc.getLine(cursor.row); + var rightChar = line.substring(cursor.column, cursor.column + 1); + if (rightChar == '}') { + var matching = session.$findOpeningBracket('}', {column: cursor.column + 1, row: cursor.row}); + if (matching !== null) { + return { + text: '', + selection: [1, 1] + } + } + } + } else if (text == "\n") { + var cursor = editor.getCursorPosition(); + var line = session.doc.getLine(cursor.row); + var rightChar = line.substring(cursor.column, cursor.column + 1); + if (rightChar == '}') { + var openBracePos = session.findMatchingBracket({row: cursor.row, column: cursor.column}); + + var indent = this.getNextLineIndent(state, line.substring(0, line.length - 1), session.getTabString()); + var next_indent = this.$getIndent(session.doc.getLine(openBracePos.row)); + + return { + text: '\n' + indent + '\n' + next_indent, + selection: [1, indent.length, 1, indent.length] + } + } + } + return false; + }); + + this.add("braces", "deletion", function (state, action, editor, session, range) { + var selected = session.doc.getTextRange(range); + if (!range.isMultiLine() && selected == '{') { + var line = session.doc.getLine(range.start.row); + var rightChar = line.substring(range.end.column, range.end.column + 1); + if (rightChar == '}') { + return new Range(range.start.row, range.start.column, + range.start.row, range.end.column + 1); + } + } + return false; + }); + + this.add("parens", "insertion", function (state, action, editor, session, text) { + if (text == '(') { + var selection = editor.getSelectionRange(); + var selected = session.doc.getTextRange(selection); + if (selected !== "") { + return { + text: '(' + selected + ')', + selection: false + } + } else { + return { + text: '()', + selection: [1, 1] + } + } + } else if (text == ')') { + var cursor = editor.getCursorPosition(); + var line = session.doc.getLine(cursor.row); + var rightChar = line.substring(cursor.column, cursor.column + 1); + if (rightChar == ')') { + var matching = session.$findOpeningBracket(')', {column: cursor.column + 1, row: cursor.row}); + if (matching !== null) { + return { + text: '', + selection: [1, 1] + } + } + } + } + return false; + }); + + this.add("parens", "deletion", function (state, action, editor, session, range) { + var selected = session.doc.getTextRange(range); + if (!range.isMultiLine() && selected == '(') { + var line = session.doc.getLine(range.start.row); + var rightChar = line.substring(range.start.column + 1, range.start.column + 2); + if (rightChar == ')') { + return new Range(range.start.row, range.start.column, + range.start.row, range.end.column + 1); + } + } + return false; + }); + + this.add("string_dquotes", "insertion", function (state, action, editor, session, text) { + if (text == '"') { + var selection = editor.getSelectionRange(); + var selected = session.doc.getTextRange(selection); + if (selected !== "") { + return { + text: '"' + selected + '"', + selection: false + } + } else { + var cursor = editor.getCursorPosition(); + var line = session.doc.getLine(cursor.row); + var leftChar = line.substring(cursor.column-1, cursor.column); + + // We're escaped. + if (leftChar == '\\') { + return false; + } + + // Find what token we're inside. + var tokens = session.getTokens(selection.start.row, selection.start.row)[0].tokens; + var col = 0, token; + var quotepos = -1; // Track whether we're inside an open quote. + + for (var x = 0; x < tokens.length; x++) { + token = tokens[x]; + if (token.type == "string") { + quotepos = -1; + } else if (quotepos < 0) { + quotepos = token.value.indexOf('"'); + } + if ((token.value.length + col) > selection.start.column) { + break; + } + col += tokens[x].value.length; + } + + // Try and be smart about when we auto insert. + if (quotepos < 0 && token.type !== "comment" && (token.type !== "string" || ((selection.start.column !== token.value.length+col-1) && token.value.lastIndexOf('"') === token.value.length-1))) { + return { + text: '""', + selection: [1,1] + } + } else if (token && token.type === "string") { + // Ignore input and move right one if we're typing over the closing quote. + var rightChar = line.substring(cursor.column, cursor.column + 1); + if (rightChar == '"') { + return { + text: '', + selection: [1, 1] + } + } + } + } + } + return false; + }); + + this.add("string_dquotes", "deletion", function (state, action, editor, session, range) { + var selected = session.doc.getTextRange(range); + if (!range.isMultiLine() && selected == '"') { + var line = session.doc.getLine(range.start.row); + var rightChar = line.substring(range.start.column + 1, range.start.column + 2); + if (rightChar == '"') { + return new Range(range.start.row, range.start.column, + range.start.row, range.end.column + 1); + } + } + return false; + }); + +} +oop.inherits(CstyleBehaviour, Behaviour); + +exports.CstyleBehaviour = CstyleBehaviour; +}); \ No newline at end of file diff --git a/lib/ace/mode/behaviour/xml.js b/lib/ace/mode/behaviour/xml.js new file mode 100644 index 00000000..182b350e --- /dev/null +++ b/lib/ace/mode/behaviour/xml.js @@ -0,0 +1,92 @@ +/* vim:ts=4:sts=4:sw=4: + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Ajax.org Code Editor (ACE). + * + * The Initial Developer of the Original Code is + * Ajax.org B.V. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Chris Spencer + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +var oop = require("pilot/oop"); +var Behaviour = require('ace/mode/behaviour').Behaviour; +var CstyleBehaviour = require('ace/mode/behaviour/cstyle').CstyleBehaviour; + +var XmlBehaviour = function () { + + this.inherit(CstyleBehaviour, ["string_dquotes"]); // Get string behaviour + + this.add("brackets", "insertion", function (state, action, editor, session, text) { + if (text == '<') { + var selection = editor.getSelectionRange(); + var selected = session.doc.getTextRange(selection); + if (selected !== "") { + return false; + } else { + return { + text: '<>', + selection: [1, 1] + } + } + } else if (text == '>') { + var cursor = editor.getCursorPosition(); + var line = session.doc.getLine(cursor.row); + var rightChar = line.substring(cursor.column, cursor.column + 1); + if (rightChar == '>') { // need some kind of matching check here + return { + text: '', + selection: [1, 1] + } + } + } else if (text == "\n") { + var cursor = editor.getCursorPosition(); + var line = session.doc.getLine(cursor.row); + var rightChars = line.substring(cursor.column, cursor.column + 2); + if (rightChars == ')", next: "tag" @@ -184,15 +182,13 @@ var HtmlHighlightRules = function() { token: "text", regex: "<\\/(?=script)", next: "tag" - }); - - var cssRules = new CssHighlightRules().getRules(); - this.addRules(cssRules, "css-"); - this.$rules["css-start"].unshift({ + }]); + + this.embedRules(CssHighlightRules, "css-", [{ token: "text", regex: "<\\/(?=style)", next: "tag" - }); + }]); }; oop.inherits(HtmlHighlightRules, TextHighlightRules); diff --git a/lib/ace/mode/java.js b/lib/ace/mode/java.js index 6014398f..ac3c942a 100644 --- a/lib/ace/mode/java.js +++ b/lib/ace/mode/java.js @@ -5,10 +5,12 @@ var JavaScriptMode = require("ace/mode/javascript").Mode; var Tokenizer = require("ace/tokenizer").Tokenizer; var JavaHighlightRules = require("ace/mode/java_highlight_rules").JavaHighlightRules; var MatchingBraceOutdent = require("ace/mode/matching_brace_outdent").MatchingBraceOutdent; +var CstyleBehaviour = require("ace/mode/behaviour/cstyle").CstyleBehaviour; var Mode = function() { this.$tokenizer = new Tokenizer(new JavaHighlightRules().getRules()); this.$outdent = new MatchingBraceOutdent(); + this.$behaviour = new CstyleBehaviour(); }; oop.inherits(Mode, JavaScriptMode); diff --git a/lib/ace/mode/java_highlight_rules.js b/lib/ace/mode/java_highlight_rules.js index 6efcd07e..db7fe99b 100644 --- a/lib/ace/mode/java_highlight_rules.js +++ b/lib/ace/mode/java_highlight_rules.js @@ -7,8 +7,6 @@ var TextHighlightRules = require("ace/mode/text_highlight_rules").TextHighlightR var JavaHighlightRules = function() { - var docComment = new DocCommentHighlightRules(); - // taken from http://download.oracle.com/javase/tutorial/java/nutsandbolts/_keywords.html var keywords = lang.arrayToMap( ("abstract|continue|for|new|switch|" + @@ -66,7 +64,7 @@ var JavaHighlightRules = function() { token : "comment", regex : "\\/\\/.*$" }, - docComment.getStartRule("doc-start"), + new DocCommentHighlightRules().getStartRule("doc-start"), { token : "comment", // multi line comment regex : "\\/\\*", @@ -156,9 +154,9 @@ var JavaHighlightRules = function() { } ] }; - - this.addRules(docComment.getRules(), "doc-"); - this.$rules["doc-start"][0].next = "start"; + + this.embedRules(DocCommentHighlightRules, "doc-", + [ new DocCommentHighlightRules().getEndRule("start") ]); }; oop.inherits(JavaHighlightRules, TextHighlightRules); diff --git a/lib/ace/mode/javascript.js b/lib/ace/mode/javascript.js index a7634bf6..f7b934fa 100644 --- a/lib/ace/mode/javascript.js +++ b/lib/ace/mode/javascript.js @@ -44,10 +44,12 @@ var JavaScriptHighlightRules = require("ace/mode/javascript_highlight_rules").Ja var MatchingBraceOutdent = require("ace/mode/matching_brace_outdent").MatchingBraceOutdent; var Range = require("ace/range").Range; var WorkerClient = require("ace/worker/worker_client").WorkerClient; +var CstyleBehaviour = require("ace/mode/behaviour/cstyle").CstyleBehaviour; var Mode = function() { this.$tokenizer = new Tokenizer(new JavaScriptHighlightRules().getRules()); this.$outdent = new MatchingBraceOutdent(); + this.$behaviour = new CstyleBehaviour(); }; oop.inherits(Mode, TextMode); diff --git a/lib/ace/mode/javascript_highlight_rules.js b/lib/ace/mode/javascript_highlight_rules.js index f5998deb..14b1795c 100644 --- a/lib/ace/mode/javascript_highlight_rules.js +++ b/lib/ace/mode/javascript_highlight_rules.js @@ -45,8 +45,6 @@ var TextHighlightRules = require("ace/mode/text_highlight_rules").TextHighlightR var JavaScriptHighlightRules = function() { - var docComment = new DocCommentHighlightRules(); - var keywords = lang.arrayToMap( ("break|case|catch|continue|default|delete|do|else|finally|for|function|" + "if|in|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|" + @@ -71,7 +69,7 @@ var JavaScriptHighlightRules = function() { token : "comment", regex : "\\/\\/.*$" }, - docComment.getStartRule("doc-start"), + new DocCommentHighlightRules().getStartRule("doc-start"), { token : "comment", // multi line comment regex : "\\/\\*", @@ -168,9 +166,9 @@ var JavaScriptHighlightRules = function() { } ] }; - - this.addRules(docComment.getRules(), "doc-"); - this.$rules["doc-start"][0].next = "start"; + + this.embedRules(DocCommentHighlightRules, "doc-", + [ new DocCommentHighlightRules().getEndRule("start") ]); }; oop.inherits(JavaScriptHighlightRules, TextHighlightRules); diff --git a/lib/ace/mode/php.js b/lib/ace/mode/php.js index 13fdf30b..a11a7c49 100644 --- a/lib/ace/mode/php.js +++ b/lib/ace/mode/php.js @@ -43,10 +43,12 @@ var Tokenizer = require("ace/tokenizer").Tokenizer; var PhpHighlightRules = require("ace/mode/php_highlight_rules").PhpHighlightRules; var MatchingBraceOutdent = require("ace/mode/matching_brace_outdent").MatchingBraceOutdent; var Range = require("ace/range").Range; +var CstyleBehaviour = require("ace/mode/behaviour/cstyle").CstyleBehaviour; var Mode = function() { this.$tokenizer = new Tokenizer(new PhpHighlightRules().getRules()); this.$outdent = new MatchingBraceOutdent(); + this.$behaviour = new CstyleBehaviour(); }; oop.inherits(Mode, TextMode); diff --git a/lib/ace/mode/php_highlight_rules.js b/lib/ace/mode/php_highlight_rules.js index 5e5d3922..a3c1e2dc 100644 --- a/lib/ace/mode/php_highlight_rules.js +++ b/lib/ace/mode/php_highlight_rules.js @@ -44,9 +44,7 @@ var DocCommentHighlightRules = require("ace/mode/doc_comment_highlight_rules").D var TextHighlightRules = require("ace/mode/text_highlight_rules").TextHighlightRules; var PhpHighlightRules = function() { - - var docComment = new DocCommentHighlightRules(); - + var builtinFunctions = lang.arrayToMap( ('abs|acos|acosh|addcslashes|addslashes|aggregate|aggregate_info|aggregate_methods|' + 'aggregate_methods_by_list|aggregate_methods_by_regexp|aggregate_properties|aggregate_properties_by_list|' + @@ -476,7 +474,7 @@ var PhpHighlightRules = function() { token : "comment", regex : "#.*$" }, - docComment.getStartRule("doc-start"), + new DocCommentHighlightRules().getStartRule("doc-start"), { token : "comment", // multi line comment regex : "\\/\\*", @@ -596,9 +594,9 @@ var PhpHighlightRules = function() { } ] }; - - this.addRules(docComment.getRules(), "doc-"); - this.$rules["doc-start"][0].next = "start"; + + this.embedRules(DocCommentHighlightRules, "doc-", + [ new DocCommentHighlightRules().getEndRule("start") ]); }; oop.inherits(PhpHighlightRules, TextHighlightRules); diff --git a/lib/ace/mode/svg.js b/lib/ace/mode/svg.js index 4ba826a2..10384e57 100644 --- a/lib/ace/mode/svg.js +++ b/lib/ace/mode/svg.js @@ -42,10 +42,18 @@ var XmlMode = require("ace/mode/text").Mode; var JavaScriptMode = require("ace/mode/javascript").Mode; var Tokenizer = require("ace/tokenizer").Tokenizer; var SvgHighlightRules = require("ace/mode/svg_highlight_rules").SvgHighlightRules; +var XmlBehaviour = require("ace/mode/behaviour/xml").XmlBehaviour; var Mode = function() { - this.$tokenizer = new Tokenizer(new SvgHighlightRules().getRules()); - this.$js = new JavaScriptMode(); + this.highlighter = new SvgHighlightRules(); + this.$tokenizer = new Tokenizer(highlighter.getRules()); + this.$behaviour = new XmlBehaviour(); + + + this.$embeds = highlighter.getEmbeds(); + this.createModeDelegates({ + "js-": JavaScriptMode + }); }; oop.inherits(Mode, XmlMode); @@ -53,38 +61,15 @@ oop.inherits(Mode, XmlMode); (function() { this.toggleCommentLines = function(state, doc, startRow, endRow) { - this.$delegate("toggleCommentLines", arguments, function() { - return 0; - }); + return 0; }; this.getNextLineIndent = function(state, line, tab) { - var self = this; - return this.$delegate("getNextLineIndent", arguments, function() { - return self.$getIndent(line); - }); + return self.$getIndent(line); }; this.checkOutdent = function(state, line, input) { - return this.$delegate("checkOutdent", arguments, function() { - return false; - }); - }; - - this.autoOutdent = function(state, doc, row) { - this.$delegate("autoOutdent", arguments); - }; - - this.$delegate = function(method, args, defaultHandler) { - var state = args[0]; - var split = state.split("js-"); - - if (!split[0] && split[1]) { - args[0] = split[1]; - return this.$js[method].apply(this.$js, args); - } - - return defaultHandler ? defaultHandler() : undefined; + return false; }; }).call(Mode.prototype); diff --git a/lib/ace/mode/svg_highlight_rules.js b/lib/ace/mode/svg_highlight_rules.js index 731e05a5..0f9ae5b9 100644 --- a/lib/ace/mode/svg_highlight_rules.js +++ b/lib/ace/mode/svg_highlight_rules.js @@ -65,11 +65,9 @@ var SvgHighlightRules = function() { }, { token : "string", regex : "'.*?'" - }]; - - var jsRules = new JavaScriptHighlightRules().getRules(); - this.addRules(jsRules, "js-"); - this.$rules["js-start"].unshift({ + }]; + + this.embedRules(JavaScriptHighlightRules, "js-", [{ token: "comment", regex: "\\/\\/.*(?=<\\/script>)", next: "tag" @@ -77,7 +75,7 @@ var SvgHighlightRules = function() { token: "text", regex: "<\\/(?=script)", next: "tag" - }); + }], ["js-start"]); }; diff --git a/lib/ace/mode/text.js b/lib/ace/mode/text.js index d0a3e495..40e4f506 100644 --- a/lib/ace/mode/text.js +++ b/lib/ace/mode/text.js @@ -22,6 +22,7 @@ * Contributor(s): * Fabian Jakobs * Mihai Sucan + * Chris Spencer * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or @@ -41,9 +42,11 @@ define(function(require, exports, module) { var Tokenizer = require("ace/tokenizer").Tokenizer; var TextHighlightRules = require("ace/mode/text_highlight_rules").TextHighlightRules; +var Behaviour = require("ace/mode/behaviour").Behaviour; var Mode = function() { this.$tokenizer = new Tokenizer(new TextHighlightRules().getRules()); + this.$behaviour = new Behaviour(); }; (function() { @@ -147,10 +150,12 @@ var Mode = function() { } this.$modes = {}; for (var i = 0; i < this.$embeds.length; i++) { - this.$modes[this.$embeds[i]] = new mapping[this.$embeds[i]](); + if (mapping[this.$embeds[i]]) { + this.$modes[this.$embeds[i]] = new mapping[this.$embeds[i]](); + } } - var delegations = ['toggleCommentLines', 'getNextLineIndent', 'checkOutdent', 'autoOutdent']; + var delegations = ['toggleCommentLines', 'getNextLineIndent', 'checkOutdent', 'autoOutdent', 'transformAction']; for (var i = 0; i < delegations.length; i++) { (function(scope) { @@ -167,18 +172,34 @@ var Mode = function() { var state = args[0]; for (var i = 0; i < this.$embeds.length; i++) { + if (!this.$modes[this.$embeds[i]]) continue; + var split = state.split(this.$embeds[i]); - if (!split[0] && split[1]) { args[0] = split[1]; var mode = this.$modes[this.$embeds[i]]; return mode[method].apply(mode, args); } } - - return defaultHandler ? defaultHandler.apply(this, args) : undefined; + var ret = defaultHandler.apply(this, args); + return defaultHandler ? ret : undefined; }; - + + this.transformAction = function(state, action, editor, session, param) { + if (this.$behaviour) { + var behaviours = this.$behaviour.getBehaviours(); + for (var key in behaviours) { + if (behaviours[key][action]) { + var ret = behaviours[key][action].apply(this, arguments); + if (ret !== false) { + return ret; + } + } + } + } + return false; + } + }).call(Mode.prototype); exports.Mode = Mode; diff --git a/lib/ace/mode/text_highlight_rules.js b/lib/ace/mode/text_highlight_rules.js index 3ff947b1..e0feffa3 100644 --- a/lib/ace/mode/text_highlight_rules.js +++ b/lib/ace/mode/text_highlight_rules.js @@ -37,6 +37,8 @@ define(function(require, exports, module) { +var lang = require("pilot/lang"); + var TextHighlightRules = function() { // regexp must not have capturing parentheses @@ -89,7 +91,7 @@ var TextHighlightRules = function() { this.addRules(embedRules, prefix); for (var i = 0; i < states.length; i++) { - Array.prototype.unshift.apply(this.$rules[states[i]], escapeRules); + Array.prototype.unshift.apply(this.$rules[states[i]], lang.deepCopy(escapeRules)); } if (!this.$embeds) { diff --git a/lib/ace/mode/xml.js b/lib/ace/mode/xml.js index edaa5ffb..a6d5fa9c 100644 --- a/lib/ace/mode/xml.js +++ b/lib/ace/mode/xml.js @@ -41,9 +41,11 @@ var oop = require("pilot/oop"); var TextMode = require("ace/mode/text").Mode; var Tokenizer = require("ace/tokenizer").Tokenizer; var XmlHighlightRules = require("ace/mode/xml_highlight_rules").XmlHighlightRules; +var XmlBehaviour = require("ace/mode/behaviour/xml").XmlBehaviour; var Mode = function() { this.$tokenizer = new Tokenizer(new XmlHighlightRules().getRules()); + this.$behaviour = new XmlBehaviour(); }; oop.inherits(Mode, TextMode);