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";
var oop = require("./lib/oop");
var lang = require("./lib/lang");
var EventEmitter = require("./lib/event_emitter").EventEmitter;
@ -187,14 +188,15 @@ var BackgroundTokenizer = function(tokenizer, editor) {
this.lines.splice(startRow, len + 1, null);
this.states.splice(startRow, len + 1, null);
} else {
var args = Array(len + 1);
args.unshift(startRow, 1);
this.lines.splice.apply(this.lines, args);
this.states.splice.apply(this.states, args);
this.lines.splice( startRow, 1);
this.states.splice(startRow, 1);
var toInsert = Array(len + 1);
lang.spliceIntoArray(this.lines, startRow, toInsert);
lang.spliceIntoArray(this.states, startRow, toInsert);
}
this.currentLine = Math.min(startRow, this.currentLine, this.doc.getLength());
this.stop();
};

View file

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

View file

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

View file

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

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) {
return str.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1');
};

View file

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

View file

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

View file

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

View file

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