##// END OF EJS Templates
Update minified YUI to version 2.9 built from Source....
Update minified YUI to version 2.9 built from Source. yui.2.9.js used to be a minified version of YUI 2.9 until 5143b8df576c updated it to something else and applied more aggresive minification. We stick to a clean but minified version 2.9. The license of YUI is BSD 3-clause, as described on http://yuilibrary.com/license/ . Since the minified version combines with GPLv3'd Javascript, it is only GPLv3'd compliant to distribute this Object Code version with the Corresponding Source (or offer therefor). This yui.2.9.js is built from Source this way: git clone https://github.com/yui/builder git clone https://github.com/yui/yui2 cd yui2/ git checkout hudson-yui2-2800 ln -sf JumpToPageDropDown.js src/paginator/js/JumpToPageDropdown.js # work around inconsistent casing rm -f tmp.js for m in yahoo event dom connection animation dragdrop element datasource autocomplete container event-delegate json datatable paginator; do rm -f build/$m/$m.js; ( cd src/$m && ant build deploybuild ) && sed -e 's,@VERSION@,2.9.0,g' -e 's,@BUILD@,2800,g' build/$m/$m.js >> tmp.js done java -jar ../builder/componentbuild/lib/yuicompressor/yuicompressor-2.4.4.jar tmp.js -o yui.2.9.js The source is mirrored and available on https://kallithea-scm.org/repos/mirror .

File last commit:

r4120:bb9ef063 rhodecode-2.2.5-gpl
r4131:31f510a8 rhodecode-2.2.5-gpl
Show More
codemirror.js
5799 lines | 221.2 KiB | application/javascript | JavascriptLexer
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 // CodeMirror version 3.15
update codemirror to latest version
r4042 //
Added server side file editing with commit
r1305 // CodeMirror is the only global var we claim
updated codemirror to 2.34
r2861 window.CodeMirror = (function() {
"use strict";
update codemirror
r4025
// BROWSER SNIFFING
// Crude, but necessary to handle a number of hard-to-feature-detect
// bugs and behavior differences.
var gecko = /gecko\/\d/i.test(navigator.userAgent);
var ie = /MSIE \d/.test(navigator.userAgent);
var ie_lt8 = ie && (document.documentMode == null || document.documentMode < 8);
var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9);
var webkit = /WebKit\//.test(navigator.userAgent);
var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(navigator.userAgent);
var chrome = /Chrome\//.test(navigator.userAgent);
var opera = /Opera\//.test(navigator.userAgent);
var safari = /Apple Computer/.test(navigator.vendor);
var khtml = /KHTML\//.test(navigator.userAgent);
var mac_geLion = /Mac OS X 1\d\D([7-9]|\d\d)\D/.test(navigator.userAgent);
var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(navigator.userAgent);
var phantom = /PhantomJS/.test(navigator.userAgent);
var ios = /AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent);
// 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 opera_version = opera && navigator.userAgent.match(/Version\/(\d*\.\d*)/);
if (opera_version) opera_version = Number(opera_version[1]);
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 if (opera_version && opera_version >= 15) { opera = false; webkit = true; }
update codemirror
r4025 // Some browsers use the wrong event properties to signal cmd/ctrl on OS X
var flipCtrlCmd = mac && (qtwebkit || opera && (opera_version == null || opera_version < 12.11));
var captureMiddleClick = gecko || (ie && !ie_lt9);
// Optimize some code when these features are not used
var sawReadOnlySpans = false, sawCollapsedSpans = false;
// CONSTRUCTOR
function CodeMirror(place, options) {
if (!(this instanceof CodeMirror)) return new CodeMirror(place, options);
this.options = options = options || {};
Added server side file editing with commit
r1305 // Determine effective options based on given values and defaults.
update codemirror
r4025 for (var opt in defaults) if (!options.hasOwnProperty(opt) && defaults.hasOwnProperty(opt))
options[opt] = defaults[opt];
setGuttersForLineNumbers(options);
var docStart = typeof options.value == "string" ? 0 : options.value.first;
var display = this.display = makeDisplay(place, docStart);
display.wrapper.CodeMirror = this;
updateGutters(this);
if (options.autofocus && !mobile) focusInput(this);
this.state = {keyMaps: [],
overlays: [],
modeGen: 0,
overwrite: false, focused: false,
suppressEdits: false, pasteIncoming: false,
draggingText: false,
highlight: new Delayed()};
themeChanged(this);
if (options.lineWrapping)
this.display.wrapper.className += " CodeMirror-wrap";
var doc = options.value;
if (typeof doc == "string") doc = new Doc(options.value, options.mode);
operation(this, attachDoc)(this, doc);
// Override magic textarea content restore that IE sometimes does
// on our hidden textarea on reload
if (ie) setTimeout(bind(resetInput, this, true), 20);
registerEventHandlers(this);
// IE throws unspecified error in certain cases, when
// trying to access activeElement before onload
var hasFocus; try { hasFocus = (document.activeElement == display.input); } catch(e) { }
if (hasFocus || (options.autofocus && !mobile)) setTimeout(bind(onFocus, this), 20);
else onBlur(this);
operation(this, function() {
for (var opt in optionHandlers)
if (optionHandlers.propertyIsEnumerable(opt))
optionHandlers[opt](this, options[opt], Init);
for (var i = 0; i < initHooks.length; ++i) initHooks[i](this);
})();
}
// DISPLAY CONSTRUCTOR
function makeDisplay(place, docStart) {
var d = {};
var input = d.input = elt("textarea", null, null, "position: absolute; padding: 0; width: 1px; height: 1em; outline: none; font-size: 4px;");
if (webkit) input.style.width = "1000px";
else input.setAttribute("wrap", "off");
// if border: 0; -- iOS fails to open keyboard (issue #1287)
if (ios) input.style.border = "1px solid black";
update codemirror to latest version
r4042 input.setAttribute("autocorrect", "off"); input.setAttribute("autocapitalize", "off"); input.setAttribute("spellcheck", "false");
update codemirror
r4025
updated codemirror to 2.34
r2861 // Wraps and hides input textarea
update codemirror
r4025 d.inputDiv = elt("div", [input], null, "overflow: hidden; position: relative; width: 3px; height: 0px;");
// The actual fake scrollbars.
d.scrollbarH = elt("div", [elt("div", null, null, "height: 1px")], "CodeMirror-hscrollbar");
d.scrollbarV = elt("div", [elt("div", null, null, "width: 1px")], "CodeMirror-vscrollbar");
d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler");
update codemirror to latest version
r4042 d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler");
updated codemirror to 2.34
r2861 // DIVs containing the selection and the actual code
update codemirror to latest version
r4042 d.lineDiv = elt("div", null, "CodeMirror-code");
update codemirror
r4025 d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1");
updated codemirror to 2.34
r2861 // Blinky cursor, and element used to ensure cursor fits at the end of a line
update codemirror
r4025 d.cursor = elt("div", "\u00a0", "CodeMirror-cursor");
// Secondary cursor, shown when on a 'jump' in bi-directional text
d.otherCursor = elt("div", "\u00a0", "CodeMirror-cursor CodeMirror-secondarycursor");
updated codemirror to 2.34
r2861 // Used to measure text size
update codemirror
r4025 d.measure = elt("div", null, "CodeMirror-measure");
// Wraps everything that needs to exist inside the vertically-padded coordinate system
d.lineSpace = elt("div", [d.measure, d.selectionDiv, d.lineDiv, d.cursor, d.otherCursor],
null, "position: relative; outline: none");
updated codemirror to 2.34
r2861 // Moved around its parent to cover visible view
update codemirror
r4025 d.mover = elt("div", [elt("div", [d.lineSpace], "CodeMirror-lines")], null, "position: relative");
updated codemirror to 2.34
r2861 // Set to the height of the text, causes scrolling
update codemirror
r4025 d.sizer = elt("div", [d.mover], "CodeMirror-sizer");
// D is needed because behavior of elts with overflow: auto and padding is inconsistent across browsers
d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerCutOff + "px; width: 1px;");
// Will contain the gutters, if any
d.gutters = elt("div", null, "CodeMirror-gutters");
d.lineGutter = null;
updated codemirror to 2.34
r2861 // Provides scrolling
update codemirror to latest version
r4042 d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll");
update codemirror
r4025 d.scroller.setAttribute("tabIndex", "-1");
bumped codemirror to latest version
r1606 // The element in which the editor lives.
update codemirror
r4025 d.wrapper = elt("div", [d.inputDiv, d.scrollbarH, d.scrollbarV,
update codemirror to latest version
r4042 d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror");
update codemirror
r4025 // Work around IE7 z-index bug
if (ie_lt8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0; }
if (place.appendChild) place.appendChild(d.wrapper); else place(d.wrapper);
Updated codemirror script
r2547 // Needed to hide big blue blinking cursor on Mobile Safari
if (ios) input.style.width = "0px";
update codemirror
r4025 if (!webkit) d.scroller.draggable = true;
Updated codemirror script
r2547 // Needed to handle Tab key in KHTML
update codemirror
r4025 if (khtml) { d.inputDiv.style.height = "1px"; d.inputDiv.style.position = "absolute"; }
updated codemirror to 2.34
r2861 // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8).
update codemirror
r4025 else if (ie_lt8) d.scrollbarH.style.minWidth = d.scrollbarV.style.minWidth = "18px";
Added server side file editing with commit
r1305 // Current visible range (may be bigger than the view window).
update codemirror
r4025 d.viewOffset = d.lastSizeC = 0;
d.showingFrom = d.showingTo = docStart;
// Used to only resize the line number gutter when necessary (when
// the amount of lines crosses a boundary that makes its width change)
d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null;
// See readInput and resetInput
d.prevInput = "";
// Set to true when a non-horizontal-scrolling widget is added. As
// an optimization, widget aligning is skipped when d is false.
d.alignWidgets = false;
// Flag that indicates whether we currently expect input to appear
// (after some event like 'keypress' or 'input') and are polling
// intensively.
d.pollingFast = false;
// Self-resetting timeout for the poller
d.poll = new Delayed();
d.cachedCharWidth = d.cachedTextHeight = null;
d.measureLineCache = [];
d.measureLineCachePos = 0;
// Tracks when resetInput has punted to just putting a short
// string instead of the (large) selection.
d.inaccurateSelection = false;
bumped codemirror to latest version
r1606 // Tracks the maximum line length so that the horizontal scrollbar
// can be kept static when scrolling.
update codemirror
r4025 d.maxLine = null;
d.maxLineLength = 0;
d.maxLineChanged = false;
// Used for measuring wheel scrolling granularity
d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null;
return d;
}
// STATE UPDATES
// Used to get the editor into a consistent state again when options change.
function loadMode(cm) {
cm.doc.mode = CodeMirror.getMode(cm.options, cm.doc.modeOption);
cm.doc.iter(function(line) {
if (line.stateAfter) line.stateAfter = null;
if (line.styles) line.styles = null;
});
cm.doc.frontier = cm.doc.first;
startWorker(cm, 100);
cm.state.modeGen++;
if (cm.curOp) regChange(cm);
}
function wrappingChanged(cm) {
if (cm.options.lineWrapping) {
cm.display.wrapper.className += " CodeMirror-wrap";
cm.display.sizer.style.minWidth = "";
} else {
cm.display.wrapper.className = cm.display.wrapper.className.replace(" CodeMirror-wrap", "");
computeMaxLength(cm);
}
estimateLineHeights(cm);
regChange(cm);
clearCaches(cm);
update codemirror to latest version
r4042 setTimeout(function(){updateScrollbars(cm);}, 100);
update codemirror
r4025 }
function estimateHeight(cm) {
var th = textHeight(cm.display), wrapping = cm.options.lineWrapping;
var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3);
return function(line) {
if (lineIsHidden(cm.doc, line))
return 0;
else if (wrapping)
return (Math.ceil(line.text.length / perLine) || 1) * th;
else
return th;
};
}
function estimateLineHeights(cm) {
var doc = cm.doc, est = estimateHeight(cm);
doc.iter(function(line) {
var estHeight = est(line);
if (estHeight != line.height) updateLineHeight(line, estHeight);
});
}
function keyMapChanged(cm) {
update codemirror to latest version
r4042 var map = keyMap[cm.options.keyMap], style = map.style;
update codemirror
r4025 cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-keymap-\S+/g, "") +
(style ? " cm-keymap-" + style : "");
update codemirror to latest version
r4042 cm.state.disableInput = map.disableInput;
update codemirror
r4025 }
function themeChanged(cm) {
cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-s-\S+/g, "") +
cm.options.theme.replace(/(^|\s)\s*/g, " cm-s-");
clearCaches(cm);
}
function guttersChanged(cm) {
updateGutters(cm);
regChange(cm);
update codemirror to latest version
r4042 setTimeout(function(){alignHorizontally(cm);}, 20);
update codemirror
r4025 }
function updateGutters(cm) {
var gutters = cm.display.gutters, specs = cm.options.gutters;
removeChildren(gutters);
for (var i = 0; i < specs.length; ++i) {
var gutterClass = specs[i];
var gElt = gutters.appendChild(elt("div", null, "CodeMirror-gutter " + gutterClass));
if (gutterClass == "CodeMirror-linenumbers") {
cm.display.lineGutter = gElt;
gElt.style.width = (cm.display.lineNumWidth || 1) + "px";
}
}
gutters.style.display = i ? "" : "none";
}
function lineLength(doc, line) {
if (line.height == 0) return 0;
var len = line.text.length, merged, cur = line;
while (merged = collapsedSpanAtStart(cur)) {
var found = merged.find();
cur = getLine(doc, found.from.line);
len += found.from.ch - found.to.ch;
}
cur = line;
while (merged = collapsedSpanAtEnd(cur)) {
var found = merged.find();
len -= cur.text.length - found.from.ch;
cur = getLine(doc, found.to.line);
len += cur.text.length - found.to.ch;
}
return len;
}
function computeMaxLength(cm) {
var d = cm.display, doc = cm.doc;
d.maxLine = getLine(doc, doc.first);
d.maxLineLength = lineLength(doc, d.maxLine);
d.maxLineChanged = true;
doc.iter(function(line) {
var len = lineLength(doc, line);
if (len > d.maxLineLength) {
d.maxLineLength = len;
d.maxLine = line;
}
});
}
// 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);
}
}
if (!found && options.lineNumbers)
options.gutters.push("CodeMirror-linenumbers");
}
// SCROLLBARS
// Re-synchronize the fake scrollbars with the actual size of the
// content. Optionally force a scrollTop.
update codemirror to latest version
r4042 function updateScrollbars(cm) {
var d = cm.display, docHeight = cm.doc.height;
update codemirror
r4025 var totalHeight = docHeight + paddingVert(d);
d.sizer.style.minHeight = d.heightForcer.style.top = totalHeight + "px";
update codemirror to latest version
r4042 d.gutters.style.height = Math.max(totalHeight, d.scroller.clientHeight - scrollerCutOff) + "px";
update codemirror
r4025 var scrollHeight = Math.max(totalHeight, d.scroller.scrollHeight);
update codemirror to latest version
r4042 var needsH = d.scroller.scrollWidth > (d.scroller.clientWidth + 1);
var needsV = scrollHeight > (d.scroller.clientHeight + 1);
update codemirror
r4025 if (needsV) {
d.scrollbarV.style.display = "block";
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 = "";
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 = "";
if (needsH && needsV) {
d.scrollbarFiller.style.display = "block";
d.scrollbarFiller.style.height = d.scrollbarFiller.style.width = scrollbarWidth(d.measure) + "px";
} else d.scrollbarFiller.style.display = "";
update codemirror to latest version
r4042 if (needsH && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) {
d.gutterFiller.style.display = "block";
d.gutterFiller.style.height = scrollbarWidth(d.measure) + "px";
d.gutterFiller.style.width = d.gutters.offsetWidth + "px";
} else d.gutterFiller.style.display = "";
update codemirror
r4025
if (mac_geLion && scrollbarWidth(d.measure) === 0)
d.scrollbarV.style.minWidth = d.scrollbarH.style.minHeight = mac_geMountainLion ? "18px" : "12px";
}
function visibleLines(display, doc, viewPort) {
var top = display.scroller.scrollTop, height = display.wrapper.clientHeight;
if (typeof viewPort == "number") top = viewPort;
else if (viewPort) {top = viewPort.top; height = viewPort.bottom - viewPort.top;}
top = Math.floor(top - paddingTop(display));
var bottom = Math.ceil(top + height);
return {from: lineAtHeight(doc, top), to: lineAtHeight(doc, bottom)};
}
// LINE NUMBERS
function alignHorizontally(cm) {
var display = cm.display;
if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) return;
var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.doc.scrollLeft;
var gutterW = display.gutters.offsetWidth, l = comp + "px";
for (var n = display.lineDiv.firstChild; n; n = n.nextSibling) if (n.alignable) {
for (var i = 0, a = n.alignable; i < a.length; ++i) a[i].style.left = l;
}
if (cm.options.fixedGutter)
display.gutters.style.left = (comp + gutterW) + "px";
}
function maybeUpdateLineNumberWidth(cm) {
if (!cm.options.lineNumbers) return false;
var doc = cm.doc, last = lineNumberFor(cm.options, doc.first + doc.size - 1), display = cm.display;
if (last.length != display.lineNumChars) {
var test = display.measure.appendChild(elt("div", [elt("div", last)],
"CodeMirror-linenumber CodeMirror-gutter-elt"));
var innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW;
display.lineGutter.style.width = "";
display.lineNumInnerWidth = Math.max(innerW, display.lineGutter.offsetWidth - padding);
display.lineNumWidth = display.lineNumInnerWidth + padding;
display.lineNumChars = display.lineNumInnerWidth ? last.length : -1;
display.lineGutter.style.width = display.lineNumWidth + "px";
return true;
}
return false;
}
function lineNumberFor(options, i) {
return String(options.lineNumberFormatter(i + options.firstLineNumber));
}
function compensateForHScroll(display) {
return getRect(display.scroller).left - getRect(display.sizer).left;
}
// DISPLAY DRAWING
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 function updateDisplay(cm, changes, viewPort, forced) {
update codemirror
r4025 var oldFrom = cm.display.showingFrom, oldTo = cm.display.showingTo, updated;
var visible = visibleLines(cm.display, cm.doc, viewPort);
for (;;) {
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 if (!updateDisplayInner(cm, changes, visible, forced)) break;
forced = false;
update codemirror to latest version
r4042 updated = true;
update codemirror
r4025 updateSelection(cm);
update codemirror to latest version
r4042 updateScrollbars(cm);
update codemirror
r4025
// Clip forced viewport to actual scrollable area
if (viewPort)
viewPort = Math.min(cm.display.scroller.scrollHeight - cm.display.scroller.clientHeight,
typeof viewPort == "number" ? viewPort : viewPort.top);
visible = visibleLines(cm.display, cm.doc, viewPort);
if (visible.from >= cm.display.showingFrom && visible.to <= cm.display.showingTo)
break;
changes = [];
}
update codemirror to latest version
r4042 if (updated) {
signalLater(cm, "update", cm);
if (cm.display.showingFrom != oldFrom || cm.display.showingTo != oldTo)
signalLater(cm, "viewportChange", cm, cm.display.showingFrom, cm.display.showingTo);
}
update codemirror
r4025 return updated;
}
// Uses a set of changes plus the current scroll position to
// determine which DOM updates have to be made, and makes the
// updates.
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 function updateDisplayInner(cm, changes, visible, forced) {
update codemirror
r4025 var display = cm.display, doc = cm.doc;
if (!display.wrapper.clientWidth) {
display.showingFrom = display.showingTo = doc.first;
display.viewOffset = 0;
return;
}
// Bail out if the visible area is already rendered and nothing changed.
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 if (!forced && changes.length == 0 &&
update codemirror
r4025 visible.from > display.showingFrom && visible.to < display.showingTo)
return;
if (maybeUpdateLineNumberWidth(cm))
changes = [{from: doc.first, to: doc.first + doc.size}];
var gutterW = display.sizer.style.marginLeft = display.gutters.offsetWidth + "px";
display.scrollbarH.style.left = cm.options.fixedGutter ? gutterW : "0";
// Used to determine which lines need their line numbers updated
var positionsChangedFrom = Infinity;
if (cm.options.lineNumbers)
for (var i = 0; i < changes.length; ++i)
if (changes[i].diff) { positionsChangedFrom = changes[i].from; break; }
var end = doc.first + doc.size;
var from = Math.max(visible.from - cm.options.viewportMargin, doc.first);
var to = Math.min(end, visible.to + cm.options.viewportMargin);
if (display.showingFrom < from && from - display.showingFrom < 20) from = Math.max(doc.first, display.showingFrom);
if (display.showingTo > to && display.showingTo - to < 20) to = Math.min(end, display.showingTo);
if (sawCollapsedSpans) {
from = lineNo(visualLine(doc, getLine(doc, from)));
while (to < end && lineIsHidden(doc, getLine(doc, to))) ++to;
}
// Create a range of theoretically intact lines, and punch holes
// in that using the change info.
var intact = [{from: Math.max(display.showingFrom, doc.first),
to: Math.min(display.showingTo, end)}];
if (intact[0].from >= intact[0].to) intact = [];
else intact = computeIntact(intact, changes);
// When merged lines are present, we might have to reduce the
// intact ranges because changes in continued fragments of the
// intact lines do require the lines to be redrawn.
if (sawCollapsedSpans)
for (var i = 0; i < intact.length; ++i) {
var range = intact[i], merged;
while (merged = collapsedSpanAtEnd(getLine(doc, range.to - 1))) {
var newTo = merged.find().from.line;
if (newTo > range.from) range.to = newTo;
else { intact.splice(i--, 1); break; }
}
}
// Clip off the parts that won't be visible
var intactLines = 0;
for (var i = 0; i < intact.length; ++i) {
var range = intact[i];
if (range.from < from) range.from = from;
if (range.to > to) range.to = to;
if (range.from >= range.to) intact.splice(i--, 1);
else intactLines += range.to - range.from;
}
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 if (!forced && intactLines == to - from && from == display.showingFrom && to == display.showingTo) {
update codemirror
r4025 updateViewOffset(cm);
return;
}
intact.sort(function(a, b) {return a.from - b.from;});
// Avoid crashing on IE's "unspecified error" when in iframes
try {
var focused = document.activeElement;
} catch(e) {}
if (intactLines < (to - from) * .7) display.lineDiv.style.display = "none";
patchDisplay(cm, from, to, intact, positionsChangedFrom);
display.lineDiv.style.display = "";
if (focused && document.activeElement != focused && focused.offsetHeight) focused.focus();
var different = from != display.showingFrom || to != display.showingTo ||
display.lastSizeC != display.wrapper.clientHeight;
// This is just a bogus formula that detects when the editor is
// resized or the font size changes.
update codemirror to latest version
r4042 if (different) {
display.lastSizeC = display.wrapper.clientHeight;
startWorker(cm, 400);
}
update codemirror
r4025 display.showingFrom = from; display.showingTo = to;
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 updateHeightsInViewport(cm);
updateViewOffset(cm);
return true;
}
function updateHeightsInViewport(cm) {
var display = cm.display;
update codemirror
r4025 var prevBottom = display.lineDiv.offsetTop;
for (var node = display.lineDiv.firstChild, height; node; node = node.nextSibling) if (node.lineObj) {
if (ie_lt8) {
var bot = node.offsetTop + node.offsetHeight;
height = bot - prevBottom;
prevBottom = bot;
} else {
var box = getRect(node);
height = box.bottom - box.top;
}
var diff = node.lineObj.height - height;
if (height < 2) height = textHeight(display);
if (diff > .001 || diff < -.001) {
updateLineHeight(node.lineObj, height);
var widgets = node.lineObj.widgets;
if (widgets) for (var i = 0; i < widgets.length; ++i)
widgets[i].height = widgets[i].node.offsetHeight;
}
}
}
function updateViewOffset(cm) {
var off = cm.display.viewOffset = heightAtLine(cm, getLine(cm.doc, cm.display.showingFrom));
// Position the mover div to align with the current virtual scroll position
cm.display.mover.style.top = off + "px";
}
function computeIntact(intact, changes) {
for (var i = 0, l = changes.length || 0; i < l; ++i) {
var change = changes[i], intact2 = [], diff = change.diff || 0;
for (var j = 0, l2 = intact.length; j < l2; ++j) {
var range = intact[j];
if (change.to <= range.from && change.diff) {
intact2.push({from: range.from + diff, to: range.to + diff});
} else if (change.to <= range.from || change.from >= range.to) {
intact2.push(range);
} else {
if (change.from > range.from)
intact2.push({from: range.from, to: change.from});
if (change.to < range.to)
intact2.push({from: change.to + diff, to: range.to + diff});
}
}
intact = intact2;
}
return intact;
}
function getDimensions(cm) {
var d = cm.display, left = {}, width = {};
for (var n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) {
left[cm.options.gutters[i]] = n.offsetLeft;
width[cm.options.gutters[i]] = n.offsetWidth;
}
return {fixedPos: compensateForHScroll(d),
gutterTotalWidth: d.gutters.offsetWidth,
gutterLeft: left,
gutterWidth: width,
wrapperWidth: d.wrapper.clientWidth};
}
function patchDisplay(cm, from, to, intact, updateNumbersFrom) {
var dims = getDimensions(cm);
var display = cm.display, lineNumbers = cm.options.lineNumbers;
if (!intact.length && (!webkit || !cm.display.currentWheelTarget))
removeChildren(display.lineDiv);
var container = display.lineDiv, cur = container.firstChild;
function rm(node) {
var next = node.nextSibling;
if (webkit && mac && cm.display.currentWheelTarget == node) {
node.style.display = "none";
node.lineObj = null;
} else {
node.parentNode.removeChild(node);
}
return next;
}
var nextIntact = intact.shift(), lineN = from;
cm.doc.iter(from, to, function(line) {
if (nextIntact && nextIntact.to == lineN) nextIntact = intact.shift();
if (lineIsHidden(cm.doc, line)) {
if (line.height != 0) updateLineHeight(line, 0);
update codemirror to latest version
r4042 if (line.widgets && cur.previousSibling) for (var i = 0; i < line.widgets.length; ++i) {
var w = line.widgets[i];
if (w.showIfHidden) {
update codemirror
r4025 var prev = cur.previousSibling;
if (/pre/i.test(prev.nodeName)) {
var wrap = elt("div", null, null, "position: relative");
prev.parentNode.replaceChild(wrap, prev);
wrap.appendChild(prev);
prev = wrap;
}
update codemirror to latest version
r4042 var wnode = prev.appendChild(elt("div", [w.node], "CodeMirror-linewidget"));
if (!w.handleMouseEvents) wnode.ignoreEvents = true;
positionLineWidget(w, wnode, prev, dims);
update codemirror
r4025 }
update codemirror to latest version
r4042 }
update codemirror
r4025 } else if (nextIntact && nextIntact.from <= lineN && nextIntact.to > lineN) {
// This line is intact. Skip to the actual node. Update its
// line number if needed.
while (cur.lineObj != line) cur = rm(cur);
if (lineNumbers && updateNumbersFrom <= lineN && cur.lineNumber)
setTextContent(cur.lineNumber, lineNumberFor(cm.options, lineN));
cur = cur.nextSibling;
} else {
// For lines with widgets, make an attempt to find and reuse
// the existing element, so that widgets aren't needlessly
// removed and re-inserted into the dom
if (line.widgets) for (var j = 0, search = cur, reuse; search && j < 20; ++j, search = search.nextSibling)
if (search.lineObj == line && /div/i.test(search.nodeName)) { reuse = search; break; }
// This line needs to be generated.
var lineNode = buildLineElement(cm, line, lineN, dims, reuse);
if (lineNode != reuse) {
container.insertBefore(lineNode, cur);
} else {
while (cur != reuse) cur = rm(cur);
cur = cur.nextSibling;
}
lineNode.lineObj = line;
}
++lineN;
});
while (cur) cur = rm(cur);
}
function buildLineElement(cm, line, lineNo, dims, reuse) {
var lineElement = lineContent(cm, line);
var markers = line.gutterMarkers, display = cm.display, wrap;
if (!cm.options.lineNumbers && !markers && !line.bgClass && !line.wrapClass && !line.widgets)
return lineElement;
// Lines with gutter elements, widgets or a background class need
// to be wrapped again, and have the extra elements added to the
// wrapper div
if (reuse) {
reuse.alignable = null;
update codemirror to latest version
r4042 var isOk = true, widgetsSeen = 0, insertBefore = null;
update codemirror
r4025 for (var n = reuse.firstChild, next; n; n = next) {
next = n.nextSibling;
if (!/\bCodeMirror-linewidget\b/.test(n.className)) {
reuse.removeChild(n);
} else {
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 for (var i = 0; i < line.widgets.length; ++i) {
update codemirror to latest version
r4042 var widget = line.widgets[i];
update codemirror
r4025 if (widget.node == n.firstChild) {
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 if (!widget.above && !insertBefore) insertBefore = n;
update codemirror
r4025 positionLineWidget(widget, n, reuse, dims);
++widgetsSeen;
break;
}
}
if (i == line.widgets.length) { isOk = false; break; }
}
}
update codemirror to latest version
r4042 reuse.insertBefore(lineElement, insertBefore);
update codemirror
r4025 if (isOk && widgetsSeen == line.widgets.length) {
wrap = reuse;
reuse.className = line.wrapClass || "";
}
}
if (!wrap) {
wrap = elt("div", null, line.wrapClass, "position: relative");
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 (cm.options.lineNumbers || markers) {
var gutterWrap = wrap.insertBefore(elt("div", null, null, "position: absolute; left: " +
(cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px"),
wrap.firstChild);
if (cm.options.fixedGutter) (wrap.alignable || (wrap.alignable = [])).push(gutterWrap);
if (cm.options.lineNumbers && (!markers || !markers["CodeMirror-linenumbers"]))
wrap.lineNumber = gutterWrap.appendChild(
elt("div", lineNumberFor(cm.options, lineNo),
"CodeMirror-linenumber CodeMirror-gutter-elt",
"left: " + dims.gutterLeft["CodeMirror-linenumbers"] + "px; width: "
+ display.lineNumInnerWidth + "px"));
if (markers)
for (var k = 0; k < cm.options.gutters.length; ++k) {
var id = cm.options.gutters[k], found = markers.hasOwnProperty(id) && markers[id];
if (found)
gutterWrap.appendChild(elt("div", [found], "CodeMirror-gutter-elt", "left: " +
dims.gutterLeft[id] + "px; width: " + dims.gutterWidth[id] + "px"));
}
}
if (ie_lt8) wrap.style.zIndex = 2;
if (line.widgets && wrap != reuse) for (var i = 0, ws = line.widgets; i < ws.length; ++i) {
var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget");
update codemirror to latest version
r4042 if (!widget.handleMouseEvents) node.ignoreEvents = true;
update codemirror
r4025 positionLineWidget(widget, node, wrap, dims);
if (widget.above)
wrap.insertBefore(node, cm.options.lineNumbers && line.height != 0 ? gutterWrap : lineElement);
else
wrap.appendChild(node);
signalLater(widget, "redraw");
}
return wrap;
}
function positionLineWidget(widget, node, wrap, dims) {
if (widget.noHScroll) {
(wrap.alignable || (wrap.alignable = [])).push(node);
var width = dims.wrapperWidth;
node.style.left = dims.fixedPos + "px";
if (!widget.coverGutter) {
width -= dims.gutterTotalWidth;
node.style.paddingLeft = dims.gutterTotalWidth + "px";
}
node.style.width = width + "px";
}
if (widget.coverGutter) {
node.style.zIndex = 5;
node.style.position = "relative";
if (!widget.noHScroll) node.style.marginLeft = -dims.gutterTotalWidth + "px";
}
}
// SELECTION / CURSOR
function updateSelection(cm) {
var display = cm.display;
var collapsed = posEq(cm.doc.sel.from, cm.doc.sel.to);
if (collapsed || cm.options.showCursorWhenSelecting)
updateSelectionCursor(cm);
else
display.cursor.style.display = display.otherCursor.style.display = "none";
if (!collapsed)
updateSelectionRange(cm);
else
display.selectionDiv.style.display = "none";
// Move the hidden textarea near the cursor to prevent scrolling artifacts
if (cm.options.moveInputWithCursor) {
var headPos = cursorCoords(cm, cm.doc.sel.head, "div");
var wrapOff = getRect(display.wrapper), lineOff = getRect(display.lineDiv);
display.inputDiv.style.top = Math.max(0, Math.min(display.wrapper.clientHeight - 10,
headPos.top + lineOff.top - wrapOff.top)) + "px";
display.inputDiv.style.left = Math.max(0, Math.min(display.wrapper.clientWidth - 10,
headPos.left + lineOff.left - wrapOff.left)) + "px";
}
}
// No selection, plain cursor
function updateSelectionCursor(cm) {
var display = cm.display, pos = cursorCoords(cm, cm.doc.sel.head, "div");
display.cursor.style.left = pos.left + "px";
display.cursor.style.top = pos.top + "px";
display.cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight + "px";
display.cursor.style.display = "";
if (pos.other) {
display.otherCursor.style.display = "";
display.otherCursor.style.left = pos.other.left + "px";
display.otherCursor.style.top = pos.other.top + "px";
display.otherCursor.style.height = (pos.other.bottom - pos.other.top) * .85 + "px";
} else { display.otherCursor.style.display = "none"; }
}
// Highlight selection
function updateSelectionRange(cm) {
var display = cm.display, doc = cm.doc, sel = cm.doc.sel;
var fragment = document.createDocumentFragment();
var clientWidth = display.lineSpace.offsetWidth, pl = paddingLeft(cm.display);
function add(left, top, width, bottom) {
if (top < 0) top = 0;
fragment.appendChild(elt("div", null, "CodeMirror-selected", "position: absolute; left: " + left +
"px; top: " + top + "px; width: " + (width == null ? clientWidth - left : width) +
"px; height: " + (bottom - top) + "px"));
}
update codemirror to latest version
r4042 function drawForLine(line, fromArg, toArg) {
update codemirror
r4025 var lineObj = getLine(doc, line);
update codemirror to latest version
r4042 var lineLen = lineObj.text.length;
var start, end;
function coords(ch, bias) {
return charCoords(cm, Pos(line, ch), "div", lineObj, bias);
update codemirror
r4025 }
iterateBidiSections(getOrder(lineObj), fromArg || 0, toArg == null ? lineLen : toArg, function(from, to, dir) {
update codemirror to latest version
r4042 var leftPos = coords(from, "left"), rightPos, left, right;
update codemirror
r4025 if (from == to) {
rightPos = leftPos;
left = right = leftPos.left;
} else {
update codemirror to latest version
r4042 rightPos = coords(to - 1, "right");
update codemirror
r4025 if (dir == "rtl") { var tmp = leftPos; leftPos = rightPos; rightPos = tmp; }
left = leftPos.left;
right = rightPos.right;
}
update codemirror to latest version
r4042 if (fromArg == null && from == 0) left = pl;
update codemirror
r4025 if (rightPos.top - leftPos.top > 3) { // Different lines, draw top part
add(left, leftPos.top, null, leftPos.bottom);
left = pl;
if (leftPos.bottom < rightPos.top) add(left, leftPos.bottom, null, rightPos.top);
}
if (toArg == null && to == lineLen) right = clientWidth;
update codemirror to latest version
r4042 if (!start || leftPos.top < start.top || leftPos.top == start.top && leftPos.left < start.left)
start = leftPos;
if (!end || rightPos.bottom > end.bottom || rightPos.bottom == end.bottom && rightPos.right > end.right)
end = rightPos;
update codemirror
r4025 if (left < pl + 1) left = pl;
add(left, rightPos.top, right - left, rightPos.bottom);
});
update codemirror to latest version
r4042 return {start: start, end: end};
update codemirror
r4025 }
if (sel.from.line == sel.to.line) {
drawForLine(sel.from.line, sel.from.ch, sel.to.ch);
} else {
update codemirror to latest version
r4042 var fromLine = getLine(doc, sel.from.line), toLine = getLine(doc, sel.to.line);
var singleVLine = visualLine(doc, fromLine) == visualLine(doc, toLine);
var leftEnd = drawForLine(sel.from.line, sel.from.ch, singleVLine ? fromLine.text.length : null).end;
var rightStart = drawForLine(sel.to.line, singleVLine ? 0 : null, sel.to.ch).start;
if (singleVLine) {
if (leftEnd.top < rightStart.top - 2) {
add(leftEnd.right, leftEnd.top, null, leftEnd.bottom);
add(pl, rightStart.top, rightStart.left, rightStart.bottom);
} else {
add(leftEnd.right, leftEnd.top, rightStart.left - leftEnd.right, leftEnd.bottom);
update codemirror
r4025 }
}
update codemirror to latest version
r4042 if (leftEnd.bottom < rightStart.top)
add(pl, leftEnd.bottom, null, rightStart.top);
update codemirror
r4025 }
removeChildrenAndAdd(display.selectionDiv, fragment);
display.selectionDiv.style.display = "";
}
// Cursor-blinking
function restartBlink(cm) {
if (!cm.state.focused) return;
var display = cm.display;
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);
}
// HIGHLIGHT WORKER
function startWorker(cm, time) {
if (cm.doc.mode.startState && cm.doc.frontier < cm.display.showingTo)
cm.state.highlight.set(time, bind(highlightWorker, cm));
}
function highlightWorker(cm) {
var doc = cm.doc;
if (doc.frontier < doc.first) doc.frontier = doc.first;
if (doc.frontier >= cm.display.showingTo) return;
var end = +new Date + cm.options.workTime;
var state = copyState(doc.mode, getStateBefore(cm, doc.frontier));
var changed = [], prevChange;
doc.iter(doc.frontier, Math.min(doc.first + doc.size, cm.display.showingTo + 500), function(line) {
if (doc.frontier >= cm.display.showingFrom) { // Visible
var oldStyles = line.styles;
line.styles = highlightLine(cm, line, state);
var ischange = !oldStyles || oldStyles.length != line.styles.length;
for (var i = 0; !ischange && i < oldStyles.length; ++i) ischange = oldStyles[i] != line.styles[i];
if (ischange) {
if (prevChange && prevChange.end == doc.frontier) prevChange.end++;
else changed.push(prevChange = {start: doc.frontier, end: doc.frontier + 1});
}
line.stateAfter = copyState(doc.mode, state);
} else {
processLine(cm, line, state);
line.stateAfter = doc.frontier % 5 == 0 ? copyState(doc.mode, state) : null;
}
++doc.frontier;
if (+new Date > end) {
startWorker(cm, cm.options.workDelay);
return true;
}
});
if (changed.length)
operation(cm, function() {
for (var i = 0; i < changed.length; ++i)
regChange(this, changed[i].start, changed[i].end);
})();
}
// Finds the line to start with when starting a parse. Tries to
// find a line with a stateAfter, so that it can start with a
// valid state. If that fails, it returns the line with the
// smallest indentation, which tends to need the least context to
// parse correctly.
update codemirror to latest version
r4042 function findStartLine(cm, n, precise) {
update codemirror
r4025 var minindent, minline, doc = cm.doc;
for (var search = n, lim = n - 100; search > lim; --search) {
if (search <= doc.first) return doc.first;
var line = getLine(doc, search - 1);
update codemirror to latest version
r4042 if (line.stateAfter && (!precise || search <= doc.frontier)) return search;
update codemirror
r4025 var indented = countColumn(line.text, null, cm.options.tabSize);
if (minline == null || minindent > indented) {
minline = search - 1;
minindent = indented;
}
}
return minline;
}
update codemirror to latest version
r4042 function getStateBefore(cm, n, precise) {
update codemirror
r4025 var doc = cm.doc, display = cm.display;
if (!doc.mode.startState) return true;
update codemirror to latest version
r4042 var pos = findStartLine(cm, n, precise), state = pos > doc.first && getLine(doc, pos-1).stateAfter;
update codemirror
r4025 if (!state) state = startState(doc.mode);
else state = copyState(doc.mode, state);
doc.iter(pos, n, function(line) {
processLine(cm, line, state);
var save = pos == n - 1 || pos % 5 == 0 || pos >= display.showingFrom && pos < display.showingTo;
line.stateAfter = save ? copyState(doc.mode, state) : null;
++pos;
});
return state;
}
// POSITION MEASUREMENT
function paddingTop(display) {return display.lineSpace.offsetTop;}
function paddingVert(display) {return display.mover.offsetHeight - display.lineSpace.offsetHeight;}
function paddingLeft(display) {
var e = removeChildrenAndAdd(display.measure, elt("pre", null, null, "text-align: left")).appendChild(elt("span", "x"));
return e.offsetLeft;
}
update codemirror to latest version
r4042 function measureChar(cm, line, ch, data, bias) {
update codemirror
r4025 var dir = -1;
data = data || measureLine(cm, line);
for (var pos = ch;; pos += dir) {
var r = data[pos];
if (r) break;
if (dir < 0 && pos == 0) dir = 1;
}
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 bias = pos > ch ? "left" : pos < ch ? "right" : bias;
if (bias == "left" && r.leftSide) r = r.leftSide;
else if (bias == "right" && r.rightSide) r = r.rightSide;
update codemirror
r4025 return {left: pos < ch ? r.right : r.left,
right: pos > ch ? r.left : r.right,
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 top: r.top,
bottom: r.bottom};
update codemirror
r4025 }
function findCachedMeasurement(cm, line) {
var cache = cm.display.measureLineCache;
for (var i = 0; i < cache.length; ++i) {
var memo = cache[i];
if (memo.text == line.text && memo.markedSpans == line.markedSpans &&
cm.display.scroller.clientWidth == memo.width &&
memo.classes == line.textClass + "|" + line.bgClass + "|" + line.wrapClass)
update codemirror to latest version
r4042 return memo;
}
}
function clearCachedMeasurement(cm, line) {
var exists = findCachedMeasurement(cm, line);
if (exists) exists.text = exists.measure = exists.markedSpans = null;
update codemirror
r4025 }
function measureLine(cm, line) {
// First look in the cache
update codemirror to latest version
r4042 var cached = findCachedMeasurement(cm, line);
if (cached) return cached.measure;
// Failing that, recompute and store result in cache
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,
classes: line.textClass + "|" + line.bgClass + "|" + line.wrapClass};
if (cache.length == 16) cache[++cm.display.measureLineCachePos % 16] = memo;
else cache.push(memo);
update codemirror
r4025 return measure;
}
function measureLineInner(cm, line) {
var display = cm.display, measure = emptyArray(line.text.length);
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 var pre = lineContent(cm, line, measure, true);
update codemirror
r4025
// IE does not cache element positions of inline elements between
// calls to getBoundingClientRect. This makes the loop below,
// which gathers the positions of all the characters on the line,
// do an amount of layout work quadratic to the number of
// characters. When line wrapping is off, we try to improve things
// by first subdividing the line into a bunch of inline blocks, so
// that IE can reuse most of the layout information from caches
// for those blocks. This does interfere with line wrapping, so it
// doesn't work when wrapping is on, but in that case the
// situation is slightly better, since IE does cache line-wrapping
// information and only recomputes per-line.
if (ie && !ie_lt8 && !cm.options.lineWrapping && pre.childNodes.length > 100) {
var fragment = document.createDocumentFragment();
var chunk = 10, n = pre.childNodes.length;
for (var i = 0, chunks = Math.ceil(n / chunk); i < chunks; ++i) {
var wrap = elt("div", null, null, "display: inline-block");
for (var j = 0; j < chunk && n; ++j) {
wrap.appendChild(pre.firstChild);
--n;
}
fragment.appendChild(wrap);
}
pre.appendChild(fragment);
}
removeChildrenAndAdd(display.measure, pre);
var outer = getRect(display.lineDiv);
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)
removeChildrenAndAdd(display.measure, pre);
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 function measureRect(rect) {
var top = rect.top - outer.top, bot = rect.bottom - outer.top;
update codemirror to latest version
r4042 if (bot > maxBot) bot = maxBot;
if (top < 0) top = 0;
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 for (var i = vranges.length - 2; i >= 0; i -= 2) {
var rtop = vranges[i], rbot = vranges[i+1];
update codemirror
r4025 if (rtop > bot || rbot < top) continue;
if (rtop <= top && rbot >= bot ||
top <= rtop && bot >= rbot ||
Math.min(bot, rbot) - Math.max(top, rtop) >= (bot - top) >> 1) {
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 vranges[i] = Math.min(top, rtop);
vranges[i+1] = Math.max(bot, rbot);
break;
update codemirror
r4025 }
}
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 if (i < 0) { i = vranges.length; vranges.push(top, bot); }
return {left: rect.left - outer.left,
right: rect.right - outer.left,
top: i, bottom: null};
}
function finishRect(rect) {
rect.bottom = vranges[rect.top+1];
rect.top = vranges[rect.top];
update codemirror to latest version
r4042 }
for (var i = 0, cur; i < measure.length; ++i) if (cur = measure[i]) {
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 var node = cur, rect = null;
update codemirror to latest version
r4042 // A widget might wrap, needs special care
if (/\bCodeMirror-widget\b/.test(cur.className) && cur.getClientRects) {
if (cur.firstChild.nodeType == 1) node = cur.firstChild;
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 var rects = node.getClientRects();
update codemirror to latest version
r4042 if (rects.length > 1) {
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 rect = data[i] = measureRect(rects[0]);
rect.rightSide = measureRect(rects[rects.length - 1]);
update codemirror to latest version
r4042 }
}
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 if (!rect) rect = data[i] = measureRect(getRect(node));
if (cur.measureRight) rect.right = getRect(cur.measureRight).left;
if (cur.leftSide) rect.leftSide = measureRect(getRect(cur.leftSide));
update codemirror
r4025 }
for (var i = 0, cur; i < data.length; ++i) if (cur = data[i]) {
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 finishRect(cur);
if (cur.leftSide) finishRect(cur.leftSide);
if (cur.rightSide) finishRect(cur.rightSide);
update codemirror to latest version
r4042 }
update codemirror
r4025 return data;
}
function measureLineWidth(cm, line) {
var hasBadSpan = false;
if (line.markedSpans) for (var i = 0; i < line.markedSpans; ++i) {
var sp = line.markedSpans[i];
if (sp.collapsed && (sp.to == null || sp.to == line.text.length)) hasBadSpan = true;
}
var cached = !hasBadSpan && findCachedMeasurement(cm, line);
update codemirror to latest version
r4042 if (cached) return measureChar(cm, line, line.text.length, cached.measure, "right").right;
update codemirror
r4025
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 var pre = lineContent(cm, line, null, true);
update codemirror
r4025 var end = pre.appendChild(zeroWidthElement(cm.display.measure));
removeChildrenAndAdd(cm.display.measure, pre);
return getRect(end).right - getRect(cm.display.lineDiv).left;
}
function clearCaches(cm) {
cm.display.measureLineCache.length = cm.display.measureLineCachePos = 0;
cm.display.cachedCharWidth = cm.display.cachedTextHeight = null;
if (!cm.options.lineWrapping) cm.display.maxLineChanged = true;
cm.display.lineNumChars = null;
}
update codemirror to latest version
r4042 function pageScrollX() { return window.pageXOffset || (document.documentElement || document.body).scrollLeft; }
function pageScrollY() { return window.pageYOffset || (document.documentElement || document.body).scrollTop; }
update codemirror
r4025 // Context is one of "line", "div" (display.lineDiv), "local"/null (editor), or "page"
function intoCoordSystem(cm, lineObj, rect, context) {
if (lineObj.widgets) for (var i = 0; i < lineObj.widgets.length; ++i) if (lineObj.widgets[i].above) {
var size = widgetHeight(lineObj.widgets[i]);
rect.top += size; rect.bottom += size;
}
if (context == "line") return rect;
if (!context) context = "local";
var yOff = heightAtLine(cm, lineObj);
update codemirror to latest version
r4042 if (context == "local") yOff += paddingTop(cm.display);
else yOff -= cm.display.viewOffset;
if (context == "page" || context == "window") {
update codemirror
r4025 var lOff = getRect(cm.display.lineSpace);
update codemirror to latest version
r4042 yOff += lOff.top + (context == "window" ? 0 : pageScrollY());
var xOff = lOff.left + (context == "window" ? 0 : pageScrollX());
update codemirror
r4025 rect.left += xOff; rect.right += xOff;
}
rect.top += yOff; rect.bottom += yOff;
return rect;
}
// Context may be "window", "page", "div", or "local"/null
// Result is in "div" coords
function fromCoordSystem(cm, coords, context) {
if (context == "div") return coords;
var left = coords.left, top = coords.top;
update codemirror to latest version
r4042 // First move into "page" coordinate system
update codemirror
r4025 if (context == "page") {
update codemirror to latest version
r4042 left -= pageScrollX();
top -= pageScrollY();
} else if (context == "local" || !context) {
var localBox = getRect(cm.display.sizer);
left += localBox.left;
top += localBox.top;
}
update codemirror
r4025 var lineSpaceBox = getRect(cm.display.lineSpace);
update codemirror to latest version
r4042 return {left: left - lineSpaceBox.left, top: top - lineSpaceBox.top};
}
function charCoords(cm, pos, context, lineObj, bias) {
update codemirror
r4025 if (!lineObj) lineObj = getLine(cm.doc, pos.line);
update codemirror to latest version
r4042 return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch, null, bias), context);
update codemirror
r4025 }
function cursorCoords(cm, pos, context, lineObj, measurement) {
lineObj = lineObj || getLine(cm.doc, pos.line);
if (!measurement) measurement = measureLine(cm, lineObj);
function get(ch, right) {
update codemirror to latest version
r4042 var m = measureChar(cm, lineObj, ch, measurement, right ? "right" : "left");
update codemirror
r4025 if (right) m.left = m.right; else m.right = m.left;
return intoCoordSystem(cm, lineObj, m, context);
}
update codemirror to latest version
r4042 function getBidi(ch, partPos) {
var part = order[partPos], right = part.level % 2;
if (ch == bidiLeft(part) && partPos && part.level < order[partPos - 1].level) {
part = order[--partPos];
ch = bidiRight(part) - (part.level % 2 ? 0 : 1);
right = true;
} else if (ch == bidiRight(part) && partPos < order.length - 1 && part.level < order[partPos + 1].level) {
part = order[++partPos];
ch = bidiLeft(part) - part.level % 2;
right = false;
}
if (right && ch == part.to && ch > part.from) return get(ch - 1);
return get(ch, right);
}
update codemirror
r4025 var order = getOrder(lineObj), ch = pos.ch;
if (!order) return get(ch);
update codemirror to latest version
r4042 var partPos = getBidiPartAt(order, ch);
var val = getBidi(ch, partPos);
if (bidiOther != null) val.other = getBidi(ch, bidiOther);
return val;
}
function PosWithInfo(line, ch, outside, xRel) {
update codemirror
r4025 var pos = new Pos(line, ch);
update codemirror to latest version
r4042 pos.xRel = xRel;
update codemirror
r4025 if (outside) pos.outside = true;
return pos;
}
// Coords must be lineSpace-local
function coordsChar(cm, x, y) {
var doc = cm.doc;
y += cm.display.viewOffset;
update codemirror to latest version
r4042 if (y < 0) return PosWithInfo(doc.first, 0, true, -1);
update codemirror
r4025 var lineNo = lineAtHeight(doc, y), last = doc.first + doc.size - 1;
if (lineNo > last)
update codemirror to latest version
r4042 return PosWithInfo(doc.first + doc.size - 1, getLine(doc, last).text.length, true, 1);
update codemirror
r4025 if (x < 0) x = 0;
for (;;) {
var lineObj = getLine(doc, lineNo);
var found = coordsCharInner(cm, lineObj, lineNo, x, y);
var merged = collapsedSpanAtEnd(lineObj);
var mergedPos = merged && merged.find();
update codemirror to latest version
r4042 if (merged && (found.ch > mergedPos.from.ch || found.ch == mergedPos.from.ch && found.xRel > 0))
update codemirror
r4025 lineNo = mergedPos.to.line;
else
return found;
}
}
function coordsCharInner(cm, lineObj, lineNo, x, y) {
var innerOff = y - heightAtLine(cm, lineObj);
var wrongLine = false, adjust = 2 * cm.display.wrapper.clientWidth;
var measurement = measureLine(cm, lineObj);
function getX(ch) {
var sp = cursorCoords(cm, Pos(lineNo, ch), "line",
lineObj, measurement);
wrongLine = true;
if (innerOff > sp.bottom) return sp.left - adjust;
else if (innerOff < sp.top) return sp.left + adjust;
else wrongLine = false;
return sp.left;
}
var bidi = getOrder(lineObj), dist = lineObj.text.length;
var from = lineLeft(lineObj), to = lineRight(lineObj);
var fromX = getX(from), fromOutside = wrongLine, toX = getX(to), toOutside = wrongLine;
update codemirror to latest version
r4042 if (x > toX) return PosWithInfo(lineNo, to, toOutside, 1);
update codemirror
r4025 // Do a binary search between these bounds.
for (;;) {
if (bidi ? to == from || to == moveVisually(lineObj, from, 1) : to - from <= 1) {
update codemirror to latest version
r4042 var ch = x < fromX || x - fromX <= toX - x ? from : to;
var xDiff = x - (ch == from ? fromX : toX);
update codemirror
r4025 while (isExtendingChar.test(lineObj.text.charAt(ch))) ++ch;
update codemirror to latest version
r4042 var pos = PosWithInfo(lineNo, ch, ch == from ? fromOutside : toOutside,
xDiff < 0 ? -1 : xDiff ? 1 : 0);
update codemirror
r4025 return pos;
}
var step = Math.ceil(dist / 2), middle = from + step;
if (bidi) {
middle = from;
for (var i = 0; i < step; ++i) middle = moveVisually(lineObj, middle, 1);
}
var middleX = getX(middle);
if (middleX > x) {to = middle; toX = middleX; if (toOutside = wrongLine) toX += 1000; dist = step;}
else {from = middle; fromX = middleX; fromOutside = wrongLine; dist -= step;}
}
}
var measureText;
function textHeight(display) {
if (display.cachedTextHeight != null) return display.cachedTextHeight;
if (measureText == null) {
measureText = elt("pre");
// Measure a bunch of lines, for browsers that compute
// fractional heights.
for (var i = 0; i < 49; ++i) {
measureText.appendChild(document.createTextNode("x"));
measureText.appendChild(elt("br"));
}
measureText.appendChild(document.createTextNode("x"));
}
removeChildrenAndAdd(display.measure, measureText);
var height = measureText.offsetHeight / 50;
if (height > 3) display.cachedTextHeight = height;
removeChildren(display.measure);
return height || 1;
}
function charWidth(display) {
if (display.cachedCharWidth != null) return display.cachedCharWidth;
var anchor = elt("span", "x");
var pre = elt("pre", [anchor]);
removeChildrenAndAdd(display.measure, pre);
var width = anchor.offsetWidth;
if (width > 2) display.cachedCharWidth = width;
return width || 10;
}
// OPERATIONS
// Operations are used to wrap changes in such a way that each
// change won't have to update the cursor and display (which would
// be awkward, slow, and error-prone), but instead updates are
// batched and then all combined and executed at once.
var nextOpId = 0;
function startOperation(cm) {
cm.curOp = {
// An array of ranges of lines that have to be updated. See
// updateDisplay.
changes: [],
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 forceUpdate: false,
update codemirror
r4025 updateInput: null,
userSelChange: null,
textChanged: null,
selectionChanged: false,
cursorActivity: false,
updateMaxLine: false,
updateScrollPos: false,
id: ++nextOpId
};
if (!delayedCallbackDepth++) delayedCallbacks = [];
}
function endOperation(cm) {
var op = cm.curOp, doc = cm.doc, display = cm.display;
cm.curOp = null;
if (op.updateMaxLine) computeMaxLength(cm);
if (display.maxLineChanged && !cm.options.lineWrapping && display.maxLine) {
var width = measureLineWidth(cm, display.maxLine);
display.sizer.style.minWidth = Math.max(0, width + 3 + scrollerCutOff) + "px";
display.maxLineChanged = false;
var maxScrollLeft = Math.max(0, display.sizer.offsetLeft + display.sizer.offsetWidth - display.scroller.clientWidth);
if (maxScrollLeft < doc.scrollLeft && !op.updateScrollPos)
setScrollLeft(cm, Math.min(display.scroller.scrollLeft, maxScrollLeft), true);
}
var newScrollPos, updated;
if (op.updateScrollPos) {
newScrollPos = op.updateScrollPos;
} else if (op.selectionChanged && display.scroller.clientHeight) { // don't rescroll if not visible
var coords = cursorCoords(cm, doc.sel.head);
newScrollPos = calculateScrollPos(cm, coords.left, coords.top, coords.left, coords.bottom);
}
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 if (op.changes.length || op.forceUpdate || newScrollPos && newScrollPos.scrollTop != null) {
updated = updateDisplay(cm, op.changes, newScrollPos && newScrollPos.scrollTop, op.forceUpdate);
update codemirror
r4025 if (cm.display.scroller.offsetHeight) cm.doc.scrollTop = cm.display.scroller.scrollTop;
}
if (!updated && op.selectionChanged) updateSelection(cm);
if (op.updateScrollPos) {
display.scroller.scrollTop = display.scrollbarV.scrollTop = doc.scrollTop = newScrollPos.scrollTop;
display.scroller.scrollLeft = display.scrollbarH.scrollLeft = doc.scrollLeft = newScrollPos.scrollLeft;
alignHorizontally(cm);
if (op.scrollToPos)
scrollPosIntoView(cm, clipPos(cm.doc, op.scrollToPos), op.scrollToPosMargin);
} else if (newScrollPos) {
scrollCursorIntoView(cm);
}
if (op.selectionChanged) restartBlink(cm);
if (cm.state.focused && op.updateInput)
resetInput(cm, op.userSelChange);
var hidden = op.maybeHiddenMarkers, unhidden = op.maybeUnhiddenMarkers;
if (hidden) for (var i = 0; i < hidden.length; ++i)
if (!hidden[i].lines.length) signal(hidden[i], "hide");
if (unhidden) for (var i = 0; i < unhidden.length; ++i)
if (unhidden[i].lines.length) signal(unhidden[i], "unhide");
var delayed;
if (!--delayedCallbackDepth) {
delayed = delayedCallbacks;
delayedCallbacks = null;
}
if (op.textChanged)
signal(cm, "change", cm, op.textChanged);
if (op.cursorActivity) signal(cm, "cursorActivity", cm);
if (delayed) for (var i = 0; i < delayed.length; ++i) delayed[i]();
}
// Wraps a function in an operation. Returns the wrapped function.
function operation(cm1, f) {
return function() {
var cm = cm1 || this, withOp = !cm.curOp;
if (withOp) startOperation(cm);
try { var result = f.apply(cm, arguments); }
finally { if (withOp) endOperation(cm); }
return result;
};
}
function docOperation(f) {
return function() {
var withOp = this.cm && !this.cm.curOp, result;
if (withOp) startOperation(this.cm);
try { result = f.apply(this, arguments); }
finally { if (withOp) endOperation(this.cm); }
return result;
};
}
function runInOp(cm, f) {
var withOp = !cm.curOp, result;
if (withOp) startOperation(cm);
try { result = f(); }
finally { if (withOp) endOperation(cm); }
return result;
}
function regChange(cm, from, to, lendiff) {
if (from == null) from = cm.doc.first;
if (to == null) to = cm.doc.first + cm.doc.size;
cm.curOp.changes.push({from: from, to: to, diff: lendiff});
}
// INPUT HANDLING
function slowPoll(cm) {
if (cm.display.pollingFast) return;
cm.display.poll.set(cm.options.pollInterval, function() {
readInput(cm);
if (cm.state.focused) slowPoll(cm);
});
}
function fastPoll(cm) {
var missed = false;
cm.display.pollingFast = true;
function p() {
var changed = readInput(cm);
if (!changed && !missed) {missed = true; cm.display.poll.set(60, p);}
else {cm.display.pollingFast = false; slowPoll(cm);}
}
cm.display.poll.set(20, p);
}
// prevInput is a hack to work with IME. If we reset the textarea
// on every change, that breaks IME. So we look for changes
// compared to the previous content instead. (Modern browsers have
// events that indicate IME taking place, but these are not widely
// supported or compatible enough yet to rely on.)
function readInput(cm) {
var input = cm.display.input, prevInput = cm.display.prevInput, doc = cm.doc, sel = doc.sel;
update codemirror to latest version
r4042 if (!cm.state.focused || hasSelection(input) || isReadOnly(cm) || cm.state.disableInput) return false;
update codemirror
r4025 var text = input.value;
if (text == prevInput && posEq(sel.from, sel.to)) return false;
if (ie && !ie_lt9 && cm.display.inputHasSelection === text) {
resetInput(cm, true);
return false;
}
var withOp = !cm.curOp;
if (withOp) startOperation(cm);
sel.shift = false;
var same = 0, l = Math.min(prevInput.length, text.length);
while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) ++same;
var from = sel.from, to = sel.to;
if (same < prevInput.length)
from = Pos(from.line, from.ch - (prevInput.length - same));
else if (cm.state.overwrite && posEq(from, to) && !cm.state.pasteIncoming)
to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + (text.length - same)));
update codemirror to latest version
r4042
update codemirror
r4025 var updateInput = cm.curOp.updateInput;
update codemirror to latest version
r4042 var changeEvent = {from: from, to: to, text: splitLines(text.slice(same)),
origin: cm.state.pasteIncoming ? "paste" : "+input"};
makeChange(cm.doc, changeEvent, "end");
update codemirror
r4025 cm.curOp.updateInput = updateInput;
update codemirror to latest version
r4042 signalLater(cm, "inputRead", cm, changeEvent);
update codemirror
r4025 if (text.length > 1000 || text.indexOf("\n") > -1) input.value = cm.display.prevInput = "";
else cm.display.prevInput = text;
if (withOp) endOperation(cm);
cm.state.pasteIncoming = false;
return true;
}
function resetInput(cm, user) {
var minimal, selected, doc = cm.doc;
if (!posEq(doc.sel.from, doc.sel.to)) {
cm.display.prevInput = "";
minimal = hasCopyEvent &&
(doc.sel.to.line - doc.sel.from.line > 100 || (selected = cm.getSelection()).length > 1000);
var content = minimal ? "-" : selected || cm.getSelection();
cm.display.input.value = content;
if (cm.state.focused) selectInput(cm.display.input);
if (ie && !ie_lt9) cm.display.inputHasSelection = content;
} else if (user) {
cm.display.prevInput = cm.display.input.value = "";
if (ie && !ie_lt9) cm.display.inputHasSelection = null;
}
cm.display.inaccurateSelection = minimal;
}
function focusInput(cm) {
if (cm.options.readOnly != "nocursor" && (!mobile || document.activeElement != cm.display.input))
cm.display.input.focus();
}
function isReadOnly(cm) {
return cm.options.readOnly || cm.doc.cantEdit;
}
// EVENT HANDLERS
function registerEventHandlers(cm) {
var d = cm.display;
on(d.scroller, "mousedown", operation(cm, onMouseDown));
if (ie)
on(d.scroller, "dblclick", operation(cm, function(e) {
update codemirror to latest version
r4042 if (signalDOMEvent(cm, e)) return;
update codemirror
r4025 var pos = posFromMouse(cm, e);
if (!pos || clickInGutter(cm, e) || eventInWidget(cm.display, e)) return;
e_preventDefault(e);
var word = findWordAt(getLine(cm.doc, pos.line).text, pos);
extendSelection(cm.doc, word.from, word.to);
}));
else
update codemirror to latest version
r4042 on(d.scroller, "dblclick", function(e) { signalDOMEvent(cm, e) || e_preventDefault(e); });
update codemirror
r4025 on(d.lineSpace, "selectstart", function(e) {
if (!eventInWidget(d, e)) e_preventDefault(e);
});
Added server side file editing with commit
r1305 // Gecko browsers fire contextmenu *after* opening the menu, at
// which point we can't mess with it anymore. Context menu is
// handled in onMouseDown for Gecko.
update codemirror
r4025 if (!captureMiddleClick) on(d.scroller, "contextmenu", function(e) {onContextMenu(cm, e);});
on(d.scroller, "scroll", function() {
if (d.scroller.clientHeight) {
setScrollTop(cm, d.scroller.scrollTop);
setScrollLeft(cm, d.scroller.scrollLeft, true);
signal(cm, "scroll", cm);
}
});
on(d.scrollbarV, "scroll", function() {
if (d.scroller.clientHeight) setScrollTop(cm, d.scrollbarV.scrollTop);
});
on(d.scrollbarH, "scroll", function() {
if (d.scroller.clientHeight) setScrollLeft(cm, d.scrollbarH.scrollLeft);
});
on(d.scroller, "mousewheel", function(e){onScrollWheel(cm, e);});
on(d.scroller, "DOMMouseScroll", function(e){onScrollWheel(cm, e);});
function reFocus() { if (cm.state.focused) setTimeout(bind(focusInput, cm), 0); }
on(d.scrollbarH, "mousedown", reFocus);
on(d.scrollbarV, "mousedown", reFocus);
// Prevent wrapper from ever scrolling
on(d.wrapper, "scroll", function() { d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; });
update codemirror to latest version
r4042 var resizeTimer;
update codemirror
r4025 function onResize() {
update codemirror to latest version
r4042 if (resizeTimer == null) resizeTimer = setTimeout(function() {
resizeTimer = null;
// Might be a text scaling operation, clear size caches.
d.cachedCharWidth = d.cachedTextHeight = knownScrollbarWidth = null;
clearCaches(cm);
runInOp(cm, bind(regChange, cm));
}, 100);
update codemirror
r4025 }
on(window, "resize", onResize);
// Above handler holds on to the editor and its data structures.
// Here we poll to unregister it when the editor is no longer in
// the document, so that it can be garbage-collected.
function unregister() {
for (var p = d.wrapper.parentNode; p && p != document.body; p = p.parentNode) {}
if (p) setTimeout(unregister, 5000);
else off(window, "resize", onResize);
}
setTimeout(unregister, 5000);
on(d.input, "keyup", operation(cm, function(e) {
update codemirror to latest version
r4042 if (signalDOMEvent(cm, e) || cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return;
update codemirror
r4025 if (e.keyCode == 16) cm.doc.sel.shift = false;
}));
on(d.input, "input", bind(fastPoll, cm));
on(d.input, "keydown", operation(cm, onKeyDown));
on(d.input, "keypress", operation(cm, onKeyPress));
on(d.input, "focus", bind(onFocus, cm));
on(d.input, "blur", bind(onBlur, cm));
Added server side file editing with commit
r1305
updated codemirror to 2.34
r2861 function drag_(e) {
update codemirror to latest version
r4042 if (signalDOMEvent(cm, e) || cm.options.onDragEvent && cm.options.onDragEvent(cm, addStop(e))) return;
updated codemirror to 2.34
r2861 e_stop(e);
}
update codemirror
r4025 if (cm.options.dragDrop) {
on(d.scroller, "dragstart", function(e){onDragStart(cm, e);});
on(d.scroller, "dragenter", drag_);
on(d.scroller, "dragover", drag_);
on(d.scroller, "drop", operation(cm, onDrop));
}
on(d.scroller, "paste", function(e){
if (eventInWidget(d, e)) return;
focusInput(cm);
fastPoll(cm);
});
on(d.input, "paste", function() {
cm.state.pasteIncoming = true;
fastPoll(cm);
});
function prepareCopy() {
if (d.inaccurateSelection) {
d.prevInput = "";
d.inaccurateSelection = false;
d.input.value = cm.getSelection();
selectInput(d.input);
}
}
on(d.input, "cut", prepareCopy);
on(d.input, "copy", prepareCopy);
Updated codemirror script
r2547
// Needed to handle Tab key in KHTML
update codemirror
r4025 if (khtml) on(d.sizer, "mouseup", function() {
if (document.activeElement == d.input) d.input.blur();
focusInput(cm);
Updated codemirror script
r2547 });
update codemirror
r4025 }
function eventInWidget(display, e) {
for (var n = e_target(e); n != display.wrapper; n = n.parentNode) {
update codemirror to latest version
r4042 if (!n || n.ignoreEvents || n.parentNode == display.sizer && n != display.mover) return true;
update codemirror
r4025 }
}
function posFromMouse(cm, e, liberal) {
var display = cm.display;
if (!liberal) {
var target = e_target(e);
if (target == display.scrollbarH || target == display.scrollbarH.firstChild ||
target == display.scrollbarV || target == display.scrollbarV.firstChild ||
update codemirror to latest version
r4042 target == display.scrollbarFiller || target == display.gutterFiller) return null;
update codemirror
r4025 }
var x, y, space = getRect(display.lineSpace);
// Fails unpredictably on IE[67] when mouse is dragged around quickly.
try { x = e.clientX; y = e.clientY; } catch (e) { return null; }
return coordsChar(cm, x - space.left, y - space.top);
}
var lastClick, lastDoubleClick;
function onMouseDown(e) {
update codemirror to latest version
r4042 if (signalDOMEvent(this, e)) return;
update codemirror
r4025 var cm = this, display = cm.display, doc = cm.doc, sel = doc.sel;
sel.shift = e.shiftKey;
if (eventInWidget(display, e)) {
if (!webkit) {
display.scroller.draggable = false;
setTimeout(function(){display.scroller.draggable = true;}, 100);
}
return;
}
if (clickInGutter(cm, e)) return;
var start = posFromMouse(cm, e);
switch (e_button(e)) {
case 3:
if (captureMiddleClick) onContextMenu.call(cm, cm, e);
return;
case 2:
if (start) extendSelection(cm.doc, start);
setTimeout(bind(focusInput, cm), 20);
e_preventDefault(e);
return;
}
// For button 1, if it was clicked inside the editor
// (posFromMouse returning non-null), we have to adjust the
// selection.
if (!start) {if (e_target(e) == display.scroller) e_preventDefault(e); return;}
if (!cm.state.focused) onFocus(cm);
var now = +new Date, type = "single";
if (lastDoubleClick && lastDoubleClick.time > now - 400 && posEq(lastDoubleClick.pos, start)) {
type = "triple";
e_preventDefault(e);
setTimeout(bind(focusInput, cm), 20);
selectLine(cm, start.line);
} else if (lastClick && lastClick.time > now - 400 && posEq(lastClick.pos, start)) {
type = "double";
lastDoubleClick = {time: now, pos: start};
e_preventDefault(e);
var word = findWordAt(getLine(doc, start.line).text, start);
extendSelection(cm.doc, word.from, word.to);
} else { lastClick = {time: now, pos: start}; }
var last = start;
if (cm.options.dragDrop && dragAndDrop && !isReadOnly(cm) && !posEq(sel.from, sel.to) &&
!posLess(start, sel.from) && !posLess(sel.to, start) && type == "single") {
var dragEnd = operation(cm, function(e2) {
if (webkit) display.scroller.draggable = false;
cm.state.draggingText = false;
off(document, "mouseup", dragEnd);
off(display.scroller, "drop", dragEnd);
if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) {
e_preventDefault(e2);
extendSelection(cm.doc, start);
focusInput(cm);
bumped codemirror to latest version
r1606 }
update codemirror
r4025 });
// Let the drag handler handle this.
if (webkit) display.scroller.draggable = true;
cm.state.draggingText = dragEnd;
// IE's approach to draggable
if (display.scroller.dragDrop) display.scroller.dragDrop();
on(document, "mouseup", dragEnd);
on(display.scroller, "drop", dragEnd);
return;
}
e_preventDefault(e);
if (type == "single") extendSelection(cm.doc, clipPos(doc, start));
var startstart = sel.from, startend = sel.to, lastPos = start;
function doSelect(cur) {
if (posEq(lastPos, cur)) return;
lastPos = cur;
if (type == "single") {
extendSelection(cm.doc, clipPos(doc, start), cur);
return;
}
startstart = clipPos(doc, startstart);
startend = clipPos(doc, startend);
if (type == "double") {
var word = findWordAt(getLine(doc, cur.line).text, cur);
if (posLess(cur, startstart)) extendSelection(cm.doc, word.from, startend);
else extendSelection(cm.doc, startstart, word.to);
} else if (type == "triple") {
if (posLess(cur, startstart)) extendSelection(cm.doc, startend, clipPos(doc, Pos(cur.line, 0)));
else extendSelection(cm.doc, startstart, clipPos(doc, Pos(cur.line + 1, 0)));
Updated codemirror script
r2547 }
}
update codemirror
r4025 var editorSize = getRect(display.wrapper);
// Used to ensure timeout re-tries don't fire when another extend
// happened in the meantime (clearTimeout isn't reliable -- at
// least on Chrome, the timeouts still happen even when cleared,
// if the clear happens after their scheduled firing time).
var counter = 0;
function extend(e) {
var curCount = ++counter;
var cur = posFromMouse(cm, e, true);
if (!cur) return;
if (!posEq(cur, last)) {
if (!cm.state.focused) onFocus(cm);
last = cur;
doSelect(cur);
var visible = visibleLines(display, doc);
if (cur.line >= visible.to || cur.line < visible.from)
setTimeout(operation(cm, function(){if (counter == curCount) extend(e);}), 150);
} else {
var outside = e.clientY < editorSize.top ? -20 : e.clientY > editorSize.bottom ? 20 : 0;
if (outside) setTimeout(operation(cm, function() {
if (counter != curCount) return;
display.scroller.scrollTop += outside;
extend(e);
}), 50);
updated codemirror to 2.34
r2861 }
update codemirror
r4025 }
function done(e) {
counter = Infinity;
e_preventDefault(e);
focusInput(cm);
off(document, "mousemove", move);
off(document, "mouseup", up);
}
var move = operation(cm, function(e) {
if (!ie && !e_button(e)) done(e);
else extend(e);
});
var up = operation(cm, done);
on(document, "mousemove", move);
on(document, "mouseup", up);
}
update codemirror to latest version
r4042 function clickInGutter(cm, e) {
var display = cm.display;
try { var mX = e.clientX, mY = e.clientY; }
catch(e) { return false; }
if (mX >= Math.floor(getRect(display.gutters).right)) return false;
e_preventDefault(e);
if (!hasHandler(cm, "gutterClick")) return true;
var lineBox = getRect(display.lineDiv);
if (mY > lineBox.bottom) return true;
mY -= lineBox.top - display.viewOffset;
for (var i = 0; i < cm.options.gutters.length; ++i) {
var g = display.gutters.childNodes[i];
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;
}
}
return true;
}
// Kludge to work around strange IE behavior where it'll sometimes
// re-fire a series of drag-related events right after the drop (#1551)
var lastDrop = 0;
update codemirror
r4025 function onDrop(e) {
var cm = this;
update codemirror to latest version
r4042 if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e) || (cm.options.onDragEvent && cm.options.onDragEvent(cm, addStop(e))))
update codemirror
r4025 return;
e_preventDefault(e);
update codemirror to latest version
r4042 if (ie) lastDrop = +new Date;
update codemirror
r4025 var pos = posFromMouse(cm, e, true), files = e.dataTransfer.files;
if (!pos || isReadOnly(cm)) return;
if (files && files.length && window.FileReader && window.File) {
var n = files.length, text = Array(n), read = 0;
var loadFile = function(file, i) {
var reader = new FileReader;
reader.onload = function() {
text[i] = reader.result;
if (++read == n) {
pos = clipPos(cm.doc, pos);
makeChange(cm.doc, {from: pos, to: pos, text: splitLines(text.join("\n")), origin: "paste"}, "around");
}
};
reader.readAsText(file);
};
for (var i = 0; i < n; ++i) loadFile(files[i], i);
} else {
// Don't do a replace if the drop happened inside of the selected text.
if (cm.state.draggingText && !(posLess(pos, cm.doc.sel.from) || posLess(cm.doc.sel.to, pos))) {
cm.state.draggingText(e);
// Ensure the editor is re-focused
setTimeout(bind(focusInput, cm), 20);
bumped codemirror to latest version
r1606 return;
}
update codemirror
r4025 try {
var text = e.dataTransfer.getData("Text");
if (text) {
var curFrom = cm.doc.sel.from, curTo = cm.doc.sel.to;
setSelection(cm.doc, pos, pos);
if (cm.state.draggingText) replaceRange(cm.doc, "", curFrom, curTo, "paste");
cm.replaceSelection(text, null, "paste");
focusInput(cm);
onFocus(cm);
updated codemirror to 2.34
r2861 }
}
update codemirror
r4025 catch(e){}
}
}
function onDragStart(cm, e) {
update codemirror to latest version
r4042 if (ie && (!cm.state.draggingText || +new Date - lastDrop < 100)) { e_stop(e); return; }
if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) return;
update codemirror
r4025
var txt = cm.getSelection();
e.dataTransfer.setData("Text", txt);
// Use dummy image instead of default browsers image.
// Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there.
update codemirror to latest version
r4042 if (e.dataTransfer.setDragImage && !safari) {
update codemirror
r4025 var img = elt("img", null, null, "position: fixed; left: 0; top: 0;");
if (opera) {
img.width = img.height = 1;
cm.display.wrapper.appendChild(img);
// Force a relayout, or Opera won't use our image for some obscure reason
img._top = img.offsetTop;
}
e.dataTransfer.setDragImage(img, 0, 0);
if (opera) img.parentNode.removeChild(img);
}
}
function setScrollTop(cm, val) {
if (Math.abs(cm.doc.scrollTop - val) < 2) return;
cm.doc.scrollTop = val;
if (!gecko) updateDisplay(cm, [], val);
if (cm.display.scroller.scrollTop != val) cm.display.scroller.scrollTop = val;
if (cm.display.scrollbarV.scrollTop != val) cm.display.scrollbarV.scrollTop = val;
if (gecko) updateDisplay(cm, []);
update codemirror to latest version
r4042 startWorker(cm, 100);
update codemirror
r4025 }
function setScrollLeft(cm, val, isScroller) {
if (isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) return;
val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth);
cm.doc.scrollLeft = val;
alignHorizontally(cm);
if (cm.display.scroller.scrollLeft != val) cm.display.scroller.scrollLeft = val;
if (cm.display.scrollbarH.scrollLeft != val) cm.display.scrollbarH.scrollLeft = val;
}
// Since the delta values reported on mouse wheel events are
// unstandardized between browsers and even browser versions, and
// generally horribly unpredictable, this code starts by measuring
// the scroll effect that the first few mouse wheel events have,
// and, from that, detects the way it can convert deltas to pixel
// offsets afterwards.
//
// The reason we want to know the amount a wheel event will scroll
// is that it gives us a chance to update the display before the
// actual scrolling happens, reducing flickering.
var wheelSamples = 0, wheelPixelsPerUnit = null;
// Fill in a browser-detected starting value on browsers where we
// know one. These don't have to be accurate -- the result of them
// being wrong would just be a slight flicker on the first wheel
// scroll (if it is large enough).
if (ie) wheelPixelsPerUnit = -.53;
else if (gecko) wheelPixelsPerUnit = 15;
else if (chrome) wheelPixelsPerUnit = -.7;
else if (safari) wheelPixelsPerUnit = -1/3;
function onScrollWheel(cm, e) {
var dx = e.wheelDeltaX, dy = e.wheelDeltaY;
if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) dx = e.detail;
if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) dy = e.detail;
else if (dy == null) dy = e.wheelDelta;
var display = cm.display, scroll = display.scroller;
// Quit if there's nothing to scroll here
if (!(dx && scroll.scrollWidth > scroll.clientWidth ||
dy && scroll.scrollHeight > scroll.clientHeight)) return;
// Webkit browsers on OS X abort momentum scrolls when the target
// of the scroll event is removed from the scrollable element.
// This hack (see related code in patchDisplay) makes sure the
// element is kept around.
if (dy && mac && webkit) {
for (var cur = e.target; cur != scroll; cur = cur.parentNode) {
if (cur.lineObj) {
cm.display.currentWheelTarget = cur;
break;
updated codemirror to 2.34
r2861 }
}
update codemirror
r4025 }
// On some browsers, horizontal scrolling will cause redraws to
// happen before the gutter has been realigned, causing it to
// wriggle around in a most unseemly way. When we have an
// estimated pixels/delta value, we just handle horizontal
// scrolling entirely here. It'll be slightly off from native, but
// better than glitching out.
if (dx && !gecko && !opera && wheelPixelsPerUnit != null) {
if (dy)
setScrollTop(cm, Math.max(0, Math.min(scroll.scrollTop + dy * wheelPixelsPerUnit, scroll.scrollHeight - scroll.clientHeight)));
setScrollLeft(cm, Math.max(0, Math.min(scroll.scrollLeft + dx * wheelPixelsPerUnit, scroll.scrollWidth - scroll.clientWidth)));
e_preventDefault(e);
display.wheelStartX = null; // Abort measurement, if in progress
return;
}
if (dy && wheelPixelsPerUnit != null) {
var pixels = dy * wheelPixelsPerUnit;
var top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight;
if (pixels < 0) top = Math.max(0, top + pixels - 50);
else bot = Math.min(cm.doc.height, bot + pixels + 50);
updateDisplay(cm, [], {top: top, bottom: bot});
}
if (wheelSamples < 20) {
if (display.wheelStartX == null) {
display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop;
display.wheelDX = dx; display.wheelDY = dy;
setTimeout(function() {
if (display.wheelStartX == null) return;
var movedX = scroll.scrollLeft - display.wheelStartX;
var movedY = scroll.scrollTop - display.wheelStartY;
var sample = (movedY && display.wheelDY && movedY / display.wheelDY) ||
(movedX && display.wheelDX && movedX / display.wheelDX);
display.wheelStartX = display.wheelStartY = null;
if (!sample) return;
wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1);
++wheelSamples;
}, 200);
} else {
display.wheelDX += dx; display.wheelDY += dy;
}
}
}
function doHandleBinding(cm, bound, dropShift) {
if (typeof bound == "string") {
bound = commands[bound];
if (!bound) return false;
}
// Ensure previous input has been read, so that the handler sees a
// consistent view of the document
if (cm.display.pollingFast && readInput(cm)) cm.display.pollingFast = false;
var doc = cm.doc, prevShift = doc.sel.shift, done = false;
try {
if (isReadOnly(cm)) cm.state.suppressEdits = true;
if (dropShift) doc.sel.shift = false;
done = bound(cm) != Pass;
} finally {
doc.sel.shift = prevShift;
cm.state.suppressEdits = false;
}
return done;
}
function allKeyMaps(cm) {
var maps = cm.state.keyMaps.slice(0);
if (cm.options.extraKeys) maps.push(cm.options.extraKeys);
maps.push(cm.options.keyMap);
return maps;
}
var maybeTransition;
function handleKeyBinding(cm, e) {
// Handle auto keymap transitions
var startMap = getKeyMap(cm.options.keyMap), next = startMap.auto;
clearTimeout(maybeTransition);
if (next && !isModifierKey(e)) maybeTransition = setTimeout(function() {
update codemirror to latest version
r4042 if (getKeyMap(cm.options.keyMap) == startMap) {
update codemirror
r4025 cm.options.keyMap = (next.call ? next.call(null, cm) : next);
update codemirror to latest version
r4042 keyMapChanged(cm);
}
update codemirror
r4025 }, 50);
var name = keyName(e, true), handled = false;
if (!name) return false;
var keymaps = allKeyMaps(cm);
if (e.shiftKey) {
// First try to resolve full name (including 'Shift-'). Failing
// that, see if there is a cursor-motion command (starting with
// 'go') bound to the keyname without 'Shift-'.
handled = lookupKey("Shift-" + name, keymaps, function(b) {return doHandleBinding(cm, b, true);})
|| lookupKey(name, keymaps, function(b) {
update codemirror to latest version
r4042 if (typeof b == "string" ? /^go[A-Z]/.test(b) : b.motion)
return doHandleBinding(cm, b);
update codemirror
r4025 });
} else {
handled = lookupKey(name, keymaps, function(b) { return doHandleBinding(cm, b); });
}
if (handled) {
e_preventDefault(e);
restartBlink(cm);
if (ie_lt9) { e.oldKeyCode = e.keyCode; e.keyCode = 0; }
update codemirror to latest version
r4042 signalLater(cm, "keyHandled", cm, name, e);
update codemirror
r4025 }
return handled;
}
function handleCharBinding(cm, e, ch) {
var handled = lookupKey("'" + ch + "'", allKeyMaps(cm),
function(b) { return doHandleBinding(cm, b, true); });
if (handled) {
e_preventDefault(e);
restartBlink(cm);
update codemirror to latest version
r4042 signalLater(cm, "keyHandled", cm, "'" + ch + "'", e);
update codemirror
r4025 }
return handled;
}
var lastStoppedKey = null;
function onKeyDown(e) {
var cm = this;
if (!cm.state.focused) onFocus(cm);
if (ie && e.keyCode == 27) { e.returnValue = false; }
update codemirror to latest version
r4042 if (signalDOMEvent(cm, e) || cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return;
update codemirror
r4025 var code = e.keyCode;
// IE does strange things with escape.
cm.doc.sel.shift = code == 16 || e.shiftKey;
// First give onKeyEvent option a chance to handle this.
var handled = handleKeyBinding(cm, e);
if (opera) {
lastStoppedKey = handled ? code : null;
// Opera has no cut event... we try to at least catch the key combo
if (!handled && code == 88 && !hasCopyEvent && (mac ? e.metaKey : e.ctrlKey))
cm.replaceSelection("");
}
}
function onKeyPress(e) {
var cm = this;
update codemirror to latest version
r4042 if (signalDOMEvent(cm, e) || cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return;
update codemirror
r4025 var keyCode = e.keyCode, charCode = e.charCode;
if (opera && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return;}
if (((opera && (!e.which || e.which < 10)) || khtml) && handleKeyBinding(cm, e)) return;
var ch = String.fromCharCode(charCode == null ? keyCode : charCode);
if (this.options.electricChars && this.doc.mode.electricChars &&
this.options.smartIndent && !isReadOnly(this) &&
this.doc.mode.electricChars.indexOf(ch) > -1)
setTimeout(operation(cm, function() {indentLine(cm, cm.doc.sel.to.line, "smart");}), 75);
if (handleCharBinding(cm, e, ch)) return;
if (ie && !ie_lt9) cm.display.inputHasSelection = null;
fastPoll(cm);
}
function onFocus(cm) {
if (cm.options.readOnly == "nocursor") return;
if (!cm.state.focused) {
signal(cm, "focus", cm);
cm.state.focused = true;
if (cm.display.wrapper.className.search(/\bCodeMirror-focused\b/) == -1)
cm.display.wrapper.className += " CodeMirror-focused";
resetInput(cm, true);
}
slowPoll(cm);
restartBlink(cm);
}
function onBlur(cm) {
if (cm.state.focused) {
signal(cm, "blur", cm);
cm.state.focused = false;
cm.display.wrapper.className = cm.display.wrapper.className.replace(" CodeMirror-focused", "");
}
clearInterval(cm.display.blinker);
setTimeout(function() {if (!cm.state.focused) cm.doc.sel.shift = false;}, 150);
}
var detectingSelectAll;
function onContextMenu(cm, e) {
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 if (signalDOMEvent(cm, e, "contextmenu")) return;
update codemirror
r4025 var display = cm.display, sel = cm.doc.sel;
if (eventInWidget(display, e)) return;
var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop;
if (!pos || opera) return; // Opera is difficult.
if (posEq(sel.from, sel.to) || posLess(pos, sel.from) || !posLess(pos, sel.to))
operation(cm, setSelection)(cm.doc, pos, pos);
var oldCSS = display.input.style.cssText;
display.inputDiv.style.position = "absolute";
display.input.style.cssText = "position: fixed; width: 30px; height: 30px; top: " + (e.clientY - 5) +
"px; left: " + (e.clientX - 5) + "px; z-index: 1000; background: white; outline: none;" +
"border-width: 0; outline: none; overflow: hidden; opacity: .05; -ms-opacity: .05; filter: alpha(opacity=5);";
focusInput(cm);
resetInput(cm, true);
// Adds "Select all" to context menu in FF
if (posEq(sel.from, sel.to)) display.input.value = display.prevInput = " ";
update codemirror to latest version
r4042 function prepareSelectAllHack() {
if (display.input.selectionStart != null) {
var extval = display.input.value = " " + (posEq(sel.from, sel.to) ? "" : display.input.value);
display.prevInput = " ";
display.input.selectionStart = 1; display.input.selectionEnd = extval.length;
}
}
update codemirror
r4025 function rehide() {
display.inputDiv.style.position = "relative";
display.input.style.cssText = oldCSS;
if (ie_lt9) display.scrollbarV.scrollTop = display.scroller.scrollTop = scrollPos;
slowPoll(cm);
// Try to detect the user choosing select-all
update codemirror to latest version
r4042 if (display.input.selectionStart != null) {
if (!ie || ie_lt9) prepareSelectAllHack();
update codemirror
r4025 clearTimeout(detectingSelectAll);
update codemirror to latest version
r4042 var i = 0, poll = function(){
update codemirror
r4025 if (display.prevInput == " " && display.input.selectionStart == 0)
operation(cm, commands.selectAll)(cm);
else if (i++ < 10) detectingSelectAll = setTimeout(poll, 500);
else resetInput(cm);
};
detectingSelectAll = setTimeout(poll, 200);
}
}
update codemirror to latest version
r4042 if (ie && !ie_lt9) prepareSelectAllHack();
update codemirror
r4025 if (captureMiddleClick) {
e_stop(e);
var mouseup = function() {
off(window, "mouseup", mouseup);
setTimeout(rehide, 20);
};
on(window, "mouseup", mouseup);
} else {
setTimeout(rehide, 50);
}
}
// UPDATING
update codemirror to latest version
r4042 var changeEnd = CodeMirror.changeEnd = function(change) {
update codemirror
r4025 if (!change.text) return change.to;
return Pos(change.from.line + change.text.length - 1,
lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0));
update codemirror to latest version
r4042 };
update codemirror
r4025
// Make sure a position will be valid after the given change.
function clipPostChange(doc, change, pos) {
if (!posLess(change.from, pos)) return clipPos(doc, pos);
var diff = (change.text.length - 1) - (change.to.line - change.from.line);
if (pos.line > change.to.line + diff) {
var preLine = pos.line - diff, lastLine = doc.first + doc.size - 1;
if (preLine > lastLine) return Pos(lastLine, getLine(doc, lastLine).text.length);
return clipToLen(pos, getLine(doc, preLine).text.length);
}
if (pos.line == change.to.line + diff)
return clipToLen(pos, lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0) +
getLine(doc, change.to.line).text.length - change.to.ch);
var inside = pos.line - change.from.line;
return clipToLen(pos, change.text[inside].length + (inside ? 0 : change.from.ch));
}
// Hint can be null|"end"|"start"|"around"|{anchor,head}
function computeSelAfterChange(doc, change, hint) {
if (hint && typeof hint == "object") // Assumed to be {anchor, head} object
return {anchor: clipPostChange(doc, change, hint.anchor),
head: clipPostChange(doc, change, hint.head)};
if (hint == "start") return {anchor: change.from, head: change.from};
var end = changeEnd(change);
if (hint == "around") return {anchor: change.from, head: end};
if (hint == "end") return {anchor: end, head: end};
// hint is null, leave the selection alone as much as possible
var adjustPos = function(pos) {
if (posLess(pos, change.from)) return pos;
if (!posLess(change.to, pos)) return end;
var line = pos.line + change.text.length - (change.to.line - change.from.line) - 1, ch = pos.ch;
if (pos.line == change.to.line) ch += end.ch - change.to.ch;
return Pos(line, ch);
};
return {anchor: adjustPos(doc.sel.anchor), head: adjustPos(doc.sel.head)};
}
update codemirror to latest version
r4042 function filterChange(doc, change, update) {
update codemirror
r4025 var obj = {
canceled: false,
from: change.from,
to: change.to,
text: change.text,
origin: change.origin,
cancel: function() { this.canceled = true; }
};
update codemirror to latest version
r4042 if (update) obj.update = function(from, to, text, origin) {
if (from) this.from = clipPos(doc, from);
if (to) this.to = clipPos(doc, to);
if (text) this.text = text;
if (origin !== undefined) this.origin = origin;
};
update codemirror
r4025 signal(doc, "beforeChange", doc, obj);
if (doc.cm) signal(doc.cm, "beforeChange", doc.cm, obj);
if (obj.canceled) return null;
return {from: obj.from, to: obj.to, text: obj.text, origin: obj.origin};
}
// Replace the range from from to to by the strings in replacement.
// change is a {from, to, text [, origin]} object
function makeChange(doc, change, selUpdate, ignoreReadOnly) {
if (doc.cm) {
if (!doc.cm.curOp) return operation(doc.cm, makeChange)(doc, change, selUpdate, ignoreReadOnly);
if (doc.cm.state.suppressEdits) return;
}
if (hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange")) {
update codemirror to latest version
r4042 change = filterChange(doc, change, true);
update codemirror
r4025 if (!change) return;
}
// Possibly split or suppress the update based on the presence
// of read-only spans in its range.
var split = sawReadOnlySpans && !ignoreReadOnly && removeReadOnlyRanges(doc, change.from, change.to);
if (split) {
for (var i = split.length - 1; i >= 1; --i)
makeChangeNoReadonly(doc, {from: split[i].from, to: split[i].to, text: [""]});
if (split.length)
makeChangeNoReadonly(doc, {from: split[0].from, to: split[0].to, text: change.text}, selUpdate);
} else {
makeChangeNoReadonly(doc, change, selUpdate);
}
}
function makeChangeNoReadonly(doc, change, selUpdate) {
var selAfter = computeSelAfterChange(doc, change, selUpdate);
addToHistory(doc, change, selAfter, doc.cm ? doc.cm.curOp.id : NaN);
makeChangeSingleDoc(doc, change, selAfter, stretchSpansOverChange(doc, change));
var rebased = [];
linkedDocs(doc, function(doc, sharedHist) {
if (!sharedHist && indexOf(rebased, doc.history) == -1) {
rebaseHist(doc.history, change);
rebased.push(doc.history);
}
makeChangeSingleDoc(doc, change, null, stretchSpansOverChange(doc, change));
});
}
function makeChangeFromHistory(doc, type) {
if (doc.cm && doc.cm.state.suppressEdits) return;
var hist = doc.history;
var event = (type == "undo" ? hist.done : hist.undone).pop();
if (!event) return;
var anti = {changes: [], anchorBefore: event.anchorAfter, headBefore: event.headAfter,
update codemirror to latest version
r4042 anchorAfter: event.anchorBefore, headAfter: event.headBefore,
generation: hist.generation};
update codemirror
r4025 (type == "undo" ? hist.undone : hist.done).push(anti);
update codemirror to latest version
r4042 hist.generation = event.generation || ++hist.maxGeneration;
var filter = hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange");
update codemirror
r4025
for (var i = event.changes.length - 1; i >= 0; --i) {
var change = event.changes[i];
change.origin = type;
update codemirror to latest version
r4042 if (filter && !filterChange(doc, change, false)) {
(type == "undo" ? hist.done : hist.undone).length = 0;
return;
}
update codemirror
r4025 anti.changes.push(historyChangeFromChange(doc, change));
var after = i ? computeSelAfterChange(doc, change, null)
: {anchor: event.anchorBefore, head: event.headBefore};
makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change));
var rebased = [];
linkedDocs(doc, function(doc, sharedHist) {
if (!sharedHist && indexOf(rebased, doc.history) == -1) {
rebaseHist(doc.history, change);
rebased.push(doc.history);
}
makeChangeSingleDoc(doc, change, null, mergeOldSpans(doc, change));
});
}
}
function shiftDoc(doc, distance) {
function shiftPos(pos) {return Pos(pos.line + distance, pos.ch);}
doc.first += distance;
if (doc.cm) regChange(doc.cm, doc.first, doc.first, distance);
doc.sel.head = shiftPos(doc.sel.head); doc.sel.anchor = shiftPos(doc.sel.anchor);
doc.sel.from = shiftPos(doc.sel.from); doc.sel.to = shiftPos(doc.sel.to);
}
function makeChangeSingleDoc(doc, change, selAfter, spans) {
if (doc.cm && !doc.cm.curOp)
return operation(doc.cm, makeChangeSingleDoc)(doc, change, selAfter, spans);
if (change.to.line < doc.first) {
shiftDoc(doc, change.text.length - 1 - (change.to.line - change.from.line));
return;
}
if (change.from.line > doc.lastLine()) return;
// Clip the change to the size of this doc
if (change.from.line < doc.first) {
var shift = change.text.length - 1 - (doc.first - change.from.line);
shiftDoc(doc, shift);
change = {from: Pos(doc.first, 0), to: Pos(change.to.line + shift, change.to.ch),
text: [lst(change.text)], origin: change.origin};
}
var last = doc.lastLine();
if (change.to.line > last) {
change = {from: change.from, to: Pos(last, getLine(doc, last).text.length),
text: [change.text[0]], origin: change.origin};
}
change.removed = getBetween(doc, change.from, change.to);
if (!selAfter) selAfter = computeSelAfterChange(doc, change, null);
if (doc.cm) makeChangeSingleDocInEditor(doc.cm, change, spans, selAfter);
else updateDoc(doc, change, spans, selAfter);
}
function makeChangeSingleDocInEditor(cm, change, spans, selAfter) {
var doc = cm.doc, display = cm.display, from = change.from, to = change.to;
var recomputeMaxLength = false, checkWidthStart = from.line;
if (!cm.options.lineWrapping) {
checkWidthStart = lineNo(visualLine(doc, getLine(doc, from.line)));
doc.iter(checkWidthStart, to.line + 1, function(line) {
if (line == display.maxLine) {
recomputeMaxLength = true;
return true;
}
});
}
if (!posLess(doc.sel.head, change.from) && !posLess(change.to, doc.sel.head))
cm.curOp.cursorActivity = true;
updateDoc(doc, change, spans, selAfter, estimateHeight(cm));
if (!cm.options.lineWrapping) {
doc.iter(checkWidthStart, from.line + change.text.length, function(line) {
var len = lineLength(doc, line);
if (len > display.maxLineLength) {
display.maxLine = line;
display.maxLineLength = len;
display.maxLineChanged = true;
recomputeMaxLength = false;
}
});
if (recomputeMaxLength) cm.curOp.updateMaxLine = true;
}
// Adjust frontier, schedule worker
doc.frontier = Math.min(doc.frontier, from.line);
startWorker(cm, 400);
var lendiff = change.text.length - (to.line - from.line) - 1;
// Remember that these lines changed, for updating the display
regChange(cm, from.line, to.line + 1, lendiff);
if (hasHandler(cm, "change")) {
var changeObj = {from: from, to: to,
text: change.text,
removed: change.removed,
origin: change.origin};
if (cm.curOp.textChanged) {
for (var cur = cm.curOp.textChanged; cur.next; cur = cur.next) {}
cur.next = changeObj;
} else cm.curOp.textChanged = changeObj;
}
}
function replaceRange(doc, code, from, to, origin) {
if (!to) to = from;
if (posLess(to, from)) { var tmp = to; to = from; from = tmp; }
if (typeof code == "string") code = splitLines(code);
makeChange(doc, {from: from, to: to, text: code, origin: origin}, null);
}
// POSITION OBJECT
function Pos(line, ch) {
if (!(this instanceof Pos)) return new Pos(line, ch);
this.line = line; this.ch = ch;
}
CodeMirror.Pos = Pos;
function posEq(a, b) {return a.line == b.line && a.ch == b.ch;}
function posLess(a, b) {return a.line < b.line || (a.line == b.line && a.ch < b.ch);}
function copyPos(x) {return Pos(x.line, x.ch);}
// SELECTION
function clipLine(doc, n) {return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1));}
function clipPos(doc, pos) {
if (pos.line < doc.first) return Pos(doc.first, 0);
var last = doc.first + doc.size - 1;
if (pos.line > last) return Pos(last, getLine(doc, last).text.length);
return clipToLen(pos, getLine(doc, pos.line).text.length);
}
function clipToLen(pos, linelen) {
var ch = pos.ch;
if (ch == null || ch > linelen) return Pos(pos.line, linelen);
else if (ch < 0) return Pos(pos.line, 0);
else return pos;
}
function isLine(doc, l) {return l >= doc.first && l < doc.first + doc.size;}
// If shift is held, this will move the selection anchor. Otherwise,
// it'll set the whole selection.
function extendSelection(doc, pos, other, bias) {
if (doc.sel.shift || doc.sel.extend) {
var anchor = doc.sel.anchor;
if (other) {
var posBefore = posLess(pos, anchor);
if (posBefore != posLess(other, anchor)) {
anchor = pos;
pos = other;
} else if (posBefore != posLess(pos, other)) {
pos = other;
Added server side file editing with commit
r1305 }
}
update codemirror
r4025 setSelection(doc, anchor, pos, bias);
} else {
setSelection(doc, pos, other || pos, bias);
}
if (doc.cm) doc.cm.curOp.userSelChange = true;
}
function filterSelectionChange(doc, anchor, head) {
var obj = {anchor: anchor, head: head};
signal(doc, "beforeSelectionChange", doc, obj);
if (doc.cm) signal(doc.cm, "beforeSelectionChange", doc.cm, obj);
obj.anchor = clipPos(doc, obj.anchor); obj.head = clipPos(doc, obj.head);
return obj;
}
// Update the selection. Last two args are only used by
// updateDoc, since they have to be expressed in the line
// numbers before the update.
function setSelection(doc, anchor, head, bias, checkAtomic) {
if (!checkAtomic && hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange")) {
var filtered = filterSelectionChange(doc, anchor, head);
head = filtered.head;
anchor = filtered.anchor;
}
var sel = doc.sel;
sel.goalColumn = null;
// Skip over atomic spans.
if (checkAtomic || !posEq(anchor, sel.anchor))
anchor = skipAtomic(doc, anchor, bias, checkAtomic != "push");
if (checkAtomic || !posEq(head, sel.head))
head = skipAtomic(doc, head, bias, checkAtomic != "push");
if (posEq(sel.anchor, anchor) && posEq(sel.head, head)) return;
sel.anchor = anchor; sel.head = head;
var inv = posLess(head, anchor);
sel.from = inv ? head : anchor;
sel.to = inv ? anchor : head;
if (doc.cm)
doc.cm.curOp.updateInput = doc.cm.curOp.selectionChanged =
doc.cm.curOp.cursorActivity = true;
signalLater(doc, "cursorActivity", doc);
}
function reCheckSelection(cm) {
setSelection(cm.doc, cm.doc.sel.from, cm.doc.sel.to, null, "push");
}
function skipAtomic(doc, pos, bias, mayClear) {
var flipped = false, curPos = pos;
var dir = bias || 1;
doc.cantEdit = false;
search: for (;;) {
var line = getLine(doc, curPos.line);
if (line.markedSpans) {
for (var i = 0; i < line.markedSpans.length; ++i) {
var sp = line.markedSpans[i], m = sp.marker;
if ((sp.from == null || (m.inclusiveLeft ? sp.from <= curPos.ch : sp.from < curPos.ch)) &&
(sp.to == null || (m.inclusiveRight ? sp.to >= curPos.ch : sp.to > curPos.ch))) {
if (mayClear) {
signal(m, "beforeCursorEnter");
if (m.explicitlyCleared) {
if (!line.markedSpans) break;
else {--i; continue;}
}
Updated codemirror script
r2547 }
update codemirror
r4025 if (!m.atomic) continue;
var newPos = m.find()[dir < 0 ? "from" : "to"];
if (posEq(newPos, curPos)) {
newPos.ch += dir;
if (newPos.ch < 0) {
if (newPos.line > doc.first) newPos = clipPos(doc, Pos(newPos.line - 1));
else newPos = null;
} else if (newPos.ch > line.text.length) {
if (newPos.line < doc.first + doc.size - 1) newPos = Pos(newPos.line + 1, 0);
else newPos = null;
}
if (!newPos) {
if (flipped) {
// Driven in a corner -- no valid cursor position found at all
// -- try again *with* clearing, if we didn't already
if (!mayClear) return skipAtomic(doc, pos, bias, true);
// Otherwise, turn off editing until further notice, and return the start of the doc
doc.cantEdit = true;
return Pos(doc.first, 0);
}
flipped = true; newPos = pos; dir = -dir;
}
}
curPos = newPos;
continue search;
Updated codemirror script
r2547 }
Added server side file editing with commit
r1305 }
Updated codemirror script
r2547 }
update codemirror
r4025 return curPos;
}
}
// SCROLLING
function scrollCursorIntoView(cm) {
update codemirror to latest version
r4042 var coords = scrollPosIntoView(cm, cm.doc.sel.head, cm.options.cursorScrollMargin);
update codemirror
r4025 if (!cm.state.focused) return;
update codemirror to latest version
r4042 var display = cm.display, box = getRect(display.sizer), doScroll = null;
if (coords.top + box.top < 0) doScroll = true;
else if (coords.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) doScroll = false;
update codemirror
r4025 if (doScroll != null && !phantom) {
var hidden = display.cursor.style.display == "none";
if (hidden) {
display.cursor.style.display = "";
display.cursor.style.left = coords.left + "px";
display.cursor.style.top = (coords.top - display.viewOffset) + "px";
Added server side file editing with commit
r1305 }
update codemirror
r4025 display.cursor.scrollIntoView(doScroll);
if (hidden) display.cursor.style.display = "none";
}
}
function scrollPosIntoView(cm, pos, margin) {
if (margin == null) margin = 0;
for (;;) {
var changed = false, coords = cursorCoords(cm, pos);
var scrollPos = calculateScrollPos(cm, coords.left, coords.top - margin, coords.left, coords.bottom + margin);
var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft;
if (scrollPos.scrollTop != null) {
setScrollTop(cm, scrollPos.scrollTop);
if (Math.abs(cm.doc.scrollTop - startTop) > 1) changed = true;
bumped codemirror to latest version
r1606 }
update codemirror
r4025 if (scrollPos.scrollLeft != null) {
setScrollLeft(cm, scrollPos.scrollLeft);
if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) changed = true;
Added server side file editing with commit
r1305 }
update codemirror
r4025 if (!changed) return coords;
}
}
function scrollIntoView(cm, x1, y1, x2, y2) {
var scrollPos = calculateScrollPos(cm, x1, y1, x2, y2);
if (scrollPos.scrollTop != null) setScrollTop(cm, scrollPos.scrollTop);
if (scrollPos.scrollLeft != null) setScrollLeft(cm, scrollPos.scrollLeft);
}
function calculateScrollPos(cm, x1, y1, x2, y2) {
update codemirror to latest version
r4042 var display = cm.display, snapMargin = textHeight(cm.display);
update codemirror
r4025 if (y1 < 0) y1 = 0;
var screen = display.scroller.clientHeight - scrollerCutOff, screentop = display.scroller.scrollTop, result = {};
var docBottom = cm.doc.height + paddingVert(display);
update codemirror to latest version
r4042 var atTop = y1 < snapMargin, atBottom = y2 > docBottom - snapMargin;
update codemirror
r4025 if (y1 < screentop) {
result.scrollTop = atTop ? 0 : y1;
} else if (y2 > screentop + screen) {
var newTop = Math.min(y1, (atBottom ? docBottom : y2) - screen);
if (newTop != screentop) result.scrollTop = newTop;
}
var screenw = display.scroller.clientWidth - scrollerCutOff, screenleft = display.scroller.scrollLeft;
x1 += display.gutters.offsetWidth; x2 += display.gutters.offsetWidth;
var gutterw = display.gutters.offsetWidth;
var atLeft = x1 < gutterw + 10;
if (x1 < screenleft + gutterw || atLeft) {
if (atLeft) x1 = 0;
result.scrollLeft = Math.max(0, x1 - 10 - gutterw);
} else if (x2 > screenw + screenleft - 3) {
result.scrollLeft = x2 + 10 - screenw;
}
return result;
}
function updateScrollPos(cm, left, top) {
cm.curOp.updateScrollPos = {scrollLeft: left == null ? cm.doc.scrollLeft : left,
scrollTop: top == null ? cm.doc.scrollTop : top};
}
function addToScrollPos(cm, left, top) {
var pos = cm.curOp.updateScrollPos || (cm.curOp.updateScrollPos = {scrollLeft: cm.doc.scrollLeft, scrollTop: cm.doc.scrollTop});
var scroll = cm.display.scroller;
pos.scrollTop = Math.max(0, Math.min(scroll.scrollHeight - scroll.clientHeight, pos.scrollTop + top));
pos.scrollLeft = Math.max(0, Math.min(scroll.scrollWidth - scroll.clientWidth, pos.scrollLeft + left));
}
// API UTILITIES
function indentLine(cm, n, how, aggressive) {
var doc = cm.doc;
update codemirror to latest version
r4042 if (how == null) how = "add";
update codemirror
r4025 if (how == "smart") {
if (!cm.doc.mode.indent) how = "prev";
else var state = getStateBefore(cm, n);
}
var tabSize = cm.options.tabSize;
var line = getLine(doc, n), curSpace = countColumn(line.text, null, tabSize);
var curSpaceString = line.text.match(/^\s*/)[0], indentation;
if (how == "smart") {
indentation = cm.doc.mode.indent(state, line.text.slice(curSpaceString.length), line.text);
if (indentation == Pass) {
if (!aggressive) return;
how = "prev";
Added server side file editing with commit
r1305 }
update codemirror
r4025 }
if (how == "prev") {
if (n > doc.first) indentation = countColumn(getLine(doc, n-1).text, null, tabSize);
else indentation = 0;
} else if (how == "add") {
indentation = curSpace + cm.options.indentUnit;
} else if (how == "subtract") {
indentation = curSpace - cm.options.indentUnit;
update codemirror to latest version
r4042 } else if (typeof how == "number") {
indentation = curSpace + how;
update codemirror
r4025 }
indentation = Math.max(0, indentation);
var indentString = "", pos = 0;
if (cm.options.indentWithTabs)
for (var i = Math.floor(indentation / tabSize); i; --i) {pos += tabSize; indentString += "\t";}
if (pos < indentation) indentString += spaceStr(indentation - pos);
if (indentString != curSpaceString)
replaceRange(cm.doc, indentString, Pos(n, 0), Pos(n, curSpaceString.length), "+input");
line.stateAfter = null;
}
function changeLine(cm, handle, op) {
var no = handle, line = handle, doc = cm.doc;
if (typeof handle == "number") line = getLine(doc, clipLine(doc, handle));
else no = lineNo(handle);
if (no == null) return null;
if (op(line, no)) regChange(cm, no, no + 1);
else return null;
return line;
}
function findPosH(doc, pos, dir, unit, visually) {
update codemirror to latest version
r4042 var line = pos.line, ch = pos.ch, origDir = dir;
update codemirror
r4025 var lineObj = getLine(doc, line);
var possible = true;
function findNextLine() {
var l = line + dir;
if (l < doc.first || l >= doc.first + doc.size) return (possible = false);
line = l;
return lineObj = getLine(doc, l);
}
function moveOnce(boundToLine) {
var next = (visually ? moveVisually : moveLogically)(lineObj, ch, dir, true);
if (next == null) {
if (!boundToLine && findNextLine()) {
if (visually) ch = (dir < 0 ? lineRight : lineLeft)(lineObj);
else ch = dir < 0 ? lineObj.text.length : 0;
} else return (possible = false);
} else ch = next;
Updated codemirror script
r2547 return true;
}
update codemirror
r4025
if (unit == "char") moveOnce();
else if (unit == "column") moveOnce(true);
else if (unit == "word" || unit == "group") {
var sawType = null, group = unit == "group";
for (var first = true;; first = false) {
if (dir < 0 && !moveOnce(!first)) break;
var cur = lineObj.text.charAt(ch) || "\n";
var type = isWordChar(cur) ? "w"
: !group ? null
: /\s/.test(cur) ? null
: "p";
if (sawType && sawType != type) {
if (dir < 0) {dir = 1; moveOnce();}
break;
updated codemirror to 2.34
r2861 }
update codemirror
r4025 if (type) sawType = type;
if (dir > 0 && !moveOnce(!first)) break;
Updated codemirror script
r2547 }
update codemirror
r4025 }
update codemirror to latest version
r4042 var result = skipAtomic(doc, Pos(line, ch), origDir, true);
update codemirror
r4025 if (!possible) result.hitSide = true;
return result;
}
function findPosV(cm, pos, dir, unit) {
var doc = cm.doc, x = pos.left, y;
if (unit == "page") {
var pageSize = Math.min(cm.display.wrapper.clientHeight, window.innerHeight || document.documentElement.clientHeight);
y = pos.top + dir * (pageSize - (dir < 0 ? 1.5 : .5) * textHeight(cm.display));
} else if (unit == "line") {
y = dir > 0 ? pos.bottom + 3 : pos.top - 3;
}
for (;;) {
var target = coordsChar(cm, x, y);
if (!target.outside) break;
if (dir < 0 ? y <= 0 : y >= doc.height) { target.hitSide = true; break; }
y += dir * 5;
}
return target;
}
function findWordAt(line, pos) {
var start = pos.ch, end = pos.ch;
if (line) {
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 if ((pos.xRel < 0 || end == line.length) && start) --start; else ++end;
update codemirror
r4025 var startChar = line.charAt(start);
var check = isWordChar(startChar) ? isWordChar
: /\s/.test(startChar) ? function(ch) {return /\s/.test(ch);}
: function(ch) {return !/\s/.test(ch) && !isWordChar(ch);};
while (start > 0 && check(line.charAt(start - 1))) --start;
while (end < line.length && check(line.charAt(end))) ++end;
}
return {from: Pos(pos.line, start), to: Pos(pos.line, end)};
}
function selectLine(cm, line) {
extendSelection(cm.doc, Pos(line, 0), clipPos(cm.doc, Pos(line + 1, 0)));
}
// PROTOTYPE
// The publicly visible API. Note that operation(null, f) means
// 'wrap f in an operation, performed on its `this` parameter'
CodeMirror.prototype = {
update codemirror to latest version
r4042 constructor: CodeMirror,
update codemirror
r4025 focus: function(){window.focus(); focusInput(this); onFocus(this); fastPoll(this);},
setOption: function(option, value) {
var options = this.options, old = options[option];
if (options[option] == value && option != "mode") return;
options[option] = value;
if (optionHandlers.hasOwnProperty(option))
operation(this, optionHandlers[option])(this, value, old);
},
getOption: function(option) {return this.options[option];},
getDoc: function() {return this.doc;},
addKeyMap: function(map, bottom) {
this.state.keyMaps[bottom ? "push" : "unshift"](map);
},
removeKeyMap: function(map) {
var maps = this.state.keyMaps;
for (var i = 0; i < maps.length; ++i)
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 if (maps[i] == map || (typeof maps[i] != "string" && maps[i].name == map)) {
update codemirror
r4025 maps.splice(i, 1);
return true;
}
},
addOverlay: operation(null, function(spec, options) {
var mode = spec.token ? spec : CodeMirror.getMode(this.options, spec);
if (mode.startState) throw new Error("Overlays may not be stateful.");
this.state.overlays.push({mode: mode, modeSpec: spec, opaque: options && options.opaque});
this.state.modeGen++;
regChange(this);
}),
removeOverlay: operation(null, function(spec) {
var overlays = this.state.overlays;
for (var i = 0; i < overlays.length; ++i) {
update codemirror to latest version
r4042 var cur = overlays[i].modeSpec;
if (cur == spec || typeof spec == "string" && cur.name == spec) {
update codemirror
r4025 overlays.splice(i, 1);
this.state.modeGen++;
regChange(this);
return;
}
Updated codemirror script
r2547 }
update codemirror
r4025 }),
indentLine: operation(null, function(n, dir, aggressive) {
update codemirror to latest version
r4042 if (typeof dir != "string" && typeof dir != "number") {
update codemirror
r4025 if (dir == null) dir = this.options.smartIndent ? "smart" : "prev";
else dir = dir ? "add" : "subtract";
Added server side file editing with commit
r1305 }
update codemirror
r4025 if (isLine(this.doc, n)) indentLine(this, n, dir, aggressive);
}),
indentSelection: operation(null, function(how) {
var sel = this.doc.sel;
if (posEq(sel.from, sel.to)) return indentLine(this, sel.from.line, how);
var e = sel.to.line - (sel.to.ch ? 0 : 1);
for (var i = sel.from.line; i <= e; ++i) indentLine(this, i, how);
}),
// Fetch the parser token for a given character. Useful for hacks
// that want to inspect the mode state (say, for completion).
update codemirror to latest version
r4042 getTokenAt: function(pos, precise) {
update codemirror
r4025 var doc = this.doc;
pos = clipPos(doc, pos);
update codemirror to latest version
r4042 var state = getStateBefore(this, pos.line, precise), mode = this.doc.mode;
update codemirror
r4025 var line = getLine(doc, pos.line);
var stream = new StringStream(line.text, this.options.tabSize);
while (stream.pos < pos.ch && !stream.eol()) {
stream.start = stream.pos;
var style = mode.token(stream, state);
Added server side file editing with commit
r1305 }
update codemirror
r4025 return {start: stream.start,
end: stream.pos,
string: stream.current(),
className: style || null, // Deprecated, use 'type' instead
type: style || null,
state: state};
},
update codemirror to latest version
r4042 getTokenTypeAt: function(pos) {
pos = clipPos(this.doc, pos);
var styles = getLineStyles(this, getLine(this.doc, pos.line));
var before = 0, after = (styles.length - 1) / 2, ch = pos.ch;
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 if (ch == 0) return styles[2];
update codemirror to latest version
r4042 for (;;) {
var mid = (before + after) >> 1;
if ((mid ? styles[mid * 2 - 1] : 0) >= ch) after = mid;
else if (styles[mid * 2 + 1] < ch) before = mid + 1;
else return styles[mid * 2 + 2];
}
},
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 getModeAt: function(pos) {
var mode = this.doc.mode;
if (!mode.innerMode) return mode;
return CodeMirror.innerMode(mode, this.getTokenAt(pos).state).mode;
},
getHelper: function(pos, type) {
if (!helpers.hasOwnProperty(type)) return;
var help = helpers[type], mode = this.getModeAt(pos);
return mode[type] && help[mode[type]] ||
mode.helperType && help[mode.helperType] ||
help[mode.name];
},
update codemirror to latest version
r4042 getStateAfter: function(line, precise) {
update codemirror
r4025 var doc = this.doc;
line = clipLine(doc, line == null ? doc.first + doc.size - 1: line);
update codemirror to latest version
r4042 return getStateBefore(this, line + 1, precise);
update codemirror
r4025 },
cursorCoords: function(start, mode) {
var pos, sel = this.doc.sel;
if (start == null) pos = sel.head;
else if (typeof start == "object") pos = clipPos(this.doc, start);
else pos = start ? sel.from : sel.to;
return cursorCoords(this, pos, mode || "page");
},
charCoords: function(pos, mode) {
return charCoords(this, clipPos(this.doc, pos), mode || "page");
},
coordsChar: function(coords, mode) {
coords = fromCoordSystem(this, coords, mode || "page");
return coordsChar(this, coords.left, coords.top);
},
update codemirror to latest version
r4042 lineAtHeight: function(height, mode) {
height = fromCoordSystem(this, {top: height, left: 0}, mode || "page").top;
return lineAtHeight(this.doc, height + this.display.viewOffset);
},
heightAtLine: function(line, mode) {
var end = false, last = this.doc.first + this.doc.size - 1;
if (line < this.doc.first) line = this.doc.first;
else if (line > last) { line = last; end = true; }
var lineObj = getLine(this.doc, line);
return intoCoordSystem(this, getLine(this.doc, line), {top: 0, left: 0}, mode || "page").top +
(end ? lineObj.height : 0);
},
update codemirror
r4025 defaultTextHeight: function() { return textHeight(this.display); },
defaultCharWidth: function() { return charWidth(this.display); },
setGutterMarker: operation(null, function(line, gutterID, value) {
return changeLine(this, line, function(line) {
var markers = line.gutterMarkers || (line.gutterMarkers = {});
markers[gutterID] = value;
if (!value && isEmpty(markers)) line.gutterMarkers = null;
return true;
Updated codemirror script
r2547 });
update codemirror
r4025 }),
clearGutter: operation(null, function(gutterID) {
var cm = this, doc = cm.doc, i = doc.first;
doc.iter(function(line) {
if (line.gutterMarkers && line.gutterMarkers[gutterID]) {
line.gutterMarkers[gutterID] = null;
regChange(cm, i, i + 1);
if (isEmpty(line.gutterMarkers)) line.gutterMarkers = null;
Updated codemirror script
r2547 }
++i;
});
update codemirror
r4025 }),
addLineClass: operation(null, function(handle, where, cls) {
return changeLine(this, handle, function(line) {
var prop = where == "text" ? "textClass" : where == "background" ? "bgClass" : "wrapClass";
if (!line[prop]) line[prop] = cls;
update codemirror to latest version
r4042 else if (new RegExp("(?:^|\\s)" + cls + "(?:$|\\s)").test(line[prop])) return false;
update codemirror
r4025 else line[prop] += " " + cls;
Updated codemirror script
r2547 return true;
update codemirror
r4025 });
}),
removeLineClass: operation(null, function(handle, where, cls) {
return changeLine(this, handle, function(line) {
var prop = where == "text" ? "textClass" : where == "background" ? "bgClass" : "wrapClass";
var cur = line[prop];
if (!cur) return false;
else if (cls == null) line[prop] = null;
else {
update codemirror to latest version
r4042 var found = cur.match(new RegExp("(?:^|\\s+)" + cls + "(?:$|\\s+)"));
if (!found) return false;
var end = found.index + found[0].length;
line[prop] = cur.slice(0, found.index) + (!found.index || end == cur.length ? "" : " ") + cur.slice(end) || null;
Updated codemirror script
r2547 }
update codemirror
r4025 return true;
updated codemirror to 2.34
r2861 });
update codemirror
r4025 }),
addLineWidget: operation(null, function(handle, node, options) {
return addLineWidget(this, handle, node, options);
}),
removeLineWidget: function(widget) { widget.clear(); },
lineInfo: function(line) {
Added server side file editing with commit
r1305 if (typeof line == "number") {
update codemirror
r4025 if (!isLine(this.doc, line)) return null;
Added server side file editing with commit
r1305 var n = line;
update codemirror
r4025 line = getLine(this.doc, line);
Added server side file editing with commit
r1305 if (!line) return null;
Updated codemirror script
r2547 } else {
var n = lineNo(line);
if (n == null) return null;
Added server side file editing with commit
r1305 }
update codemirror
r4025 return {line: n, handle: line, text: line.text, gutterMarkers: line.gutterMarkers,
textClass: line.textClass, bgClass: line.bgClass, wrapClass: line.wrapClass,
widgets: line.widgets};
},
getViewport: function() { return {from: this.display.showingFrom, to: this.display.showingTo};},
addWidget: function(pos, node, scroll, vert, horiz) {
var display = this.display;
pos = cursorCoords(this, clipPos(this.doc, pos));
var top = pos.bottom, left = pos.left;
node.style.position = "absolute";
display.sizer.appendChild(node);
if (vert == "over") {
top = pos.top;
} else if (vert == "above" || vert == "near") {
var vspace = Math.max(display.wrapper.clientHeight, this.doc.height),
hspace = Math.max(display.sizer.clientWidth, display.lineSpace.clientWidth);
// Default to positioning above (if specified and possible); otherwise default to positioning below
if ((vert == 'above' || pos.bottom + node.offsetHeight > vspace) && pos.top > node.offsetHeight)
top = pos.top - node.offsetHeight;
else if (pos.bottom + node.offsetHeight <= vspace)
top = pos.bottom;
if (left + node.offsetWidth > hspace)
left = hspace - node.offsetWidth;
Updated codemirror script
r2547 }
update codemirror to latest version
r4042 node.style.top = top + "px";
update codemirror
r4025 node.style.left = node.style.right = "";
if (horiz == "right") {
left = display.sizer.clientWidth - node.offsetWidth;
node.style.right = "0px";
} else {
if (horiz == "left") left = 0;
else if (horiz == "middle") left = (display.sizer.clientWidth - node.offsetWidth) / 2;
node.style.left = left + "px";
Updated codemirror script
r2547 }
update codemirror
r4025 if (scroll)
scrollIntoView(this, left, top, left + node.offsetWidth, top + node.offsetHeight);
},
triggerOnKeyDown: operation(null, onKeyDown),
execCommand: function(cmd) {return commands[cmd](this);},
findPosH: function(from, amount, unit, visually) {
var dir = 1;
if (amount < 0) { dir = -1; amount = -amount; }
for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) {
cur = findPosH(this.doc, cur, dir, unit, visually);
if (cur.hitSide) break;
Updated codemirror script
r2547 }
update codemirror
r4025 return cur;
},
moveH: operation(null, function(dir, unit) {
var sel = this.doc.sel, pos;
if (sel.shift || sel.extend || posEq(sel.from, sel.to))
pos = findPosH(this.doc, sel.head, dir, unit, this.options.rtlMoveVisually);
else
pos = dir < 0 ? sel.from : sel.to;
extendSelection(this.doc, pos, pos, dir);
}),
deleteH: operation(null, function(dir, unit) {
var sel = this.doc.sel;
if (!posEq(sel.from, sel.to)) replaceRange(this.doc, "", sel.from, sel.to, "+delete");
else replaceRange(this.doc, "", sel.from, findPosH(this.doc, sel.head, dir, unit, false), "+delete");
this.curOp.userSelChange = true;
}),
findPosV: function(from, amount, unit, goalColumn) {
var dir = 1, x = goalColumn;
if (amount < 0) { dir = -1; amount = -amount; }
for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) {
var coords = cursorCoords(this, cur, "div");
if (x == null) x = coords.left;
else coords.left = x;
cur = findPosV(this, coords, dir, unit);
if (cur.hitSide) break;
bumped codemirror to latest version
r1606 }
update codemirror
r4025 return cur;
},
moveV: operation(null, function(dir, unit) {
var sel = this.doc.sel;
var pos = cursorCoords(this, sel.head, "div");
if (sel.goalColumn != null) pos.left = sel.goalColumn;
var target = findPosV(this, pos, dir, unit);
if (unit == "page") addToScrollPos(this, 0, charCoords(this, target, "div").top - pos.top);
extendSelection(this.doc, target, target, dir);
sel.goalColumn = pos.left;
}),
update codemirror to latest version
r4042 toggleOverwrite: function(value) {
if (value != null && value == this.state.overwrite) return;
update codemirror
r4025 if (this.state.overwrite = !this.state.overwrite)
this.display.cursor.className += " CodeMirror-overwrite";
else
this.display.cursor.className = this.display.cursor.className.replace(" CodeMirror-overwrite", "");
},
hasFocus: function() { return this.state.focused; },
scrollTo: operation(null, function(x, y) {
updateScrollPos(this, x, y);
}),
getScrollInfo: function() {
var scroller = this.display.scroller, co = scrollerCutOff;
return {left: scroller.scrollLeft, top: scroller.scrollTop,
height: scroller.scrollHeight - co, width: scroller.scrollWidth - co,
clientHeight: scroller.clientHeight - co, clientWidth: scroller.clientWidth - co};
},
scrollIntoView: operation(null, function(pos, margin) {
if (typeof pos == "number") pos = Pos(pos, 0);
if (!margin) margin = 0;
var coords = pos;
if (!pos || pos.line != null) {
this.curOp.scrollToPos = pos ? clipPos(this.doc, pos) : this.doc.sel.head;
this.curOp.scrollToPosMargin = margin;
coords = cursorCoords(this, this.curOp.scrollToPos);
Added server side file editing with commit
r1305 }
update codemirror
r4025 var sPos = calculateScrollPos(this, coords.left, coords.top - margin, coords.right, coords.bottom + margin);
updateScrollPos(this, sPos.scrollLeft, sPos.scrollTop);
}),
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 setSize: operation(null, function(width, height) {
update codemirror
r4025 function interpret(val) {
return typeof val == "number" || /^\d+$/.test(String(val)) ? val + "px" : val;
Updated codemirror script
r2547 }
update codemirror
r4025 if (width != null) this.display.wrapper.style.width = interpret(width);
if (height != null) this.display.wrapper.style.height = interpret(height);
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 if (this.options.lineWrapping)
this.display.measureLineCache.length = this.display.measureLineCachePos = 0;
this.curOp.forceUpdate = true;
}),
update codemirror
r4025
operation: function(f){return runInOp(this, f);},
refresh: operation(null, function() {
clearCaches(this);
updateScrollPos(this, this.doc.scrollLeft, this.doc.scrollTop);
regChange(this);
}),
swapDoc: operation(null, function(doc) {
var old = this.doc;
old.cm = null;
attachDoc(this, doc);
clearCaches(this);
resetInput(this, true);
updateScrollPos(this, doc.scrollLeft, doc.scrollTop);
return old;
}),
getInputField: function(){return this.display.input;},
getWrapperElement: function(){return this.display.wrapper;},
getScrollerElement: function(){return this.display.scroller;},
getGutterElement: function(){return this.display.gutters;}
};
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 eventMixin(CodeMirror);
update codemirror
r4025
// OPTION DEFAULTS
var optionHandlers = CodeMirror.optionHandlers = {};
Added server side file editing with commit
r1305
// The default configuration options.
update codemirror
r4025 var defaults = CodeMirror.defaults = {};
function option(name, deflt, handle, notOnInit) {
CodeMirror.defaults[name] = deflt;
if (handle) optionHandlers[name] =
notOnInit ? function(cm, val, old) {if (old != Init) handle(cm, val, old);} : handle;
}
var Init = CodeMirror.Init = {toString: function(){return "CodeMirror.Init";}};
// These two are, on init, called from the constructor because they
// have to be initialized before the editor can start at all.
option("value", "", function(cm, val) {
cm.setValue(val);
}, true);
option("mode", null, function(cm, val) {
cm.doc.modeOption = val;
loadMode(cm);
}, true);
option("indentUnit", 2, loadMode, true);
option("indentWithTabs", false);
option("smartIndent", true);
option("tabSize", 4, function(cm) {
loadMode(cm);
clearCaches(cm);
regChange(cm);
}, true);
option("electricChars", true);
option("rtlMoveVisually", !windows);
option("theme", "default", function(cm) {
themeChanged(cm);
guttersChanged(cm);
}, true);
option("keyMap", "default", keyMapChanged);
option("extraKeys", null);
option("onKeyEvent", null);
option("onDragEvent", null);
option("lineWrapping", false, wrappingChanged, true);
option("gutters", [], function(cm) {
setGuttersForLineNumbers(cm.options);
guttersChanged(cm);
}, true);
option("fixedGutter", true, function(cm, val) {
cm.display.gutters.style.left = val ? compensateForHScroll(cm.display) + "px" : "0";
cm.refresh();
}, true);
update codemirror to latest version
r4042 option("coverGutterNextToScrollbar", false, updateScrollbars, true);
update codemirror
r4025 option("lineNumbers", false, function(cm) {
setGuttersForLineNumbers(cm.options);
guttersChanged(cm);
}, true);
option("firstLineNumber", 1, guttersChanged, true);
option("lineNumberFormatter", function(integer) {return integer;}, guttersChanged, true);
option("showCursorWhenSelecting", false, updateSelection, true);
option("readOnly", false, function(cm, val) {
if (val == "nocursor") {onBlur(cm); cm.display.input.blur();}
else if (!val) resetInput(cm, true);
});
option("dragDrop", true);
option("cursorBlinkRate", 530);
update codemirror to latest version
r4042 option("cursorScrollMargin", 0);
update codemirror
r4025 option("cursorHeight", 1);
option("workTime", 100);
option("workDelay", 100);
option("flattenSpans", true);
option("pollInterval", 100);
option("undoDepth", 40, function(cm, val){cm.doc.history.undoDepth = val;});
option("historyEventDelay", 500);
option("viewportMargin", 10, function(cm){cm.refresh();}, true);
option("maxHighlightLength", 10000, function(cm){loadMode(cm); cm.refresh();}, true);
option("moveInputWithCursor", true, function(cm, val) {
if (!val) cm.display.inputDiv.style.top = cm.display.inputDiv.style.left = 0;
});
option("tabindex", null, function(cm, val) {
cm.display.input.tabIndex = val || "";
});
option("autofocus", null);
// MODE DEFINITION AND QUERYING
Updated codemirror script
r2547
Added server side file editing with commit
r1305 // Known modes, by name and by MIME
Updated codemirror script
r2547 var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {};
update codemirror
r4025
Added server side file editing with commit
r1305 CodeMirror.defineMode = function(name, mode) {
if (!CodeMirror.defaults.mode && name != "null") CodeMirror.defaults.mode = name;
Updated codemirror script
r2547 if (arguments.length > 2) {
mode.dependencies = [];
for (var i = 2; i < arguments.length; ++i) mode.dependencies.push(arguments[i]);
}
Added server side file editing with commit
r1305 modes[name] = mode;
};
update codemirror
r4025
Added server side file editing with commit
r1305 CodeMirror.defineMIME = function(mime, spec) {
mimeModes[mime] = spec;
};
update codemirror
r4025
Updated codemirror script
r2547 CodeMirror.resolveMode = function(spec) {
update codemirror to latest version
r4042 if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) {
Added server side file editing with commit
r1305 spec = mimeModes[spec];
update codemirror to latest version
r4042 } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) {
var found = mimeModes[spec.name];
spec = createObj(found, spec);
spec.name = found.name;
} else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) {
Updated codemirror script
r2547 return CodeMirror.resolveMode("application/xml");
update codemirror to latest version
r4042 }
Updated codemirror script
r2547 if (typeof spec == "string") return {name: spec};
else return spec || {name: "null"};
};
update codemirror
r4025
Updated codemirror script
r2547 CodeMirror.getMode = function(options, spec) {
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 var spec = CodeMirror.resolveMode(spec);
Updated codemirror script
r2547 var mfactory = modes[spec.name];
if (!mfactory) return CodeMirror.getMode(options, "text/plain");
updated codemirror to 2.34
r2861 var modeObj = mfactory(options, spec);
if (modeExtensions.hasOwnProperty(spec.name)) {
var exts = modeExtensions[spec.name];
update codemirror
r4025 for (var prop in exts) {
if (!exts.hasOwnProperty(prop)) continue;
if (modeObj.hasOwnProperty(prop)) modeObj["_" + prop] = modeObj[prop];
modeObj[prop] = exts[prop];
}
updated codemirror to 2.34
r2861 }
modeObj.name = spec.name;
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120
updated codemirror to 2.34
r2861 return modeObj;
bumped codemirror to latest version
r1606 };
update codemirror
r4025
CodeMirror.defineMode("null", function() {
return {token: function(stream) {stream.skipToEnd();}};
});
CodeMirror.defineMIME("text/plain", "null");
updated codemirror version
r3036
updated codemirror to 2.34
r2861 var modeExtensions = CodeMirror.modeExtensions = {};
CodeMirror.extendMode = function(mode, properties) {
var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {});
update codemirror
r4025 copyObj(properties, exts);
updated codemirror to 2.34
r2861 };
update codemirror
r4025 // EXTENSIONS
CodeMirror.defineExtension = function(name, func) {
CodeMirror.prototype[name] = func;
Updated codemirror script
r2547 };
update codemirror
r4025 CodeMirror.defineDocExtension = function(name, func) {
Doc.prototype[name] = func;
Added server side file editing with commit
r1305 };
update codemirror
r4025 CodeMirror.defineOption = option;
var initHooks = [];
CodeMirror.defineInitHook = function(f) {initHooks.push(f);};
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 var helpers = CodeMirror.helpers = {};
CodeMirror.registerHelper = function(type, name, value) {
if (!helpers.hasOwnProperty(type)) helpers[type] = CodeMirror[type] = {};
helpers[type][name] = value;
};
// UTILITIES
CodeMirror.isWordChar = isWordChar;
update codemirror
r4025 // MODE STATE HANDLING
updated codemirror to 2.34
r2861
Added server side file editing with commit
r1305 // Utility functions for working with state. Exported because modes
// sometimes need to do this.
function copyState(mode, state) {
if (state === true) return state;
if (mode.copyState) return mode.copyState(state);
var nstate = {};
for (var n in state) {
var val = state[n];
if (val instanceof Array) val = val.concat([]);
nstate[n] = val;
}
return nstate;
}
Updated codemirror script
r2547 CodeMirror.copyState = copyState;
update codemirror
r4025
Added server side file editing with commit
r1305 function startState(mode, a1, a2) {
return mode.startState ? mode.startState(a1, a2) : true;
}
Updated codemirror script
r2547 CodeMirror.startState = startState;
update codemirror
r4025
updated codemirror to 2.34
r2861 CodeMirror.innerMode = function(mode, state) {
while (mode.innerMode) {
var info = mode.innerMode(state);
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 if (!info || info.mode == mode) break;
updated codemirror to 2.34
r2861 state = info.state;
mode = info.mode;
}
return info || {mode: mode, state: state};
};
Added server side file editing with commit
r1305
update codemirror
r4025 // STANDARD COMMANDS
var commands = CodeMirror.commands = {
selectAll: function(cm) {cm.setSelection(Pos(cm.firstLine(), 0), Pos(cm.lastLine()));},
killLine: function(cm) {
var from = cm.getCursor(true), to = cm.getCursor(false), sel = !posEq(from, to);
if (!sel && cm.getLine(from.line).length == from.ch)
cm.replaceRange("", from, Pos(from.line + 1, 0), "+delete");
else cm.replaceRange("", from, sel ? to : Pos(from.line), "+delete");
},
deleteLine: function(cm) {
var l = cm.getCursor().line;
cm.replaceRange("", Pos(l, 0), Pos(l), "+delete");
},
update codemirror to latest version
r4042 delLineLeft: function(cm) {
var cur = cm.getCursor();
cm.replaceRange("", Pos(cur.line, 0), cur, "+delete");
},
update codemirror
r4025 undo: function(cm) {cm.undo();},
redo: function(cm) {cm.redo();},
goDocStart: function(cm) {cm.extendSelection(Pos(cm.firstLine(), 0));},
goDocEnd: function(cm) {cm.extendSelection(Pos(cm.lastLine()));},
goLineStart: function(cm) {
cm.extendSelection(lineStart(cm, cm.getCursor().line));
},
goLineStartSmart: function(cm) {
var cur = cm.getCursor(), start = lineStart(cm, cur.line);
var line = cm.getLineHandle(start.line);
var order = getOrder(line);
if (!order || order[0].level == 0) {
var firstNonWS = Math.max(0, line.text.search(/\S/));
var inWS = cur.line == start.line && cur.ch <= firstNonWS && cur.ch;
cm.extendSelection(Pos(start.line, inWS ? 0 : firstNonWS));
} else cm.extendSelection(start);
},
goLineEnd: function(cm) {
cm.extendSelection(lineEnd(cm, cm.getCursor().line));
},
goLineRight: function(cm) {
var top = cm.charCoords(cm.getCursor(), "div").top + 5;
cm.extendSelection(cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div"));
},
goLineLeft: function(cm) {
var top = cm.charCoords(cm.getCursor(), "div").top + 5;
cm.extendSelection(cm.coordsChar({left: 0, top: top}, "div"));
},
goLineUp: function(cm) {cm.moveV(-1, "line");},
goLineDown: function(cm) {cm.moveV(1, "line");},
goPageUp: function(cm) {cm.moveV(-1, "page");},
goPageDown: function(cm) {cm.moveV(1, "page");},
goCharLeft: function(cm) {cm.moveH(-1, "char");},
goCharRight: function(cm) {cm.moveH(1, "char");},
goColumnLeft: function(cm) {cm.moveH(-1, "column");},
goColumnRight: function(cm) {cm.moveH(1, "column");},
goWordLeft: function(cm) {cm.moveH(-1, "word");},
goGroupRight: function(cm) {cm.moveH(1, "group");},
goGroupLeft: function(cm) {cm.moveH(-1, "group");},
goWordRight: function(cm) {cm.moveH(1, "word");},
delCharBefore: function(cm) {cm.deleteH(-1, "char");},
delCharAfter: function(cm) {cm.deleteH(1, "char");},
delWordBefore: function(cm) {cm.deleteH(-1, "word");},
delWordAfter: function(cm) {cm.deleteH(1, "word");},
delGroupBefore: function(cm) {cm.deleteH(-1, "group");},
delGroupAfter: function(cm) {cm.deleteH(1, "group");},
indentAuto: function(cm) {cm.indentSelection("smart");},
indentMore: function(cm) {cm.indentSelection("add");},
indentLess: function(cm) {cm.indentSelection("subtract");},
insertTab: function(cm) {cm.replaceSelection("\t", "end", "+input");},
defaultTab: function(cm) {
if (cm.somethingSelected()) cm.indentSelection("add");
else cm.replaceSelection("\t", "end", "+input");
},
transposeChars: function(cm) {
var cur = cm.getCursor(), line = cm.getLine(cur.line);
if (cur.ch > 0 && cur.ch < line.length - 1)
cm.replaceRange(line.charAt(cur.ch) + line.charAt(cur.ch - 1),
Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1));
},
newlineAndIndent: function(cm) {
operation(cm, function() {
cm.replaceSelection("\n", "end", "+input");
cm.indentLine(cm.getCursor().line, null, true);
})();
},
toggleOverwrite: function(cm) {cm.toggleOverwrite();}
};
// STANDARD KEYMAPS
var keyMap = CodeMirror.keyMap = {};
keyMap.basic = {
"Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown",
"End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown",
"Delete": "delCharAfter", "Backspace": "delCharBefore", "Tab": "defaultTab", "Shift-Tab": "indentAuto",
"Enter": "newlineAndIndent", "Insert": "toggleOverwrite"
};
// Note that the save and find-related commands aren't defined by
// default. Unknown commands are simply ignored.
keyMap.pcDefault = {
"Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo",
"Ctrl-Home": "goDocStart", "Alt-Up": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Down": "goDocEnd",
"Ctrl-Left": "goGroupLeft", "Ctrl-Right": "goGroupRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd",
"Ctrl-Backspace": "delGroupBefore", "Ctrl-Delete": "delGroupAfter", "Ctrl-S": "save", "Ctrl-F": "find",
"Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll",
"Ctrl-[": "indentLess", "Ctrl-]": "indentMore",
fallthrough: "basic"
};
keyMap.macDefault = {
"Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo",
"Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goGroupLeft",
"Alt-Right": "goGroupRight", "Cmd-Left": "goLineStart", "Cmd-Right": "goLineEnd", "Alt-Backspace": "delGroupBefore",
"Ctrl-Alt-Backspace": "delGroupAfter", "Alt-Delete": "delGroupAfter", "Cmd-S": "save", "Cmd-F": "find",
"Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll",
update codemirror to latest version
r4042 "Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delLineLeft",
update codemirror
r4025 fallthrough: ["basic", "emacsy"]
};
keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault;
keyMap.emacsy = {
"Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown",
"Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd",
"Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp", "Ctrl-D": "delCharAfter", "Ctrl-H": "delCharBefore",
"Alt-D": "delWordAfter", "Alt-Backspace": "delWordBefore", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars"
};
// KEYMAP DISPATCH
function getKeyMap(val) {
if (typeof val == "string") return keyMap[val];
else return val;
}
function lookupKey(name, maps, handle) {
function lookup(map) {
map = getKeyMap(map);
var found = map[name];
if (found === false) return "stop";
if (found != null && handle(found)) return true;
if (map.nofallthrough) return "stop";
var fallthrough = map.fallthrough;
if (fallthrough == null) return false;
if (Object.prototype.toString.call(fallthrough) != "[object Array]")
return lookup(fallthrough);
for (var i = 0, e = fallthrough.length; i < e; ++i) {
var done = lookup(fallthrough[i]);
if (done) return done;
}
return false;
}
for (var i = 0; i < maps.length; ++i) {
var done = lookup(maps[i]);
update codemirror to latest version
r4042 if (done) return done != "stop";
update codemirror
r4025 }
}
function isModifierKey(event) {
var name = keyNames[event.keyCode];
return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod";
}
function keyName(event, noShift) {
if (opera && event.keyCode == 34 && event["char"]) return false;
var name = keyNames[event.keyCode];
if (name == null || event.altGraphKey) return false;
if (event.altKey) name = "Alt-" + name;
if (flipCtrlCmd ? event.metaKey : event.ctrlKey) name = "Ctrl-" + name;
if (flipCtrlCmd ? event.ctrlKey : event.metaKey) name = "Cmd-" + name;
if (!noShift && event.shiftKey) name = "Shift-" + name;
return name;
}
CodeMirror.lookupKey = lookupKey;
CodeMirror.isModifierKey = isModifierKey;
CodeMirror.keyName = keyName;
// FROMTEXTAREA
CodeMirror.fromTextArea = function(textarea, options) {
if (!options) options = {};
options.value = textarea.value;
if (!options.tabindex && textarea.tabindex)
options.tabindex = textarea.tabindex;
if (!options.placeholder && textarea.placeholder)
options.placeholder = textarea.placeholder;
// Set autofocus to true if this textarea is focused, or if it has
// autofocus and no other element is focused.
if (options.autofocus == null) {
var hasFocus = document.body;
// doc.activeElement occasionally throws on IE
try { hasFocus = document.activeElement; } catch(e) {}
options.autofocus = hasFocus == textarea ||
textarea.getAttribute("autofocus") != null && hasFocus == document.body;
}
function save() {textarea.value = cm.getValue();}
if (textarea.form) {
on(textarea.form, "submit", save);
// Deplorable hack to make the submit method do the right thing.
if (!options.leaveSubmitMethodAlone) {
var form = textarea.form, realSubmit = form.submit;
try {
var wrappedSubmit = form.submit = function() {
save();
form.submit = realSubmit;
form.submit();
form.submit = wrappedSubmit;
};
} catch(e) {}
}
}
textarea.style.display = "none";
var cm = CodeMirror(function(node) {
textarea.parentNode.insertBefore(node, textarea.nextSibling);
}, options);
cm.save = save;
cm.getTextArea = function() { return textarea; };
cm.toTextArea = function() {
save();
textarea.parentNode.removeChild(cm.getWrapperElement());
textarea.style.display = "";
if (textarea.form) {
off(textarea.form, "submit", save);
if (typeof textarea.form.submit == "function")
textarea.form.submit = realSubmit;
}
};
return cm;
};
// STRING STREAM
// Fed to the mode parsers, provides helper functions to make
// parsers more succinct.
Added server side file editing with commit
r1305 // The character stream used by a mode's parser.
Updated codemirror script
r2547 function StringStream(string, tabSize) {
Added server side file editing with commit
r1305 this.pos = this.start = 0;
this.string = string;
Updated codemirror script
r2547 this.tabSize = tabSize || 8;
update codemirror
r4025 this.lastColumnPos = this.lastColumnValue = 0;
}
Added server side file editing with commit
r1305 StringStream.prototype = {
eol: function() {return this.pos >= this.string.length;},
sol: function() {return this.pos == 0;},
updated codemirror to 2.34
r2861 peek: function() {return this.string.charAt(this.pos) || undefined;},
Added server side file editing with commit
r1305 next: function() {
if (this.pos < this.string.length)
return this.string.charAt(this.pos++);
},
eat: function(match) {
var ch = this.string.charAt(this.pos);
if (typeof match == "string") var ok = ch == match;
else var ok = ch && (match.test ? match.test(ch) : match(ch));
if (ok) {++this.pos; return ch;}
},
eatWhile: function(match) {
bumped codemirror to latest version
r1606 var start = this.pos;
Added server side file editing with commit
r1305 while (this.eat(match)){}
return this.pos > start;
},
eatSpace: function() {
var start = this.pos;
while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos;
return this.pos > start;
},
skipToEnd: function() {this.pos = this.string.length;},
skipTo: function(ch) {
var found = this.string.indexOf(ch, this.pos);
if (found > -1) {this.pos = found; return true;}
},
backUp: function(n) {this.pos -= n;},
update codemirror
r4025 column: function() {
if (this.lastColumnPos < this.start) {
this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue);
this.lastColumnPos = this.start;
}
return this.lastColumnValue;
},
Updated codemirror script
r2547 indentation: function() {return countColumn(this.string, null, this.tabSize);},
Added server side file editing with commit
r1305 match: function(pattern, consume, caseInsensitive) {
if (typeof pattern == "string") {
updated codemirror to 2.34
r2861 var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;};
update codemirror
r4025 var substr = this.string.substr(this.pos, pattern.length);
if (cased(substr) == cased(pattern)) {
Added server side file editing with commit
r1305 if (consume !== false) this.pos += pattern.length;
return true;
}
Updated codemirror script
r2547 } else {
Added server side file editing with commit
r1305 var match = this.string.slice(this.pos).match(pattern);
updated codemirror to 2.34
r2861 if (match && match.index > 0) return null;
Added server side file editing with commit
r1305 if (match && consume !== false) this.pos += match[0].length;
return match;
}
},
current: function(){return this.string.slice(this.start, this.pos);}
};
bumped codemirror to latest version
r1606 CodeMirror.StringStream = StringStream;
Added server side file editing with commit
r1305
update codemirror
r4025 // TEXTMARKERS
function TextMarker(doc, type) {
this.lines = [];
this.type = type;
this.doc = doc;
}
CodeMirror.TextMarker = TextMarker;
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 eventMixin(TextMarker);
update codemirror
r4025
TextMarker.prototype.clear = function() {
if (this.explicitlyCleared) return;
var cm = this.doc.cm, withOp = cm && !cm.curOp;
if (withOp) startOperation(cm);
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 if (hasHandler(this, "clear")) {
var found = this.find();
if (found) signalLater(this, "clear", found.from, found.to);
}
update codemirror
r4025 var min = null, max = null;
for (var i = 0; i < this.lines.length; ++i) {
var line = this.lines[i];
var span = getMarkedSpanFor(line.markedSpans, this);
if (span.to != null) max = lineNo(line);
line.markedSpans = removeMarkedSpan(line.markedSpans, span);
if (span.from != null)
min = lineNo(line);
else if (this.collapsed && !lineIsHidden(this.doc, line) && cm)
updateLineHeight(line, textHeight(cm.display));
}
if (cm && this.collapsed && !cm.options.lineWrapping) for (var i = 0; i < this.lines.length; ++i) {
var visual = visualLine(cm.doc, this.lines[i]), len = lineLength(cm.doc, visual);
if (len > cm.display.maxLineLength) {
cm.display.maxLine = visual;
cm.display.maxLineLength = len;
cm.display.maxLineChanged = true;
}
}
if (min != null && cm) regChange(cm, min, max + 1);
this.lines.length = 0;
this.explicitlyCleared = true;
update codemirror to latest version
r4042 if (this.atomic && this.doc.cantEdit) {
update codemirror
r4025 this.doc.cantEdit = false;
if (cm) reCheckSelection(cm);
}
if (withOp) endOperation(cm);
};
TextMarker.prototype.find = function() {
var from, to;
for (var i = 0; i < this.lines.length; ++i) {
var line = this.lines[i];
var span = getMarkedSpanFor(line.markedSpans, this);
if (span.from != null || span.to != null) {
var found = lineNo(line);
if (span.from != null) from = Pos(found, span.from);
if (span.to != null) to = Pos(found, span.to);
}
}
if (this.type == "bookmark") return from;
return from && {from: from, to: to};
};
update codemirror to latest version
r4042 TextMarker.prototype.changed = function() {
var pos = this.find(), cm = this.doc.cm;
if (!pos || !cm) return;
var line = getLine(this.doc, pos.from.line);
clearCachedMeasurement(cm, line);
if (pos.from.line >= cm.display.showingFrom && pos.from.line < cm.display.showingTo) {
for (var node = cm.display.lineDiv.firstChild; node; node = node.nextSibling) if (node.lineObj == line) {
if (node.offsetHeight != line.height) updateLineHeight(line, node.offsetHeight);
break;
}
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 runInOp(cm, function() {
cm.curOp.selectionChanged = cm.curOp.forceUpdate = cm.curOp.updateMaxLine = true;
});
update codemirror to latest version
r4042 }
update codemirror
r4025 };
TextMarker.prototype.attachLine = function(line) {
if (!this.lines.length && this.doc.cm) {
var op = this.doc.cm.curOp;
if (!op.maybeHiddenMarkers || indexOf(op.maybeHiddenMarkers, this) == -1)
(op.maybeUnhiddenMarkers || (op.maybeUnhiddenMarkers = [])).push(this);
}
this.lines.push(line);
};
TextMarker.prototype.detachLine = function(line) {
this.lines.splice(indexOf(this.lines, line), 1);
if (!this.lines.length && this.doc.cm) {
var op = this.doc.cm.curOp;
(op.maybeHiddenMarkers || (op.maybeHiddenMarkers = [])).push(this);
}
};
function markText(doc, from, to, options, type) {
if (options && options.shared) return markTextShared(doc, from, to, options, type);
if (doc.cm && !doc.cm.curOp) return operation(doc.cm, markText)(doc, from, to, options, type);
var marker = new TextMarker(doc, type);
if (type == "range" && !posLess(from, to)) return marker;
if (options) copyObj(options, marker);
if (marker.replacedWith) {
marker.collapsed = true;
marker.replacedWith = elt("span", [marker.replacedWith], "CodeMirror-widget");
update codemirror to latest version
r4042 if (!options.handleMouseEvents) marker.replacedWith.ignoreEvents = true;
update codemirror
r4025 }
if (marker.collapsed) sawCollapsedSpans = true;
if (marker.addToHistory)
addToHistory(doc, {from: from, to: to, origin: "markText"},
{head: doc.sel.head, anchor: doc.sel.anchor}, NaN);
var curLine = from.line, size = 0, collapsedAtStart, collapsedAtEnd, cm = doc.cm, updateMaxLine;
doc.iter(curLine, to.line + 1, function(line) {
if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(doc, line) == cm.display.maxLine)
updateMaxLine = true;
var span = {from: null, to: null, marker: marker};
size += line.text.length;
if (curLine == from.line) {span.from = from.ch; size -= from.ch;}
if (curLine == to.line) {span.to = to.ch; size -= line.text.length - to.ch;}
if (marker.collapsed) {
if (curLine == to.line) collapsedAtEnd = collapsedSpanAt(line, to.ch);
if (curLine == from.line) collapsedAtStart = collapsedSpanAt(line, from.ch);
else updateLineHeight(line, 0);
}
addMarkedSpan(line, span);
++curLine;
});
if (marker.collapsed) doc.iter(from.line, to.line + 1, function(line) {
if (lineIsHidden(doc, line)) updateLineHeight(line, 0);
});
if (marker.clearOnEnter) on(marker, "beforeCursorEnter", function() { marker.clear(); });
if (marker.readOnly) {
sawReadOnlySpans = true;
if (doc.history.done.length || doc.history.undone.length)
doc.clearHistory();
}
if (marker.collapsed) {
if (collapsedAtStart != collapsedAtEnd)
throw new Error("Inserting collapsed marker overlapping an existing one");
marker.size = size;
marker.atomic = true;
}
if (cm) {
if (updateMaxLine) cm.curOp.updateMaxLine = true;
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 if (marker.className || marker.title || marker.startStyle || marker.endStyle || marker.collapsed)
update codemirror
r4025 regChange(cm, from.line, to.line + 1);
if (marker.atomic) reCheckSelection(cm);
}
return marker;
}
// SHARED TEXTMARKERS
function SharedTextMarker(markers, primary) {
this.markers = markers;
this.primary = primary;
for (var i = 0, me = this; i < markers.length; ++i) {
markers[i].parent = this;
on(markers[i], "clear", function(){me.clear();});
}
}
CodeMirror.SharedTextMarker = SharedTextMarker;
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 eventMixin(SharedTextMarker);
update codemirror
r4025
SharedTextMarker.prototype.clear = function() {
if (this.explicitlyCleared) return;
this.explicitlyCleared = true;
for (var i = 0; i < this.markers.length; ++i)
this.markers[i].clear();
signalLater(this, "clear");
};
SharedTextMarker.prototype.find = function() {
return this.primary.find();
};
function markTextShared(doc, from, to, options, type) {
options = copyObj(options);
options.shared = false;
var markers = [markText(doc, from, to, options, type)], primary = markers[0];
var widget = options.replacedWith;
linkedDocs(doc, function(doc) {
if (widget) options.replacedWith = widget.cloneNode(true);
markers.push(markText(doc, clipPos(doc, from), clipPos(doc, to), options, type));
for (var i = 0; i < doc.linked.length; ++i)
if (doc.linked[i].isParent) return;
primary = lst(markers);
});
return new SharedTextMarker(markers, primary);
}
// TEXTMARKER SPANS
Updated codemirror script
r2547
updated codemirror version
r3036 function getMarkedSpanFor(spans, marker) {
updated codemirror to 2.34
r2861 if (spans) for (var i = 0; i < spans.length; ++i) {
var span = spans[i];
updated codemirror version
r3036 if (span.marker == marker) return span;
updated codemirror to 2.34
r2861 }
}
updated codemirror version
r3036 function removeMarkedSpan(spans, span) {
update codemirror
r4025 for (var r, i = 0; i < spans.length; ++i)
updated codemirror version
r3036 if (spans[i] != span) (r || (r = [])).push(spans[i]);
return r;
}
update codemirror
r4025 function addMarkedSpan(line, span) {
line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span];
span.marker.attachLine(line);
}
function markedSpansBefore(old, startCh, isInsert) {
updated codemirror to 2.34
r2861 if (old) for (var i = 0, nw; i < old.length; ++i) {
var span = old[i], marker = span.marker;
var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh);
update codemirror
r4025 if (startsBefore || marker.type == "bookmark" && span.from == startCh && (!isInsert || !span.marker.insertLeft)) {
updated codemirror to 2.34
r2861 var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh);
(nw || (nw = [])).push({from: span.from,
to: endsAfter ? null : span.to,
marker: marker});
Updated codemirror script
r2547 }
}
updated codemirror to 2.34
r2861 return nw;
}
update codemirror
r4025 function markedSpansAfter(old, endCh, isInsert) {
updated codemirror to 2.34
r2861 if (old) for (var i = 0, nw; i < old.length; ++i) {
var span = old[i], marker = span.marker;
var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh);
update codemirror
r4025 if (endsAfter || marker.type == "bookmark" && span.from == endCh && (!isInsert || span.marker.insertLeft)) {
updated codemirror to 2.34
r2861 var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh);
(nw || (nw = [])).push({from: startsBefore ? null : span.from - endCh,
to: span.to == null ? null : span.to - endCh,
marker: marker});
}
}
return nw;
}
Updated codemirror script
r2547
update codemirror
r4025 function stretchSpansOverChange(doc, change) {
var oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans;
var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans;
if (!oldFirst && !oldLast) return null;
var startCh = change.from.ch, endCh = change.to.ch, isInsert = posEq(change.from, change.to);
updated codemirror to 2.34
r2861 // Get the spans that 'stick out' on both sides
update codemirror
r4025 var first = markedSpansBefore(oldFirst, startCh, isInsert);
var last = markedSpansAfter(oldLast, endCh, isInsert);
updated codemirror to 2.34
r2861
// Next, merge those two ends
update codemirror
r4025 var sameLine = change.text.length == 1, offset = lst(change.text).length + (sameLine ? startCh : 0);
updated codemirror to 2.34
r2861 if (first) {
// Fix up .to properties of first
for (var i = 0; i < first.length; ++i) {
var span = first[i];
if (span.to == null) {
var found = getMarkedSpanFor(last, span.marker);
if (!found) span.to = startCh;
else if (sameLine) span.to = found.to == null ? null : found.to + offset;
bumped codemirror to latest version
r1606 }
}
}
updated codemirror to 2.34
r2861 if (last) {
// Fix up .from in last (or move them into first in case of sameLine)
for (var i = 0; i < last.length; ++i) {
var span = last[i];
if (span.to != null) span.to += offset;
if (span.from == null) {
var found = getMarkedSpanFor(first, span.marker);
if (!found) {
span.from = offset;
if (sameLine) (first || (first = [])).push(span);
bumped codemirror to latest version
r1606 }
updated codemirror to 2.34
r2861 } else {
span.from += offset;
if (sameLine) (first || (first = [])).push(span);
bumped codemirror to latest version
r1606 }
}
updated codemirror to 2.34
r2861 }
update codemirror to latest version
r4042 if (sameLine && first) {
// Make sure we didn't create any zero-length spans
for (var i = 0; i < first.length; ++i)
if (first[i].from != null && first[i].from == first[i].to && first[i].marker.type != "bookmark")
first.splice(i--, 1);
if (!first.length) first = null;
}
updated codemirror to 2.34
r2861
update codemirror
r4025 var newMarkers = [first];
updated codemirror to 2.34
r2861 if (!sameLine) {
// Fill gap with whole-line-spans
update codemirror
r4025 var gap = change.text.length - 2, gapMarkers;
updated codemirror to 2.34
r2861 if (gap > 0 && first)
for (var i = 0; i < first.length; ++i)
if (first[i].to == null)
(gapMarkers || (gapMarkers = [])).push({from: null, to: null, marker: first[i].marker});
for (var i = 0; i < gap; ++i)
update codemirror
r4025 newMarkers.push(gapMarkers);
newMarkers.push(last);
updated codemirror to 2.34
r2861 }
return newMarkers;
}
update codemirror
r4025 function mergeOldSpans(doc, change) {
var old = getOldSpans(doc, change);
var stretched = stretchSpansOverChange(doc, change);
if (!old) return stretched;
if (!stretched) return old;
for (var i = 0; i < old.length; ++i) {
var oldCur = old[i], stretchCur = stretched[i];
if (oldCur && stretchCur) {
spans: for (var j = 0; j < stretchCur.length; ++j) {
var span = stretchCur[j];
for (var k = 0; k < oldCur.length; ++k)
if (oldCur[k].marker == span.marker) continue spans;
oldCur.push(span);
}
} else if (stretchCur) {
old[i] = stretchCur;
}
}
return old;
}
function removeReadOnlyRanges(doc, from, to) {
var markers = null;
doc.iter(from.line, to.line + 1, function(line) {
if (line.markedSpans) for (var i = 0; i < line.markedSpans.length; ++i) {
var mark = line.markedSpans[i].marker;
if (mark.readOnly && (!markers || indexOf(markers, mark) == -1))
(markers || (markers = [])).push(mark);
}
});
if (!markers) return null;
var parts = [{from: from, to: to}];
for (var i = 0; i < markers.length; ++i) {
var mk = markers[i], m = mk.find();
for (var j = 0; j < parts.length; ++j) {
var p = parts[j];
if (posLess(p.to, m.from) || posLess(m.to, p.from)) continue;
var newParts = [j, 1];
if (posLess(p.from, m.from) || !mk.inclusiveLeft && posEq(p.from, m.from))
newParts.push({from: p.from, to: m.from});
if (posLess(m.to, p.to) || !mk.inclusiveRight && posEq(p.to, m.to))
newParts.push({from: m.to, to: p.to});
parts.splice.apply(parts, newParts);
j += newParts.length - 1;
}
}
return parts;
}
function collapsedSpanAt(line, ch) {
var sps = sawCollapsedSpans && line.markedSpans, found;
if (sps) for (var sp, i = 0; i < sps.length; ++i) {
sp = sps[i];
if (!sp.marker.collapsed) continue;
if ((sp.from == null || sp.from < ch) &&
(sp.to == null || sp.to > ch) &&
(!found || found.width < sp.marker.width))
found = sp.marker;
}
return found;
}
function collapsedSpanAtStart(line) { return collapsedSpanAt(line, -1); }
function collapsedSpanAtEnd(line) { return collapsedSpanAt(line, line.text.length + 1); }
function visualLine(doc, line) {
var merged;
while (merged = collapsedSpanAtStart(line))
line = getLine(doc, merged.find().from.line);
return line;
}
function lineIsHidden(doc, line) {
var sps = sawCollapsedSpans && line.markedSpans;
if (sps) for (var sp, i = 0; i < sps.length; ++i) {
sp = sps[i];
if (!sp.marker.collapsed) continue;
if (sp.from == null) return true;
update codemirror to latest version
r4042 if (sp.marker.replacedWith) continue;
update codemirror
r4025 if (sp.from == 0 && sp.marker.inclusiveLeft && lineIsHiddenInner(doc, line, sp))
return true;
}
}
function lineIsHiddenInner(doc, line, span) {
if (span.to == null) {
var end = span.marker.find().to, endLine = getLine(doc, end.line);
return lineIsHiddenInner(doc, endLine, getMarkedSpanFor(endLine.markedSpans, span.marker));
}
if (span.marker.inclusiveRight && span.to == line.text.length)
return true;
for (var sp, i = 0; i < line.markedSpans.length; ++i) {
sp = line.markedSpans[i];
update codemirror to latest version
r4042 if (sp.marker.collapsed && !sp.marker.replacedWith && sp.from == span.to &&
update codemirror
r4025 (sp.marker.inclusiveLeft || span.marker.inclusiveRight) &&
lineIsHiddenInner(doc, line, sp)) return true;
}
}
updated codemirror to 2.34
r2861
function detachMarkedSpans(line) {
var spans = line.markedSpans;
if (!spans) return;
update codemirror
r4025 for (var i = 0; i < spans.length; ++i)
spans[i].marker.detachLine(line);
updated codemirror to 2.34
r2861 line.markedSpans = null;
}
function attachMarkedSpans(line, spans) {
if (!spans) return;
for (var i = 0; i < spans.length; ++i)
update codemirror
r4025 spans[i].marker.attachLine(line);
updated codemirror to 2.34
r2861 line.markedSpans = spans;
}
update codemirror
r4025 // LINE WIDGETS
var LineWidget = CodeMirror.LineWidget = function(cm, node, options) {
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 if (options) for (var opt in options) if (options.hasOwnProperty(opt))
update codemirror
r4025 this[opt] = options[opt];
this.cm = cm;
this.node = node;
};
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 eventMixin(LineWidget);
update codemirror
r4025 function widgetOperation(f) {
return function() {
var withOp = !this.cm.curOp;
if (withOp) startOperation(this.cm);
try {var result = f.apply(this, arguments);}
finally {if (withOp) endOperation(this.cm);}
return result;
};
}
LineWidget.prototype.clear = widgetOperation(function() {
var ws = this.line.widgets, no = lineNo(this.line);
if (no == null || !ws) return;
for (var i = 0; i < ws.length; ++i) if (ws[i] == this) ws.splice(i--, 1);
if (!ws.length) this.line.widgets = null;
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 var aboveVisible = heightAtLine(this.cm, this.line) < this.cm.doc.scrollTop;
update codemirror
r4025 updateLineHeight(this.line, Math.max(0, this.line.height - widgetHeight(this)));
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 if (aboveVisible) addToScrollPos(this.cm, 0, -this.height);
update codemirror
r4025 regChange(this.cm, no, no + 1);
});
LineWidget.prototype.changed = widgetOperation(function() {
var oldH = this.height;
this.height = null;
var diff = widgetHeight(this) - oldH;
if (!diff) return;
updateLineHeight(this.line, this.line.height + diff);
var no = lineNo(this.line);
regChange(this.cm, no, no + 1);
});
function widgetHeight(widget) {
if (widget.height != null) return widget.height;
if (!widget.node.parentNode || widget.node.parentNode.nodeType != 1)
removeChildrenAndAdd(widget.cm.display.measure, elt("div", [widget.node], null, "position: relative"));
return widget.height = widget.node.offsetHeight;
}
function addLineWidget(cm, handle, node, options) {
var widget = new LineWidget(cm, node, options);
if (widget.noHScroll) cm.display.alignWidgets = true;
changeLine(cm, handle, function(line) {
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 var widgets = line.widgets || (line.widgets = []);
if (widget.insertAt == null) widgets.push(widget);
else widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget);
update codemirror
r4025 widget.line = line;
if (!lineIsHidden(cm.doc, line) || widget.showIfHidden) {
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 var aboveVisible = heightAtLine(cm, line) < cm.doc.scrollTop;
update codemirror
r4025 updateLineHeight(line, line.height + widgetHeight(widget));
if (aboveVisible) addToScrollPos(cm, 0, widget.height);
}
return true;
});
return widget;
}
// LINE DATA STRUCTURE
updated codemirror to 2.34
r2861
// Line objects. These hold state related to a line, including
// highlighting info (the styles array).
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 var Line = CodeMirror.Line = function(text, markedSpans, estimateHeight) {
this.text = text;
attachMarkedSpans(this, markedSpans);
this.height = estimateHeight ? estimateHeight(this) : 1;
};
eventMixin(Line);
update codemirror
r4025
function updateLine(line, text, markedSpans, estimateHeight) {
line.text = text;
if (line.stateAfter) line.stateAfter = null;
if (line.styles) line.styles = null;
if (line.order != null) line.order = null;
detachMarkedSpans(line);
attachMarkedSpans(line, markedSpans);
var estHeight = estimateHeight ? estimateHeight(line) : 1;
if (estHeight != line.height) updateLineHeight(line, estHeight);
}
function cleanUpLine(line) {
line.parent = null;
detachMarkedSpans(line);
}
// Run the given mode's parser over a line, update the styles
// array, which contains alternating fragments of text and CSS
// classes.
function runMode(cm, text, mode, state, f) {
var flattenSpans = mode.flattenSpans;
if (flattenSpans == null) flattenSpans = cm.options.flattenSpans;
update codemirror to latest version
r4042 var curStart = 0, curStyle = null;
update codemirror
r4025 var stream = new StringStream(text, cm.options.tabSize), style;
if (text == "" && mode.blankLine) mode.blankLine(state);
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);
style = null;
} else {
style = mode.token(stream, state);
updated codemirror to 2.34
r2861 }
update codemirror to latest version
r4042 if (!flattenSpans || curStyle != style) {
if (curStart < stream.start) f(stream.start, curStyle);
curStart = stream.start; curStyle = style;
}
update codemirror
r4025 stream.start = stream.pos;
update codemirror to latest version
r4042 }
if (curStart < stream.pos) f(stream.pos, curStyle);
update codemirror
r4025 }
function highlightLine(cm, line, state) {
// A styles array always starts with a number identifying the
// mode/overlays that it is based on (for easy invalidation).
var st = [cm.state.modeGen];
// Compute the base array of styles
update codemirror to latest version
r4042 runMode(cm, line.text, cm.doc.mode, state, function(end, style) {st.push(end, style);});
update codemirror
r4025
// Run overlays, adjust style array.
for (var o = 0; o < cm.state.overlays.length; ++o) {
update codemirror to latest version
r4042 var overlay = cm.state.overlays[o], i = 1, at = 0;
runMode(cm, line.text, overlay.mode, true, function(end, style) {
var start = i;
update codemirror
r4025 // Ensure there's a token end at the current position, and that i points at it
update codemirror to latest version
r4042 while (at < end) {
var i_end = st[i];
if (i_end > end)
st.splice(i, 1, end, st[i+1], i_end);
update codemirror
r4025 i += 2;
update codemirror to latest version
r4042 at = Math.min(end, i_end);
update codemirror
r4025 }
if (!style) return;
if (overlay.opaque) {
update codemirror to latest version
r4042 st.splice(start, i - start, end, style);
update codemirror
r4025 i = start + 2;
Updated codemirror script
r2547 } else {
update codemirror
r4025 for (; start < i; start += 2) {
var cur = st[start+1];
st[start+1] = cur ? cur + " " + style : style;
Updated codemirror script
r2547 }
}
update codemirror
r4025 });
}
return st;
}
function getLineStyles(cm, line) {
if (!line.styles || line.styles[0] != cm.state.modeGen)
line.styles = highlightLine(cm, line, line.stateAfter = getStateBefore(cm, lineNo(line)));
return line.styles;
}
// Lightweight form of highlight -- proceed over this line and
// update state, but don't save a style array.
function processLine(cm, line, state) {
var mode = cm.doc.mode;
var stream = new StringStream(line.text, cm.options.tabSize);
if (line.text == "" && mode.blankLine) mode.blankLine(state);
while (!stream.eol() && stream.pos <= cm.options.maxHighlightLength) {
mode.token(stream, state);
stream.start = stream.pos;
}
}
var styleToClassCache = {};
function styleToClass(style) {
if (!style) return null;
return styleToClassCache[style] ||
(styleToClassCache[style] = "cm-" + style.replace(/ +/g, " cm-"));
}
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 function lineContent(cm, realLine, measure, copyWidgets) {
update codemirror to latest version
r4042 var merged, line = realLine, empty = true;
while (merged = collapsedSpanAtStart(line))
update codemirror
r4025 line = getLine(cm.doc, merged.find().from.line);
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 var builder = {pre: elt("pre"), col: 0, pos: 0,
measure: null, measuredSomething: false, cm: cm,
copyWidgets: copyWidgets};
update codemirror
r4025 if (line.textClass) builder.pre.className = line.textClass;
do {
update codemirror to latest version
r4042 if (line.text) empty = false;
update codemirror
r4025 builder.measure = line == realLine && measure;
builder.pos = 0;
builder.addToken = builder.measure ? buildTokenMeasure : buildToken;
if ((ie || webkit) && cm.getOption("lineWrapping"))
builder.addToken = buildTokenSplitSpaces(builder.addToken);
update codemirror to latest version
r4042 var next = insertLineContent(line, builder, getLineStyles(cm, line));
if (measure && line == realLine && !builder.measuredSomething) {
update codemirror
r4025 measure[0] = builder.pre.appendChild(zeroWidthElement(cm.display.measure));
update codemirror to latest version
r4042 builder.measuredSomething = true;
Updated codemirror script
r2547 }
update codemirror to latest version
r4042 if (next) line = getLine(cm.doc, next.to.line);
update codemirror
r4025 } while (next);
update codemirror to latest version
r4042 if (measure && !builder.measuredSomething && !measure[0])
measure[0] = builder.pre.appendChild(empty ? elt("span", "\u00a0") : zeroWidthElement(cm.display.measure));
update codemirror
r4025 if (!builder.pre.firstChild && !lineIsHidden(cm.doc, realLine))
builder.pre.appendChild(document.createTextNode("\u00a0"));
var order;
// Work around problem with the reported dimensions of single-char
// direction spans on IE (issue #1129). See also the comment in
// cursorCoords.
if (measure && ie && (order = getOrder(line))) {
var l = order.length - 1;
if (order[l].from == order[l].to) --l;
var last = order[l], prev = order[l - 1];
if (last.from + 1 == last.to && prev && last.level < prev.level) {
var span = measure[builder.pos - 1];
if (span) span.parentNode.insertBefore(span.measureRight = zeroWidthElement(cm.display.measure),
span.nextSibling);
}
}
signal(cm, "renderLine", cm, realLine, builder.pre);
return builder.pre;
}
var tokenSpecialChars = /[\t\u0000-\u0019\u00ad\u200b\u2028\u2029\uFEFF]/g;
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 function buildToken(builder, text, style, startStyle, endStyle, title) {
update codemirror
r4025 if (!text) return;
if (!tokenSpecialChars.test(text)) {
builder.col += text.length;
var content = document.createTextNode(text);
} else {
var content = document.createDocumentFragment(), pos = 0;
while (true) {
tokenSpecialChars.lastIndex = pos;
var m = tokenSpecialChars.exec(text);
var skipped = m ? m.index - pos : text.length - pos;
if (skipped) {
content.appendChild(document.createTextNode(text.slice(pos, pos + skipped)));
builder.col += skipped;
bumped codemirror to latest version
r1606 }
update codemirror
r4025 if (!m) break;
pos += skipped + 1;
if (m[0] == "\t") {
var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize;
content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab"));
builder.col += tabWidth;
} else {
var token = elt("span", "\u2022", "cm-invalidchar");
token.title = "\\u" + m[0].charCodeAt(0).toString(16);
content.appendChild(token);
builder.col += 1;
Added server side file editing with commit
r1305 }
}
update codemirror
r4025 }
if (style || startStyle || endStyle || builder.measure) {
var fullStyle = style || "";
if (startStyle) fullStyle += startStyle;
if (endStyle) fullStyle += endStyle;
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 var token = elt("span", [content], fullStyle);
if (title) token.title = title;
return builder.pre.appendChild(token);
update codemirror
r4025 }
builder.pre.appendChild(content);
}
function buildTokenMeasure(builder, text, style, startStyle, endStyle) {
var wrapping = builder.cm.options.lineWrapping;
for (var i = 0; i < text.length; ++i) {
var ch = text.charAt(i), start = i == 0;
if (ch >= "\ud800" && ch < "\udbff" && i < text.length - 1) {
ch = text.slice(i, i + 2);
++i;
update codemirror to latest version
r4042 } else if (i && wrapping && spanAffectsWrapping(text, i)) {
update codemirror
r4025 builder.pre.appendChild(elt("wbr"));
}
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 var old = builder.measure[builder.pos];
update codemirror
r4025 var span = builder.measure[builder.pos] =
buildToken(builder, ch, style,
start && startStyle, i == text.length - 1 && endStyle);
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 if (old) span.leftSide = old.leftSide || old;
update codemirror
r4025 // In IE single-space nodes wrap differently than spaces
// embedded in larger text nodes, except when set to
// white-space: normal (issue #1268).
if (ie && wrapping && ch == " " && i && !/\s/.test(text.charAt(i - 1)) &&
i < text.length - 1 && !/\s/.test(text.charAt(i + 1)))
span.style.whiteSpace = "normal";
builder.pos += ch.length;
}
update codemirror to latest version
r4042 if (text.length) builder.measuredSomething = true;
update codemirror
r4025 }
function buildTokenSplitSpaces(inner) {
function split(old) {
var out = " ";
for (var i = 0; i < old.length - 2; ++i) out += i % 2 ? " " : "\u00a0";
out += " ";
return out;
}
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 return function(builder, text, style, startStyle, endStyle, title) {
return inner(builder, text.replace(/ {3,}/, split), style, startStyle, endStyle, title);
update codemirror
r4025 };
}
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 function buildCollapsedSpan(builder, size, marker, ignoreWidget) {
var widget = !ignoreWidget && marker.replacedWith;
update codemirror
r4025 if (widget) {
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 if (builder.copyWidgets) widget = widget.cloneNode(true);
builder.pre.appendChild(widget);
update codemirror to latest version
r4042 if (builder.measure) {
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 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);
else
builder.pre.appendChild(elt);
}
update codemirror to latest version
r4042 builder.measuredSomething = true;
}
update codemirror
r4025 }
builder.pos += size;
}
// Outputs a number of spans to make up a line, taking highlighting
// and marked text into account.
function insertLineContent(line, builder, styles) {
update codemirror to latest version
r4042 var spans = line.markedSpans, allText = line.text, at = 0;
update codemirror
r4025 if (!spans) {
for (var i = 1; i < styles.length; i+=2)
update codemirror to latest version
r4042 builder.addToken(builder, allText.slice(at, at = styles[i]), styleToClass(styles[i+1]));
update codemirror
r4025 return;
}
update codemirror to latest version
r4042 var len = allText.length, pos = 0, i = 1, text = "", style;
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, title, collapsed;
update codemirror
r4025 for (;;) {
if (nextChange == pos) { // Update current marker set
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 spanStyle = spanEndStyle = spanStartStyle = title = "";
update codemirror
r4025 collapsed = null; nextChange = Infinity;
var foundBookmark = null;
for (var j = 0; j < spans.length; ++j) {
var sp = spans[j], m = sp.marker;
if (sp.from <= pos && (sp.to == null || sp.to > pos)) {
if (sp.to != null && nextChange > sp.to) { nextChange = sp.to; spanEndStyle = ""; }
if (m.className) spanStyle += " " + m.className;
if (m.startStyle && sp.from == pos) spanStartStyle += " " + m.startStyle;
if (m.endStyle && sp.to == nextChange) spanEndStyle += " " + m.endStyle;
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 if (m.title && !title) title = m.title;
update codemirror to latest version
r4042 if (m.collapsed && (!collapsed || collapsed.marker.size < m.size))
update codemirror
r4025 collapsed = sp;
} else if (sp.from > pos && nextChange > sp.from) {
nextChange = sp.from;
}
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 if (m.type == "bookmark" && sp.from == pos && m.replacedWith) foundBookmark = m;
update codemirror
r4025 }
if (collapsed && (collapsed.from || 0) == pos) {
buildCollapsedSpan(builder, (collapsed.to == null ? len : collapsed.to) - pos,
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 collapsed.marker, collapsed.from == null);
update codemirror
r4025 if (collapsed.to == null) return collapsed.marker.find();
}
if (foundBookmark && !collapsed) buildCollapsedSpan(builder, 0, foundBookmark);
}
if (pos >= len) break;
var upto = Math.min(len, nextChange);
while (true) {
if (text) {
var end = pos + text.length;
if (!collapsed) {
var tokenText = end > upto ? text.slice(0, upto - pos) : text;
builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle,
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "", title);
update codemirror
r4025 }
if (end >= upto) {text = text.slice(upto - pos); pos = upto; break;}
pos = end;
spanStartStyle = "";
}
update codemirror to latest version
r4042 text = allText.slice(at, at = styles[i++]);
style = styleToClass(styles[i++]);
update codemirror
r4025 }
}
}
// DOCUMENT DATA STRUCTURE
function updateDoc(doc, change, markedSpans, selAfter, estimateHeight) {
function spansFor(n) {return markedSpans ? markedSpans[n] : null;}
function update(line, text, spans) {
updateLine(line, text, spans, estimateHeight);
signalLater(line, "change", line, change);
}
var from = change.from, to = change.to, text = change.text;
var firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line);
var lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line;
// First adjust the line structure
if (from.ch == 0 && to.ch == 0 && lastText == "") {
// This is a whole-line replace. Treated specially to make
// sure line objects move the way they are supposed to.
for (var i = 0, e = text.length - 1, added = []; i < e; ++i)
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 added.push(new Line(text[i], spansFor(i), estimateHeight));
update codemirror
r4025 update(lastLine, lastLine.text, lastSpans);
if (nlines) doc.remove(from.line, nlines);
if (added.length) doc.insert(from.line, added);
} else if (firstLine == lastLine) {
if (text.length == 1) {
update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans);
} else {
for (var added = [], i = 1, e = text.length - 1; i < e; ++i)
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 added.push(new Line(text[i], spansFor(i), estimateHeight));
added.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight));
update codemirror
r4025 update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
doc.insert(from.line + 1, added);
}
} else if (text.length == 1) {
update(firstLine, firstLine.text.slice(0, from.ch) + text[0] + lastLine.text.slice(to.ch), spansFor(0));
doc.remove(from.line + 1, nlines);
} else {
update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans);
for (var i = 1, e = text.length - 1, added = []; i < e; ++i)
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 added.push(new Line(text[i], spansFor(i), estimateHeight));
update codemirror
r4025 if (nlines > 1) doc.remove(from.line + 1, nlines - 1);
doc.insert(from.line + 1, added);
}
signalLater(doc, "change", doc, change);
setSelection(doc, selAfter.anchor, selAfter.head, null, true);
}
Updated codemirror script
r2547 function LeafChunk(lines) {
this.lines = lines;
this.parent = null;
for (var i = 0, e = lines.length, height = 0; i < e; ++i) {
lines[i].parent = this;
height += lines[i].height;
}
this.height = height;
}
update codemirror
r4025
Updated codemirror script
r2547 LeafChunk.prototype = {
chunkSize: function() { return this.lines.length; },
update codemirror
r4025 removeInner: function(at, n) {
Updated codemirror script
r2547 for (var i = at, e = at + n; i < e; ++i) {
var line = this.lines[i];
this.height -= line.height;
update codemirror
r4025 cleanUpLine(line);
signalLater(line, "delete");
Updated codemirror script
r2547 }
this.lines.splice(at, n);
},
collapse: function(lines) {
lines.splice.apply(lines, [lines.length, 0].concat(this.lines));
},
update codemirror
r4025 insertInner: function(at, lines, height) {
Updated codemirror script
r2547 this.height += height;
this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at));
for (var i = 0, e = lines.length; i < e; ++i) lines[i].parent = this;
},
iterN: function(at, n, op) {
for (var e = at + n; at < e; ++at)
if (op(this.lines[at])) return true;
}
};
update codemirror
r4025
Updated codemirror script
r2547 function BranchChunk(children) {
this.children = children;
var size = 0, height = 0;
for (var i = 0, e = children.length; i < e; ++i) {
var ch = children[i];
size += ch.chunkSize(); height += ch.height;
ch.parent = this;
}
this.size = size;
this.height = height;
this.parent = null;
}
update codemirror
r4025
Updated codemirror script
r2547 BranchChunk.prototype = {
chunkSize: function() { return this.size; },
update codemirror
r4025 removeInner: function(at, n) {
Updated codemirror script
r2547 this.size -= n;
for (var i = 0; i < this.children.length; ++i) {
var child = this.children[i], sz = child.chunkSize();
if (at < sz) {
var rm = Math.min(n, sz - at), oldHeight = child.height;
update codemirror
r4025 child.removeInner(at, rm);
Updated codemirror script
r2547 this.height -= oldHeight - child.height;
if (sz == rm) { this.children.splice(i--, 1); child.parent = null; }
if ((n -= rm) == 0) break;
at = 0;
} else at -= sz;
}
if (this.size - n < 25) {
var lines = [];
this.collapse(lines);
this.children = [new LeafChunk(lines)];
this.children[0].parent = this;
}
},
collapse: function(lines) {
for (var i = 0, e = this.children.length; i < e; ++i) this.children[i].collapse(lines);
},
update codemirror
r4025 insertInner: function(at, lines, height) {
Updated codemirror script
r2547 this.size += lines.length;
this.height += height;
for (var i = 0, e = this.children.length; i < e; ++i) {
var child = this.children[i], sz = child.chunkSize();
if (at <= sz) {
update codemirror
r4025 child.insertInner(at, lines, height);
Updated codemirror script
r2547 if (child.lines && child.lines.length > 50) {
while (child.lines.length > 50) {
var spilled = child.lines.splice(child.lines.length - 25, 25);
var newleaf = new LeafChunk(spilled);
child.height -= newleaf.height;
this.children.splice(i + 1, 0, newleaf);
newleaf.parent = this;
}
this.maybeSpill();
}
break;
}
at -= sz;
}
},
maybeSpill: function() {
if (this.children.length <= 10) return;
var me = this;
do {
var spilled = me.children.splice(me.children.length - 5, 5);
var sibling = new BranchChunk(spilled);
if (!me.parent) { // Become the parent node
var copy = new BranchChunk(me.children);
copy.parent = me;
me.children = [copy, sibling];
me = copy;
} else {
me.size -= sibling.size;
me.height -= sibling.height;
var myIndex = indexOf(me.parent.children, me);
me.parent.children.splice(myIndex + 1, 0, sibling);
}
sibling.parent = me.parent;
} while (me.children.length > 10);
me.parent.maybeSpill();
},
iterN: function(at, n, op) {
for (var i = 0, e = this.children.length; i < e; ++i) {
var child = this.children[i], sz = child.chunkSize();
if (at < sz) {
var used = Math.min(n, sz - at);
if (child.iterN(at, used, op)) return true;
if ((n -= used) == 0) break;
at = 0;
} else at -= sz;
}
}
};
update codemirror
r4025 var nextDocId = 0;
var Doc = CodeMirror.Doc = function(text, mode, firstLine) {
if (!(this instanceof Doc)) return new Doc(text, mode, firstLine);
if (firstLine == null) firstLine = 0;
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 BranchChunk.call(this, [new LeafChunk([new Line("", null)])]);
update codemirror
r4025 this.first = firstLine;
this.scrollTop = this.scrollLeft = 0;
this.cantEdit = false;
this.history = makeHistory();
update codemirror to latest version
r4042 this.cleanGeneration = 1;
update codemirror
r4025 this.frontier = firstLine;
var start = Pos(firstLine, 0);
this.sel = {from: start, to: start, head: start, anchor: start, shift: false, extend: false, goalColumn: null};
this.id = ++nextDocId;
this.modeOption = mode;
if (typeof text == "string") text = splitLines(text);
updateDoc(this, {from: start, to: start, text: text}, null, {head: start, anchor: start});
};
Doc.prototype = createObj(BranchChunk.prototype, {
update codemirror to latest version
r4042 constructor: Doc,
update codemirror
r4025 iter: function(from, to, op) {
if (op) this.iterN(from - this.first, to - from, op);
else this.iterN(this.first, this.first + this.size, from);
},
insert: function(at, lines) {
var height = 0;
for (var i = 0, e = lines.length; i < e; ++i) height += lines[i].height;
this.insertInner(at - this.first, lines, height);
},
remove: function(at, n) { this.removeInner(at - this.first, n); },
getValue: function(lineSep) {
var lines = getLines(this, this.first, this.first + this.size);
if (lineSep === false) return lines;
return lines.join(lineSep || "\n");
},
setValue: function(code) {
var top = Pos(this.first, 0), last = this.first + this.size - 1;
makeChange(this, {from: top, to: Pos(last, getLine(this, last).text.length),
text: splitLines(code), origin: "setValue"},
{head: top, anchor: top}, true);
},
replaceRange: function(code, from, to, origin) {
from = clipPos(this, from);
to = to ? clipPos(this, to) : from;
replaceRange(this, code, from, to, origin);
},
getRange: function(from, to, lineSep) {
var lines = getBetween(this, clipPos(this, from), clipPos(this, to));
if (lineSep === false) return lines;
return lines.join(lineSep || "\n");
},
getLine: function(line) {var l = this.getLineHandle(line); return l && l.text;},
setLine: function(line, text) {
if (isLine(this, line))
replaceRange(this, text, Pos(line, 0), clipPos(this, Pos(line)));
},
removeLine: function(line) {
if (line) replaceRange(this, "", clipPos(this, Pos(line - 1)), clipPos(this, Pos(line)));
else replaceRange(this, "", Pos(0, 0), clipPos(this, Pos(1, 0)));
},
getLineHandle: function(line) {if (isLine(this, line)) return getLine(this, line);},
getLineNumber: function(line) {return lineNo(line);},
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 getLineHandleVisualStart: function(line) {
if (typeof line == "number") line = getLine(this, line);
return visualLine(this, line);
},
update codemirror
r4025 lineCount: function() {return this.size;},
firstLine: function() {return this.first;},
lastLine: function() {return this.first + this.size - 1;},
clipPos: function(pos) {return clipPos(this, pos);},
getCursor: function(start) {
var sel = this.sel, pos;
if (start == null || start == "head") pos = sel.head;
else if (start == "anchor") pos = sel.anchor;
else if (start == "end" || start === false) pos = sel.to;
else pos = sel.from;
return copyPos(pos);
},
somethingSelected: function() {return !posEq(this.sel.head, this.sel.anchor);},
setCursor: docOperation(function(line, ch, extend) {
var pos = clipPos(this, typeof line == "number" ? Pos(line, ch || 0) : line);
if (extend) extendSelection(this, pos);
else setSelection(this, pos, pos);
}),
setSelection: docOperation(function(anchor, head) {
setSelection(this, clipPos(this, anchor), clipPos(this, head || anchor));
}),
extendSelection: docOperation(function(from, to) {
extendSelection(this, clipPos(this, from), to && clipPos(this, to));
}),
getSelection: function(lineSep) {return this.getRange(this.sel.from, this.sel.to, lineSep);},
replaceSelection: function(code, collapse, origin) {
makeChange(this, {from: this.sel.from, to: this.sel.to, text: splitLines(code), origin: origin}, collapse || "around");
},
undo: docOperation(function() {makeChangeFromHistory(this, "undo");}),
redo: docOperation(function() {makeChangeFromHistory(this, "redo");}),
setExtending: function(val) {this.sel.extend = val;},
historySize: function() {
var hist = this.history;
return {undo: hist.done.length, redo: hist.undone.length};
},
update codemirror to latest version
r4042 clearHistory: function() {this.history = makeHistory(this.history.maxGeneration);},
update codemirror
r4025
markClean: function() {
update codemirror to latest version
r4042 this.cleanGeneration = this.changeGeneration();
},
changeGeneration: function() {
update codemirror
r4025 this.history.lastOp = this.history.lastOrigin = null;
update codemirror to latest version
r4042 return this.history.generation;
update codemirror
r4025 },
update codemirror to latest version
r4042 isClean: function (gen) {
return this.history.generation == (gen || this.cleanGeneration);
},
update codemirror
r4025
getHistory: function() {
return {done: copyHistoryArray(this.history.done),
undone: copyHistoryArray(this.history.undone)};
},
setHistory: function(histData) {
update codemirror to latest version
r4042 var hist = this.history = makeHistory(this.history.maxGeneration);
update codemirror
r4025 hist.done = histData.done.slice(0);
hist.undone = histData.undone.slice(0);
},
markText: function(from, to, options) {
return markText(this, clipPos(this, from), clipPos(this, to), options, "range");
},
setBookmark: function(pos, options) {
var realOpts = {replacedWith: options && (options.nodeType == null ? options.widget : options),
insertLeft: options && options.insertLeft};
pos = clipPos(this, pos);
return markText(this, pos, pos, realOpts, "bookmark");
},
findMarksAt: function(pos) {
pos = clipPos(this, pos);
var markers = [], spans = getLine(this, pos.line).markedSpans;
if (spans) for (var i = 0; i < spans.length; ++i) {
var span = spans[i];
if ((span.from == null || span.from <= pos.ch) &&
(span.to == null || span.to >= pos.ch))
markers.push(span.marker.parent || span.marker);
}
return markers;
},
getAllMarks: function() {
var markers = [];
this.iter(function(line) {
var sps = line.markedSpans;
if (sps) for (var i = 0; i < sps.length; ++i)
if (sps[i].from != null) markers.push(sps[i].marker);
});
return markers;
},
posFromIndex: function(off) {
var ch, lineNo = this.first;
this.iter(function(line) {
var sz = line.text.length + 1;
if (sz > off) { ch = off; return true; }
off -= sz;
++lineNo;
});
return clipPos(this, Pos(lineNo, ch));
},
indexFromPos: function (coords) {
coords = clipPos(this, coords);
var index = coords.ch;
if (coords.line < this.first || coords.ch < 0) return 0;
this.iter(this.first, coords.line, function (line) {
index += line.text.length + 1;
});
return index;
},
copy: function(copyHistory) {
var doc = new Doc(getLines(this, this.first, this.first + this.size), this.modeOption, this.first);
doc.scrollTop = this.scrollTop; doc.scrollLeft = this.scrollLeft;
doc.sel = {from: this.sel.from, to: this.sel.to, head: this.sel.head, anchor: this.sel.anchor,
shift: this.sel.shift, extend: false, goalColumn: this.sel.goalColumn};
if (copyHistory) {
doc.history.undoDepth = this.history.undoDepth;
doc.setHistory(this.getHistory());
}
return doc;
},
linkedDoc: function(options) {
if (!options) options = {};
var from = this.first, to = this.first + this.size;
if (options.from != null && options.from > from) from = options.from;
if (options.to != null && options.to < to) to = options.to;
var copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from);
if (options.sharedHist) copy.history = this.history;
(this.linked || (this.linked = [])).push({doc: copy, sharedHist: options.sharedHist});
copy.linked = [{doc: this, isParent: true, sharedHist: options.sharedHist}];
return copy;
},
unlinkDoc: function(other) {
if (other instanceof CodeMirror) other = other.doc;
if (this.linked) for (var i = 0; i < this.linked.length; ++i) {
var link = this.linked[i];
if (link.doc != other) continue;
this.linked.splice(i, 1);
other.unlinkDoc(this);
break;
}
// If the histories were shared, split them again
if (other.history == this.history) {
var splitIds = [other.id];
linkedDocs(other, function(doc) {splitIds.push(doc.id);}, true);
other.history = makeHistory();
other.history.done = copyHistoryArray(this.history.done, splitIds);
other.history.undone = copyHistoryArray(this.history.undone, splitIds);
}
},
iterLinkedDocs: function(f) {linkedDocs(this, f);},
getMode: function() {return this.mode;},
getEditor: function() {return this.cm;}
});
Doc.prototype.eachLine = Doc.prototype.iter;
// The Doc methods that should be available on CodeMirror instances
var dontDelegate = "iter insert remove copy getEditor".split(" ");
for (var prop in Doc.prototype) if (Doc.prototype.hasOwnProperty(prop) && indexOf(dontDelegate, prop) < 0)
CodeMirror.prototype[prop] = (function(method) {
return function() {return method.apply(this.doc, arguments);};
})(Doc.prototype[prop]);
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 eventMixin(Doc);
update codemirror
r4025 function linkedDocs(doc, f, sharedHistOnly) {
function propagate(doc, skip, sharedHist) {
if (doc.linked) for (var i = 0; i < doc.linked.length; ++i) {
var rel = doc.linked[i];
if (rel.doc == skip) continue;
var shared = sharedHist && rel.sharedHist;
if (sharedHistOnly && !shared) continue;
f(rel.doc, shared);
propagate(rel.doc, doc, shared);
}
}
propagate(doc, null, true);
}
function attachDoc(cm, doc) {
if (doc.cm) throw new Error("This document is already in use.");
cm.doc = doc;
doc.cm = cm;
estimateLineHeights(cm);
loadMode(cm);
if (!cm.options.lineWrapping) computeMaxLength(cm);
cm.options.mode = doc.modeOption;
regChange(cm);
}
// LINE UTILITIES
function getLine(chunk, n) {
n -= chunk.first;
Updated codemirror script
r2547 while (!chunk.lines) {
for (var i = 0;; ++i) {
var child = chunk.children[i], sz = child.chunkSize();
if (n < sz) { chunk = child; break; }
n -= sz;
}
}
return chunk.lines[n];
}
update codemirror
r4025
function getBetween(doc, start, end) {
var out = [], n = start.line;
doc.iter(start.line, end.line + 1, function(line) {
var text = line.text;
if (n == end.line) text = text.slice(0, end.ch);
if (n == start.line) text = text.slice(start.ch);
out.push(text);
++n;
});
return out;
}
function getLines(doc, from, to) {
var out = [];
doc.iter(from, to, function(line) { out.push(line.text); });
return out;
}
function updateLineHeight(line, height) {
var diff = height - line.height;
for (var n = line; n; n = n.parent) n.height += diff;
}
Updated codemirror script
r2547 function lineNo(line) {
if (line.parent == null) return null;
var cur = line.parent, no = indexOf(cur.lines, line);
for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) {
update codemirror
r4025 for (var i = 0;; ++i) {
Updated codemirror script
r2547 if (chunk.children[i] == cur) break;
no += chunk.children[i].chunkSize();
}
}
update codemirror
r4025 return no + cur.first;
}
Updated codemirror script
r2547 function lineAtHeight(chunk, h) {
update codemirror
r4025 var n = chunk.first;
Updated codemirror script
r2547 outer: do {
for (var i = 0, e = chunk.children.length; i < e; ++i) {
var child = chunk.children[i], ch = child.height;
if (h < ch) { chunk = child; continue outer; }
h -= ch;
n += child.chunkSize();
}
return n;
} while (!chunk.lines);
for (var i = 0, e = chunk.lines.length; i < e; ++i) {
var line = chunk.lines[i], lh = line.height;
if (h < lh) break;
h -= lh;
}
return n + i;
}
update codemirror
r4025
function heightAtLine(cm, lineObj) {
lineObj = visualLine(cm.doc, lineObj);
var h = 0, chunk = lineObj.parent;
for (var i = 0; i < chunk.lines.length; ++i) {
var line = chunk.lines[i];
if (line == lineObj) break;
else h += line.height;
}
for (var p = chunk.parent; p; chunk = p, p = chunk.parent) {
for (var i = 0; i < p.children.length; ++i) {
var cur = p.children[i];
if (cur == chunk) break;
else h += cur.height;
Updated codemirror script
r2547 }
update codemirror
r4025 }
Updated codemirror script
r2547 return h;
}
update codemirror
r4025 function getOrder(line) {
var order = line.order;
if (order == null) order = line.order = bidiOrdering(line.text);
return order;
}
// HISTORY
update codemirror to latest version
r4042 function makeHistory(startGen) {
update codemirror
r4025 return {
// Arrays of history events. Doing something adds an event to
// done and clears undo. Undoing moves events from done to
// undone, redoing moves them in the other direction.
done: [], undone: [], undoDepth: Infinity,
// Used to track when changes can be merged into a single undo
// event
lastTime: 0, lastOp: null, lastOrigin: null,
// Used by the isClean() method
update codemirror to latest version
r4042 generation: startGen || 1, maxGeneration: startGen || 1
update codemirror
r4025 };
}
function attachLocalSpans(doc, change, from, to) {
var existing = change["spans_" + doc.id], n = 0;
doc.iter(Math.max(doc.first, from), Math.min(doc.first + doc.size, to), function(line) {
if (line.markedSpans)
(existing || (existing = change["spans_" + doc.id] = {}))[n] = line.markedSpans;
++n;
});
}
function historyChangeFromChange(doc, change) {
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 var from = { line: change.from.line, ch: change.from.ch };
var histChange = {from: from, to: changeEnd(change), text: getBetween(doc, change.from, change.to)};
update codemirror
r4025 attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);
linkedDocs(doc, function(doc) {attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);}, true);
return histChange;
}
function addToHistory(doc, change, selAfter, opId) {
var hist = doc.history;
hist.undone.length = 0;
var time = +new Date, cur = lst(hist.done);
if (cur &&
(hist.lastOp == opId ||
hist.lastOrigin == change.origin && change.origin &&
((change.origin.charAt(0) == "+" && doc.cm && hist.lastTime > time - doc.cm.options.historyEventDelay) ||
change.origin.charAt(0) == "*"))) {
// Merge this change into the last event
var last = lst(cur.changes);
if (posEq(change.from, change.to) && posEq(change.from, last.to)) {
// Optimized case for simple insertion -- don't want to add
// new changesets for every character typed
last.to = changeEnd(change);
Updated codemirror script
r2547 } else {
update codemirror
r4025 // Add new sub-event
cur.changes.push(historyChangeFromChange(doc, change));
}
cur.anchorAfter = selAfter.anchor; cur.headAfter = selAfter.head;
} else {
// Can not be merged, start a new event.
cur = {changes: [historyChangeFromChange(doc, change)],
update codemirror to latest version
r4042 generation: hist.generation,
update codemirror
r4025 anchorBefore: doc.sel.anchor, headBefore: doc.sel.head,
anchorAfter: selAfter.anchor, headAfter: selAfter.head};
hist.done.push(cur);
update codemirror to latest version
r4042 hist.generation = ++hist.maxGeneration;
update codemirror
r4025 while (hist.done.length > hist.undoDepth)
hist.done.shift();
}
hist.lastTime = time;
hist.lastOp = opId;
hist.lastOrigin = change.origin;
}
function removeClearedSpans(spans) {
if (!spans) return null;
for (var i = 0, out; i < spans.length; ++i) {
if (spans[i].marker.explicitlyCleared) { if (!out) out = spans.slice(0, i); }
else if (out) out.push(spans[i]);
}
return !out ? spans : out.length ? out : null;
}
function getOldSpans(doc, change) {
var found = change["spans_" + doc.id];
if (!found) return null;
for (var i = 0, nw = []; i < change.text.length; ++i)
nw.push(removeClearedSpans(found[i]));
return nw;
}
// Used both to provide a JSON-safe object in .getHistory, and, when
// detaching a document, to split the history in two
function copyHistoryArray(events, newGroup) {
for (var i = 0, copy = []; i < events.length; ++i) {
var event = events[i], changes = event.changes, newChanges = [];
copy.push({changes: newChanges, anchorBefore: event.anchorBefore, headBefore: event.headBefore,
anchorAfter: event.anchorAfter, headAfter: event.headAfter});
for (var j = 0; j < changes.length; ++j) {
var change = changes[j], m;
newChanges.push({from: change.from, to: change.to, text: change.text});
if (newGroup) for (var prop in change) if (m = prop.match(/^spans_(\d+)$/)) {
if (indexOf(newGroup, Number(m[1])) > -1) {
lst(newChanges)[prop] = change[prop];
delete change[prop];
}
}
Added server side file editing with commit
r1305 }
update codemirror
r4025 }
return copy;
}
// Rebasing/resetting history to deal with externally-sourced changes
function rebaseHistSel(pos, from, to, diff) {
if (to < pos.line) {
pos.line += diff;
} else if (from < pos.line) {
pos.line = from;
pos.ch = 0;
}
}
// Tries to rebase an array of history events given a change in the
// document. If the change touches the same lines as the event, the
// event, and everything 'behind' it, is discarded. If the change is
// before the event, the event's positions are updated. Uses a
// copy-on-write scheme for the positions, to avoid having to
// reallocate them all on every rebase, but also avoid problems with
// shared position objects being unsafely updated.
function rebaseHistArray(array, from, to, diff) {
for (var i = 0; i < array.length; ++i) {
var sub = array[i], ok = true;
for (var j = 0; j < sub.changes.length; ++j) {
var cur = sub.changes[j];
if (!sub.copied) { cur.from = copyPos(cur.from); cur.to = copyPos(cur.to); }
if (to < cur.from.line) {
cur.from.line += diff;
cur.to.line += diff;
} else if (from <= cur.to.line) {
ok = false;
break;
}
}
if (!sub.copied) {
sub.anchorBefore = copyPos(sub.anchorBefore); sub.headBefore = copyPos(sub.headBefore);
sub.anchorAfter = copyPos(sub.anchorAfter); sub.readAfter = copyPos(sub.headAfter);
sub.copied = true;
}
if (!ok) {
array.splice(0, i + 1);
i = 0;
} else {
rebaseHistSel(sub.anchorBefore); rebaseHistSel(sub.headBefore);
rebaseHistSel(sub.anchorAfter); rebaseHistSel(sub.headAfter);
}
}
}
function rebaseHist(hist, change) {
var from = change.from.line, to = change.to.line, diff = change.text.length - (to - from) - 1;
rebaseHistArray(hist.done, from, to, diff);
rebaseHistArray(hist.undone, from, to, diff);
}
// EVENT OPERATORS
Added server side file editing with commit
r1305
bumped codemirror to latest version
r1606 function stopMethod() {e_stop(this);}
Added server side file editing with commit
r1305 // Ensure an event has a stop method.
function addStop(event) {
bumped codemirror to latest version
r1606 if (!event.stop) event.stop = stopMethod;
Added server side file editing with commit
r1305 return event;
}
bumped codemirror to latest version
r1606 function e_preventDefault(e) {
if (e.preventDefault) e.preventDefault();
else e.returnValue = false;
}
function e_stopPropagation(e) {
if (e.stopPropagation) e.stopPropagation();
else e.cancelBubble = true;
}
update codemirror to latest version
r4042 function e_defaultPrevented(e) {
return e.defaultPrevented != null ? e.defaultPrevented : e.returnValue == false;
}
bumped codemirror to latest version
r1606 function e_stop(e) {e_preventDefault(e); e_stopPropagation(e);}
Updated codemirror script
r2547 CodeMirror.e_stop = e_stop;
CodeMirror.e_preventDefault = e_preventDefault;
CodeMirror.e_stopPropagation = e_stopPropagation;
bumped codemirror to latest version
r1606 function e_target(e) {return e.target || e.srcElement;}
function e_button(e) {
updated codemirror to 2.34
r2861 var b = e.which;
if (b == null) {
if (e.button & 1) b = 1;
else if (e.button & 2) b = 3;
else if (e.button & 4) b = 2;
}
if (mac && e.ctrlKey && b == 1) b = 3;
return b;
bumped codemirror to latest version
r1606 }
Added server side file editing with commit
r1305
update codemirror
r4025 // EVENT HANDLING
function on(emitter, type, f) {
if (emitter.addEventListener)
emitter.addEventListener(type, f, false);
else if (emitter.attachEvent)
emitter.attachEvent("on" + type, f);
else {
var map = emitter._handlers || (emitter._handlers = {});
var arr = map[type] || (map[type] = []);
arr.push(f);
}
}
function off(emitter, type, f) {
if (emitter.removeEventListener)
emitter.removeEventListener(type, f, false);
else if (emitter.detachEvent)
emitter.detachEvent("on" + type, f);
else {
var arr = emitter._handlers && emitter._handlers[type];
if (!arr) return;
for (var i = 0; i < arr.length; ++i)
if (arr[i] == f) { arr.splice(i, 1); break; }
}
}
function signal(emitter, type /*, values...*/) {
var arr = emitter._handlers && emitter._handlers[type];
if (!arr) return;
var args = Array.prototype.slice.call(arguments, 2);
for (var i = 0; i < arr.length; ++i) arr[i].apply(null, args);
}
var delayedCallbacks, delayedCallbackDepth = 0;
function signalLater(emitter, type /*, values...*/) {
var arr = emitter._handlers && emitter._handlers[type];
if (!arr) return;
var args = Array.prototype.slice.call(arguments, 2);
if (!delayedCallbacks) {
++delayedCallbackDepth;
delayedCallbacks = [];
setTimeout(fireDelayed, 0);
}
function bnd(f) {return function(){f.apply(null, args);};};
for (var i = 0; i < arr.length; ++i)
delayedCallbacks.push(bnd(arr[i]));
}
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 function signalDOMEvent(cm, e, override) {
signal(cm, override || e.type, cm, e);
return e_defaultPrevented(e) || e.codemirrorIgnore;
update codemirror to latest version
r4042 }
update codemirror
r4025 function fireDelayed() {
--delayedCallbackDepth;
var delayed = delayedCallbacks;
delayedCallbacks = null;
for (var i = 0; i < delayed.length; ++i) delayed[i]();
}
function hasHandler(emitter, type) {
var arr = emitter._handlers && emitter._handlers[type];
return arr && arr.length > 0;
}
CodeMirror.on = on; CodeMirror.off = off; CodeMirror.signal = signal;
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 function eventMixin(ctor) {
ctor.prototype.on = function(type, f) {on(this, type, f);};
ctor.prototype.off = function(type, f) {off(this, type, f);};
}
update codemirror
r4025 // MISC UTILITIES
// Number of pixels added to scroller and sizer to hide scrollbar
var scrollerCutOff = 30;
// Returned or thrown by various protocols to signal 'I'm not
// handling this'.
var Pass = CodeMirror.Pass = {toString: function(){return "CodeMirror.Pass";}};
Added server side file editing with commit
r1305
function Delayed() {this.id = null;}
Delayed.prototype = {set: function(ms, f) {clearTimeout(this.id); this.id = setTimeout(f, ms);}};
// Counts the column offset in a string, taking tabs into account.
// Used mostly to find indentation.
update codemirror
r4025 function countColumn(string, end, tabSize, startIndex, startValue) {
Added server side file editing with commit
r1305 if (end == null) {
end = string.search(/[^\s\u00a0]/);
if (end == -1) end = string.length;
}
update codemirror
r4025 for (var i = startIndex || 0, n = startValue || 0; i < end; ++i) {
Added server side file editing with commit
r1305 if (string.charAt(i) == "\t") n += tabSize - (n % tabSize);
else ++n;
}
return n;
}
update codemirror
r4025 CodeMirror.countColumn = countColumn;
updated codemirror to 2.34
r2861
var spaceStrs = [""];
function spaceStr(n) {
while (spaceStrs.length <= n)
spaceStrs.push(lst(spaceStrs) + " ");
return spaceStrs[n];
}
function lst(arr) { return arr[arr.length-1]; }
Updated codemirror script
r2547 function selectInput(node) {
if (ios) { // Mobile Safari apparently has a bug where select() is broken.
node.selectionStart = 0;
node.selectionEnd = node.value.length;
update codemirror to latest version
r4042 } else {
// Suppress mysterious IE10 errors
try { node.select(); }
catch(_e) {}
}
Updated codemirror script
r2547 }
Added server side file editing with commit
r1305
update codemirror
r4025 function indexOf(collection, elt) {
if (collection.indexOf) return collection.indexOf(elt);
for (var i = 0, e = collection.length; i < e; ++i)
if (collection[i] == elt) return i;
return -1;
}
function createObj(base, props) {
function Obj() {}
Obj.prototype = base;
var inst = new Obj();
if (props) copyObj(props, inst);
return inst;
}
function copyObj(obj, target) {
if (!target) target = {};
for (var prop in obj) if (obj.hasOwnProperty(prop)) target[prop] = obj[prop];
return target;
}
function emptyArray(size) {
for (var a = [], i = 0; i < size; ++i) a.push(undefined);
return a;
}
function bind(f) {
var args = Array.prototype.slice.call(arguments, 1);
return function(){return f.apply(null, args);};
}
update codemirror to latest version
r4042 var nonASCIISingleCaseWordChar = /[\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/;
update codemirror
r4025 function isWordChar(ch) {
return /\w/.test(ch) || ch > "\x80" &&
(ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch));
}
function isEmpty(obj) {
for (var n in obj) if (obj.hasOwnProperty(n) && obj[n]) return false;
return true;
}
var isExtendingChar = /[\u0300-\u036F\u0483-\u0487\u0488-\u0489\u0591-\u05BD\u05BF\u05C1-\u05C2\u05C4-\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7-\u06E8\u06EA-\u06ED\uA66F\uA670-\uA672\uA674-\uA67D\uA69F\udc00-\udfff]/;
// DOM UTILITIES
Added server side file editing with commit
r1305
updated codemirror to 2.34
r2861 function elt(tag, content, className, style) {
var e = document.createElement(tag);
if (className) e.className = className;
if (style) e.style.cssText = style;
if (typeof content == "string") setTextContent(e, content);
else if (content) for (var i = 0; i < content.length; ++i) e.appendChild(content[i]);
return e;
Updated codemirror script
r2547 }
update codemirror
r4025
updated codemirror to 2.34
r2861 function removeChildren(e) {
update codemirror
r4025 for (var count = e.childNodes.length; count > 0; --count)
e.removeChild(e.firstChild);
updated codemirror to 2.34
r2861 return e;
}
update codemirror
r4025
updated codemirror to 2.34
r2861 function removeChildrenAndAdd(parent, e) {
update codemirror
r4025 return removeChildren(parent).appendChild(e);
}
updated codemirror to 2.34
r2861 function setTextContent(e, str) {
if (ie_lt9) {
e.innerHTML = "";
e.appendChild(document.createTextNode(str));
} else e.textContent = str;
}
Added server side file editing with commit
r1305
update codemirror
r4025 function getRect(node) {
return node.getBoundingClientRect();
}
CodeMirror.replaceGetRect = function(f) { getRect = f; };
// FEATURE DETECTION
// Detect drag-and-drop
var dragAndDrop = function() {
// There is *some* kind of drag-and-drop support in IE6-8, but I
// couldn't get it to work yet.
if (ie_lt9) return false;
var div = elt('div');
return "draggable" in div || "dragDrop" in div;
}();
// For a reason I have yet to figure out, some browsers disallow
// word wrapping between certain characters *only* if a new inline
// element is started between them. This makes it hard to reliably
// measure the position of things, since that requires inserting an
update codemirror to latest version
r4042 // extra span. This terribly fragile set of tests matches the
update codemirror
r4025 // character combinations that suffer from this phenomenon on the
// various browsers.
update codemirror to latest version
r4042 function spanAffectsWrapping() { return false; }
if (gecko) // Only for "$'"
spanAffectsWrapping = function(str, i) {
return str.charCodeAt(i - 1) == 36 && str.charCodeAt(i) == 39;
};
else if (safari && !/Version\/([6-9]|\d\d)\b/.test(navigator.userAgent))
spanAffectsWrapping = function(str, i) {
return /\-[^ \-?]|\?[^ !\'\"\),.\-\/:;\?\]\}]/.test(str.slice(i - 1, i + 1));
};
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 else if (webkit && !/Chrome\/(?:29|[3-9]\d|\d\d\d)\./.test(navigator.userAgent))
update codemirror to latest version
r4042 spanAffectsWrapping = function(str, i) {
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 if (i > 1 && str.charCodeAt(i - 1) == 45) {
if (/\w/.test(str.charAt(i - 2)) && /[^\-?\.]/.test(str.charAt(i))) return true;
if (i > 2 && /[\d\.,]/.test(str.charAt(i - 2)) && /[\d\.,]/.test(str.charAt(i))) return false;
}
update codemirror to latest version
r4042 return /[~!#%&*)=+}\]|\"\.>,:;][({[<]|-[^\-?\.\u2010-\u201f\u2026]|\?[\w~`@#$%\^&*(_=+{[|><]|…[\w~`@#$%\^&*(_=+{[><]/.test(str.slice(i - 1, i + 1));
};
update codemirror
r4025
var knownScrollbarWidth;
function scrollbarWidth(measure) {
if (knownScrollbarWidth != null) return knownScrollbarWidth;
var test = elt("div", null, null, "width: 50px; height: 50px; overflow-x: scroll");
removeChildrenAndAdd(measure, test);
if (test.offsetWidth)
knownScrollbarWidth = test.offsetHeight - test.clientHeight;
return knownScrollbarWidth || 0;
}
var zwspSupported;
function zeroWidthElement(measure) {
if (zwspSupported == null) {
var test = elt("span", "\u200b");
removeChildrenAndAdd(measure, elt("span", [test, document.createTextNode("x")]));
if (measure.firstChild.offsetHeight != 0)
zwspSupported = test.offsetWidth <= 1 && test.offsetHeight > 2 && !ie_lt8;
}
if (zwspSupported) return elt("span", "\u200b");
else return elt("span", "\u00a0", null, "display: inline-block; width: 1px; margin-right: -1px");
Updated codemirror script
r2547 }
Added server side file editing with commit
r1305
// See if "".split is the broken IE version, if so, provide an
// alternative way to split lines.
Updated codemirror script
r2547 var splitLines = "\n\nb".split(/\n/).length != 3 ? function(string) {
updated codemirror to 2.34
r2861 var pos = 0, result = [], l = string.length;
while (pos <= l) {
var nl = string.indexOf("\n", pos);
if (nl == -1) nl = string.length;
var line = string.slice(pos, string.charAt(nl - 1) == "\r" ? nl - 1 : nl);
var rt = line.indexOf("\r");
if (rt != -1) {
result.push(line.slice(0, rt));
pos += rt + 1;
} else {
result.push(line);
pos = nl + 1;
}
Updated codemirror script
r2547 }
return result;
updated codemirror to 2.34
r2861 } : function(string){return string.split(/\r\n?|\n/);};
bumped codemirror to latest version
r1606 CodeMirror.splitLines = splitLines;
Added server side file editing with commit
r1305
Updated codemirror script
r2547 var hasSelection = window.getSelection ? function(te) {
try { return te.selectionStart != te.selectionEnd; }
catch(e) { return false; }
} : function(te) {
try {var range = te.ownerDocument.selection.createRange();}
catch(e) {}
if (!range || range.parentElement() != te) return false;
return range.compareEndPoints("StartToEnd", range) != 0;
};
Added server side file editing with commit
r1305
update codemirror
r4025 var hasCopyEvent = (function() {
var e = elt("div");
if ("oncopy" in e) return true;
e.setAttribute("oncopy", "return;");
return typeof e.oncopy == 'function';
})();
// KEY NAMING
Added server side file editing with commit
r1305
Updated codemirror script
r2547 var keyNames = {3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt",
19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End",
36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert",
46: "Delete", 59: ";", 91: "Mod", 92: "Mod", 93: "Mod", 109: "-", 107: "=", 127: "Delete",
186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\",
221: "]", 222: "'", 63276: "PageUp", 63277: "PageDown", 63275: "End", 63273: "Home",
63234: "Left", 63232: "Up", 63235: "Right", 63233: "Down", 63302: "Insert", 63272: "Delete"};
CodeMirror.keyNames = keyNames;
(function() {
// Number keys
for (var i = 0; i < 10; i++) keyNames[i + 48] = String(i);
// Alphabetic keys
for (var i = 65; i <= 90; i++) keyNames[i] = String.fromCharCode(i);
// Function keys
for (var i = 1; i <= 12; i++) keyNames[i + 111] = keyNames[i + 63235] = "F" + i;
})();
update codemirror
r4025 // BIDI HELPERS
function iterateBidiSections(order, from, to, f) {
if (!order) return f(from, to, "ltr");
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 var found = false;
update codemirror
r4025 for (var i = 0; i < order.length; ++i) {
var part = order[i];
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 if (part.from < to && part.to > from || from == to && part.to == from) {
update codemirror
r4025 f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr");
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 found = true;
}
}
if (!found) f(from, to, "ltr");
update codemirror
r4025 }
function bidiLeft(part) { return part.level % 2 ? part.to : part.from; }
function bidiRight(part) { return part.level % 2 ? part.from : part.to; }
function lineLeft(line) { var order = getOrder(line); return order ? bidiLeft(order[0]) : 0; }
function lineRight(line) {
var order = getOrder(line);
if (!order) return line.text.length;
return bidiRight(lst(order));
}
function lineStart(cm, lineN) {
var line = getLine(cm.doc, lineN);
var visual = visualLine(cm.doc, line);
if (visual != line) lineN = lineNo(visual);
var order = getOrder(visual);
var ch = !order ? 0 : order[0].level % 2 ? lineRight(visual) : lineLeft(visual);
return Pos(lineN, ch);
}
function lineEnd(cm, lineN) {
var merged, line;
while (merged = collapsedSpanAtEnd(line = getLine(cm.doc, lineN)))
lineN = merged.find().to.line;
var order = getOrder(line);
var ch = !order ? line.text.length : order[0].level % 2 ? lineLeft(line) : lineRight(line);
return Pos(lineN, ch);
}
update codemirror to latest version
r4042 function compareBidiLevel(order, a, b) {
var linedir = order[0].level;
if (a == linedir) return true;
if (b == linedir) return false;
return a < b;
}
var bidiOther;
function getBidiPartAt(order, pos) {
for (var i = 0, found; i < order.length; ++i) {
var cur = order[i];
if (cur.from < pos && cur.to > pos) { bidiOther = null; return i; }
if (cur.from == pos || cur.to == pos) {
if (found == null) {
found = i;
} else if (compareBidiLevel(order, cur.level, order[found].level)) {
bidiOther = found;
return i;
} else {
bidiOther = i;
return found;
}
}
}
bidiOther = null;
return found;
}
function moveInLine(line, pos, dir, byUnit) {
if (!byUnit) return pos + dir;
do pos += dir;
while (pos > 0 && isExtendingChar.test(line.text.charAt(pos)));
return pos;
}
update codemirror
r4025 // This is somewhat involved. It is needed in order to move
// 'visually' through bi-directional text -- i.e., pressing left
// should make the cursor go left, even when in RTL text. The
// tricky part is the 'jumps', where RTL and LTR text touch each
// other. This often requires the cursor offset to move more than
// one unit, in order to visually move one unit.
function moveVisually(line, start, dir, byUnit) {
var bidi = getOrder(line);
if (!bidi) return moveLogically(line, start, dir, byUnit);
update codemirror to latest version
r4042 var pos = getBidiPartAt(bidi, start), part = bidi[pos];
var target = moveInLine(line, start, part.level % 2 ? -dir : dir, byUnit);
for (;;) {
if (target > part.from && target < part.to) return target;
if (target == part.from || target == part.to) {
if (getBidiPartAt(bidi, target) == pos) return target;
part = bidi[pos += dir];
return (dir > 0) == part.level % 2 ? part.to : part.from;
update codemirror
r4025 } else {
update codemirror to latest version
r4042 part = bidi[pos += dir];
if (!part) return null;
if ((dir > 0) == part.level % 2)
target = moveInLine(line, part.to, -1, byUnit);
else
target = moveInLine(line, part.from, 1, byUnit);
update codemirror
r4025 }
}
}
function moveLogically(line, start, dir, byUnit) {
var target = start + dir;
if (byUnit) while (target > 0 && isExtendingChar.test(line.text.charAt(target))) target += dir;
return target < 0 || target > line.text.length ? null : target;
}
// Bidirectional ordering algorithm
// See http://unicode.org/reports/tr9/tr9-13.html for the algorithm
// that this (partially) implements.
// One-char codes used for character types:
// L (L): Left-to-Right
// R (R): Right-to-Left
// r (AL): Right-to-Left Arabic
// 1 (EN): European Number
// + (ES): European Number Separator
// % (ET): European Number Terminator
// n (AN): Arabic Number
// , (CS): Common Number Separator
// m (NSM): Non-Spacing Mark
// b (BN): Boundary Neutral
// s (B): Paragraph Separator
// t (S): Segment Separator
// w (WS): Whitespace
// N (ON): Other Neutrals
// Returns null if characters are ordered as they appear
// (left-to-right), or an array of sections ({from, to, level}
// objects) in the order in which they occur visually.
var bidiOrdering = (function() {
// Character types for codepoints 0 to 0xff
var lowTypes = "bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLL";
// Character types for codepoints 0x600 to 0x6ff
var arabicTypes = "rrrrrrrrrrrr,rNNmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmrrrrrrrnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmNmmmmrrrrrrrrrrrrrrrrrr";
function charType(code) {
if (code <= 0xff) return lowTypes.charAt(code);
else if (0x590 <= code && code <= 0x5f4) return "R";
else if (0x600 <= code && code <= 0x6ff) return arabicTypes.charAt(code - 0x600);
else if (0x700 <= code && code <= 0x8ac) return "r";
else return "L";
}
var bidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/;
var isNeutral = /[stwN]/, isStrong = /[LRr]/, countsAsLeft = /[Lb1n]/, countsAsNum = /[1n]/;
// Browsers seem to always treat the boundaries of block elements as being L.
var outerType = "L";
return function(str) {
if (!bidiRE.test(str)) return false;
var len = str.length, types = [];
for (var i = 0, type; i < len; ++i)
types.push(type = charType(str.charCodeAt(i)));
// W1. Examine each non-spacing mark (NSM) in the level run, and
// change the type of the NSM to the type of the previous
// character. If the NSM is at the start of the level run, it will
// get the type of sor.
for (var i = 0, prev = outerType; i < len; ++i) {
var type = types[i];
if (type == "m") types[i] = prev;
else prev = type;
}
// W2. Search backwards from each instance of a European number
// until the first strong type (R, L, AL, or sor) is found. If an
// AL is found, change the type of the European number to Arabic
// number.
// W3. Change all ALs to R.
for (var i = 0, cur = outerType; i < len; ++i) {
var type = types[i];
if (type == "1" && cur == "r") types[i] = "n";
else if (isStrong.test(type)) { cur = type; if (type == "r") types[i] = "R"; }
}
// W4. A single European separator between two European numbers
// changes to a European number. A single common separator between
// two numbers of the same type changes to that type.
for (var i = 1, prev = types[0]; i < len - 1; ++i) {
var type = types[i];
if (type == "+" && prev == "1" && types[i+1] == "1") types[i] = "1";
else if (type == "," && prev == types[i+1] &&
(prev == "1" || prev == "n")) types[i] = prev;
prev = type;
}
// W5. A sequence of European terminators adjacent to European
// numbers changes to all European numbers.
// W6. Otherwise, separators and terminators change to Other
// Neutral.
for (var i = 0; i < len; ++i) {
var type = types[i];
if (type == ",") types[i] = "N";
else if (type == "%") {
for (var end = i + 1; end < len && types[end] == "%"; ++end) {}
var replace = (i && types[i-1] == "!") || (end < len - 1 && types[end] == "1") ? "1" : "N";
for (var j = i; j < end; ++j) types[j] = replace;
i = end - 1;
}
}
// W7. Search backwards from each instance of a European number
// until the first strong type (R, L, or sor) is found. If an L is
// found, then change the type of the European number to L.
for (var i = 0, cur = outerType; i < len; ++i) {
var type = types[i];
if (cur == "L" && type == "1") types[i] = "L";
else if (isStrong.test(type)) cur = type;
}
// N1. A sequence of neutrals takes the direction of the
// surrounding strong text if the text on both sides has the same
// direction. European and Arabic numbers act as if they were R in
// terms of their influence on neutrals. Start-of-level-run (sor)
// and end-of-level-run (eor) are used at level run boundaries.
// N2. Any remaining neutrals take the embedding direction.
for (var i = 0; i < len; ++i) {
if (isNeutral.test(types[i])) {
for (var end = i + 1; end < len && isNeutral.test(types[end]); ++end) {}
var before = (i ? types[i-1] : outerType) == "L";
var after = (end < len - 1 ? types[end] : outerType) == "L";
var replace = before || after ? "L" : "R";
for (var j = i; j < end; ++j) types[j] = replace;
i = end - 1;
}
}
// Here we depart from the documented algorithm, in order to avoid
// building up an actual levels array. Since there are only three
// levels (0, 1, 2) in an implementation that doesn't take
// explicit embedding into account, we can build up the order on
// the fly, without following the level-based algorithm.
var order = [], m;
for (var i = 0; i < len;) {
if (countsAsLeft.test(types[i])) {
var start = i;
for (++i; i < len && countsAsLeft.test(types[i]); ++i) {}
order.push({from: start, to: i, level: 0});
} else {
var pos = i, at = order.length;
for (++i; i < len && types[i] != "L"; ++i) {}
for (var j = pos; j < i;) {
if (countsAsNum.test(types[j])) {
if (pos < j) order.splice(at, 0, {from: pos, to: j, level: 1});
var nstart = j;
for (++j; j < i && countsAsNum.test(types[j]); ++j) {}
order.splice(at, 0, {from: nstart, to: j, level: 2});
pos = j;
} else ++j;
}
if (pos < i) order.splice(at, 0, {from: pos, to: i, level: 1});
}
}
if (order[0].level == 1 && (m = str.match(/^\s+/))) {
order[0].from = m[0].length;
order.unshift({from: 0, to: m[0].length, level: 0});
}
if (lst(order).level == 1 && (m = str.match(/\s+$/))) {
lst(order).to -= m[0].length;
order.push({from: len - m[0].length, to: len, level: 0});
}
if (order[0].level != lst(order).level)
order.push({from: len, to: len, level: order[0].level});
return order;
};
})();
// THE END
Bradley M. Kuhn
Update CodeMirror CSS and Javascript files to version 3.15, under MIT-permissive license....
r4120 CodeMirror.version = "3.15.0";
updated codemirror to 2.34
r2861
Added server side file editing with commit
r1305 return CodeMirror;
})();