Stop using splice.appy() in ace

Since .apply() can't handle more than 65535 parameters, splice.apply()
is brittle. It's also hard to read. This replaces splice.apply() calls
throughout ace code with lang.spliceIntoArray().
This commit is contained in:
aldendaniels 2014-01-04 01:59:30 -06:00
commit 8624ab8dcb
9 changed files with 53 additions and 37 deletions

View file

@ -32,6 +32,7 @@ define(function(require, exports, module) {
"use strict"; "use strict";
var oop = require("./lib/oop"); var oop = require("./lib/oop");
var lang = require("./lib/lang");
var EventEmitter = require("./lib/event_emitter").EventEmitter; var EventEmitter = require("./lib/event_emitter").EventEmitter;
@ -187,14 +188,15 @@ var BackgroundTokenizer = function(tokenizer, editor) {
this.lines.splice(startRow, len + 1, null); this.lines.splice(startRow, len + 1, null);
this.states.splice(startRow, len + 1, null); this.states.splice(startRow, len + 1, null);
} else { } else {
var args = Array(len + 1); this.lines.splice( startRow, 1);
args.unshift(startRow, 1); this.states.splice(startRow, 1);
this.lines.splice.apply(this.lines, args); var toInsert = Array(len + 1);
this.states.splice.apply(this.states, args); lang.spliceIntoArray(this.lines, startRow, toInsert);
lang.spliceIntoArray(this.states, startRow, toInsert);
} }
this.currentLine = Math.min(startRow, this.currentLine, this.doc.getLength()); this.currentLine = Math.min(startRow, this.currentLine, this.doc.getLength());
this.stop(); this.stop();
}; };

View file

@ -1723,15 +1723,15 @@ var EditSession = function(text, mode) {
} else { } else {
var args; var args;
if (useWrapMode) { if (useWrapMode) {
args = [firstRow, 0]; var toInsert = [];
for (var i = 0; i < len; i++) args.push([]); for (var i = 0; i < len; i++)
this.$wrapData.splice.apply(this.$wrapData, args); toInsert.push([]);
lang.spliceIntoArray(this.$wrapData, firstRow, toInsert);
} else { } else {
args = Array(len); var toInsert = Array(len);
args.unshift(firstRow, 0); lang.spliceIntoArray(this.$rowLengthCache, firstRow, toInsert);
this.$rowLengthCache.splice.apply(this.$rowLengthCache, args);
} }
// If some new line is added inside of a foldLine, then split // If some new line is added inside of a foldLine, then split
// the fold line up. // the fold line up.
var foldLines = this.$foldData; var foldLines = this.$foldData;

View file

@ -31,6 +31,7 @@
define(function(require, exports, module) { define(function(require, exports, module) {
"use strict"; "use strict";
var lang = require("../lib/lang");
var Range = require("../range").Range; var Range = require("../range").Range;
var FoldLine = require("./fold_line").FoldLine; var FoldLine = require("./fold_line").FoldLine;
var Fold = require("./fold").Fold; var Fold = require("./fold").Fold;
@ -836,9 +837,8 @@ function Folding() {
} else if (delta.action == "delete") { } else if (delta.action == "delete") {
this.foldWidgets.splice(firstRow, len + 1, null); this.foldWidgets.splice(firstRow, len + 1, null);
} else { } else {
var args = Array(len + 1); this.foldWidgets.splice(firstRow, 1);
args.unshift(firstRow, 1); lang.spliceIntoArray(this.foldWidgets, firstRow, Array(len + 1));
this.foldWidgets.splice.apply(this.foldWidgets, args);
} }
}; };

View file

@ -111,9 +111,8 @@ var Gutter = function(parentEl) {
} else if (delta.action == "delete") { } else if (delta.action == "delete") {
this.$annotations.splice(firstRow, len + 1, null); this.$annotations.splice(firstRow, len + 1, null);
} else { } else {
var args = new Array(len + 1); this.$annotations.splice(firstRow, 1);
args.unshift(firstRow, 1); lang.spliceIntoArray(this.$annotations, firstRow, new Array(len + 1));
this.$annotations.splice.apply(this.$annotations, args);
} }
}; };

View file

@ -123,6 +123,20 @@ exports.arrayRemove = function(array, value) {
} }
}; };
/*
* Splice the items in `a2` into `a1` at position `offset`.
*/
exports.spliceIntoArray = function(a1, offset, a2) {
// Handle negative offsets.
if (offset < 0)
offset = Math.max(a1.length + offset, 0);
// Splice.
for (var i = 0; i < a2.length; i++)
a1.splice(i + offset, 0, a2[i]);
}
exports.escapeRegExp = function(str) { exports.escapeRegExp = function(str) {
return str.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1'); return str.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1');
}; };

View file

@ -32,6 +32,7 @@ define(function(require, exports, module) {
"use strict"; "use strict";
var oop = require("./lib/oop"); var oop = require("./lib/oop");
var lang = require("./lib/lang");
var dom = require("./lib/dom"); var dom = require("./lib/dom");
var Range = require("./range").Range; var Range = require("./range").Range;
@ -130,9 +131,7 @@ function LineWidgets(session) {
}, this); }, this);
this.$updateRows(); this.$updateRows();
} else { } else {
var args = Array(len); lang.spliceIntoArray(cells, startRow, new Array(len));
args.unshift(startRow, 0);
cells.splice.apply(cells, args);
this.$updateRows(); this.$updateRows();
} }
}; };

View file

@ -32,6 +32,7 @@ define(function(require, exports, module) {
"use strict"; "use strict";
var oop = require("../lib/oop"); var oop = require("../lib/oop");
var lang = require("../lib/lang");
var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
var AsciidocHighlightRules = function() { var AsciidocHighlightRules = function() {
@ -215,13 +216,14 @@ var AsciidocHighlightRules = function() {
for (var i = stateRules.length; i--; ) { for (var i = stateRules.length; i--; ) {
var rule = stateRules[i]; var rule = stateRules[i];
if (rule.include || typeof rule == "string") { if (rule.include || typeof rule == "string") {
var args = [i, 1].concat(this.$rules[rule.include || rule]); var toInsert = this.$rules[rule.include || rule];
if (rule.noEscape) { if (rule.noEscape) {
args = args.filter(function(x) { toInsert = toInsert.filter(function(x) {
return !x.next; return !x.next;
}); });
} }
stateRules.splice.apply(stateRules, args); stateRules.splice(i, 1);
lang.spliceIntoArray(stateRules, i, toInsert);
} else if (rule.token in tokenMap) { } else if (rule.token in tokenMap) {
rule.token = tokenMap[rule.token]; rule.token = tokenMap[rule.token];
} }

View file

@ -181,10 +181,10 @@ var TextHighlightRules = function() {
toInsert = rule; toInsert = rule;
if (toInsert) { if (toInsert) {
var args = [i, 1].concat(toInsert);
if (rule.noEscape) if (rule.noEscape)
args = args.filter(function(x) {return !x.next;}); toInsert = toInsert.filter(function(x) {return !x.next;});
state.splice.apply(state, args); state.splice(i, 1);
lang.spliceIntoArray(state, i, toInsert);
// skip included rules since they are already processed // skip included rules since they are already processed
//i += args.length - 3; //i += args.length - 3;
i--; i--;

View file

@ -335,12 +335,12 @@ var SnippetManager = function() {
} }
var ts = tabstops[id]; var ts = tabstops[id];
var arg = typeof ts.value == "string" ? [ts.value] : copyValue(ts.value); var toInsert = typeof ts.value == "string" ? [ts.value] : copyValue(ts.value);
arg.unshift(i + 1, Math.max(0, i1 - i)); toInsert.push(p);
arg.push(p);
expanding[id] = p; expanding[id] = p;
tokens.splice.apply(tokens, arg); tokens.splice(i + 1, Math.max(0, i1 - i));
lang.spliceIntoArray(tokens, i + 1, toInsert);
if (ts.indexOf(p) === -1) if (ts.indexOf(p) === -1)
ts.push(p); ts.push(p);
}; };
@ -755,7 +755,7 @@ var TabstopManager = function(editor) {
} }
var i = this.index; var i = this.index;
var arg = [i, 0]; var toInsert = [];
var ranges = this.ranges; var ranges = this.ranges;
var editor = this.editor; var editor = this.editor;
tabstops.forEach(function(ts) { tabstops.forEach(function(ts) {
@ -776,12 +776,12 @@ var TabstopManager = function(editor) {
} }
if (!ts.firstNonLinked) if (!ts.firstNonLinked)
ts.hasLinkedRanges = false; ts.hasLinkedRanges = false;
arg.push(ts); toInsert.push(ts);
this.addTabstopMarkers(ts); this.addTabstopMarkers(ts);
}, this); }, this);
// tabstop 0 is the last one // tabstop 0 is the last one
arg.push(arg.splice(2, 1)[0]); toInsert.push(toInsert.splice(0, 1)[0]);
this.tabstops.splice.apply(this.tabstops, arg); lang.spliceIntoArray(this.tabstops, this.index, toInsert);
}; };
this.addTabstopMarkers = function(ts) { this.addTabstopMarkers = function(ts) {