diff --git a/demo/ie7.html b/demo/ie7.html new file mode 100644 index 00000000..3a525f86 --- /dev/null +++ b/demo/ie7.html @@ -0,0 +1,44 @@ + + + + + + ACE Editor StatusBar Demo + + + + +
+require("ace/ext/old_ie");
+// now ace will work even on ie7!
+var editor = ace.edit("editor");
+
+ + + + + + + + diff --git a/lib/ace/ext/old_ie.js b/lib/ace/ext/old_ie.js new file mode 100644 index 00000000..ca67888f --- /dev/null +++ b/lib/ace/ext/old_ie.js @@ -0,0 +1,108 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, 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"; +var MAX_TOKEN_COUNT = 1000; +var useragent = require("../lib/useragent"); +var TokenizerModule = require("../tokenizer"); + +function patch(obj, name, regexp, replacement) { + eval("obj['" + name + "']=" + obj[name].toString().replace( + regexp, replacement + )); +} + +if (useragent.isIE && useragent.isIE < 10 && window.top.document.compatMode === "BackCompat") + useragent.isOldIE = true; + +if (typeof document != "undefined" && !document.documentElement.querySelector) { + useragent.isOldIE = true; + var qs = function(el, selector) { + if (selector.charAt(0) == ".") { + var classNeme = selector.slice(1); + } else { + var m = selector.match(/(\w+)=(\w+)/); + var attr = m && m[1]; + var attrVal = m && m[2]; + } + for (var i = 0; i < el.all.length; i++) { + var ch = el.all[i]; + if (classNeme) { + if (ch.className.indexOf(classNeme) != -1) + return ch; + } else if (attr) { + if (ch.getAttribute(attr) == attrVal) + return ch; + } + } + }; + var sb = require("./searchbox").SearchBox.prototype; + patch( + sb, "$initElements", + /([^\s=]*).querySelector\((".*?")\)/g, + "qs($1, $2)" + ); +} + +var compliantExecNpcg = /()??/.exec("")[1] === undefined; +if (compliantExecNpcg) + return; +var proto = TokenizerModule.Tokenizer.prototype; +TokenizerModule.Tokenizer_orig = TokenizerModule.Tokenizer; +proto.getLineTokens_orig = proto.getLineTokens; + +patch( + TokenizerModule, "Tokenizer", + "ruleRegExps.push(adjustedregex);\n", + function(m) { + return m + '\ + if (state[i].next && RegExp(adjustedregex).test(""))\n\ + rule._qre = RegExp(adjustedregex, "g");\n\ + '; + } +); +TokenizerModule.Tokenizer.prototype = proto; +patch( + proto, "getLineTokens", + /if \(match\[i \+ 1\] === undefined\)\s*continue;/, + "if (!match[i + 1]) {\n\ + if (value)continue;\n\ + var qre = state[mapping[i]]._qre;\n\ + if (!qre) continue;\n\ + qre.lastIndex = lastIndex;\n\ + if (!qre.exec(line) || qre.lastIndex != lastIndex)\n\ + continue;\n\ + }" +); + +useragent.isOldIE = true; + +}); diff --git a/lib/ace/ext/old_ie_test.js b/lib/ace/ext/old_ie_test.js new file mode 100644 index 00000000..98652e14 --- /dev/null +++ b/lib/ace/ext/old_ie_test.js @@ -0,0 +1,77 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, 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 ***** */ + +if (typeof process !== "undefined") { + require("amd-loader"); +} + +define(function(require, exports, module) { +"use strict"; + +var assert = require("../test/assertions"); + +module.exports = { + "test: getTokenizer() (smoke test)" : function() { + var exec = RegExp.prototype.exec + var brokenExec = function(str) { + var result = exec.call(this, str); + if (result) { + for (var i = result.length; i--;) + if (!result[i]) + result[i] = ""; + } + return result; + } + + try { + // break this to emulate old ie + RegExp.prototype.exec = brokenExec; + require("./old_ie"); + var Tokenizer = require("../tokenizer").Tokenizer; + var JavaScriptHighlightRules = require("../mode/javascript_highlight_rules").JavaScriptHighlightRules; + var tokenizer = new Tokenizer((new JavaScriptHighlightRules).getRules()); + + var tokens = tokenizer.getLineTokens("'juhu'", "start").tokens; + assert.equal("string", tokens[0].type); + } finally { + // restore modified functions + RegExp.prototype.exec = exec; + var module = require("../tokenizer"); + module.Tokenizer = module.Tokenizer_orig; + module.Tokenizer.prototype.getLineTokens = module.Tokenizer.prototype.getLineTokens_orig; + } + } +}; + +}); + +if (typeof module !== "undefined" && module === require.main) { + require("asyncjs").test.testcase(module.exports).exec() +} diff --git a/lib/ace/ext/searchbox.js b/lib/ace/ext/searchbox.js index c416b275..fb704d4a 100644 --- a/lib/ace/ext/searchbox.js +++ b/lib/ace/ext/searchbox.js @@ -75,9 +75,7 @@ var SearchBox = function(editor, range, showReplaceForm) { this.editor = editor; }; - this.$init = function() { - var sb = this.element; - + this.$initElements = function(sb) { this.searchBox = sb.querySelector(".ace_search_form"); this.replaceBox = sb.querySelector(".ace_replace_form"); this.searchOptions = sb.querySelector(".ace_search_options"); @@ -86,7 +84,13 @@ var SearchBox = function(editor, range, showReplaceForm) { this.wholeWordOption = sb.querySelector("[action=toggleWholeWords]"); this.searchInput = this.searchBox.querySelector(".ace_search_field"); this.replaceInput = this.replaceBox.querySelector(".ace_search_field"); - + }; + + this.$init = function() { + var sb = this.element; + + this.$initElements(sb); + var _this = this; event.addListener(sb, "mousedown", function(e) { setTimeout(function(){ diff --git a/lib/ace/keyboard/textinput.js b/lib/ace/keyboard/textinput.js index 79202931..802b9236 100644 --- a/lib/ace/keyboard/textinput.js +++ b/lib/ace/keyboard/textinput.js @@ -215,18 +215,18 @@ var TextInput = function(parentNode, host) { if (data) host.onPaste(data); pasted = false; - } else if (data == PLACEHOLDER[0]) { + } else if (data == PLACEHOLDER.charAt(0)) { if (afterContextMenu) host.execCommand("del", {source: "ace"}); } else { if (data.substring(0, 2) == PLACEHOLDER) data = data.substr(2); - else if (data[0] == PLACEHOLDER[0]) + else if (data.charAt(0) == PLACEHOLDER.charAt(0)) data = data.substr(1); - else if (data[data.length - 1] == PLACEHOLDER[0]) + else if (data.charAt(data.length - 1) == PLACEHOLDER.charAt(0)) data = data.slice(0, -1); // can happen if undo in textarea isn't stopped - if (data[data.length - 1] == PLACEHOLDER[0]) + if (data.charAt(data.length - 1) == PLACEHOLDER.charAt(0)) data = data.slice(0, -1); if (data) diff --git a/lib/ace/mode/html_highlight_rules.js b/lib/ace/mode/html_highlight_rules.js index 96e666b0..26bca6df 100644 --- a/lib/ace/mode/html_highlight_rules.js +++ b/lib/ace/mode/html_highlight_rules.js @@ -69,7 +69,7 @@ var HtmlHighlightRules = function() { token : "keyword.operator.separator", regex : "=", push : [{ - include: "space", + include: "space" }, { token : "string", regex : "[^<>='\"`\\s]+", diff --git a/lib/ace/mode/js_regex_highlight_rules.js b/lib/ace/mode/js_regex_highlight_rules.js index 96bbe5b6..d54e2ca3 100644 --- a/lib/ace/mode/js_regex_highlight_rules.js +++ b/lib/ace/mode/js_regex_highlight_rules.js @@ -21,7 +21,7 @@ var JsRegexHighlightRules = function() { // flag token: "string.regexp", regex: "/\\w*", - next: "start", + next: "start" }, { token : ["string", "string.regex"], regex: quantifier, @@ -43,7 +43,7 @@ var JsRegexHighlightRules = function() { }, { token: "constant.language.escape", regex: /\[\^?/, - next: "character_class", + next: "character_class" }, { token: "empty", regex: "$", @@ -63,7 +63,7 @@ var JsRegexHighlightRules = function() { }, { token: "constant.language.escape", regex: "]", - next: "start", + next: "start" }, { token: "constant.language.escape", regex: "-" diff --git a/lib/ace/mode/mushcode_high_rules.js b/lib/ace/mode/mushcode_high_rules.js index e2ad064c..e3197bee 100644 --- a/lib/ace/mode/mushcode_high_rules.js +++ b/lib/ace/mode/mushcode_high_rules.js @@ -559,7 +559,7 @@ var MushCodeRules = function() { }, { token : "text", regex : "\\s+" - } ], + } ] }; }; diff --git a/lib/ace/mode/mysql_highlight_rules.js b/lib/ace/mode/mysql_highlight_rules.js index c531c650..7f428bc8 100644 --- a/lib/ace/mode/mysql_highlight_rules.js +++ b/lib/ace/mode/mysql_highlight_rules.js @@ -108,7 +108,7 @@ var MysqlHighlightRules = function() { "comment" : [ {token : "comment", regex : "\\*\\/", next : "start"}, {defaultToken : "comment"} - ], + ] }; this.embedRules(DocCommentHighlightRules, "doc-", [ DocCommentHighlightRules.getEndRule("start") ]); diff --git a/lib/ace/mode/php_highlight_rules.js b/lib/ace/mode/php_highlight_rules.js index 8c080214..3828f20a 100644 --- a/lib/ace/mode/php_highlight_rules.js +++ b/lib/ace/mode/php_highlight_rules.js @@ -1013,7 +1013,7 @@ var PhpLangHighlightRules = function() { next: "start" }, { token: "string", - regex : ".*", + regex : ".*" } ], "comment" : [ diff --git a/lib/ace/mode/properties_highlight_rules.js b/lib/ace/mode/properties_highlight_rules.js index 36640175..0fbaceb6 100644 --- a/lib/ace/mode/properties_highlight_rules.js +++ b/lib/ace/mode/properties_highlight_rules.js @@ -53,7 +53,7 @@ var PropertiesHighlightRules = function() { next : "value" }, { token : "constant.language.escape", - regex : escapeRe, + regex : escapeRe }, { defaultToken: "variable" } diff --git a/lib/ace/mode/snippets.js b/lib/ace/mode/snippets.js index ed394c8a..f22efa2d 100644 --- a/lib/ace/mode/snippets.js +++ b/lib/ace/mode/snippets.js @@ -86,7 +86,7 @@ var SnippetGroupHighlightRules = function() { {onMatch: function(value, state, stack) { stack.splice(stack.length); return this.tokenName; - }, tokenName: "text", regex: "^(?!\t)", next: "start"}, + }, tokenName: "text", regex: "^(?!\t)", next: "start"} ]) }; diff --git a/lib/ace/mode/twig_highlight_rules.js b/lib/ace/mode/twig_highlight_rules.js index 4a71973f..dcd37a50 100644 --- a/lib/ace/mode/twig_highlight_rules.js +++ b/lib/ace/mode/twig_highlight_rules.js @@ -139,7 +139,7 @@ var TwigHighlightRules = function() { }, { token : "string", regex : '"', - next : "twig-start", + next : "twig-start" }, { defaultToken : "string" } @@ -151,7 +151,7 @@ var TwigHighlightRules = function() { }, { token : "string", regex : "'", - next : "twig-start", + next : "twig-start" }, { defaultToken : "string" }