Index: Source/devtools/front_end/cm/codemirror.js |
diff --git a/Source/devtools/front_end/cm/codemirror.js b/Source/devtools/front_end/cm/codemirror.js |
index 4c621e9265acf30b72cf3d8336d5d47c9475a6cb..a14ce5358f426fd818b6cdbe1ea86ca5eb0bbee5 100644 |
--- a/Source/devtools/front_end/cm/codemirror.js |
+++ b/Source/devtools/front_end/cm/codemirror.js |
@@ -24,7 +24,7 @@ window.CodeMirror = (function() { |
// This is woefully incomplete. Suggestions for alternative methods welcome. |
var mobile = ios || /Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(navigator.userAgent); |
var mac = ios || /Mac/.test(navigator.platform); |
- var windows = /windows/i.test(navigator.platform); |
+ var windows = /win/i.test(navigator.platform); |
var opera_version = opera && navigator.userAgent.match(/Version\/(\d*\.\d*)/); |
if (opera_version) opera_version = Number(opera_version[1]); |
@@ -304,15 +304,13 @@ window.CodeMirror = (function() { |
// Make sure the gutters options contains the element |
// "CodeMirror-linenumbers" when the lineNumbers option is true. |
function setGuttersForLineNumbers(options) { |
- var found = false; |
- for (var i = 0; i < options.gutters.length; ++i) { |
- if (options.gutters[i] == "CodeMirror-linenumbers") { |
- if (options.lineNumbers) found = true; |
- else options.gutters.splice(i--, 1); |
- } |
+ var found = indexOf(options.gutters, "CodeMirror-linenumbers"); |
+ if (found == -1 && options.lineNumbers) { |
+ options.gutters = options.gutters.concat(["CodeMirror-linenumbers"]); |
+ } else if (found > -1 && !options.lineNumbers) { |
+ options.gutters = options.gutters.slice(0); |
+ options.gutters.splice(i, 1); |
} |
- if (!found && options.lineNumbers) |
- options.gutters.push("CodeMirror-linenumbers"); |
} |
// SCROLLBARS |
@@ -332,13 +330,19 @@ window.CodeMirror = (function() { |
d.scrollbarV.style.bottom = needsH ? scrollbarWidth(d.measure) + "px" : "0"; |
d.scrollbarV.firstChild.style.height = |
(scrollHeight - d.scroller.clientHeight + d.scrollbarV.clientHeight) + "px"; |
- } else d.scrollbarV.style.display = ""; |
+ } else { |
+ d.scrollbarV.style.display = ""; |
+ d.scrollbarV.firstChild.style.height = "0"; |
+ } |
if (needsH) { |
d.scrollbarH.style.display = "block"; |
d.scrollbarH.style.right = needsV ? scrollbarWidth(d.measure) + "px" : "0"; |
d.scrollbarH.firstChild.style.width = |
(d.scroller.scrollWidth - d.scroller.clientWidth + d.scrollbarH.clientWidth) + "px"; |
- } else d.scrollbarH.style.display = ""; |
+ } else { |
+ d.scrollbarH.style.display = ""; |
+ d.scrollbarH.firstChild.style.width = "0"; |
+ } |
if (needsH && needsV) { |
d.scrollbarFiller.style.display = "block"; |
d.scrollbarFiller.style.height = d.scrollbarFiller.style.width = scrollbarWidth(d.measure) + "px"; |
@@ -406,11 +410,17 @@ window.CodeMirror = (function() { |
var oldFrom = cm.display.showingFrom, oldTo = cm.display.showingTo, updated; |
var visible = visibleLines(cm.display, cm.doc, viewPort); |
for (;;) { |
+ var oldWidth = cm.display.scroller.clientWidth; |
if (!updateDisplayInner(cm, changes, visible, forced)) break; |
- forced = false; |
updated = true; |
+ changes = []; |
updateSelection(cm); |
updateScrollbars(cm); |
+ if (cm.options.lineWrapping && oldWidth != cm.display.scroller.clientWidth) { |
+ forced = true; |
+ continue; |
+ } |
+ forced = false; |
// Clip forced viewport to actual scrollable area |
if (viewPort) |
@@ -419,7 +429,6 @@ window.CodeMirror = (function() { |
visible = visibleLines(cm.display, cm.doc, viewPort); |
if (visible.from >= cm.display.showingFrom && visible.to <= cm.display.showingTo) |
break; |
- changes = []; |
} |
if (updated) { |
@@ -455,7 +464,7 @@ window.CodeMirror = (function() { |
var positionsChangedFrom = Infinity; |
if (cm.options.lineNumbers) |
for (var i = 0; i < changes.length; ++i) |
- if (changes[i].diff) { positionsChangedFrom = changes[i].from; break; } |
+ if (changes[i].diff && changes[i].from < positionsChangedFrom) { positionsChangedFrom = changes[i].from; } |
var end = doc.first + doc.size; |
var from = Math.max(visible.from - cm.options.viewportMargin, doc.first); |
@@ -612,7 +621,7 @@ window.CodeMirror = (function() { |
if (nextIntact && nextIntact.to == lineN) nextIntact = intact.shift(); |
if (lineIsHidden(cm.doc, line)) { |
if (line.height != 0) updateLineHeight(line, 0); |
- if (line.widgets && cur.previousSibling) for (var i = 0; i < line.widgets.length; ++i) { |
+ if (line.widgets && cur && cur.previousSibling) for (var i = 0; i < line.widgets.length; ++i) { |
var w = line.widgets[i]; |
if (w.showIfHidden) { |
var prev = cur.previousSibling; |
@@ -657,10 +666,11 @@ window.CodeMirror = (function() { |
} |
function buildLineElement(cm, line, lineNo, dims, reuse) { |
- var lineElement = lineContent(cm, line); |
+ var built = buildLineContent(cm, line), lineElement = built.pre; |
var markers = line.gutterMarkers, display = cm.display, wrap; |
- if (!cm.options.lineNumbers && !markers && !line.bgClass && !line.wrapClass && !line.widgets) |
+ var bgClass = built.bgClass ? built.bgClass + " " + (line.bgClass || "") : line.bgClass; |
+ if (!cm.options.lineNumbers && !markers && !bgClass && !line.wrapClass && !line.widgets) |
return lineElement; |
// Lines with gutter elements, widgets or a background class need |
@@ -698,8 +708,8 @@ window.CodeMirror = (function() { |
wrap.appendChild(lineElement); |
} |
// Kludge to make sure the styled element lies behind the selection (by z-index) |
- if (line.bgClass) |
- wrap.insertBefore(elt("div", null, line.bgClass + " CodeMirror-linebackground"), wrap.firstChild); |
+ if (bgClass) |
+ wrap.insertBefore(elt("div", null, bgClass + " CodeMirror-linebackground"), wrap.firstChild); |
if (cm.options.lineNumbers || markers) { |
var gutterWrap = wrap.insertBefore(elt("div", null, null, "position: absolute; left: " + |
(cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px"), |
@@ -871,9 +881,10 @@ window.CodeMirror = (function() { |
clearInterval(display.blinker); |
var on = true; |
display.cursor.style.visibility = display.otherCursor.style.visibility = ""; |
- display.blinker = setInterval(function() { |
- display.cursor.style.visibility = display.otherCursor.style.visibility = (on = !on) ? "" : "hidden"; |
- }, cm.options.cursorBlinkRate); |
+ if (cm.options.cursorBlinkRate > 0) |
+ display.blinker = setInterval(function() { |
+ display.cursor.style.visibility = display.otherCursor.style.visibility = (on = !on) ? "" : "hidden"; |
+ }, cm.options.cursorBlinkRate); |
} |
// HIGHLIGHT WORKER |
@@ -924,8 +935,8 @@ window.CodeMirror = (function() { |
// smallest indentation, which tends to need the least context to |
// parse correctly. |
function findStartLine(cm, n, precise) { |
- var minindent, minline, doc = cm.doc; |
- for (var search = n, lim = n - 100; search > lim; --search) { |
+ var minindent, minline, doc = cm.doc, maxScan = cm.doc.mode.innerMode ? 1000 : 100; |
+ for (var search = n, lim = n - maxScan; search > lim; --search) { |
if (search <= doc.first) return doc.first; |
var line = getLine(doc, search - 1); |
if (line.stateAfter && (!precise || search <= doc.frontier)) return search; |
@@ -940,7 +951,7 @@ window.CodeMirror = (function() { |
function getStateBefore(cm, n, precise) { |
var doc = cm.doc, display = cm.display; |
- if (!doc.mode.startState) return true; |
+ if (!doc.mode.startState) return true; |
var pos = findStartLine(cm, n, precise), state = pos > doc.first && getLine(doc, pos-1).stateAfter; |
if (!state) state = startState(doc.mode); |
else state = copyState(doc.mode, state); |
@@ -965,9 +976,13 @@ window.CodeMirror = (function() { |
function measureChar(cm, line, ch, data, bias) { |
var dir = -1; |
data = data || measureLine(cm, line); |
+ if (data.crude) { |
+ var left = data.left + ch * data.width; |
+ return {left: left, right: left + data.width, top: data.top, bottom: data.bottom}; |
+ } |
for (var pos = ch;; pos += dir) { |
- var r = data.get(pos); |
+ var r = data[pos]; |
if (r) break; |
if (dir < 0 && pos == 0) dir = 1; |
} |
@@ -1002,13 +1017,7 @@ window.CodeMirror = (function() { |
if (cached) return cached.measure; |
// Failing that, recompute and store result in cache |
- var measure = measureLineInner(cm, line, 0, 10); |
- measure.get = function(num) { |
- if (this[num]) return this[num]; |
- if (num < 0 || num >= line.text.length) return null; |
- measureLineInner(cm, line, Math.max(num - 50, 0), Math.min(num + 50, line.text.length), this); |
- return this[num]; |
- }; |
+ var measure = measureLineInner(cm, line); |
var cache = cm.display.measureLineCache; |
var memo = {text: line.text, width: cm.display.scroller.clientWidth, |
markedSpans: line.markedSpans, measure: measure, |
@@ -1018,9 +1027,12 @@ window.CodeMirror = (function() { |
return measure; |
} |
- function measureLineInner(cm, line, from, to, oldMeasure) { |
+ function measureLineInner(cm, line) { |
+ if (!cm.options.lineWrapping && line.text.length >= cm.options.crudeMeasuringFrom) |
+ return crudelyMeasureLine(cm, line); |
+ |
var display = cm.display, measure = emptyArray(line.text.length); |
- var pre = lineContent(cm, line, measure, true, from, to); |
+ var pre = buildLineContent(cm, line, measure, true).pre; |
// IE does not cache element positions of inline elements between |
// calls to getBoundingClientRect. This makes the loop below, |
@@ -1050,7 +1062,7 @@ window.CodeMirror = (function() { |
removeChildrenAndAdd(display.measure, pre); |
var outer = getRect(display.lineDiv); |
- var vranges = [], data = oldMeasure || emptyArray(line.text.length), maxBot = pre.offsetHeight; |
+ var vranges = [], data = emptyArray(line.text.length), maxBot = pre.offsetHeight; |
// Work around an IE7/8 bug where it will sometimes have randomly |
// replaced our pre with a clone at this point. |
if (ie_lt9 && display.measure.first != pre) |
@@ -1096,7 +1108,8 @@ window.CodeMirror = (function() { |
if (cur.measureRight) rect.right = getRect(cur.measureRight).left; |
if (cur.leftSide) rect.leftSide = measureRect(getRect(cur.leftSide)); |
} |
- for (var i = 0, cur; i < data.length; ++i) if (measure[i] && (cur = data[i])) { |
+ removeChildren(cm.display.measure); |
+ for (var i = 0, cur; i < data.length; ++i) if (cur = data[i]) { |
finishRect(cur); |
if (cur.leftSide) finishRect(cur.leftSide); |
if (cur.rightSide) finishRect(cur.rightSide); |
@@ -1104,6 +1117,15 @@ window.CodeMirror = (function() { |
return data; |
} |
+ function crudelyMeasureLine(cm, line) { |
+ var copy = new Line(line.text.slice(0, 100), null); |
+ if (line.textClass) copy.textClass = line.textClass; |
+ var measure = measureLineInner(cm, copy); |
+ var left = measureChar(cm, copy, 0, measure, "left"); |
+ var right = measureChar(cm, copy, 99, measure, "right"); |
+ return {crude: true, top: left.top, left: left.left, bottom: left.bottom, width: (right.right - left.left) / 100}; |
+ } |
+ |
function measureLineWidth(cm, line) { |
var hasBadSpan = false; |
if (line.markedSpans) for (var i = 0; i < line.markedSpans; ++i) { |
@@ -1111,9 +1133,10 @@ window.CodeMirror = (function() { |
if (sp.collapsed && (sp.to == null || sp.to == line.text.length)) hasBadSpan = true; |
} |
var cached = !hasBadSpan && findCachedMeasurement(cm, line); |
- if (cached) return measureChar(cm, line, line.text.length, cached.measure, "right").right; |
+ if (cached || line.text.length >= cm.options.crudeMeasuringFrom) |
+ return measureChar(cm, line, line.text.length, cached && cached.measure, "right").right; |
- var pre = lineContent(cm, line, null, true); |
+ var pre = buildLineContent(cm, line, null, true).pre; |
var end = pre.appendChild(zeroWidthElement(cm.display.measure)); |
removeChildrenAndAdd(cm.display.measure, pre); |
return getRect(end).right - getRect(cm.display.lineDiv).left; |
@@ -1598,7 +1621,7 @@ window.CodeMirror = (function() { |
on(d.scroller, "dragover", drag_); |
on(d.scroller, "drop", operation(cm, onDrop)); |
} |
- on(d.scroller, "paste", function(e){ |
+ on(d.scroller, "paste", function(e) { |
if (eventInWidget(d, e)) return; |
focusInput(cm); |
fastPoll(cm); |
@@ -1607,7 +1630,7 @@ window.CodeMirror = (function() { |
// Workaround for webkit bug https://bugs.webkit.org/show_bug.cgi?id=90206 |
// Add a char to the end of textarea before paste occur so that |
// selection doesn't span to the end of textarea. |
- if (webkit && !cm.state.fakedLastChar) { |
+ if (webkit && !cm.state.fakedLastChar && !(new Date - cm.state.lastMiddleDown < 200)) { |
var start = d.input.selectionStart, end = d.input.selectionEnd; |
d.input.value += "$"; |
d.input.selectionStart = start; |
@@ -1677,6 +1700,7 @@ window.CodeMirror = (function() { |
if (captureMiddleClick) onContextMenu.call(cm, cm, e); |
return; |
case 2: |
+ if (webkit) cm.state.lastMiddleDown = +new Date; |
if (start) extendSelection(cm.doc, start); |
setTimeout(bind(focusInput, cm), 20); |
e_preventDefault(e); |
@@ -1797,17 +1821,16 @@ window.CodeMirror = (function() { |
on(document, "mouseup", up); |
} |
- function clickInGutter(cm, e) { |
- var display = cm.display; |
+ function gutterEvent(cm, e, type, prevent, signalfn) { |
try { var mX = e.clientX, mY = e.clientY; } |
catch(e) { return false; } |
+ if (mX >= Math.floor(getRect(cm.display.gutters).right)) return false; |
+ if (prevent) e_preventDefault(e); |
- if (mX >= Math.floor(getRect(display.gutters).right)) return false; |
- e_preventDefault(e); |
- if (!hasHandler(cm, "gutterClick")) return true; |
- |
+ var display = cm.display; |
var lineBox = getRect(display.lineDiv); |
- if (mY > lineBox.bottom) return true; |
+ |
+ if (mY > lineBox.bottom || !hasHandler(cm, type)) return e_defaultPrevented(e); |
mY -= lineBox.top - display.viewOffset; |
for (var i = 0; i < cm.options.gutters.length; ++i) { |
@@ -1815,11 +1838,19 @@ window.CodeMirror = (function() { |
if (g && getRect(g).right >= mX) { |
var line = lineAtHeight(cm.doc, mY); |
var gutter = cm.options.gutters[i]; |
- signalLater(cm, "gutterClick", cm, line, gutter, e); |
- break; |
+ signalfn(cm, type, cm, line, gutter, e); |
+ return e_defaultPrevented(e); |
} |
} |
- return true; |
+ } |
+ |
+ function contextMenuInGutter(cm, e) { |
+ if (!hasHandler(cm, "gutterContextMenu")) return false; |
+ return gutterEvent(cm, e, "gutterContextMenu", false, signal); |
+ } |
+ |
+ function clickInGutter(cm, e) { |
+ return gutterEvent(cm, e, "gutterClick", true, signalLater); |
} |
// Kludge to work around strange IE behavior where it'll sometimes |
@@ -1882,6 +1913,7 @@ window.CodeMirror = (function() { |
// Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there. |
if (e.dataTransfer.setDragImage && !safari) { |
var img = elt("img", null, null, "position: fixed; left: 0; top: 0;"); |
+ img.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="; |
if (opera) { |
img.width = img.height = 1; |
cm.display.wrapper.appendChild(img); |
@@ -2080,8 +2112,8 @@ window.CodeMirror = (function() { |
function onKeyDown(e) { |
var cm = this; |
if (!cm.state.focused) onFocus(cm); |
- if (ie && e.keyCode == 27) { e.returnValue = false; } |
if (signalDOMEvent(cm, e) || cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return; |
+ if (ie && e.keyCode == 27) e.returnValue = false; |
var code = e.keyCode; |
// IE does strange things with escape. |
cm.doc.sel.shift = code == 16 || e.shiftKey; |
@@ -2118,7 +2150,10 @@ window.CodeMirror = (function() { |
cm.state.focused = true; |
if (cm.display.wrapper.className.search(/\bCodeMirror-focused\b/) == -1) |
cm.display.wrapper.className += " CodeMirror-focused"; |
- resetInput(cm, true); |
+ if (!cm.curOp) { |
+ resetInput(cm, true); |
+ if (webkit) setTimeout(bind(resetInput, cm, true), 0); // Issue #1730 |
+ } |
} |
slowPoll(cm); |
restartBlink(cm); |
@@ -2137,7 +2172,7 @@ window.CodeMirror = (function() { |
function onContextMenu(cm, e) { |
if (signalDOMEvent(cm, e, "contextmenu")) return; |
var display = cm.display, sel = cm.doc.sel; |
- if (eventInWidget(display, e)) return; |
+ if (eventInWidget(display, e) || contextMenuInGutter(cm, e)) return; |
var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop; |
if (!pos || opera) return; // Opera is difficult. |
@@ -2156,8 +2191,8 @@ window.CodeMirror = (function() { |
function prepareSelectAllHack() { |
if (display.input.selectionStart != null) { |
- var extval = display.input.value = " " + (posEq(sel.from, sel.to) ? "" : display.input.value); |
- display.prevInput = " "; |
+ var extval = display.input.value = "\u200b" + (posEq(sel.from, sel.to) ? "" : display.input.value); |
+ display.prevInput = "\u200b"; |
display.input.selectionStart = 1; display.input.selectionEnd = extval.length; |
} |
} |
@@ -2513,6 +2548,7 @@ window.CodeMirror = (function() { |
var sel = doc.sel; |
sel.goalColumn = null; |
+ if (bias == null) bias = posLess(head, sel.head) ? -1 : 1; |
// Skip over atomic spans. |
if (checkAtomic || !posEq(anchor, sel.anchor)) |
anchor = skipAtomic(doc, anchor, bias, checkAtomic != "push"); |
@@ -3157,9 +3193,11 @@ window.CodeMirror = (function() { |
operation: function(f){return runInOp(this, f);}, |
refresh: operation(null, function() { |
+ var badHeight = this.display.cachedTextHeight == null; |
clearCaches(this); |
updateScrollPos(this, this.doc.scrollLeft, this.doc.scrollTop); |
regChange(this); |
+ if (badHeight) estimateLineHeights(this); |
}), |
swapDoc: operation(null, function(doc) { |
@@ -3260,6 +3298,7 @@ window.CodeMirror = (function() { |
option("historyEventDelay", 500); |
option("viewportMargin", 10, function(cm){cm.refresh();}, true); |
option("maxHighlightLength", 10000, function(cm){loadMode(cm); cm.refresh();}, true); |
+ option("crudeMeasuringFrom", 10000); |
option("moveInputWithCursor", true, function(cm, val) { |
if (!val) cm.display.inputDiv.style.top = cm.display.inputDiv.style.left = 0; |
}); |
@@ -4202,8 +4241,7 @@ window.CodeMirror = (function() { |
while (!stream.eol()) { |
if (stream.pos > cm.options.maxHighlightLength) { |
flattenSpans = false; |
- // Webkit seems to refuse to render text nodes longer than 57444 characters |
- stream.pos = Math.min(text.length, stream.start + 50000); |
+ stream.pos = text.length; |
style = null; |
} else { |
style = mode.token(stream, state); |
@@ -4214,7 +4252,12 @@ window.CodeMirror = (function() { |
} |
stream.start = stream.pos; |
} |
- if (curStart < stream.pos) f(stream.pos, curStyle); |
+ while (curStart < stream.pos) { |
+ // Webkit seems to refuse to render text nodes longer than 57444 characters |
+ var pos = Math.min(stream.pos, curStart + 50000); |
+ f(pos, curStyle); |
+ curStart = pos; |
+ } |
} |
function highlightLine(cm, line, state) { |
@@ -4272,21 +4315,30 @@ window.CodeMirror = (function() { |
} |
var styleToClassCache = {}; |
- function styleToClass(style) { |
+ function interpretTokenStyle(style, builder) { |
if (!style) return null; |
+ for (;;) { |
+ var lineClass = style.match(/(?:^|\s)line-(background-)?(\S+)/); |
+ if (!lineClass) break; |
+ style = style.slice(0, lineClass.index) + style.slice(lineClass.index + lineClass[0].length); |
+ var prop = lineClass[1] ? "bgClass" : "textClass"; |
+ if (builder[prop] == null) |
+ builder[prop] = lineClass[2]; |
+ else if (!(new RegExp("(?:^|\s)" + lineClass[2] + "(?:$|\s)")).test(builder[prop])) |
+ builder[prop] += " " + lineClass[2]; |
+ } |
return styleToClassCache[style] || |
(styleToClassCache[style] = "cm-" + style.replace(/ +/g, " cm-")); |
} |
- function lineContent(cm, realLine, measure, copyWidgets, from, to) { |
+ function buildLineContent(cm, realLine, measure, copyWidgets) { |
var merged, line = realLine, empty = true; |
while (merged = collapsedSpanAtStart(line)) |
line = getLine(cm.doc, merged.find().from.line); |
var builder = {pre: elt("pre"), col: 0, pos: 0, |
- measure: null, measuredSomething: false, cm: cm, from: from, to: to, |
+ measure: null, measuredSomething: false, cm: cm, |
copyWidgets: copyWidgets}; |
- if (line.textClass) builder.pre.className = line.textClass; |
do { |
if (line.text) empty = false; |
@@ -4323,8 +4375,11 @@ window.CodeMirror = (function() { |
} |
} |
+ var textClass = builder.textClass ? builder.textClass + " " + (realLine.textClass || "") : realLine.textClass; |
+ if (textClass) builder.pre.className = textClass; |
+ |
signal(cm, "renderLine", cm, realLine, builder.pre); |
- return builder.pre; |
+ return builder; |
} |
var tokenSpecialChars = /[\t\u0000-\u0019\u00ad\u200b\u2028\u2029\uFEFF]/g; |
@@ -4369,14 +4424,6 @@ window.CodeMirror = (function() { |
} |
function buildTokenMeasure(builder, text, style, startStyle, endStyle) { |
- //FIXME consider 2-byte chars |
- if (builder.from || builder.to) { |
- if (builder.from >= builder.pos + text.length) { |
- buildToken(builder, text, style, startStyle, endStyle); |
- builder.pos += text.length; |
- return; |
- } |
- } |
var wrapping = builder.cm.options.lineWrapping; |
for (var i = 0; i < text.length; ++i) { |
var ch = text.charAt(i), start = i == 0; |
@@ -4423,11 +4470,13 @@ window.CodeMirror = (function() { |
if (size) { |
builder.measure[builder.pos] = widget; |
} else { |
- var elt = builder.measure[builder.pos] = zeroWidthElement(builder.cm.display.measure); |
- if (marker.type != "bookmark" || marker.insertLeft) |
- builder.pre.insertBefore(elt, widget); |
+ var elt = zeroWidthElement(builder.cm.display.measure); |
+ if (marker.type == "bookmark" && !marker.insertLeft) |
+ builder.measure[builder.pos] = builder.pre.appendChild(elt); |
+ else if (builder.measure[builder.pos]) |
+ return; |
else |
- builder.pre.appendChild(elt); |
+ builder.measure[builder.pos] = builder.pre.insertBefore(elt, widget); |
} |
builder.measuredSomething = true; |
} |
@@ -4440,27 +4489,8 @@ window.CodeMirror = (function() { |
function insertLineContent(line, builder, styles) { |
var spans = line.markedSpans, allText = line.text, at = 0; |
if (!spans) { |
- if (builder.to || builder.from) { |
- for (var i = 1; i < styles.length && (!builder.to || builder.pos < builder.to); i+=2) { |
- var text = allText.slice(at, at = styles[i]); |
- var textLength = text.length; |
- var resolvedStyles = styleToClass(styles[i+1]); |
- if (builder.pos + textLength <= builder.from) { |
- builder.addToken(builder, text, resolvedStyles); |
- continue; |
- } |
- // if we are not inside, but will get over it |
- if (builder.pos < builder.from && builder.pos + textLength > builder.from) { |
- var overlap = builder.from - builder.pos; |
- builder.addToken(builder, text.substring(0, overlap), resolvedStyles); |
- text = text.substring(overlap); |
- } |
- builder.addToken(builder, text.substr(0, Math.min(builder.to - builder.from, text.length)), resolvedStyles); |
- } |
- } else { |
- for (var i = 1; i < styles.length; i+=2) |
- builder.addToken(builder, allText.slice(at, at = styles[i]), styleToClass(styles[i+1])); |
- } |
+ for (var i = 1; i < styles.length; i+=2) |
+ builder.addToken(builder, allText.slice(at, at = styles[i]), interpretTokenStyle(styles[i+1], builder)); |
return; |
} |
@@ -4504,15 +4534,13 @@ window.CodeMirror = (function() { |
var tokenText = end > upto ? text.slice(0, upto - pos) : text; |
builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle, |
spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "", title); |
- if (builder.to && builder.pos >= builder.to) |
- return; |
} |
if (end >= upto) {text = text.slice(upto - pos); pos = upto; break;} |
pos = end; |
spanStartStyle = ""; |
} |
text = allText.slice(at, at = styles[i++]); |
- style = styleToClass(styles[i++]); |
+ style = interpretTokenStyle(styles[i++], builder); |
} |
} |
} |
@@ -4790,11 +4818,11 @@ window.CodeMirror = (function() { |
if (extend) extendSelection(this, pos); |
else setSelection(this, pos, pos); |
}), |
- setSelection: docOperation(function(anchor, head) { |
- setSelection(this, clipPos(this, anchor), clipPos(this, head || anchor)); |
+ setSelection: docOperation(function(anchor, head, bias) { |
+ setSelection(this, clipPos(this, anchor), clipPos(this, head || anchor), bias); |
}), |
- extendSelection: docOperation(function(from, to) { |
- extendSelection(this, clipPos(this, from), to && clipPos(this, to)); |
+ extendSelection: docOperation(function(from, to, bias) { |
+ extendSelection(this, clipPos(this, from), to && clipPos(this, to), bias); |
}), |
getSelection: function(lineSep) {return this.getRange(this.sel.from, this.sel.to, lineSep);}, |
@@ -5480,7 +5508,12 @@ window.CodeMirror = (function() { |
spanAffectsWrapping = function(str, i) { |
return /\-[^ \-?]|\?[^ !\'\"\),.\-\/:;\?\]\}]/.test(str.slice(i - 1, i + 1)); |
}; |
- else if (webkit && !/Chrome\/(?:29|[3-9]\d|\d\d\d)\./.test(navigator.userAgent)) |
+ else if (webkit && /Chrome\/(?:29|[3-9]\d|\d\d\d)\./.test(navigator.userAgent)) |
+ spanAffectsWrapping = function(str, i) { |
+ var code = str.charCodeAt(i - 1); |
+ return code >= 8208 && code <= 8212; |
+ }; |
+ else if (webkit) |
spanAffectsWrapping = function(str, i) { |
if (i > 1 && str.charCodeAt(i - 1) == 45) { |
if (/\w/.test(str.charAt(i - 2)) && /[^\-?\.]/.test(str.charAt(i))) return true; |
@@ -5842,7 +5875,7 @@ window.CodeMirror = (function() { |
// THE END |
- CodeMirror.version = "3.15.1"; |
+ CodeMirror.version = "3.16.1"; |
return CodeMirror; |
})(); |