Edit File by line

Deprecated: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in /home/sportsfever/public_html/filemanger/function.php on line 93

Warning: Undefined array key "page_file_edit_line" in /home/sportsfever/public_html/filemanger/edit_text_line.php on line 32
/home/sportsfe.../httpdocs/wp-conte.../plugins/wp-file-.../lib/codemirr.../lib
File: codemirror.js
}, options);
[6000] Fix | Delete
return cm;
[6001] Fix | Delete
};
[6002] Fix | Delete
[6003] Fix | Delete
// STRING STREAM
[6004] Fix | Delete
[6005] Fix | Delete
// Fed to the mode parsers, provides helper functions to make
[6006] Fix | Delete
// parsers more succinct.
[6007] Fix | Delete
[6008] Fix | Delete
var StringStream = CodeMirror.StringStream = function(string, tabSize) {
[6009] Fix | Delete
this.pos = this.start = 0;
[6010] Fix | Delete
this.string = string;
[6011] Fix | Delete
this.tabSize = tabSize || 8;
[6012] Fix | Delete
this.lastColumnPos = this.lastColumnValue = 0;
[6013] Fix | Delete
this.lineStart = 0;
[6014] Fix | Delete
};
[6015] Fix | Delete
[6016] Fix | Delete
StringStream.prototype = {
[6017] Fix | Delete
eol: function() {return this.pos >= this.string.length;},
[6018] Fix | Delete
sol: function() {return this.pos == this.lineStart;},
[6019] Fix | Delete
peek: function() {return this.string.charAt(this.pos) || undefined;},
[6020] Fix | Delete
next: function() {
[6021] Fix | Delete
if (this.pos < this.string.length)
[6022] Fix | Delete
return this.string.charAt(this.pos++);
[6023] Fix | Delete
},
[6024] Fix | Delete
eat: function(match) {
[6025] Fix | Delete
var ch = this.string.charAt(this.pos);
[6026] Fix | Delete
if (typeof match == "string") var ok = ch == match;
[6027] Fix | Delete
else var ok = ch && (match.test ? match.test(ch) : match(ch));
[6028] Fix | Delete
if (ok) {++this.pos; return ch;}
[6029] Fix | Delete
},
[6030] Fix | Delete
eatWhile: function(match) {
[6031] Fix | Delete
var start = this.pos;
[6032] Fix | Delete
while (this.eat(match)){}
[6033] Fix | Delete
return this.pos > start;
[6034] Fix | Delete
},
[6035] Fix | Delete
eatSpace: function() {
[6036] Fix | Delete
var start = this.pos;
[6037] Fix | Delete
while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos;
[6038] Fix | Delete
return this.pos > start;
[6039] Fix | Delete
},
[6040] Fix | Delete
skipToEnd: function() {this.pos = this.string.length;},
[6041] Fix | Delete
skipTo: function(ch) {
[6042] Fix | Delete
var found = this.string.indexOf(ch, this.pos);
[6043] Fix | Delete
if (found > -1) {this.pos = found; return true;}
[6044] Fix | Delete
},
[6045] Fix | Delete
backUp: function(n) {this.pos -= n;},
[6046] Fix | Delete
column: function() {
[6047] Fix | Delete
if (this.lastColumnPos < this.start) {
[6048] Fix | Delete
this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue);
[6049] Fix | Delete
this.lastColumnPos = this.start;
[6050] Fix | Delete
}
[6051] Fix | Delete
return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0);
[6052] Fix | Delete
},
[6053] Fix | Delete
indentation: function() {
[6054] Fix | Delete
return countColumn(this.string, null, this.tabSize) -
[6055] Fix | Delete
(this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0);
[6056] Fix | Delete
},
[6057] Fix | Delete
match: function(pattern, consume, caseInsensitive) {
[6058] Fix | Delete
if (typeof pattern == "string") {
[6059] Fix | Delete
var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;};
[6060] Fix | Delete
var substr = this.string.substr(this.pos, pattern.length);
[6061] Fix | Delete
if (cased(substr) == cased(pattern)) {
[6062] Fix | Delete
if (consume !== false) this.pos += pattern.length;
[6063] Fix | Delete
return true;
[6064] Fix | Delete
}
[6065] Fix | Delete
} else {
[6066] Fix | Delete
var match = this.string.slice(this.pos).match(pattern);
[6067] Fix | Delete
if (match && match.index > 0) return null;
[6068] Fix | Delete
if (match && consume !== false) this.pos += match[0].length;
[6069] Fix | Delete
return match;
[6070] Fix | Delete
}
[6071] Fix | Delete
},
[6072] Fix | Delete
current: function(){return this.string.slice(this.start, this.pos);},
[6073] Fix | Delete
hideFirstChars: function(n, inner) {
[6074] Fix | Delete
this.lineStart += n;
[6075] Fix | Delete
try { return inner(); }
[6076] Fix | Delete
finally { this.lineStart -= n; }
[6077] Fix | Delete
}
[6078] Fix | Delete
};
[6079] Fix | Delete
[6080] Fix | Delete
// TEXTMARKERS
[6081] Fix | Delete
[6082] Fix | Delete
// Created with markText and setBookmark methods. A TextMarker is a
[6083] Fix | Delete
// handle that can be used to clear or find a marked position in the
[6084] Fix | Delete
// document. Line objects hold arrays (markedSpans) containing
[6085] Fix | Delete
// {from, to, marker} object pointing to such marker objects, and
[6086] Fix | Delete
// indicating that such a marker is present on that line. Multiple
[6087] Fix | Delete
// lines may point to the same marker when it spans across lines.
[6088] Fix | Delete
// The spans will have null for their from/to properties when the
[6089] Fix | Delete
// marker continues beyond the start/end of the line. Markers have
[6090] Fix | Delete
// links back to the lines they currently touch.
[6091] Fix | Delete
[6092] Fix | Delete
var nextMarkerId = 0;
[6093] Fix | Delete
[6094] Fix | Delete
var TextMarker = CodeMirror.TextMarker = function(doc, type) {
[6095] Fix | Delete
this.lines = [];
[6096] Fix | Delete
this.type = type;
[6097] Fix | Delete
this.doc = doc;
[6098] Fix | Delete
this.id = ++nextMarkerId;
[6099] Fix | Delete
};
[6100] Fix | Delete
eventMixin(TextMarker);
[6101] Fix | Delete
[6102] Fix | Delete
// Clear the marker.
[6103] Fix | Delete
TextMarker.prototype.clear = function() {
[6104] Fix | Delete
if (this.explicitlyCleared) return;
[6105] Fix | Delete
var cm = this.doc.cm, withOp = cm && !cm.curOp;
[6106] Fix | Delete
if (withOp) startOperation(cm);
[6107] Fix | Delete
if (hasHandler(this, "clear")) {
[6108] Fix | Delete
var found = this.find();
[6109] Fix | Delete
if (found) signalLater(this, "clear", found.from, found.to);
[6110] Fix | Delete
}
[6111] Fix | Delete
var min = null, max = null;
[6112] Fix | Delete
for (var i = 0; i < this.lines.length; ++i) {
[6113] Fix | Delete
var line = this.lines[i];
[6114] Fix | Delete
var span = getMarkedSpanFor(line.markedSpans, this);
[6115] Fix | Delete
if (cm && !this.collapsed) regLineChange(cm, lineNo(line), "text");
[6116] Fix | Delete
else if (cm) {
[6117] Fix | Delete
if (span.to != null) max = lineNo(line);
[6118] Fix | Delete
if (span.from != null) min = lineNo(line);
[6119] Fix | Delete
}
[6120] Fix | Delete
line.markedSpans = removeMarkedSpan(line.markedSpans, span);
[6121] Fix | Delete
if (span.from == null && this.collapsed && !lineIsHidden(this.doc, line) && cm)
[6122] Fix | Delete
updateLineHeight(line, textHeight(cm.display));
[6123] Fix | Delete
}
[6124] Fix | Delete
if (cm && this.collapsed && !cm.options.lineWrapping) for (var i = 0; i < this.lines.length; ++i) {
[6125] Fix | Delete
var visual = visualLine(this.lines[i]), len = lineLength(visual);
[6126] Fix | Delete
if (len > cm.display.maxLineLength) {
[6127] Fix | Delete
cm.display.maxLine = visual;
[6128] Fix | Delete
cm.display.maxLineLength = len;
[6129] Fix | Delete
cm.display.maxLineChanged = true;
[6130] Fix | Delete
}
[6131] Fix | Delete
}
[6132] Fix | Delete
[6133] Fix | Delete
if (min != null && cm && this.collapsed) regChange(cm, min, max + 1);
[6134] Fix | Delete
this.lines.length = 0;
[6135] Fix | Delete
this.explicitlyCleared = true;
[6136] Fix | Delete
if (this.atomic && this.doc.cantEdit) {
[6137] Fix | Delete
this.doc.cantEdit = false;
[6138] Fix | Delete
if (cm) reCheckSelection(cm.doc);
[6139] Fix | Delete
}
[6140] Fix | Delete
if (cm) signalLater(cm, "markerCleared", cm, this);
[6141] Fix | Delete
if (withOp) endOperation(cm);
[6142] Fix | Delete
if (this.parent) this.parent.clear();
[6143] Fix | Delete
};
[6144] Fix | Delete
[6145] Fix | Delete
// Find the position of the marker in the document. Returns a {from,
[6146] Fix | Delete
// to} object by default. Side can be passed to get a specific side
[6147] Fix | Delete
// -- 0 (both), -1 (left), or 1 (right). When lineObj is true, the
[6148] Fix | Delete
// Pos objects returned contain a line object, rather than a line
[6149] Fix | Delete
// number (used to prevent looking up the same line twice).
[6150] Fix | Delete
TextMarker.prototype.find = function(side, lineObj) {
[6151] Fix | Delete
if (side == null && this.type == "bookmark") side = 1;
[6152] Fix | Delete
var from, to;
[6153] Fix | Delete
for (var i = 0; i < this.lines.length; ++i) {
[6154] Fix | Delete
var line = this.lines[i];
[6155] Fix | Delete
var span = getMarkedSpanFor(line.markedSpans, this);
[6156] Fix | Delete
if (span.from != null) {
[6157] Fix | Delete
from = Pos(lineObj ? line : lineNo(line), span.from);
[6158] Fix | Delete
if (side == -1) return from;
[6159] Fix | Delete
}
[6160] Fix | Delete
if (span.to != null) {
[6161] Fix | Delete
to = Pos(lineObj ? line : lineNo(line), span.to);
[6162] Fix | Delete
if (side == 1) return to;
[6163] Fix | Delete
}
[6164] Fix | Delete
}
[6165] Fix | Delete
return from && {from: from, to: to};
[6166] Fix | Delete
};
[6167] Fix | Delete
[6168] Fix | Delete
// Signals that the marker's widget changed, and surrounding layout
[6169] Fix | Delete
// should be recomputed.
[6170] Fix | Delete
TextMarker.prototype.changed = function() {
[6171] Fix | Delete
var pos = this.find(-1, true), widget = this, cm = this.doc.cm;
[6172] Fix | Delete
if (!pos || !cm) return;
[6173] Fix | Delete
runInOp(cm, function() {
[6174] Fix | Delete
var line = pos.line, lineN = lineNo(pos.line);
[6175] Fix | Delete
var view = findViewForLine(cm, lineN);
[6176] Fix | Delete
if (view) {
[6177] Fix | Delete
clearLineMeasurementCacheFor(view);
[6178] Fix | Delete
cm.curOp.selectionChanged = cm.curOp.forceUpdate = true;
[6179] Fix | Delete
}
[6180] Fix | Delete
cm.curOp.updateMaxLine = true;
[6181] Fix | Delete
if (!lineIsHidden(widget.doc, line) && widget.height != null) {
[6182] Fix | Delete
var oldHeight = widget.height;
[6183] Fix | Delete
widget.height = null;
[6184] Fix | Delete
var dHeight = widgetHeight(widget) - oldHeight;
[6185] Fix | Delete
if (dHeight)
[6186] Fix | Delete
updateLineHeight(line, line.height + dHeight);
[6187] Fix | Delete
}
[6188] Fix | Delete
});
[6189] Fix | Delete
};
[6190] Fix | Delete
[6191] Fix | Delete
TextMarker.prototype.attachLine = function(line) {
[6192] Fix | Delete
if (!this.lines.length && this.doc.cm) {
[6193] Fix | Delete
var op = this.doc.cm.curOp;
[6194] Fix | Delete
if (!op.maybeHiddenMarkers || indexOf(op.maybeHiddenMarkers, this) == -1)
[6195] Fix | Delete
(op.maybeUnhiddenMarkers || (op.maybeUnhiddenMarkers = [])).push(this);
[6196] Fix | Delete
}
[6197] Fix | Delete
this.lines.push(line);
[6198] Fix | Delete
};
[6199] Fix | Delete
TextMarker.prototype.detachLine = function(line) {
[6200] Fix | Delete
this.lines.splice(indexOf(this.lines, line), 1);
[6201] Fix | Delete
if (!this.lines.length && this.doc.cm) {
[6202] Fix | Delete
var op = this.doc.cm.curOp;
[6203] Fix | Delete
(op.maybeHiddenMarkers || (op.maybeHiddenMarkers = [])).push(this);
[6204] Fix | Delete
}
[6205] Fix | Delete
};
[6206] Fix | Delete
[6207] Fix | Delete
// Collapsed markers have unique ids, in order to be able to order
[6208] Fix | Delete
// them, which is needed for uniquely determining an outer marker
[6209] Fix | Delete
// when they overlap (they may nest, but not partially overlap).
[6210] Fix | Delete
var nextMarkerId = 0;
[6211] Fix | Delete
[6212] Fix | Delete
// Create a marker, wire it up to the right lines, and
[6213] Fix | Delete
function markText(doc, from, to, options, type) {
[6214] Fix | Delete
// Shared markers (across linked documents) are handled separately
[6215] Fix | Delete
// (markTextShared will call out to this again, once per
[6216] Fix | Delete
// document).
[6217] Fix | Delete
if (options && options.shared) return markTextShared(doc, from, to, options, type);
[6218] Fix | Delete
// Ensure we are in an operation.
[6219] Fix | Delete
if (doc.cm && !doc.cm.curOp) return operation(doc.cm, markText)(doc, from, to, options, type);
[6220] Fix | Delete
[6221] Fix | Delete
var marker = new TextMarker(doc, type), diff = cmp(from, to);
[6222] Fix | Delete
if (options) copyObj(options, marker, false);
[6223] Fix | Delete
// Don't connect empty markers unless clearWhenEmpty is false
[6224] Fix | Delete
if (diff > 0 || diff == 0 && marker.clearWhenEmpty !== false)
[6225] Fix | Delete
return marker;
[6226] Fix | Delete
if (marker.replacedWith) {
[6227] Fix | Delete
// Showing up as a widget implies collapsed (widget replaces text)
[6228] Fix | Delete
marker.collapsed = true;
[6229] Fix | Delete
marker.widgetNode = elt("span", [marker.replacedWith], "CodeMirror-widget");
[6230] Fix | Delete
if (!options.handleMouseEvents) marker.widgetNode.setAttribute("cm-ignore-events", "true");
[6231] Fix | Delete
if (options.insertLeft) marker.widgetNode.insertLeft = true;
[6232] Fix | Delete
}
[6233] Fix | Delete
if (marker.collapsed) {
[6234] Fix | Delete
if (conflictingCollapsedRange(doc, from.line, from, to, marker) ||
[6235] Fix | Delete
from.line != to.line && conflictingCollapsedRange(doc, to.line, from, to, marker))
[6236] Fix | Delete
throw new Error("Inserting collapsed marker partially overlapping an existing one");
[6237] Fix | Delete
sawCollapsedSpans = true;
[6238] Fix | Delete
}
[6239] Fix | Delete
[6240] Fix | Delete
if (marker.addToHistory)
[6241] Fix | Delete
addChangeToHistory(doc, {from: from, to: to, origin: "markText"}, doc.sel, NaN);
[6242] Fix | Delete
[6243] Fix | Delete
var curLine = from.line, cm = doc.cm, updateMaxLine;
[6244] Fix | Delete
doc.iter(curLine, to.line + 1, function(line) {
[6245] Fix | Delete
if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(line) == cm.display.maxLine)
[6246] Fix | Delete
updateMaxLine = true;
[6247] Fix | Delete
if (marker.collapsed && curLine != from.line) updateLineHeight(line, 0);
[6248] Fix | Delete
addMarkedSpan(line, new MarkedSpan(marker,
[6249] Fix | Delete
curLine == from.line ? from.ch : null,
[6250] Fix | Delete
curLine == to.line ? to.ch : null));
[6251] Fix | Delete
++curLine;
[6252] Fix | Delete
});
[6253] Fix | Delete
// lineIsHidden depends on the presence of the spans, so needs a second pass
[6254] Fix | Delete
if (marker.collapsed) doc.iter(from.line, to.line + 1, function(line) {
[6255] Fix | Delete
if (lineIsHidden(doc, line)) updateLineHeight(line, 0);
[6256] Fix | Delete
});
[6257] Fix | Delete
[6258] Fix | Delete
if (marker.clearOnEnter) on(marker, "beforeCursorEnter", function() { marker.clear(); });
[6259] Fix | Delete
[6260] Fix | Delete
if (marker.readOnly) {
[6261] Fix | Delete
sawReadOnlySpans = true;
[6262] Fix | Delete
if (doc.history.done.length || doc.history.undone.length)
[6263] Fix | Delete
doc.clearHistory();
[6264] Fix | Delete
}
[6265] Fix | Delete
if (marker.collapsed) {
[6266] Fix | Delete
marker.id = ++nextMarkerId;
[6267] Fix | Delete
marker.atomic = true;
[6268] Fix | Delete
}
[6269] Fix | Delete
if (cm) {
[6270] Fix | Delete
// Sync editor state
[6271] Fix | Delete
if (updateMaxLine) cm.curOp.updateMaxLine = true;
[6272] Fix | Delete
if (marker.collapsed)
[6273] Fix | Delete
regChange(cm, from.line, to.line + 1);
[6274] Fix | Delete
else if (marker.className || marker.title || marker.startStyle || marker.endStyle || marker.css)
[6275] Fix | Delete
for (var i = from.line; i <= to.line; i++) regLineChange(cm, i, "text");
[6276] Fix | Delete
if (marker.atomic) reCheckSelection(cm.doc);
[6277] Fix | Delete
signalLater(cm, "markerAdded", cm, marker);
[6278] Fix | Delete
}
[6279] Fix | Delete
return marker;
[6280] Fix | Delete
}
[6281] Fix | Delete
[6282] Fix | Delete
// SHARED TEXTMARKERS
[6283] Fix | Delete
[6284] Fix | Delete
// A shared marker spans multiple linked documents. It is
[6285] Fix | Delete
// implemented as a meta-marker-object controlling multiple normal
[6286] Fix | Delete
// markers.
[6287] Fix | Delete
var SharedTextMarker = CodeMirror.SharedTextMarker = function(markers, primary) {
[6288] Fix | Delete
this.markers = markers;
[6289] Fix | Delete
this.primary = primary;
[6290] Fix | Delete
for (var i = 0; i < markers.length; ++i)
[6291] Fix | Delete
markers[i].parent = this;
[6292] Fix | Delete
};
[6293] Fix | Delete
eventMixin(SharedTextMarker);
[6294] Fix | Delete
[6295] Fix | Delete
SharedTextMarker.prototype.clear = function() {
[6296] Fix | Delete
if (this.explicitlyCleared) return;
[6297] Fix | Delete
this.explicitlyCleared = true;
[6298] Fix | Delete
for (var i = 0; i < this.markers.length; ++i)
[6299] Fix | Delete
this.markers[i].clear();
[6300] Fix | Delete
signalLater(this, "clear");
[6301] Fix | Delete
};
[6302] Fix | Delete
SharedTextMarker.prototype.find = function(side, lineObj) {
[6303] Fix | Delete
return this.primary.find(side, lineObj);
[6304] Fix | Delete
};
[6305] Fix | Delete
[6306] Fix | Delete
function markTextShared(doc, from, to, options, type) {
[6307] Fix | Delete
options = copyObj(options);
[6308] Fix | Delete
options.shared = false;
[6309] Fix | Delete
var markers = [markText(doc, from, to, options, type)], primary = markers[0];
[6310] Fix | Delete
var widget = options.widgetNode;
[6311] Fix | Delete
linkedDocs(doc, function(doc) {
[6312] Fix | Delete
if (widget) options.widgetNode = widget.cloneNode(true);
[6313] Fix | Delete
markers.push(markText(doc, clipPos(doc, from), clipPos(doc, to), options, type));
[6314] Fix | Delete
for (var i = 0; i < doc.linked.length; ++i)
[6315] Fix | Delete
if (doc.linked[i].isParent) return;
[6316] Fix | Delete
primary = lst(markers);
[6317] Fix | Delete
});
[6318] Fix | Delete
return new SharedTextMarker(markers, primary);
[6319] Fix | Delete
}
[6320] Fix | Delete
[6321] Fix | Delete
function findSharedMarkers(doc) {
[6322] Fix | Delete
return doc.findMarks(Pos(doc.first, 0), doc.clipPos(Pos(doc.lastLine())),
[6323] Fix | Delete
function(m) { return m.parent; });
[6324] Fix | Delete
}
[6325] Fix | Delete
[6326] Fix | Delete
function copySharedMarkers(doc, markers) {
[6327] Fix | Delete
for (var i = 0; i < markers.length; i++) {
[6328] Fix | Delete
var marker = markers[i], pos = marker.find();
[6329] Fix | Delete
var mFrom = doc.clipPos(pos.from), mTo = doc.clipPos(pos.to);
[6330] Fix | Delete
if (cmp(mFrom, mTo)) {
[6331] Fix | Delete
var subMark = markText(doc, mFrom, mTo, marker.primary, marker.primary.type);
[6332] Fix | Delete
marker.markers.push(subMark);
[6333] Fix | Delete
subMark.parent = marker;
[6334] Fix | Delete
}
[6335] Fix | Delete
}
[6336] Fix | Delete
}
[6337] Fix | Delete
[6338] Fix | Delete
function detachSharedMarkers(markers) {
[6339] Fix | Delete
for (var i = 0; i < markers.length; i++) {
[6340] Fix | Delete
var marker = markers[i], linked = [marker.primary.doc];;
[6341] Fix | Delete
linkedDocs(marker.primary.doc, function(d) { linked.push(d); });
[6342] Fix | Delete
for (var j = 0; j < marker.markers.length; j++) {
[6343] Fix | Delete
var subMarker = marker.markers[j];
[6344] Fix | Delete
if (indexOf(linked, subMarker.doc) == -1) {
[6345] Fix | Delete
subMarker.parent = null;
[6346] Fix | Delete
marker.markers.splice(j--, 1);
[6347] Fix | Delete
}
[6348] Fix | Delete
}
[6349] Fix | Delete
}
[6350] Fix | Delete
}
[6351] Fix | Delete
[6352] Fix | Delete
// TEXTMARKER SPANS
[6353] Fix | Delete
[6354] Fix | Delete
function MarkedSpan(marker, from, to) {
[6355] Fix | Delete
this.marker = marker;
[6356] Fix | Delete
this.from = from; this.to = to;
[6357] Fix | Delete
}
[6358] Fix | Delete
[6359] Fix | Delete
// Search an array of spans for a span matching the given marker.
[6360] Fix | Delete
function getMarkedSpanFor(spans, marker) {
[6361] Fix | Delete
if (spans) for (var i = 0; i < spans.length; ++i) {
[6362] Fix | Delete
var span = spans[i];
[6363] Fix | Delete
if (span.marker == marker) return span;
[6364] Fix | Delete
}
[6365] Fix | Delete
}
[6366] Fix | Delete
// Remove a span from an array, returning undefined if no spans are
[6367] Fix | Delete
// left (we don't store arrays for lines without spans).
[6368] Fix | Delete
function removeMarkedSpan(spans, span) {
[6369] Fix | Delete
for (var r, i = 0; i < spans.length; ++i)
[6370] Fix | Delete
if (spans[i] != span) (r || (r = [])).push(spans[i]);
[6371] Fix | Delete
return r;
[6372] Fix | Delete
}
[6373] Fix | Delete
// Add a span to a line.
[6374] Fix | Delete
function addMarkedSpan(line, span) {
[6375] Fix | Delete
line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span];
[6376] Fix | Delete
span.marker.attachLine(line);
[6377] Fix | Delete
}
[6378] Fix | Delete
[6379] Fix | Delete
// Used for the algorithm that adjusts markers for a change in the
[6380] Fix | Delete
// document. These functions cut an array of spans at a given
[6381] Fix | Delete
// character position, returning an array of remaining chunks (or
[6382] Fix | Delete
// undefined if nothing remains).
[6383] Fix | Delete
function markedSpansBefore(old, startCh, isInsert) {
[6384] Fix | Delete
if (old) for (var i = 0, nw; i < old.length; ++i) {
[6385] Fix | Delete
var span = old[i], marker = span.marker;
[6386] Fix | Delete
var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh);
[6387] Fix | Delete
if (startsBefore || span.from == startCh && marker.type == "bookmark" && (!isInsert || !span.marker.insertLeft)) {
[6388] Fix | Delete
var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh);
[6389] Fix | Delete
(nw || (nw = [])).push(new MarkedSpan(marker, span.from, endsAfter ? null : span.to));
[6390] Fix | Delete
}
[6391] Fix | Delete
}
[6392] Fix | Delete
return nw;
[6393] Fix | Delete
}
[6394] Fix | Delete
function markedSpansAfter(old, endCh, isInsert) {
[6395] Fix | Delete
if (old) for (var i = 0, nw; i < old.length; ++i) {
[6396] Fix | Delete
var span = old[i], marker = span.marker;
[6397] Fix | Delete
var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh);
[6398] Fix | Delete
if (endsAfter || span.from == endCh && marker.type == "bookmark" && (!isInsert || span.marker.insertLeft)) {
[6399] Fix | Delete
var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh);
[6400] Fix | Delete
(nw || (nw = [])).push(new MarkedSpan(marker, startsBefore ? null : span.from - endCh,
[6401] Fix | Delete
span.to == null ? null : span.to - endCh));
[6402] Fix | Delete
}
[6403] Fix | Delete
}
[6404] Fix | Delete
return nw;
[6405] Fix | Delete
}
[6406] Fix | Delete
[6407] Fix | Delete
// Given a change object, compute the new set of marker spans that
[6408] Fix | Delete
// cover the line in which the change took place. Removes spans
[6409] Fix | Delete
// entirely within the change, reconnects spans belonging to the
[6410] Fix | Delete
// same marker that appear on both sides of the change, and cuts off
[6411] Fix | Delete
// spans partially within the change. Returns an array of span
[6412] Fix | Delete
// arrays with one element for each line in (after) the change.
[6413] Fix | Delete
function stretchSpansOverChange(doc, change) {
[6414] Fix | Delete
if (change.full) return null;
[6415] Fix | Delete
var oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans;
[6416] Fix | Delete
var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans;
[6417] Fix | Delete
if (!oldFirst && !oldLast) return null;
[6418] Fix | Delete
[6419] Fix | Delete
var startCh = change.from.ch, endCh = change.to.ch, isInsert = cmp(change.from, change.to) == 0;
[6420] Fix | Delete
// Get the spans that 'stick out' on both sides
[6421] Fix | Delete
var first = markedSpansBefore(oldFirst, startCh, isInsert);
[6422] Fix | Delete
var last = markedSpansAfter(oldLast, endCh, isInsert);
[6423] Fix | Delete
[6424] Fix | Delete
// Next, merge those two ends
[6425] Fix | Delete
var sameLine = change.text.length == 1, offset = lst(change.text).length + (sameLine ? startCh : 0);
[6426] Fix | Delete
if (first) {
[6427] Fix | Delete
// Fix up .to properties of first
[6428] Fix | Delete
for (var i = 0; i < first.length; ++i) {
[6429] Fix | Delete
var span = first[i];
[6430] Fix | Delete
if (span.to == null) {
[6431] Fix | Delete
var found = getMarkedSpanFor(last, span.marker);
[6432] Fix | Delete
if (!found) span.to = startCh;
[6433] Fix | Delete
else if (sameLine) span.to = found.to == null ? null : found.to + offset;
[6434] Fix | Delete
}
[6435] Fix | Delete
}
[6436] Fix | Delete
}
[6437] Fix | Delete
if (last) {
[6438] Fix | Delete
// Fix up .from in last (or move them into first in case of sameLine)
[6439] Fix | Delete
for (var i = 0; i < last.length; ++i) {
[6440] Fix | Delete
var span = last[i];
[6441] Fix | Delete
if (span.to != null) span.to += offset;
[6442] Fix | Delete
if (span.from == null) {
[6443] Fix | Delete
var found = getMarkedSpanFor(first, span.marker);
[6444] Fix | Delete
if (!found) {
[6445] Fix | Delete
span.from = offset;
[6446] Fix | Delete
if (sameLine) (first || (first = [])).push(span);
[6447] Fix | Delete
}
[6448] Fix | Delete
} else {
[6449] Fix | Delete
span.from += offset;
[6450] Fix | Delete
if (sameLine) (first || (first = [])).push(span);
[6451] Fix | Delete
}
[6452] Fix | Delete
}
[6453] Fix | Delete
}
[6454] Fix | Delete
// Make sure we didn't create any zero-length spans
[6455] Fix | Delete
if (first) first = clearEmptySpans(first);
[6456] Fix | Delete
if (last && last != first) last = clearEmptySpans(last);
[6457] Fix | Delete
[6458] Fix | Delete
var newMarkers = [first];
[6459] Fix | Delete
if (!sameLine) {
[6460] Fix | Delete
// Fill gap with whole-line-spans
[6461] Fix | Delete
var gap = change.text.length - 2, gapMarkers;
[6462] Fix | Delete
if (gap > 0 && first)
[6463] Fix | Delete
for (var i = 0; i < first.length; ++i)
[6464] Fix | Delete
if (first[i].to == null)
[6465] Fix | Delete
(gapMarkers || (gapMarkers = [])).push(new MarkedSpan(first[i].marker, null, null));
[6466] Fix | Delete
for (var i = 0; i < gap; ++i)
[6467] Fix | Delete
newMarkers.push(gapMarkers);
[6468] Fix | Delete
newMarkers.push(last);
[6469] Fix | Delete
}
[6470] Fix | Delete
return newMarkers;
[6471] Fix | Delete
}
[6472] Fix | Delete
[6473] Fix | Delete
// Remove spans that are empty and don't have a clearWhenEmpty
[6474] Fix | Delete
// option of false.
[6475] Fix | Delete
function clearEmptySpans(spans) {
[6476] Fix | Delete
for (var i = 0; i < spans.length; ++i) {
[6477] Fix | Delete
var span = spans[i];
[6478] Fix | Delete
if (span.from != null && span.from == span.to && span.marker.clearWhenEmpty !== false)
[6479] Fix | Delete
spans.splice(i--, 1);
[6480] Fix | Delete
}
[6481] Fix | Delete
if (!spans.length) return null;
[6482] Fix | Delete
return spans;
[6483] Fix | Delete
}
[6484] Fix | Delete
[6485] Fix | Delete
// Used for un/re-doing changes from the history. Combines the
[6486] Fix | Delete
// result of computing the existing spans with the set of spans that
[6487] Fix | Delete
// existed in the history (so that deleting around a span and then
[6488] Fix | Delete
// undoing brings back the span).
[6489] Fix | Delete
function mergeOldSpans(doc, change) {
[6490] Fix | Delete
var old = getOldSpans(doc, change);
[6491] Fix | Delete
var stretched = stretchSpansOverChange(doc, change);
[6492] Fix | Delete
if (!old) return stretched;
[6493] Fix | Delete
if (!stretched) return old;
[6494] Fix | Delete
[6495] Fix | Delete
for (var i = 0; i < old.length; ++i) {
[6496] Fix | Delete
var oldCur = old[i], stretchCur = stretched[i];
[6497] Fix | Delete
if (oldCur && stretchCur) {
[6498] Fix | Delete
spans: for (var j = 0; j < stretchCur.length; ++j) {
[6499] Fix | Delete
It is recommended that you Edit text format, this type of Fix handles quite a lot in one request
Function