| Index: chrome_linux/resources/inspector/CodeMirrorTextEditor.js
|
| ===================================================================
|
| --- chrome_linux/resources/inspector/CodeMirrorTextEditor.js (revision 221742)
|
| +++ chrome_linux/resources/inspector/CodeMirrorTextEditor.js (working copy)
|
| @@ -1,7815 +1,1389 @@
|
| -/*
|
| - * Copyright (C) 2012 Google Inc. All rights reserved.
|
| - *
|
| - * Redistribution and use in source and binary forms, with or without
|
| - * modification, are permitted provided that the following conditions are
|
| - * met:
|
| - *
|
| - * * Redistributions of source code must retain the above copyright
|
| - * notice, this list of conditions and the following disclaimer.
|
| - * * Redistributions in binary form must reproduce the above
|
| - * copyright notice, this list of conditions and the following disclaimer
|
| - * in the documentation and/or other materials provided with the
|
| - * distribution.
|
| - * * Neither the name of Google Inc. nor the names of its
|
| - * contributors may be used to endorse or promote products derived from
|
| - * this software without specific prior written permission.
|
| - *
|
| - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
| - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
| - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
| - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
| - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
| - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
| - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
| - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
| - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
| - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
| - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
| - */
|
| -
|
| -// CodeMirror is the only global var we claim
|
| -window.CodeMirror = (function() {
|
| - "use strict";
|
| -
|
| - // 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]);
|
| - // 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 || {};
|
| - // Determine effective options based on given values and defaults.
|
| - 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;");
|
| - 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";
|
| - input.setAttribute("autocorrect", "off"); input.setAttribute("autocapitalize", "off");
|
| -
|
| - // Wraps and hides input textarea
|
| - 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");
|
| - // DIVs containing the selection and the actual code
|
| - d.lineDiv = elt("div");
|
| - d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1");
|
| - // Blinky cursor, and element used to ensure cursor fits at the end of a line
|
| - 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");
|
| - // Used to measure text size
|
| - 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");
|
| - // Moved around its parent to cover visible view
|
| - d.mover = elt("div", [elt("div", [d.lineSpace], "CodeMirror-lines")], null, "position: relative");
|
| - // Set to the height of the text, causes scrolling
|
| - 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;
|
| - // Helper element to properly size the gutter backgrounds
|
| - var scrollerInner = elt("div", [d.sizer, d.heightForcer, d.gutters], null, "position: relative; min-height: 100%");
|
| - // Provides scrolling
|
| - d.scroller = elt("div", [scrollerInner], "CodeMirror-scroll");
|
| - d.scroller.setAttribute("tabIndex", "-1");
|
| - // The element in which the editor lives.
|
| - d.wrapper = elt("div", [d.inputDiv, d.scrollbarH, d.scrollbarV,
|
| - d.scrollbarFiller, d.scroller], "CodeMirror");
|
| - // 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);
|
| -
|
| - // Needed to hide big blue blinking cursor on Mobile Safari
|
| - if (ios) input.style.width = "0px";
|
| - if (!webkit) d.scroller.draggable = true;
|
| - // Needed to handle Tab key in KHTML
|
| - if (khtml) { d.inputDiv.style.height = "1px"; d.inputDiv.style.position = "absolute"; }
|
| - // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8).
|
| - else if (ie_lt8) d.scrollbarH.style.minWidth = d.scrollbarV.style.minWidth = "18px";
|
| -
|
| - // Current visible range (may be bigger than the view window).
|
| - 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();
|
| - // True when a drag from the editor is active
|
| - d.draggingText = false;
|
| -
|
| - 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;
|
| -
|
| - // Tracks the maximum line length so that the horizontal scrollbar
|
| - // can be kept static when scrolling.
|
| - 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);
|
| - setTimeout(function(){updateScrollbars(cm.display, cm.doc.height);}, 100);
|
| - }
|
| -
|
| - 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) {
|
| - var style = keyMap[cm.options.keyMap].style;
|
| - cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-keymap-\S+/g, "") +
|
| - (style ? " cm-keymap-" + style : "");
|
| - }
|
| -
|
| - 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);
|
| - }
|
| -
|
| - 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.
|
| - function updateScrollbars(d /* display */, docHeight) {
|
| - var totalHeight = docHeight + paddingVert(d);
|
| - d.sizer.style.minHeight = d.heightForcer.style.top = totalHeight + "px";
|
| - var scrollHeight = Math.max(totalHeight, d.scroller.scrollHeight);
|
| - var needsH = d.scroller.scrollWidth > d.scroller.clientWidth;
|
| - var needsV = scrollHeight > d.scroller.clientHeight;
|
| - 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 = "";
|
| -
|
| - 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
|
| -
|
| - function updateDisplay(cm, changes, viewPort) {
|
| - var oldFrom = cm.display.showingFrom, oldTo = cm.display.showingTo;
|
| - var updated = updateDisplayInner(cm, changes, viewPort);
|
| - 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);
|
| - }
|
| - updateSelection(cm);
|
| - updateScrollbars(cm.display, cm.doc.height);
|
| -
|
| - 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.
|
| - function updateDisplayInner(cm, changes, viewPort) {
|
| - var display = cm.display, doc = cm.doc;
|
| - if (!display.wrapper.clientWidth) {
|
| - display.showingFrom = display.showingTo = doc.first;
|
| - display.viewOffset = 0;
|
| - return;
|
| - }
|
| -
|
| - // Compute the new visible window
|
| - // If scrollTop is specified, use that to determine which lines
|
| - // to render instead of the current scrollbar position.
|
| - var visible = visibleLines(display, doc, viewPort);
|
| - // Bail out if the visible area is already rendered and nothing changed.
|
| - if (changes.length == 0 &&
|
| - 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;
|
| - }
|
| - if (intactLines == to - from && from == display.showingFrom && to == display.showingTo) {
|
| - updateViewOffset(cm);
|
| - return;
|
| - }
|
| - intact.sort(function(a, b) {return a.from - b.from;});
|
| -
|
| - var focused = document.activeElement;
|
| - if (intactLines < (to - from) * .7) display.lineDiv.style.display = "none";
|
| - patchDisplay(cm, from, to, intact, positionsChangedFrom);
|
| - display.lineDiv.style.display = "";
|
| - if (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.
|
| - if (different) display.lastSizeC = display.wrapper.clientHeight;
|
| - display.showingFrom = from; display.showingTo = to;
|
| - startWorker(cm, 100);
|
| -
|
| - 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;
|
| - }
|
| - }
|
| - updateViewOffset(cm);
|
| -
|
| - if (visibleLines(display, doc, viewPort).to > to)
|
| - updateDisplayInner(cm, [], viewPort);
|
| - return true;
|
| - }
|
| -
|
| - 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);
|
| - if (line.widgets && cur.previousSibling) for (var i = 0; i < line.widgets.length; ++i)
|
| - if (line.widgets[i].showIfHidden) {
|
| - 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;
|
| - }
|
| - var wnode = prev.appendChild(elt("div", [line.widgets[i].node], "CodeMirror-linewidget"));
|
| - positionLineWidget(line.widgets[i], wnode, prev, dims);
|
| - }
|
| - } 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;
|
| - var isOk = true, widgetsSeen = 0;
|
| - for (var n = reuse.firstChild, next; n; n = next) {
|
| - next = n.nextSibling;
|
| - if (!/\bCodeMirror-linewidget\b/.test(n.className)) {
|
| - reuse.removeChild(n);
|
| - } else {
|
| - for (var i = 0, first = true; i < line.widgets.length; ++i) {
|
| - var widget = line.widgets[i], isFirst = false;
|
| - if (!widget.above) { isFirst = first; first = false; }
|
| - if (widget.node == n.firstChild) {
|
| - positionLineWidget(widget, n, reuse, dims);
|
| - ++widgetsSeen;
|
| - if (isFirst) reuse.insertBefore(lineElement, n);
|
| - break;
|
| - }
|
| - }
|
| - if (i == line.widgets.length) { isOk = false; break; }
|
| - }
|
| - }
|
| - 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");
|
| - 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
|
| - 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"));
|
| - }
|
| -
|
| - function drawForLine(line, fromArg, toArg, retTop) {
|
| - var lineObj = getLine(doc, line);
|
| - var lineLen = lineObj.text.length, rVal = retTop ? Infinity : -Infinity;
|
| - function coords(ch) {
|
| - return charCoords(cm, Pos(line, ch), "div", lineObj);
|
| - }
|
| -
|
| - iterateBidiSections(getOrder(lineObj), fromArg || 0, toArg == null ? lineLen : toArg, function(from, to, dir) {
|
| - var leftPos = coords(dir == "rtl" ? to - 1 : from);
|
| - var rightPos = coords(dir == "rtl" ? from : to - 1);
|
| - var left = leftPos.left, right = rightPos.right;
|
| - 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;
|
| - if (fromArg == null && from == 0) left = pl;
|
| - rVal = retTop ? Math.min(rightPos.top, rVal) : Math.max(rightPos.bottom, rVal);
|
| - if (left < pl + 1) left = pl;
|
| - add(left, rightPos.top, right - left, rightPos.bottom);
|
| - });
|
| - return rVal;
|
| - }
|
| -
|
| - if (sel.from.line == sel.to.line) {
|
| - drawForLine(sel.from.line, sel.from.ch, sel.to.ch);
|
| - } else {
|
| - var fromObj = getLine(doc, sel.from.line);
|
| - var cur = fromObj, merged, path = [sel.from.line, sel.from.ch], singleLine;
|
| - while (merged = collapsedSpanAtEnd(cur)) {
|
| - var found = merged.find();
|
| - path.push(found.from.ch, found.to.line, found.to.ch);
|
| - if (found.to.line == sel.to.line) {
|
| - path.push(sel.to.ch);
|
| - singleLine = true;
|
| - break;
|
| - }
|
| - cur = getLine(doc, found.to.line);
|
| - }
|
| -
|
| - // This is a single, merged line
|
| - if (singleLine) {
|
| - for (var i = 0; i < path.length; i += 3)
|
| - drawForLine(path[i], path[i+1], path[i+2]);
|
| - } else {
|
| - var middleTop, middleBot, toObj = getLine(doc, sel.to.line);
|
| - if (sel.from.ch)
|
| - // Draw the first line of selection.
|
| - middleTop = drawForLine(sel.from.line, sel.from.ch, null, false);
|
| - else
|
| - // Simply include it in the middle block.
|
| - middleTop = heightAtLine(cm, fromObj) - display.viewOffset;
|
| -
|
| - if (!sel.to.ch)
|
| - middleBot = heightAtLine(cm, toObj) - display.viewOffset;
|
| - else
|
| - middleBot = drawForLine(sel.to.line, collapsedSpanAtStart(toObj) ? null : 0, sel.to.ch, true);
|
| -
|
| - if (middleTop < middleBot) add(pl, middleTop, null, middleBot);
|
| - }
|
| - }
|
| -
|
| - removeChildrenAndAdd(display.selectionDiv, fragment);
|
| - display.selectionDiv.style.display = "";
|
| - }
|
| -
|
| - // Cursor-blinking
|
| - function restartBlink(cm) {
|
| - var display = cm.display;
|
| - clearInterval(display.blinker);
|
| - var on = true;
|
| - display.cursor.style.visibility = display.otherCursor.style.visibility = "";
|
| - display.blinker = setInterval(function() {
|
| - if (!display.cursor.offsetHeight) return;
|
| - 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.
|
| - function findStartLine(cm, n) {
|
| - 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);
|
| - if (line.stateAfter) return search;
|
| - var indented = countColumn(line.text, null, cm.options.tabSize);
|
| - if (minline == null || minindent > indented) {
|
| - minline = search - 1;
|
| - minindent = indented;
|
| - }
|
| - }
|
| - return minline;
|
| - }
|
| -
|
| - function getStateBefore(cm, n) {
|
| - var doc = cm.doc, display = cm.display;
|
| - if (!doc.mode.startState) return true;
|
| - var pos = findStartLine(cm, n), state = pos > doc.first && getLine(doc, pos-1).stateAfter;
|
| - 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;
|
| - }
|
| -
|
| - function measureChar(cm, line, ch, data) {
|
| - 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;
|
| - }
|
| - return {left: pos < ch ? r.right : r.left,
|
| - right: pos > ch ? r.left : r.right,
|
| - top: r.top, bottom: r.bottom};
|
| - }
|
| -
|
| - 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)
|
| - return memo.measure;
|
| - }
|
| - }
|
| -
|
| - function measureLine(cm, line) {
|
| - // First look in the cache
|
| - var measure = findCachedMeasurement(cm, line);
|
| - if (!measure) {
|
| - // Failing that, recompute and store result in cache
|
| - 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);
|
| - }
|
| - return measure;
|
| - }
|
| -
|
| - function measureLineInner(cm, line) {
|
| - var display = cm.display, measure = emptyArray(line.text.length);
|
| - var pre = lineContent(cm, line, measure);
|
| -
|
| - // 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);
|
| -
|
| - for (var i = 0, cur; i < measure.length; ++i) if (cur = measure[i]) {
|
| - var size = getRect(cur);
|
| - var top = Math.max(0, size.top - outer.top), bot = Math.min(size.bottom - outer.top, maxBot);
|
| - for (var j = 0; j < vranges.length; j += 2) {
|
| - var rtop = vranges[j], rbot = vranges[j+1];
|
| - 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) {
|
| - vranges[j] = Math.min(top, rtop);
|
| - vranges[j+1] = Math.max(bot, rbot);
|
| - break;
|
| - }
|
| - }
|
| - if (j == vranges.length) vranges.push(top, bot);
|
| - var right = size.right;
|
| - if (cur.measureRight) right = getRect(cur.measureRight).left;
|
| - data[i] = {left: size.left - outer.left, right: right - outer.left, top: j};
|
| - }
|
| - for (var i = 0, cur; i < data.length; ++i) if (cur = data[i]) {
|
| - var vr = cur.top;
|
| - cur.top = vranges[vr]; cur.bottom = vranges[vr+1];
|
| - }
|
| -
|
| - 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);
|
| - if (cached) return measureChar(cm, line, line.text.length, cached).right;
|
| -
|
| - var pre = lineContent(cm, line);
|
| - 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;
|
| - cm.display.maxLineChanged = true;
|
| - cm.display.lineNumChars = null;
|
| - }
|
| -
|
| - // 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);
|
| - if (context != "local") yOff -= cm.display.viewOffset;
|
| - if (context == "page") {
|
| - var lOff = getRect(cm.display.lineSpace);
|
| - yOff += lOff.top + (window.pageYOffset || (document.documentElement || document.body).scrollTop);
|
| - var xOff = lOff.left + (window.pageXOffset || (document.documentElement || document.body).scrollLeft);
|
| - 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 local coords
|
| - function fromCoordSystem(cm, coords, context) {
|
| - if (context == "div") return coords;
|
| - var left = coords.left, top = coords.top;
|
| - if (context == "page") {
|
| - left -= window.pageXOffset || (document.documentElement || document.body).scrollLeft;
|
| - top -= window.pageYOffset || (document.documentElement || document.body).scrollTop;
|
| - }
|
| - var lineSpaceBox = getRect(cm.display.lineSpace);
|
| - left -= lineSpaceBox.left;
|
| - top -= lineSpaceBox.top;
|
| - if (context == "local" || !context) {
|
| - var editorBox = getRect(cm.display.wrapper);
|
| - left -= editorBox.left;
|
| - top -= editorBox.top;
|
| - }
|
| - return {left: left, top: top};
|
| - }
|
| -
|
| - function charCoords(cm, pos, context, lineObj) {
|
| - if (!lineObj) lineObj = getLine(cm.doc, pos.line);
|
| - return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch), context);
|
| - }
|
| -
|
| - function cursorCoords(cm, pos, context, lineObj, measurement) {
|
| - lineObj = lineObj || getLine(cm.doc, pos.line);
|
| - if (!measurement) measurement = measureLine(cm, lineObj);
|
| - function get(ch, right) {
|
| - var m = measureChar(cm, lineObj, ch, measurement);
|
| - if (right) m.left = m.right; else m.right = m.left;
|
| - return intoCoordSystem(cm, lineObj, m, context);
|
| - }
|
| - var order = getOrder(lineObj), ch = pos.ch;
|
| - if (!order) return get(ch);
|
| - var main, other, linedir = order[0].level;
|
| - for (var i = 0; i < order.length; ++i) {
|
| - var part = order[i], rtl = part.level % 2, nb, here;
|
| - if (part.from < ch && part.to > ch) return get(ch, rtl);
|
| - var left = rtl ? part.to : part.from, right = rtl ? part.from : part.to;
|
| - if (left == ch) {
|
| - // IE returns bogus offsets and widths for edges where the
|
| - // direction flips, but only for the side with the lower
|
| - // level. So we try to use the side with the higher level.
|
| - if (i && part.level < (nb = order[i-1]).level) here = get(nb.level % 2 ? nb.from : nb.to - 1, true);
|
| - else here = get(rtl && part.from != part.to ? ch - 1 : ch);
|
| - if (rtl == linedir) main = here; else other = here;
|
| - } else if (right == ch) {
|
| - var nb = i < order.length - 1 && order[i+1];
|
| - if (!rtl && nb && nb.from == nb.to) continue;
|
| - if (nb && part.level < nb.level) here = get(nb.level % 2 ? nb.to - 1 : nb.from);
|
| - else here = get(rtl ? ch : ch - 1, true);
|
| - if (rtl == linedir) main = here; else other = here;
|
| - }
|
| - }
|
| - if (linedir && !ch) other = get(order[0].to - 1);
|
| - if (!main) return other;
|
| - if (other) main.other = other;
|
| - return main;
|
| - }
|
| -
|
| - function PosMaybeOutside(line, ch, outside) {
|
| - var pos = new Pos(line, ch);
|
| - 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;
|
| - if (y < 0) return PosMaybeOutside(doc.first, 0, true);
|
| - var lineNo = lineAtHeight(doc, y), last = doc.first + doc.size - 1;
|
| - if (lineNo > last)
|
| - return PosMaybeOutside(doc.first + doc.size - 1, getLine(doc, last).text.length, true);
|
| - 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();
|
| - if (merged && found.ch >= mergedPos.from.ch)
|
| - 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;
|
| -
|
| - if (x > toX) return PosMaybeOutside(lineNo, to, toOutside);
|
| - // Do a binary search between these bounds.
|
| - for (;;) {
|
| - if (bidi ? to == from || to == moveVisually(lineObj, from, 1) : to - from <= 1) {
|
| - var after = x - fromX < toX - x, ch = after ? from : to;
|
| - while (isExtendingChar.test(lineObj.text.charAt(ch))) ++ch;
|
| - var pos = PosMaybeOutside(lineNo, ch, after ? fromOutside : toOutside);
|
| - pos.after = after;
|
| - 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: [],
|
| - updateInput: null,
|
| - userSelChange: null,
|
| - textChanged: null,
|
| - selectionChanged: 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) {
|
| - 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);
|
| - }
|
| - if (op.changes.length || newScrollPos && newScrollPos.scrollTop != null) {
|
| - updated = updateDisplay(cm, op.changes, newScrollPos && newScrollPos.scrollTop);
|
| - 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);
|
| - } 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.selectionChanged) 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;
|
| - if (!cm.state.focused || hasSelection(input) || isReadOnly(cm)) return false;
|
| - var text = input.value;
|
| - if (text == prevInput && posEq(sel.from, sel.to)) return false;
|
| - // IE enjoys randomly deselecting our input's text when
|
| - // re-focusing. If the selection is gone but the cursor is at the
|
| - // start of the input, that's probably what happened.
|
| - if (ie && text && input.selectionStart === 0) {
|
| - 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[same] == text[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)));
|
| - var updateInput = cm.curOp.updateInput;
|
| - makeChange(cm.doc, {from: from, to: to, text: splitLines(text.slice(same)),
|
| - origin: cm.state.pasteIncoming ? "paste" : "+input"}, "end");
|
| -
|
| - cm.curOp.updateInput = updateInput;
|
| - if (text.length > 1000) 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);
|
| - if (minimal) cm.display.input.value = "-";
|
| - else cm.display.input.value = selected || cm.getSelection();
|
| - if (cm.state.focused) selectInput(cm.display.input);
|
| - } else if (user) cm.display.prevInput = cm.display.input.value = "";
|
| - 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));
|
| - on(d.scroller, "dblclick", operation(cm, e_preventDefault));
|
| - on(d.lineSpace, "selectstart", function(e) {
|
| - if (!eventInWidget(d, e)) e_preventDefault(e);
|
| - });
|
| - // 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.
|
| - 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; });
|
| -
|
| - function onResize() {
|
| - // Might be a text scaling operation, clear size caches.
|
| - d.cachedCharWidth = d.cachedTextHeight = null;
|
| - clearCaches(cm);
|
| - runInOp(cm, bind(regChange, cm));
|
| - }
|
| - 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) {
|
| - if (cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return;
|
| - 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));
|
| -
|
| - function drag_(e) {
|
| - if (cm.options.onDragEvent && cm.options.onDragEvent(cm, addStop(e))) return;
|
| - e_stop(e);
|
| - }
|
| - 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);
|
| -
|
| - // Needed to handle Tab key in KHTML
|
| - if (khtml) on(d.sizer, "mouseup", function() {
|
| - if (document.activeElement == d.input) d.input.blur();
|
| - focusInput(cm);
|
| - });
|
| - }
|
| -
|
| - function eventInWidget(display, e) {
|
| - for (var n = e_target(e); n != display.wrapper; n = n.parentNode) {
|
| - if (!n) return true;
|
| - if (/\bCodeMirror-(?:line)?widget\b/.test(n.className) ||
|
| - n.parentNode == display.sizer && n != display.mover) return true;
|
| - }
|
| - }
|
| -
|
| - 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 ||
|
| - target == display.scrollbarFiller) return null;
|
| - }
|
| - 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) {
|
| - 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);
|
| - }
|
| - });
|
| - // 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;
|
| -
|
| - function doSelect(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)));
|
| - }
|
| - }
|
| -
|
| - 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);
|
| - }
|
| - }
|
| -
|
| - function done(e) {
|
| - counter = Infinity;
|
| - var cur = posFromMouse(cm, e);
|
| - if (cur) doSelect(cur);
|
| - 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);
|
| - }
|
| -
|
| - function onDrop(e) {
|
| - var cm = this;
|
| - if (eventInWidget(cm.display, e) || (cm.options.onDragEvent && cm.options.onDragEvent(cm, addStop(e))))
|
| - return;
|
| - e_preventDefault(e);
|
| - 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);
|
| - return;
|
| - }
|
| - 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);
|
| - }
|
| - }
|
| - catch(e){}
|
| - }
|
| - }
|
| -
|
| - 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;
|
| - }
|
| -
|
| - function onDragStart(cm, e) {
|
| - if (eventInWidget(cm.display, e)) return;
|
| -
|
| - 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.
|
| - if (e.dataTransfer.setDragImage) {
|
| - 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;
|
| - }
|
| - if (safari) {
|
| - if (cm.display.dragImg) {
|
| - img = cm.display.dragImg;
|
| - } else {
|
| - cm.display.dragImg = img;
|
| - img.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
|
| - cm.display.wrapper.appendChild(img);
|
| - }
|
| - }
|
| - 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, []);
|
| - }
|
| - 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;
|
| -
|
| - // 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;
|
| - }
|
| - }
|
| - }
|
| -
|
| - var display = cm.display, scroll = display.scroller;
|
| - // 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);
|
| - maps.push(cm.options.keyMap);
|
| - if (cm.options.extraKeys) maps.unshift(cm.options.extraKeys);
|
| - 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() {
|
| - if (getKeyMap(cm.options.keyMap) == startMap)
|
| - cm.options.keyMap = (next.call ? next.call(null, cm) : next);
|
| - }, 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) {
|
| - if (typeof b == "string" && /^go[A-Z]/.test(b)) return doHandleBinding(cm, b);
|
| - });
|
| - } else {
|
| - handled = lookupKey(name, keymaps, function(b) { return doHandleBinding(cm, b); });
|
| - }
|
| - if (handled == "stop") handled = false;
|
| -
|
| - if (handled) {
|
| - e_preventDefault(e);
|
| - restartBlink(cm);
|
| - if (ie_lt9) { e.oldKeyCode = e.keyCode; e.keyCode = 0; }
|
| - }
|
| - 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);
|
| - }
|
| - 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; }
|
| - if (cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return;
|
| - 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;
|
| - if (cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return;
|
| - 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;
|
| - 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) {
|
| - 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 = " ";
|
| -
|
| - 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
|
| - if (display.input.selectionStart != null && (!ie || ie_lt9)) {
|
| - clearTimeout(detectingSelectAll);
|
| - var extval = display.input.value = " " + (posEq(sel.from, sel.to) ? "" : display.input.value), i = 0;
|
| - display.prevInput = " ";
|
| - display.input.selectionStart = 1; display.input.selectionEnd = extval.length;
|
| - var poll = function(){
|
| - 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);
|
| - }
|
| - }
|
| -
|
| - if (captureMiddleClick) {
|
| - e_stop(e);
|
| - var mouseup = function() {
|
| - off(window, "mouseup", mouseup);
|
| - setTimeout(rehide, 20);
|
| - };
|
| - on(window, "mouseup", mouseup);
|
| - } else {
|
| - setTimeout(rehide, 50);
|
| - }
|
| - }
|
| -
|
| - // UPDATING
|
| -
|
| - function changeEnd(change) {
|
| - return Pos(change.from.line + change.text.length - 1,
|
| - lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0));
|
| - }
|
| -
|
| - // 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)};
|
| - }
|
| -
|
| - function filterChange(doc, change) {
|
| - var obj = {
|
| - canceled: false,
|
| - from: change.from,
|
| - to: change.to,
|
| - text: change.text,
|
| - origin: change.origin,
|
| - 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;
|
| - },
|
| - cancel: function() { this.canceled = true; }
|
| - };
|
| - 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")) {
|
| - change = filterChange(doc, change);
|
| - 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) {
|
| - var hist = doc.history;
|
| - var event = (type == "undo" ? hist.done : hist.undone).pop();
|
| - if (!event) return;
|
| - hist.dirtyCounter += type == "undo" ? -1 : 1;
|
| -
|
| - var anti = {changes: [], anchorBefore: event.anchorAfter, headBefore: event.headAfter,
|
| - anchorAfter: event.anchorBefore, headAfter: event.headBefore};
|
| - (type == "undo" ? hist.undone : hist.done).push(anti);
|
| -
|
| - for (var i = event.changes.length - 1; i >= 0; --i) {
|
| - var change = event.changes[i];
|
| - change.origin = type;
|
| - 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;
|
| - }
|
| - });
|
| - }
|
| -
|
| - 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;
|
| - }
|
| - }
|
| - 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 = 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), toClear;
|
| - 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 && m.clearOnEnter) {
|
| - (toClear || (toClear = [])).push(m);
|
| - continue;
|
| - } else 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;
|
| - }
|
| - }
|
| - if (toClear) for (var i = 0; i < toClear.length; ++i) toClear[i].clear();
|
| - }
|
| - return curPos;
|
| - }
|
| - }
|
| -
|
| - // SCROLLING
|
| -
|
| - function scrollCursorIntoView(cm) {
|
| - var coords = scrollPosIntoView(cm, cm.doc.sel.head);
|
| - if (!cm.state.focused) return;
|
| - var display = cm.display, box = getRect(display.sizer), doScroll = null, pTop = paddingTop(cm.display);
|
| - if (coords.top + pTop + box.top < 0) doScroll = true;
|
| - else if (coords.bottom + pTop + box.top > (window.innerHeight || document.documentElement.clientHeight)) doScroll = false;
|
| - 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";
|
| - }
|
| - 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;
|
| - }
|
| - if (scrollPos.scrollLeft != null) {
|
| - setScrollLeft(cm, scrollPos.scrollLeft);
|
| - if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) changed = true;
|
| - }
|
| - 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) {
|
| - var display = cm.display, pt = paddingTop(display);
|
| - y1 += pt; y2 += pt;
|
| - var screen = display.scroller.clientHeight - scrollerCutOff, screentop = display.scroller.scrollTop, result = {};
|
| - var docBottom = cm.doc.height + paddingVert(display);
|
| - var atTop = y1 < pt + 10, atBottom = y2 + pt > docBottom - 10;
|
| - if (y1 < screentop) result.scrollTop = atTop ? 0 : Math.max(0, y1);
|
| - else if (y2 > screentop + screen) result.scrollTop = (atBottom ? docBottom : y2) - screen;
|
| -
|
| - 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, 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;
|
| - if (!how) how = "add";
|
| - 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";
|
| - }
|
| - }
|
| - 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;
|
| - }
|
| - 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) {
|
| - var line = pos.line, ch = pos.ch;
|
| - 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;
|
| - return true;
|
| - }
|
| -
|
| - 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;
|
| - }
|
| - if (type) sawType = type;
|
| - if (dir > 0 && !moveOnce(!first)) break;
|
| - }
|
| - }
|
| - var result = skipAtomic(doc, Pos(line, ch), dir, true);
|
| - 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) {
|
| - if (pos.after === false || end == line.length) --start; else ++end;
|
| - 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 = {
|
| - 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) {
|
| - this.state.keyMaps.push(map);
|
| - },
|
| - removeKeyMap: function(map) {
|
| - var maps = this.state.keyMaps;
|
| - for (var i = 0; i < maps.length; ++i)
|
| - if ((typeof map == "string" ? maps[i].name : maps[i]) == map) {
|
| - 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) {
|
| - if (overlays[i].modeSpec == spec) {
|
| - overlays.splice(i, 1);
|
| - this.state.modeGen++;
|
| - regChange(this);
|
| - return;
|
| - }
|
| - }
|
| - }),
|
| -
|
| - indentLine: operation(null, function(n, dir, aggressive) {
|
| - if (typeof dir != "string") {
|
| - if (dir == null) dir = this.options.smartIndent ? "smart" : "prev";
|
| - else dir = dir ? "add" : "subtract";
|
| - }
|
| - 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).
|
| - getTokenAt: function(pos) {
|
| - var doc = this.doc;
|
| - pos = clipPos(doc, pos);
|
| - var state = getStateBefore(this, pos.line), mode = this.doc.mode;
|
| - 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);
|
| - }
|
| - return {start: stream.start,
|
| - end: stream.pos,
|
| - string: stream.current(),
|
| - className: style || null, // Deprecated, use 'type' instead
|
| - type: style || null,
|
| - state: state};
|
| - },
|
| -
|
| - getStateAfter: function(line) {
|
| - var doc = this.doc;
|
| - line = clipLine(doc, line == null ? doc.first + doc.size - 1: line);
|
| - return getStateBefore(this, line + 1);
|
| - },
|
| -
|
| - 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);
|
| - },
|
| -
|
| - 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;
|
| - });
|
| - }),
|
| -
|
| - 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;
|
| - }
|
| - ++i;
|
| - });
|
| - }),
|
| -
|
| - 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;
|
| - else if (new RegExp("\\b" + cls + "\\b").test(line[prop])) return false;
|
| - else line[prop] += " " + cls;
|
| - return true;
|
| - });
|
| - }),
|
| -
|
| - 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 {
|
| - var upd = cur.replace(new RegExp("^" + cls + "\\b\\s*|\\s*\\b" + cls + "\\b"), "");
|
| - if (upd == cur) return false;
|
| - line[prop] = upd || null;
|
| - }
|
| - return true;
|
| - });
|
| - }),
|
| -
|
| - addLineWidget: operation(null, function(handle, node, options) {
|
| - return addLineWidget(this, handle, node, options);
|
| - }),
|
| -
|
| - removeLineWidget: function(widget) { widget.clear(); },
|
| -
|
| - lineInfo: function(line) {
|
| - if (typeof line == "number") {
|
| - if (!isLine(this.doc, line)) return null;
|
| - var n = line;
|
| - line = getLine(this.doc, line);
|
| - if (!line) return null;
|
| - } else {
|
| - var n = lineNo(line);
|
| - if (n == null) return null;
|
| - }
|
| - 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;
|
| - }
|
| - node.style.top = (top + paddingTop(display)) + "px";
|
| - 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";
|
| - }
|
| - 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;
|
| - }
|
| - 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;
|
| - }
|
| - 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;
|
| - }),
|
| -
|
| - toggleOverwrite: function() {
|
| - 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: function(pos, margin) {
|
| - if (typeof pos == "number") pos = Pos(pos, 0);
|
| - if (!pos || pos.line != null) {
|
| - pos = pos ? clipPos(this.doc, pos) : this.doc.sel.head;
|
| - scrollPosIntoView(this, pos, margin);
|
| - } else {
|
| - scrollIntoView(this, pos.left, pos.top - margin, pos.right, pos.bottom + margin);
|
| - }
|
| - },
|
| -
|
| - setSize: function(width, height) {
|
| - function interpret(val) {
|
| - return typeof val == "number" || /^\d+$/.test(String(val)) ? val + "px" : val;
|
| - }
|
| - if (width != null) this.display.wrapper.style.width = interpret(width);
|
| - if (height != null) this.display.wrapper.style.height = interpret(height);
|
| - this.refresh();
|
| - },
|
| -
|
| - on: function(type, f) {on(this, type, f);},
|
| - off: function(type, f) {off(this, type, f);},
|
| -
|
| - 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);
|
| - 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;}
|
| - };
|
| -
|
| - // OPTION DEFAULTS
|
| -
|
| - var optionHandlers = CodeMirror.optionHandlers = {};
|
| -
|
| - // The default configuration options.
|
| - 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);
|
| - 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);
|
| - 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("viewportMargin", 10, function(cm){cm.refresh();}, true);
|
| -
|
| - option("tabindex", null, function(cm, val) {
|
| - cm.display.input.tabIndex = val || "";
|
| - });
|
| - option("autofocus", null);
|
| -
|
| - // MODE DEFINITION AND QUERYING
|
| -
|
| - // Known modes, by name and by MIME
|
| - var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {};
|
| -
|
| - CodeMirror.defineMode = function(name, mode) {
|
| - if (!CodeMirror.defaults.mode && name != "null") CodeMirror.defaults.mode = name;
|
| - if (arguments.length > 2) {
|
| - mode.dependencies = [];
|
| - for (var i = 2; i < arguments.length; ++i) mode.dependencies.push(arguments[i]);
|
| - }
|
| - modes[name] = mode;
|
| - };
|
| -
|
| - CodeMirror.defineMIME = function(mime, spec) {
|
| - mimeModes[mime] = spec;
|
| - };
|
| -
|
| - CodeMirror.resolveMode = function(spec) {
|
| - if (typeof spec == "string" && mimeModes.hasOwnProperty(spec))
|
| - spec = mimeModes[spec];
|
| - else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec))
|
| - return CodeMirror.resolveMode("application/xml");
|
| - if (typeof spec == "string") return {name: spec};
|
| - else return spec || {name: "null"};
|
| - };
|
| -
|
| - CodeMirror.getMode = function(options, spec) {
|
| - spec = CodeMirror.resolveMode(spec);
|
| - var mfactory = modes[spec.name];
|
| - if (!mfactory) return CodeMirror.getMode(options, "text/plain");
|
| - var modeObj = mfactory(options, spec);
|
| - if (modeExtensions.hasOwnProperty(spec.name)) {
|
| - var exts = modeExtensions[spec.name];
|
| - for (var prop in exts) {
|
| - if (!exts.hasOwnProperty(prop)) continue;
|
| - if (modeObj.hasOwnProperty(prop)) modeObj["_" + prop] = modeObj[prop];
|
| - modeObj[prop] = exts[prop];
|
| - }
|
| - }
|
| - modeObj.name = spec.name;
|
| - return modeObj;
|
| - };
|
| -
|
| - CodeMirror.defineMode("null", function() {
|
| - return {token: function(stream) {stream.skipToEnd();}};
|
| - });
|
| - CodeMirror.defineMIME("text/plain", "null");
|
| -
|
| - var modeExtensions = CodeMirror.modeExtensions = {};
|
| - CodeMirror.extendMode = function(mode, properties) {
|
| - var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {});
|
| - copyObj(properties, exts);
|
| - };
|
| -
|
| - // EXTENSIONS
|
| -
|
| - CodeMirror.defineExtension = function(name, func) {
|
| - CodeMirror.prototype[name] = func;
|
| - };
|
| -
|
| - CodeMirror.defineOption = option;
|
| -
|
| - var initHooks = [];
|
| - CodeMirror.defineInitHook = function(f) {initHooks.push(f);};
|
| -
|
| - // MODE STATE HANDLING
|
| -
|
| - // 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;
|
| - }
|
| - CodeMirror.copyState = copyState;
|
| -
|
| - function startState(mode, a1, a2) {
|
| - return mode.startState ? mode.startState(a1, a2) : true;
|
| - }
|
| - CodeMirror.startState = startState;
|
| -
|
| - CodeMirror.innerMode = function(mode, state) {
|
| - while (mode.innerMode) {
|
| - var info = mode.innerMode(state);
|
| - state = info.state;
|
| - mode = info.mode;
|
| - }
|
| - return info || {mode: mode, state: state};
|
| - };
|
| -
|
| - // 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");
|
| - },
|
| - 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",
|
| - "Cmd-[": "indentLess", "Cmd-]": "indentMore",
|
| - 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]);
|
| - if (done) return done;
|
| - }
|
| - }
|
| - function isModifierKey(event) {
|
| - var name = keyNames[event.keyCode];
|
| - return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod";
|
| - }
|
| - function keyName(event, noShift) {
|
| - 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.
|
| -
|
| - // The character stream used by a mode's parser.
|
| - function StringStream(string, tabSize) {
|
| - this.pos = this.start = 0;
|
| - this.string = string;
|
| - this.tabSize = tabSize || 8;
|
| - this.lastColumnPos = this.lastColumnValue = 0;
|
| - }
|
| -
|
| - StringStream.prototype = {
|
| - eol: function() {return this.pos >= this.string.length;},
|
| - sol: function() {return this.pos == 0;},
|
| - peek: function() {return this.string.charAt(this.pos) || undefined;},
|
| - 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) {
|
| - var start = this.pos;
|
| - 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;},
|
| - 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;
|
| - },
|
| - indentation: function() {return countColumn(this.string, null, this.tabSize);},
|
| - match: function(pattern, consume, caseInsensitive) {
|
| - if (typeof pattern == "string") {
|
| - var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;};
|
| - var substr = this.string.substr(this.pos, pattern.length);
|
| - if (cased(substr) == cased(pattern)) {
|
| - if (consume !== false) this.pos += pattern.length;
|
| - return true;
|
| - }
|
| - } else {
|
| - var match = this.string.slice(this.pos).match(pattern);
|
| - if (match && match.index > 0) return null;
|
| - if (match && consume !== false) this.pos += match[0].length;
|
| - return match;
|
| - }
|
| - },
|
| - current: function(){return this.string.slice(this.start, this.pos);}
|
| - };
|
| - CodeMirror.StringStream = StringStream;
|
| -
|
| - // TEXTMARKERS
|
| -
|
| - function TextMarker(doc, type) {
|
| - this.lines = [];
|
| - this.type = type;
|
| - this.doc = doc;
|
| - }
|
| - CodeMirror.TextMarker = TextMarker;
|
| -
|
| - TextMarker.prototype.clear = function() {
|
| - if (this.explicitlyCleared) return;
|
| - var cm = this.doc.cm, withOp = cm && !cm.curOp;
|
| - if (withOp) startOperation(cm);
|
| - 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;
|
| - if (this.collapsed && this.doc.cantEdit) {
|
| - this.doc.cantEdit = false;
|
| - if (cm) reCheckSelection(cm);
|
| - }
|
| - if (withOp) endOperation(cm);
|
| - signalLater(this, "clear");
|
| - };
|
| -
|
| - 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};
|
| - };
|
| -
|
| - TextMarker.prototype.getOptions = function(copyWidget) {
|
| - var repl = this.replacedWith;
|
| - return {className: this.className,
|
| - inclusiveLeft: this.inclusiveLeft, inclusiveRight: this.inclusiveRight,
|
| - atomic: this.atomic,
|
| - collapsed: this.collapsed,
|
| - clearOnEnter: this.clearOnEnter,
|
| - replacedWith: copyWidget ? repl && repl.cloneNode(true) : repl,
|
| - readOnly: this.readOnly,
|
| - startStyle: this.startStyle, endStyle: this.endStyle};
|
| - };
|
| -
|
| - 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");
|
| - }
|
| - if (marker.collapsed) sawCollapsedSpans = true;
|
| -
|
| - 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.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;
|
| - if (marker.className || marker.startStyle || marker.endStyle || marker.collapsed)
|
| - 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;
|
| -
|
| - 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();
|
| - };
|
| - SharedTextMarker.prototype.getOptions = function(copyWidget) {
|
| - var inner = this.primary.getOptions(copyWidget);
|
| - inner.shared = true;
|
| - return inner;
|
| - };
|
| -
|
| - 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
|
| -
|
| - function getMarkedSpanFor(spans, marker) {
|
| - if (spans) for (var i = 0; i < spans.length; ++i) {
|
| - var span = spans[i];
|
| - if (span.marker == marker) return span;
|
| - }
|
| - }
|
| - function removeMarkedSpan(spans, span) {
|
| - for (var r, i = 0; i < spans.length; ++i)
|
| - if (spans[i] != span) (r || (r = [])).push(spans[i]);
|
| - return r;
|
| - }
|
| - function addMarkedSpan(line, span) {
|
| - line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span];
|
| - span.marker.attachLine(line);
|
| - }
|
| -
|
| - function markedSpansBefore(old, startCh, isInsert) {
|
| - 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);
|
| - if (startsBefore || marker.type == "bookmark" && span.from == startCh && (!isInsert || !span.marker.insertLeft)) {
|
| - 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});
|
| - }
|
| - }
|
| - return nw;
|
| - }
|
| -
|
| - function markedSpansAfter(old, endCh, isInsert) {
|
| - 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);
|
| - if (endsAfter || marker.type == "bookmark" && span.from == endCh && (!isInsert || span.marker.insertLeft)) {
|
| - 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;
|
| - }
|
| -
|
| - 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);
|
| - // Get the spans that 'stick out' on both sides
|
| - var first = markedSpansBefore(oldFirst, startCh, isInsert);
|
| - var last = markedSpansAfter(oldLast, endCh, isInsert);
|
| -
|
| - // Next, merge those two ends
|
| - var sameLine = change.text.length == 1, offset = lst(change.text).length + (sameLine ? startCh : 0);
|
| - 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;
|
| - }
|
| - }
|
| - }
|
| - 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);
|
| - }
|
| - } else {
|
| - span.from += offset;
|
| - if (sameLine) (first || (first = [])).push(span);
|
| - }
|
| - }
|
| - }
|
| -
|
| - var newMarkers = [first];
|
| - if (!sameLine) {
|
| - // Fill gap with whole-line-spans
|
| - var gap = change.text.length - 2, gapMarkers;
|
| - 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)
|
| - newMarkers.push(gapMarkers);
|
| - newMarkers.push(last);
|
| - }
|
| - return newMarkers;
|
| - }
|
| -
|
| - 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;
|
| - 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];
|
| - if (sp.marker.collapsed && sp.from == span.to &&
|
| - (sp.marker.inclusiveLeft || span.marker.inclusiveRight) &&
|
| - lineIsHiddenInner(doc, line, sp)) return true;
|
| - }
|
| - }
|
| -
|
| - function detachMarkedSpans(line) {
|
| - var spans = line.markedSpans;
|
| - if (!spans) return;
|
| - for (var i = 0; i < spans.length; ++i)
|
| - spans[i].marker.detachLine(line);
|
| - line.markedSpans = null;
|
| - }
|
| -
|
| - function attachMarkedSpans(line, spans) {
|
| - if (!spans) return;
|
| - for (var i = 0; i < spans.length; ++i)
|
| - spans[i].marker.attachLine(line);
|
| - line.markedSpans = spans;
|
| - }
|
| -
|
| - // LINE WIDGETS
|
| -
|
| - var LineWidget = CodeMirror.LineWidget = function(cm, node, options) {
|
| - for (var opt in options) if (options.hasOwnProperty(opt))
|
| - this[opt] = options[opt];
|
| - this.cm = cm;
|
| - this.node = node;
|
| - };
|
| - 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;
|
| - updateLineHeight(this.line, Math.max(0, this.line.height - widgetHeight(this)));
|
| - 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) {
|
| - (line.widgets || (line.widgets = [])).push(widget);
|
| - widget.line = line;
|
| - if (!lineIsHidden(cm.doc, line) || widget.showIfHidden) {
|
| - var aboveVisible = heightAtLine(cm, line) < cm.display.scroller.scrollTop;
|
| - updateLineHeight(line, line.height + widgetHeight(widget));
|
| - if (aboveVisible) addToScrollPos(cm, 0, widget.height);
|
| - }
|
| - return true;
|
| - });
|
| - return widget;
|
| - }
|
| -
|
| - // LINE DATA STRUCTURE
|
| -
|
| - // Line objects. These hold state related to a line, including
|
| - // highlighting info (the styles array).
|
| - function makeLine(text, markedSpans, estimateHeight) {
|
| - var line = {text: text};
|
| - attachMarkedSpans(line, markedSpans);
|
| - line.height = estimateHeight ? estimateHeight(line) : 1;
|
| - return line;
|
| - }
|
| -
|
| - 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;
|
| - var curText = "", curStyle = null;
|
| - var stream = new StringStream(text, cm.options.tabSize);
|
| - if (text == "" && mode.blankLine) mode.blankLine(state);
|
| - while (!stream.eol()) {
|
| - var style = mode.token(stream, state);
|
| - if (stream.pos > 5000) {
|
| - 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;
|
| - }
|
| - var substr = stream.current();
|
| - stream.start = stream.pos;
|
| - if (!flattenSpans || curStyle != style) {
|
| - if (curText) f(curText, curStyle);
|
| - curText = substr; curStyle = style;
|
| - } else curText = curText + substr;
|
| - }
|
| - if (curText) f(curText, curStyle);
|
| - }
|
| -
|
| - 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
|
| - runMode(cm, line.text, cm.doc.mode, state, function(txt, style) {st.push(txt, style);});
|
| -
|
| - // Run overlays, adjust style array.
|
| - for (var o = 0; o < cm.state.overlays.length; ++o) {
|
| - var overlay = cm.state.overlays[o], i = 1;
|
| - runMode(cm, line.text, overlay.mode, true, function(txt, style) {
|
| - var start = i, len = txt.length;
|
| - // Ensure there's a token end at the current position, and that i points at it
|
| - while (len) {
|
| - var cur = st[i], len_ = cur.length;
|
| - if (len_ <= len) {
|
| - len -= len_;
|
| - } else {
|
| - st.splice(i, 1, cur.slice(0, len), st[i+1], cur.slice(len));
|
| - len = 0;
|
| - }
|
| - i += 2;
|
| - }
|
| - if (!style) return;
|
| - if (overlay.opaque) {
|
| - st.splice(start, i - start, txt, style);
|
| - i = start + 2;
|
| - } else {
|
| - for (; start < i; start += 2) {
|
| - var cur = st[start+1];
|
| - st[start+1] = cur ? cur + " " + style : style;
|
| - }
|
| - }
|
| - });
|
| - }
|
| -
|
| - 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 <= 5000) {
|
| - 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-"));
|
| - }
|
| -
|
| - function lineContent(cm, realLine, measure) {
|
| - var merged, line = realLine, lineBefore, sawBefore, simple = true;
|
| - while (merged = collapsedSpanAtStart(line)) {
|
| - simple = false;
|
| - line = getLine(cm.doc, merged.find().from.line);
|
| - if (!lineBefore) lineBefore = line;
|
| - }
|
| -
|
| - var builder = {pre: elt("pre"), col: 0, pos: 0, display: !measure,
|
| - measure: null, addedOne: false, cm: cm};
|
| - if (line.textClass) builder.pre.className = line.textClass;
|
| -
|
| - do {
|
| - 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);
|
| - if (measure && sawBefore && line != realLine && !builder.addedOne) {
|
| - measure[0] = builder.pre.appendChild(zeroWidthElement(cm.display.measure));
|
| - builder.addedOne = true;
|
| - }
|
| - var next = insertLineContent(line, builder, getLineStyles(cm, line));
|
| - sawBefore = line == lineBefore;
|
| - if (next) {
|
| - line = getLine(cm.doc, next.to.line);
|
| - simple = false;
|
| - }
|
| - } while (next);
|
| -
|
| - if (measure && !builder.addedOne)
|
| - measure[0] = builder.pre.appendChild(simple ? elt("span", "\u00a0") : zeroWidthElement(cm.display.measure));
|
| - 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;
|
| - function buildToken(builder, text, style, startStyle, endStyle) {
|
| - 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;
|
| - }
|
| - 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;
|
| - }
|
| - }
|
| - }
|
| - if (style || startStyle || endStyle || builder.measure) {
|
| - var fullStyle = style || "";
|
| - if (startStyle) fullStyle += startStyle;
|
| - if (endStyle) fullStyle += endStyle;
|
| - return builder.pre.appendChild(elt("span", [content], fullStyle));
|
| - }
|
| - 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;
|
| - } else if (i && wrapping &&
|
| - spanAffectsWrapping.test(text.slice(i - 1, i + 1))) {
|
| - builder.pre.appendChild(elt("wbr"));
|
| - }
|
| - var span = builder.measure[builder.pos] =
|
| - buildToken(builder, ch, style,
|
| - start && startStyle, i == text.length - 1 && endStyle);
|
| - // 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;
|
| - }
|
| - if (text.length) builder.addedOne = true;
|
| - }
|
| -
|
| - function buildTokenSplitSpaces(inner) {
|
| - function split(old) {
|
| - var out = " ";
|
| - for (var i = 0; i < old.length - 2; ++i) out += i % 2 ? " " : "\u00a0";
|
| - out += " ";
|
| - return out;
|
| - }
|
| - return function(builder, text, style, startStyle, endStyle) {
|
| - return inner(builder, text.replace(/ {3,}/, split), style, startStyle, endStyle);
|
| - };
|
| - }
|
| -
|
| - function buildCollapsedSpan(builder, size, widget) {
|
| - if (widget) {
|
| - if (!builder.display) widget = widget.cloneNode(true);
|
| - builder.pre.appendChild(widget);
|
| - if (builder.measure && size) {
|
| - builder.measure[builder.pos] = widget;
|
| - builder.addedOne = true;
|
| - }
|
| - }
|
| - 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) {
|
| - var spans = line.markedSpans;
|
| - if (!spans) {
|
| - for (var i = 1; i < styles.length; i+=2)
|
| - builder.addToken(builder, styles[i], styleToClass(styles[i+1]));
|
| - return;
|
| - }
|
| -
|
| - var allText = line.text, len = allText.length;
|
| - var pos = 0, i = 1, text = "", style;
|
| - var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, collapsed;
|
| - for (;;) {
|
| - if (nextChange == pos) { // Update current marker set
|
| - spanStyle = spanEndStyle = spanStartStyle = "";
|
| - 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;
|
| - if (m.collapsed && (!collapsed || collapsed.marker.width < m.width))
|
| - collapsed = sp;
|
| - } else if (sp.from > pos && nextChange > sp.from) {
|
| - nextChange = sp.from;
|
| - }
|
| - if (m.type == "bookmark" && sp.from == pos && m.replacedWith)
|
| - foundBookmark = m.replacedWith;
|
| - }
|
| - if (collapsed && (collapsed.from || 0) == pos) {
|
| - buildCollapsedSpan(builder, (collapsed.to == null ? len : collapsed.to) - pos,
|
| - collapsed.from != null && collapsed.marker.replacedWith);
|
| - 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,
|
| - spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "");
|
| - }
|
| - if (end >= upto) {text = text.slice(upto - pos); pos = upto; break;}
|
| - pos = end;
|
| - spanStartStyle = "";
|
| - }
|
| - text = styles[i++]; style = styleToClass(styles[i++]);
|
| - }
|
| - }
|
| - }
|
| -
|
| - // 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)
|
| - added.push(makeLine(text[i], spansFor(i), estimateHeight));
|
| - 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)
|
| - added.push(makeLine(text[i], spansFor(i), estimateHeight));
|
| - added.push(makeLine(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight));
|
| - 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)
|
| - added.push(makeLine(text[i], spansFor(i), estimateHeight));
|
| - 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);
|
| - }
|
| -
|
| - 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;
|
| - }
|
| -
|
| - LeafChunk.prototype = {
|
| - chunkSize: function() { return this.lines.length; },
|
| - removeInner: function(at, n) {
|
| - for (var i = at, e = at + n; i < e; ++i) {
|
| - var line = this.lines[i];
|
| - this.height -= line.height;
|
| - cleanUpLine(line);
|
| - signalLater(line, "delete");
|
| - }
|
| - this.lines.splice(at, n);
|
| - },
|
| - collapse: function(lines) {
|
| - lines.splice.apply(lines, [lines.length, 0].concat(this.lines));
|
| - },
|
| - insertInner: function(at, lines, height) {
|
| - 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;
|
| - }
|
| - };
|
| -
|
| - 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;
|
| - }
|
| -
|
| - BranchChunk.prototype = {
|
| - chunkSize: function() { return this.size; },
|
| - removeInner: function(at, n) {
|
| - 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;
|
| - child.removeInner(at, rm);
|
| - 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);
|
| - },
|
| - insertInner: function(at, lines, height) {
|
| - 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) {
|
| - child.insertInner(at, lines, height);
|
| - 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;
|
| - }
|
| - }
|
| - };
|
| -
|
| - 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;
|
| -
|
| - BranchChunk.call(this, [new LeafChunk([makeLine("", null)])]);
|
| - this.first = firstLine;
|
| - this.scrollTop = this.scrollLeft = 0;
|
| - this.cantEdit = false;
|
| - this.history = makeHistory();
|
| - 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, {
|
| - 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 (isLine(this, line))
|
| - replaceRange(this, "", Pos(line, 0), clipPos(this, Pos(line + 1, 0)));
|
| - },
|
| -
|
| - getLineHandle: function(line) {if (isLine(this, line)) return getLine(this, line);},
|
| - getLineNumber: function(line) {return lineNo(line);},
|
| -
|
| - 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};
|
| - },
|
| - clearHistory: function() {this.history = makeHistory();},
|
| -
|
| - markClean: function() {
|
| - this.history.dirtyCounter = 0;
|
| - this.history.lastOp = this.history.lastOrigin = null;
|
| - },
|
| - isClean: function () {return this.history.dirtyCounter == 0;},
|
| -
|
| - getHistory: function() {
|
| - return {done: copyHistoryArray(this.history.done),
|
| - undone: copyHistoryArray(this.history.undone)};
|
| - },
|
| - setHistory: function(histData) {
|
| - var hist = this.history = makeHistory();
|
| - 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]);
|
| -
|
| - 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;
|
| - 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];
|
| - }
|
| -
|
| - 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;
|
| - }
|
| -
|
| - 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) {
|
| - for (var i = 0;; ++i) {
|
| - if (chunk.children[i] == cur) break;
|
| - no += chunk.children[i].chunkSize();
|
| - }
|
| - }
|
| - return no + cur.first;
|
| - }
|
| -
|
| - function lineAtHeight(chunk, h) {
|
| - var n = chunk.first;
|
| - 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;
|
| - }
|
| -
|
| - 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;
|
| - }
|
| - }
|
| - return h;
|
| - }
|
| -
|
| - function getOrder(line) {
|
| - var order = line.order;
|
| - if (order == null) order = line.order = bidiOrdering(line.text);
|
| - return order;
|
| - }
|
| -
|
| - // HISTORY
|
| -
|
| - function makeHistory() {
|
| - 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
|
| - dirtyCounter: 0
|
| - };
|
| - }
|
| -
|
| - 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) {
|
| - var histChange = {from: change.from, to: changeEnd(change), text: getBetween(doc, change.from, change.to)};
|
| - 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) == "+" && hist.lastTime > time - 600) || 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);
|
| - } else {
|
| - // 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)],
|
| - anchorBefore: doc.sel.anchor, headBefore: doc.sel.head,
|
| - anchorAfter: selAfter.anchor, headAfter: selAfter.head};
|
| - hist.done.push(cur);
|
| - while (hist.done.length > hist.undoDepth)
|
| - hist.done.shift();
|
| - if (hist.dirtyCounter < 0)
|
| - // The user has made a change after undoing past the last clean state.
|
| - // We can never get back to a clean state now until markClean() is called.
|
| - hist.dirtyCounter = NaN;
|
| - else
|
| - hist.dirtyCounter++;
|
| - }
|
| - 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];
|
| - }
|
| - }
|
| - }
|
| - }
|
| - 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
|
| -
|
| - function stopMethod() {e_stop(this);}
|
| - // Ensure an event has a stop method.
|
| - function addStop(event) {
|
| - if (!event.stop) event.stop = stopMethod;
|
| - return event;
|
| - }
|
| -
|
| - 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;
|
| - }
|
| - function e_stop(e) {e_preventDefault(e); e_stopPropagation(e);}
|
| - CodeMirror.e_stop = e_stop;
|
| - CodeMirror.e_preventDefault = e_preventDefault;
|
| - CodeMirror.e_stopPropagation = e_stopPropagation;
|
| -
|
| - function e_target(e) {return e.target || e.srcElement;}
|
| - function e_button(e) {
|
| - 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;
|
| - }
|
| -
|
| - // 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]));
|
| - }
|
| -
|
| - 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;
|
| -
|
| - // 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";}};
|
| -
|
| - 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.
|
| - function countColumn(string, end, tabSize, startIndex, startValue) {
|
| - if (end == null) {
|
| - end = string.search(/[^\s\u00a0]/);
|
| - if (end == -1) end = string.length;
|
| - }
|
| - for (var i = startIndex || 0, n = startValue || 0; i < end; ++i) {
|
| - if (string.charAt(i) == "\t") n += tabSize - (n % tabSize);
|
| - else ++n;
|
| - }
|
| - return n;
|
| - }
|
| - CodeMirror.countColumn = countColumn;
|
| -
|
| - var spaceStrs = [""];
|
| - function spaceStr(n) {
|
| - while (spaceStrs.length <= n)
|
| - spaceStrs.push(lst(spaceStrs) + " ");
|
| - return spaceStrs[n];
|
| - }
|
| -
|
| - function lst(arr) { return arr[arr.length-1]; }
|
| -
|
| - function selectInput(node) {
|
| - if (ios) { // Mobile Safari apparently has a bug where select() is broken.
|
| - node.selectionStart = 0;
|
| - node.selectionEnd = node.value.length;
|
| - } else node.select();
|
| - }
|
| -
|
| - 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);};
|
| - }
|
| -
|
| - var nonASCIISingleCaseWordChar = /[\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc]/;
|
| - 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
|
| -
|
| - 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;
|
| - }
|
| -
|
| - function removeChildren(e) {
|
| - // IE will break all parent-child relations in subnodes when setting innerHTML
|
| - if (!ie) e.innerHTML = "";
|
| - else while (e.firstChild) e.removeChild(e.firstChild);
|
| - return e;
|
| - }
|
| -
|
| - function removeChildrenAndAdd(parent, e) {
|
| - return removeChildren(parent).appendChild(e);
|
| - }
|
| -
|
| - function setTextContent(e, str) {
|
| - if (ie_lt9) {
|
| - e.innerHTML = "";
|
| - e.appendChild(document.createTextNode(str));
|
| - } else e.textContent = str;
|
| - }
|
| -
|
| - 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
|
| - // extra span. This terribly fragile set of regexps matches the
|
| - // character combinations that suffer from this phenomenon on the
|
| - // various browsers.
|
| - var spanAffectsWrapping = /^$/; // Won't match any two-character string
|
| - if (gecko) spanAffectsWrapping = /$'/;
|
| - else if (safari && !/Version\/([6-9]|\d\d)\b/.test(navigator.userAgent)) spanAffectsWrapping = /\-[^ \-?]|\?[^ !'\"\),.\-\/:;\?\]\}]/;
|
| - else if (webkit) spanAffectsWrapping = /[~!#%&*)=+}\]|\"\.>,:;][({[<]|-[^\-?\.]|\?[\w~`@#$%\^&*(_=+{[|><]/;
|
| -
|
| - 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");
|
| - }
|
| -
|
| - // See if "".split is the broken IE version, if so, provide an
|
| - // alternative way to split lines.
|
| - var splitLines = "\n\nb".split(/\n/).length != 3 ? function(string) {
|
| - 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;
|
| - }
|
| - }
|
| - return result;
|
| - } : function(string){return string.split(/\r\n?|\n/);};
|
| - CodeMirror.splitLines = splitLines;
|
| -
|
| - 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;
|
| - };
|
| -
|
| - var hasCopyEvent = (function() {
|
| - var e = elt("div");
|
| - if ("oncopy" in e) return true;
|
| - e.setAttribute("oncopy", "return;");
|
| - return typeof e.oncopy == 'function';
|
| - })();
|
| -
|
| - // KEY NAMING
|
| -
|
| - 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;
|
| - })();
|
| -
|
| - // BIDI HELPERS
|
| -
|
| - function iterateBidiSections(order, from, to, f) {
|
| - if (!order) return f(from, to, "ltr");
|
| - for (var i = 0; i < order.length; ++i) {
|
| - var part = order[i];
|
| - if (part.from < to && part.to > from || from == to && part.to == from)
|
| - f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr");
|
| - }
|
| - }
|
| -
|
| - 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);
|
| - }
|
| -
|
| - // 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);
|
| - var moveOneUnit = byUnit ? function(pos, dir) {
|
| - do pos += dir;
|
| - while (pos > 0 && isExtendingChar.test(line.text.charAt(pos)));
|
| - return pos;
|
| - } : function(pos, dir) { return pos + dir; };
|
| - var linedir = bidi[0].level;
|
| - for (var i = 0; i < bidi.length; ++i) {
|
| - var part = bidi[i], sticky = part.level % 2 == linedir;
|
| - if ((part.from < start && part.to > start) ||
|
| - (sticky && (part.from == start || part.to == start))) break;
|
| - }
|
| - var target = moveOneUnit(start, part.level % 2 ? -dir : dir);
|
| -
|
| - while (target != null) {
|
| - if (part.level % 2 == linedir) {
|
| - if (target < part.from || target > part.to) {
|
| - part = bidi[i += dir];
|
| - target = part && (dir > 0 == part.level % 2 ? moveOneUnit(part.to, -1) : moveOneUnit(part.from, 1));
|
| - } else break;
|
| - } else {
|
| - if (target == bidiLeft(part)) {
|
| - part = bidi[--i];
|
| - target = part && bidiRight(part);
|
| - } else if (target == bidiRight(part)) {
|
| - part = bidi[++i];
|
| - target = part && bidiLeft(part);
|
| - } else break;
|
| - }
|
| - }
|
| -
|
| - return target < 0 || target > line.text.length ? null : target;
|
| - }
|
| -
|
| - 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
|
| -
|
| - CodeMirror.version = "3.1 +";
|
| -
|
| - return CodeMirror;
|
| -})();
|
| -;
|
| -CodeMirror.defineMode("css", function(config) {
|
| - var indentUnit = config.indentUnit, type;
|
| -
|
| - var atMediaTypes = keySet([
|
| - "all", "aural", "braille", "handheld", "print", "projection", "screen",
|
| - "tty", "tv", "embossed"
|
| - ]);
|
| -
|
| - var atMediaFeatures = keySet([
|
| - "width", "min-width", "max-width", "height", "min-height", "max-height",
|
| - "device-width", "min-device-width", "max-device-width", "device-height",
|
| - "min-device-height", "max-device-height", "aspect-ratio",
|
| - "min-aspect-ratio", "max-aspect-ratio", "device-aspect-ratio",
|
| - "min-device-aspect-ratio", "max-device-aspect-ratio", "color", "min-color",
|
| - "max-color", "color-index", "min-color-index", "max-color-index",
|
| - "monochrome", "min-monochrome", "max-monochrome", "resolution",
|
| - "min-resolution", "max-resolution", "scan", "grid"
|
| - ]);
|
| -
|
| - var propertyKeywords = keySet([
|
| - "align-content", "align-items", "align-self", "alignment-adjust",
|
| - "alignment-baseline", "anchor-point", "animation", "animation-delay",
|
| - "animation-direction", "animation-duration", "animation-iteration-count",
|
| - "animation-name", "animation-play-state", "animation-timing-function",
|
| - "appearance", "azimuth", "backface-visibility", "background",
|
| - "background-attachment", "background-clip", "background-color",
|
| - "background-image", "background-origin", "background-position",
|
| - "background-repeat", "background-size", "baseline-shift", "binding",
|
| - "bleed", "bookmark-label", "bookmark-level", "bookmark-state",
|
| - "bookmark-target", "border", "border-bottom", "border-bottom-color",
|
| - "border-bottom-left-radius", "border-bottom-right-radius",
|
| - "border-bottom-style", "border-bottom-width", "border-collapse",
|
| - "border-color", "border-image", "border-image-outset",
|
| - "border-image-repeat", "border-image-slice", "border-image-source",
|
| - "border-image-width", "border-left", "border-left-color",
|
| - "border-left-style", "border-left-width", "border-radius", "border-right",
|
| - "border-right-color", "border-right-style", "border-right-width",
|
| - "border-spacing", "border-style", "border-top", "border-top-color",
|
| - "border-top-left-radius", "border-top-right-radius", "border-top-style",
|
| - "border-top-width", "border-width", "bottom", "box-decoration-break",
|
| - "box-shadow", "box-sizing", "break-after", "break-before", "break-inside",
|
| - "caption-side", "clear", "clip", "color", "color-profile", "column-count",
|
| - "column-fill", "column-gap", "column-rule", "column-rule-color",
|
| - "column-rule-style", "column-rule-width", "column-span", "column-width",
|
| - "columns", "content", "counter-increment", "counter-reset", "crop", "cue",
|
| - "cue-after", "cue-before", "cursor", "direction", "display",
|
| - "dominant-baseline", "drop-initial-after-adjust",
|
| - "drop-initial-after-align", "drop-initial-before-adjust",
|
| - "drop-initial-before-align", "drop-initial-size", "drop-initial-value",
|
| - "elevation", "empty-cells", "fit", "fit-position", "flex", "flex-basis",
|
| - "flex-direction", "flex-flow", "flex-grow", "flex-shrink", "flex-wrap",
|
| - "float", "float-offset", "font", "font-feature-settings", "font-family",
|
| - "font-kerning", "font-language-override", "font-size", "font-size-adjust",
|
| - "font-stretch", "font-style", "font-synthesis", "font-variant",
|
| - "font-variant-alternates", "font-variant-caps", "font-variant-east-asian",
|
| - "font-variant-ligatures", "font-variant-numeric", "font-variant-position",
|
| - "font-weight", "grid-cell", "grid-column", "grid-column-align",
|
| - "grid-column-sizing", "grid-column-span", "grid-columns", "grid-flow",
|
| - "grid-row", "grid-row-align", "grid-row-sizing", "grid-row-span",
|
| - "grid-rows", "grid-template", "hanging-punctuation", "height", "hyphens",
|
| - "icon", "image-orientation", "image-rendering", "image-resolution",
|
| - "inline-box-align", "justify-content", "left", "letter-spacing",
|
| - "line-break", "line-height", "line-stacking", "line-stacking-ruby",
|
| - "line-stacking-shift", "line-stacking-strategy", "list-style",
|
| - "list-style-image", "list-style-position", "list-style-type", "margin",
|
| - "margin-bottom", "margin-left", "margin-right", "margin-top",
|
| - "marker-offset", "marks", "marquee-direction", "marquee-loop",
|
| - "marquee-play-count", "marquee-speed", "marquee-style", "max-height",
|
| - "max-width", "min-height", "min-width", "move-to", "nav-down", "nav-index",
|
| - "nav-left", "nav-right", "nav-up", "opacity", "order", "orphans", "outline",
|
| - "outline-color", "outline-offset", "outline-style", "outline-width",
|
| - "overflow", "overflow-style", "overflow-wrap", "overflow-x", "overflow-y",
|
| - "padding", "padding-bottom", "padding-left", "padding-right", "padding-top",
|
| - "page", "page-break-after", "page-break-before", "page-break-inside",
|
| - "page-policy", "pause", "pause-after", "pause-before", "perspective",
|
| - "perspective-origin", "pitch", "pitch-range", "play-during", "position",
|
| - "presentation-level", "punctuation-trim", "quotes", "rendering-intent",
|
| - "resize", "rest", "rest-after", "rest-before", "richness", "right",
|
| - "rotation", "rotation-point", "ruby-align", "ruby-overhang",
|
| - "ruby-position", "ruby-span", "size", "speak", "speak-as", "speak-header",
|
| - "speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set",
|
| - "tab-size", "table-layout", "target", "target-name", "target-new",
|
| - "target-position", "text-align", "text-align-last", "text-decoration",
|
| - "text-decoration-color", "text-decoration-line", "text-decoration-skip",
|
| - "text-decoration-style", "text-emphasis", "text-emphasis-color",
|
| - "text-emphasis-position", "text-emphasis-style", "text-height",
|
| - "text-indent", "text-justify", "text-outline", "text-shadow",
|
| - "text-space-collapse", "text-transform", "text-underline-position",
|
| - "text-wrap", "top", "transform", "transform-origin", "transform-style",
|
| - "transition", "transition-delay", "transition-duration",
|
| - "transition-property", "transition-timing-function", "unicode-bidi",
|
| - "vertical-align", "visibility", "voice-balance", "voice-duration",
|
| - "voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress",
|
| - "voice-volume", "volume", "white-space", "widows", "width", "word-break",
|
| - "word-spacing", "word-wrap", "z-index"
|
| - ]);
|
| -
|
| - var colorKeywords = keySet([
|
| - "black", "silver", "gray", "white", "maroon", "red", "purple", "fuchsia",
|
| - "green", "lime", "olive", "yellow", "navy", "blue", "teal", "aqua"
|
| - ]);
|
| -
|
| - var valueKeywords = keySet([
|
| - "above", "absolute", "activeborder", "activecaption", "afar",
|
| - "after-white-space", "ahead", "alias", "all", "all-scroll", "alternate",
|
| - "always", "amharic", "amharic-abegede", "antialiased", "appworkspace",
|
| - "arabic-indic", "armenian", "asterisks", "auto", "avoid", "background",
|
| - "backwards", "baseline", "below", "bidi-override", "binary", "bengali",
|
| - "blink", "block", "block-axis", "bold", "bolder", "border", "border-box",
|
| - "both", "bottom", "break-all", "break-word", "button", "button-bevel",
|
| - "buttonface", "buttonhighlight", "buttonshadow", "buttontext", "cambodian",
|
| - "capitalize", "caps-lock-indicator", "caption", "captiontext", "caret",
|
| - "cell", "center", "checkbox", "circle", "cjk-earthly-branch",
|
| - "cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote",
|
| - "col-resize", "collapse", "compact", "condensed", "contain", "content",
|
| - "content-box", "context-menu", "continuous", "copy", "cover", "crop",
|
| - "cross", "crosshair", "currentcolor", "cursive", "dashed", "decimal",
|
| - "decimal-leading-zero", "default", "default-button", "destination-atop",
|
| - "destination-in", "destination-out", "destination-over", "devanagari",
|
| - "disc", "discard", "document", "dot-dash", "dot-dot-dash", "dotted",
|
| - "double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out",
|
| - "element", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede",
|
| - "ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er",
|
| - "ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er",
|
| - "ethiopic-halehame-aa-et", "ethiopic-halehame-am-et",
|
| - "ethiopic-halehame-gez", "ethiopic-halehame-om-et",
|
| - "ethiopic-halehame-sid-et", "ethiopic-halehame-so-et",
|
| - "ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et",
|
| - "ethiopic-halehame-tig", "ew-resize", "expanded", "extra-condensed",
|
| - "extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "footnotes",
|
| - "forwards", "from", "geometricPrecision", "georgian", "graytext", "groove",
|
| - "gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hebrew",
|
| - "help", "hidden", "hide", "higher", "highlight", "highlighttext",
|
| - "hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "icon", "ignore",
|
| - "inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite",
|
| - "infobackground", "infotext", "inherit", "initial", "inline", "inline-axis",
|
| - "inline-block", "inline-table", "inset", "inside", "intrinsic", "invert",
|
| - "italic", "justify", "kannada", "katakana", "katakana-iroha", "khmer",
|
| - "landscape", "lao", "large", "larger", "left", "level", "lighter",
|
| - "line-through", "linear", "lines", "list-item", "listbox", "listitem",
|
| - "local", "logical", "loud", "lower", "lower-alpha", "lower-armenian",
|
| - "lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian",
|
| - "lower-roman", "lowercase", "ltr", "malayalam", "match",
|
| - "media-controls-background", "media-current-time-display",
|
| - "media-fullscreen-button", "media-mute-button", "media-play-button",
|
| - "media-return-to-realtime-button", "media-rewind-button",
|
| - "media-seek-back-button", "media-seek-forward-button", "media-slider",
|
| - "media-sliderthumb", "media-time-remaining-display", "media-volume-slider",
|
| - "media-volume-slider-container", "media-volume-sliderthumb", "medium",
|
| - "menu", "menulist", "menulist-button", "menulist-text",
|
| - "menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic",
|
| - "mix", "mongolian", "monospace", "move", "multiple", "myanmar", "n-resize",
|
| - "narrower", "navy", "ne-resize", "nesw-resize", "no-close-quote", "no-drop",
|
| - "no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap",
|
| - "ns-resize", "nw-resize", "nwse-resize", "oblique", "octal", "open-quote",
|
| - "optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset",
|
| - "outside", "overlay", "overline", "padding", "padding-box", "painted",
|
| - "paused", "persian", "plus-darker", "plus-lighter", "pointer", "portrait",
|
| - "pre", "pre-line", "pre-wrap", "preserve-3d", "progress", "push-button",
|
| - "radio", "read-only", "read-write", "read-write-plaintext-only", "relative",
|
| - "repeat", "repeat-x", "repeat-y", "reset", "reverse", "rgb", "rgba",
|
| - "ridge", "right", "round", "row-resize", "rtl", "run-in", "running",
|
| - "s-resize", "sans-serif", "scroll", "scrollbar", "se-resize", "searchfield",
|
| - "searchfield-cancel-button", "searchfield-decoration",
|
| - "searchfield-results-button", "searchfield-results-decoration",
|
| - "semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama",
|
| - "single", "skip-white-space", "slide", "slider-horizontal",
|
| - "slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow",
|
| - "small", "small-caps", "small-caption", "smaller", "solid", "somali",
|
| - "source-atop", "source-in", "source-out", "source-over", "space", "square",
|
| - "square-button", "start", "static", "status-bar", "stretch", "stroke",
|
| - "sub", "subpixel-antialiased", "super", "sw-resize", "table",
|
| - "table-caption", "table-cell", "table-column", "table-column-group",
|
| - "table-footer-group", "table-header-group", "table-row", "table-row-group",
|
| - "telugu", "text", "text-bottom", "text-top", "textarea", "textfield", "thai",
|
| - "thick", "thin", "threeddarkshadow", "threedface", "threedhighlight",
|
| - "threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er",
|
| - "tigrinya-er-abegede", "tigrinya-et", "tigrinya-et-abegede", "to", "top",
|
| - "transparent", "ultra-condensed", "ultra-expanded", "underline", "up",
|
| - "upper-alpha", "upper-armenian", "upper-greek", "upper-hexadecimal",
|
| - "upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url",
|
| - "vertical", "vertical-text", "visible", "visibleFill", "visiblePainted",
|
| - "visibleStroke", "visual", "w-resize", "wait", "wave", "white", "wider",
|
| - "window", "windowframe", "windowtext", "x-large", "x-small", "xor",
|
| - "xx-large", "xx-small", "yellow"
|
| - ]);
|
| -
|
| - function keySet(array) { var keys = {}; for (var i = 0; i < array.length; ++i) keys[array[i]] = true; return keys; }
|
| - function ret(style, tp) {type = tp; return style;}
|
| -
|
| - function tokenBase(stream, state) {
|
| - var ch = stream.next();
|
| - if (ch == "@") {stream.eatWhile(/[\w\\\-]/); return ret("def", stream.current());}
|
| - else if (ch == "/" && stream.eat("*")) {
|
| - state.tokenize = tokenCComment;
|
| - return tokenCComment(stream, state);
|
| - }
|
| - else if (ch == "<" && stream.eat("!")) {
|
| - state.tokenize = tokenSGMLComment;
|
| - return tokenSGMLComment(stream, state);
|
| - }
|
| - else if (ch == "=") ret(null, "compare");
|
| - else if ((ch == "~" || ch == "|") && stream.eat("=")) return ret(null, "compare");
|
| - else if (ch == "\"" || ch == "'") {
|
| - state.tokenize = tokenString(ch);
|
| - return state.tokenize(stream, state);
|
| - }
|
| - else if (ch == "#") {
|
| - stream.eatWhile(/[\w\\\-]/);
|
| - return ret("atom", "hash");
|
| - }
|
| - else if (ch == "!") {
|
| - stream.match(/^\s*\w*/);
|
| - return ret("keyword", "important");
|
| - }
|
| - else if (/\d/.test(ch)) {
|
| - stream.eatWhile(/[\w.%]/);
|
| - return ret("number", "unit");
|
| - }
|
| - else if (ch === "-") {
|
| - if (/\d/.test(stream.peek())) {
|
| - stream.eatWhile(/[\w.%]/);
|
| - return ret("number", "unit");
|
| - } else if (stream.match(/^[^-]+-/)) {
|
| - return ret("meta", "meta");
|
| - }
|
| - }
|
| - else if (/[,+>*\/]/.test(ch)) {
|
| - return ret(null, "select-op");
|
| - }
|
| - else if (ch == "." && stream.match(/^-?[_a-z][_a-z0-9-]*/i)) {
|
| - return ret("qualifier", "qualifier");
|
| - }
|
| - else if (ch == ":") {
|
| - return ret("operator", ch);
|
| - }
|
| - else if (/[;{}\[\]\(\)]/.test(ch)) {
|
| - return ret(null, ch);
|
| - }
|
| - else if (ch == "u" && stream.match("rl(")) {
|
| - stream.backUp(1);
|
| - state.tokenize = tokenParenthesized;
|
| - return ret("property", "variable");
|
| - }
|
| - else {
|
| - stream.eatWhile(/[\w\\\-]/);
|
| - return ret("property", "variable");
|
| - }
|
| - }
|
| -
|
| - function tokenCComment(stream, state) {
|
| - var maybeEnd = false, ch;
|
| - while ((ch = stream.next()) != null) {
|
| - if (maybeEnd && ch == "/") {
|
| - state.tokenize = tokenBase;
|
| - break;
|
| - }
|
| - maybeEnd = (ch == "*");
|
| - }
|
| - return ret("comment", "comment");
|
| - }
|
| -
|
| - function tokenSGMLComment(stream, state) {
|
| - var dashes = 0, ch;
|
| - while ((ch = stream.next()) != null) {
|
| - if (dashes >= 2 && ch == ">") {
|
| - state.tokenize = tokenBase;
|
| - break;
|
| - }
|
| - dashes = (ch == "-") ? dashes + 1 : 0;
|
| - }
|
| - return ret("comment", "comment");
|
| - }
|
| -
|
| - function tokenString(quote, nonInclusive) {
|
| - return function(stream, state) {
|
| - var escaped = false, ch;
|
| - while ((ch = stream.next()) != null) {
|
| - if (ch == quote && !escaped)
|
| - break;
|
| - escaped = !escaped && ch == "\\";
|
| - }
|
| - if (!escaped) {
|
| - if (nonInclusive) stream.backUp(1);
|
| - state.tokenize = tokenBase;
|
| - }
|
| - return ret("string", "string");
|
| - };
|
| - }
|
| -
|
| - function tokenParenthesized(stream, state) {
|
| - stream.next(); // Must be '('
|
| - if (!stream.match(/\s*[\"\']/, false))
|
| - state.tokenize = tokenString(")", true);
|
| - else
|
| - state.tokenize = tokenBase;
|
| - return ret(null, "(");
|
| - }
|
| -
|
| - return {
|
| - startState: function(base) {
|
| - return {tokenize: tokenBase,
|
| - baseIndent: base || 0,
|
| - stack: []};
|
| - },
|
| -
|
| - token: function(stream, state) {
|
| -
|
| - // Use these terms when applicable (see http://www.xanthir.com/blog/b4E50)
|
| - //
|
| - // rule** or **ruleset:
|
| - // A selector + braces combo, or an at-rule.
|
| - //
|
| - // declaration block:
|
| - // A sequence of declarations.
|
| - //
|
| - // declaration:
|
| - // A property + colon + value combo.
|
| - //
|
| - // property value:
|
| - // The entire value of a property.
|
| - //
|
| - // component value:
|
| - // A single piece of a property value. Like the 5px in
|
| - // text-shadow: 0 0 5px blue;. Can also refer to things that are
|
| - // multiple terms, like the 1-4 terms that make up the background-size
|
| - // portion of the background shorthand.
|
| - //
|
| - // term:
|
| - // The basic unit of author-facing CSS, like a single number (5),
|
| - // dimension (5px), string ("foo"), or function. Officially defined
|
| - // by the CSS 2.1 grammar (look for the 'term' production)
|
| - //
|
| - //
|
| - // simple selector:
|
| - // A single atomic selector, like a type selector, an attr selector, a
|
| - // class selector, etc.
|
| - //
|
| - // compound selector:
|
| - // One or more simple selectors without a combinator. div.example is
|
| - // compound, div > .example is not.
|
| - //
|
| - // complex selector:
|
| - // One or more compound selectors chained with combinators.
|
| - //
|
| - // combinator:
|
| - // The parts of selectors that express relationships. There are four
|
| - // currently - the space (descendant combinator), the greater-than
|
| - // bracket (child combinator), the plus sign (next sibling combinator),
|
| - // and the tilda (following sibling combinator).
|
| - //
|
| - // sequence of selectors:
|
| - // One or more of the named type of selector chained with commas.
|
| -
|
| - if (state.tokenize == tokenBase && stream.eatSpace()) return null;
|
| - var style = state.tokenize(stream, state);
|
| -
|
| - // Changing style returned based on context
|
| - var context = state.stack[state.stack.length-1];
|
| - if (style == "property") {
|
| - if (context == "propertyValue"){
|
| - if (valueKeywords[stream.current()]) {
|
| - style = "string-2";
|
| - } else if (colorKeywords[stream.current()]) {
|
| - style = "keyword";
|
| - } else {
|
| - style = "variable-2";
|
| - }
|
| - } else if (context == "rule") {
|
| - if (!propertyKeywords[stream.current()]) {
|
| - style += " error";
|
| - }
|
| - } else if (!context || context == "@media{") {
|
| - style = "tag";
|
| - } else if (context == "@media") {
|
| - if (atMediaTypes[stream.current()]) {
|
| - style = "attribute"; // Known attribute
|
| - } else if (/^(only|not)$/i.test(stream.current())) {
|
| - style = "keyword";
|
| - } else if (stream.current().toLowerCase() == "and") {
|
| - style = "error"; // "and" is only allowed in @mediaType
|
| - } else if (atMediaFeatures[stream.current()]) {
|
| - style = "error"; // Known property, should be in @mediaType(
|
| - } else {
|
| - // Unknown, expecting keyword or attribute, assuming attribute
|
| - style = "attribute error";
|
| - }
|
| - } else if (context == "@mediaType") {
|
| - if (atMediaTypes[stream.current()]) {
|
| - style = "attribute";
|
| - } else if (stream.current().toLowerCase() == "and") {
|
| - style = "operator";
|
| - } else if (/^(only|not)$/i.test(stream.current())) {
|
| - style = "error"; // Only allowed in @media
|
| - } else if (atMediaFeatures[stream.current()]) {
|
| - style = "error"; // Known property, should be in parentheses
|
| - } else {
|
| - // Unknown attribute or property, but expecting property (preceded
|
| - // by "and"). Should be in parentheses
|
| - style = "error";
|
| - }
|
| - } else if (context == "@mediaType(") {
|
| - if (propertyKeywords[stream.current()]) {
|
| - // do nothing, remains "property"
|
| - } else if (atMediaTypes[stream.current()]) {
|
| - style = "error"; // Known property, should be in parentheses
|
| - } else if (stream.current().toLowerCase() == "and") {
|
| - style = "operator";
|
| - } else if (/^(only|not)$/i.test(stream.current())) {
|
| - style = "error"; // Only allowed in @media
|
| - } else {
|
| - style += " error";
|
| - }
|
| - } else {
|
| - style = "error";
|
| - }
|
| - } else if (style == "atom") {
|
| - if(!context || context == "@media{") {
|
| - style = "builtin";
|
| - } else if (context == "propertyValue") {
|
| - if (!/^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/.test(stream.current())) {
|
| - style += " error";
|
| - }
|
| - } else {
|
| - style = "error";
|
| - }
|
| - } else if (context == "@media" && type == "{") {
|
| - style = "error";
|
| - }
|
| -
|
| - // Push/pop context stack
|
| - if (type == "{") {
|
| - if (context == "@media" || context == "@mediaType") {
|
| - state.stack.pop();
|
| - state.stack[state.stack.length-1] = "@media{";
|
| - }
|
| - else state.stack.push("rule");
|
| - }
|
| - else if (type == "}") {
|
| - state.stack.pop();
|
| - if (context == "propertyValue") state.stack.pop();
|
| - }
|
| - else if (type == "@media") state.stack.push("@media");
|
| - else if (context == "@media" && /\b(keyword|attribute)\b/.test(style))
|
| - state.stack.push("@mediaType");
|
| - else if (context == "@mediaType" && stream.current() == ",") state.stack.pop();
|
| - else if (context == "@mediaType" && type == "(") state.stack.push("@mediaType(");
|
| - else if (context == "@mediaType(" && type == ")") state.stack.pop();
|
| - else if (context == "rule" && type == ":") state.stack.push("propertyValue");
|
| - else if (context == "propertyValue" && type == ";") state.stack.pop();
|
| - return style;
|
| - },
|
| -
|
| - indent: function(state, textAfter) {
|
| - var n = state.stack.length;
|
| - if (/^\}/.test(textAfter))
|
| - n -= state.stack[state.stack.length-1] == "propertyValue" ? 2 : 1;
|
| - return state.baseIndent + n * indentUnit;
|
| - },
|
| -
|
| - electricChars: "}"
|
| - };
|
| -});
|
| -
|
| -CodeMirror.defineMIME("text/css", "css");
|
| -;
|
| -// TODO actually recognize syntax of TypeScript constructs
|
| -
|
| -CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
| - var indentUnit = config.indentUnit;
|
| - var jsonMode = parserConfig.json;
|
| - var isTS = parserConfig.typescript;
|
| -
|
| - // Tokenizer
|
| -
|
| - var keywords = function(){
|
| - function kw(type) {return {type: type, style: "keyword"};}
|
| - var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
|
| - var operator = kw("operator"), atom = {type: "atom", style: "atom"};
|
| -
|
| - var jsKeywords = {
|
| - "if": A, "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
|
| - "return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C,
|
| - "var": kw("var"), "const": kw("var"), "let": kw("var"),
|
| - "function": kw("function"), "catch": kw("catch"),
|
| - "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
|
| - "in": operator, "typeof": operator, "instanceof": operator,
|
| - "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom
|
| - };
|
| -
|
| - // Extend the 'normal' keywords with the TypeScript language extensions
|
| - if (isTS) {
|
| - var type = {type: "variable", style: "variable-3"};
|
| - var tsKeywords = {
|
| - // object-like things
|
| - "interface": kw("interface"),
|
| - "class": kw("class"),
|
| - "extends": kw("extends"),
|
| - "constructor": kw("constructor"),
|
| -
|
| - // scope modifiers
|
| - "public": kw("public"),
|
| - "private": kw("private"),
|
| - "protected": kw("protected"),
|
| - "static": kw("static"),
|
| -
|
| - "super": kw("super"),
|
| -
|
| - // types
|
| - "string": type, "number": type, "bool": type, "any": type
|
| - };
|
| -
|
| - for (var attr in tsKeywords) {
|
| - jsKeywords[attr] = tsKeywords[attr];
|
| - }
|
| - }
|
| -
|
| - return jsKeywords;
|
| - }();
|
| -
|
| - var isOperatorChar = /[+\-*&%=<>!?|]/;
|
| -
|
| - function chain(stream, state, f) {
|
| - state.tokenize = f;
|
| - return f(stream, state);
|
| - }
|
| -
|
| - function nextUntilUnescaped(stream, end) {
|
| - var escaped = false, next;
|
| - while ((next = stream.next()) != null) {
|
| - if (next == end && !escaped)
|
| - return false;
|
| - escaped = !escaped && next == "\\";
|
| - }
|
| - return escaped;
|
| - }
|
| -
|
| - // Used as scratch variables to communicate multiple values without
|
| - // consing up tons of objects.
|
| - var type, content;
|
| - function ret(tp, style, cont) {
|
| - type = tp; content = cont;
|
| - return style;
|
| - }
|
| -
|
| - function jsTokenBase(stream, state) {
|
| - var ch = stream.next();
|
| - if (ch == '"' || ch == "'")
|
| - return chain(stream, state, jsTokenString(ch));
|
| - else if (/[\[\]{}\(\),;\:\.]/.test(ch))
|
| - return ret(ch);
|
| - else if (ch == "0" && stream.eat(/x/i)) {
|
| - stream.eatWhile(/[\da-f]/i);
|
| - return ret("number", "number");
|
| - }
|
| - else if (/\d/.test(ch) || ch == "-" && stream.eat(/\d/)) {
|
| - stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
|
| - return ret("number", "number");
|
| - }
|
| - else if (ch == "/") {
|
| - if (stream.eat("*")) {
|
| - return chain(stream, state, jsTokenComment);
|
| - }
|
| - else if (stream.eat("/")) {
|
| - stream.skipToEnd();
|
| - return ret("comment", "comment");
|
| - }
|
| - else if (state.lastType == "operator" || state.lastType == "keyword c" ||
|
| - /^[\[{}\(,;:]$/.test(state.lastType)) {
|
| - nextUntilUnescaped(stream, "/");
|
| - stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla
|
| - return ret("regexp", "string-2");
|
| - }
|
| - else {
|
| - stream.eatWhile(isOperatorChar);
|
| - return ret("operator", null, stream.current());
|
| - }
|
| - }
|
| - else if (ch == "#") {
|
| - stream.skipToEnd();
|
| - return ret("error", "error");
|
| - }
|
| - else if (isOperatorChar.test(ch)) {
|
| - stream.eatWhile(isOperatorChar);
|
| - return ret("operator", null, stream.current());
|
| - }
|
| - else {
|
| - stream.eatWhile(/[\w\$_]/);
|
| - var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
|
| - return (known && state.lastType != ".") ? ret(known.type, known.style, word) :
|
| - ret("variable", "variable", word);
|
| - }
|
| - }
|
| -
|
| - function jsTokenString(quote) {
|
| - return function(stream, state) {
|
| - if (!nextUntilUnescaped(stream, quote))
|
| - state.tokenize = jsTokenBase;
|
| - return ret("string", "string");
|
| - };
|
| - }
|
| -
|
| - function jsTokenComment(stream, state) {
|
| - var maybeEnd = false, ch;
|
| - while (ch = stream.next()) {
|
| - if (ch == "/" && maybeEnd) {
|
| - state.tokenize = jsTokenBase;
|
| - break;
|
| - }
|
| - maybeEnd = (ch == "*");
|
| - }
|
| - return ret("comment", "comment");
|
| - }
|
| -
|
| - // Parser
|
| -
|
| - var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true};
|
| -
|
| - function JSLexical(indented, column, type, align, prev, info) {
|
| - this.indented = indented;
|
| - this.column = column;
|
| - this.type = type;
|
| - this.prev = prev;
|
| - this.info = info;
|
| - if (align != null) this.align = align;
|
| - }
|
| -
|
| - function inScope(state, varname) {
|
| - for (var v = state.localVars; v; v = v.next)
|
| - if (v.name == varname) return true;
|
| - }
|
| -
|
| - function parseJS(state, style, type, content, stream) {
|
| - var cc = state.cc;
|
| - // Communicate our context to the combinators.
|
| - // (Less wasteful than consing up a hundred closures on every call.)
|
| - cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc;
|
| -
|
| - if (!state.lexical.hasOwnProperty("align"))
|
| - state.lexical.align = true;
|
| -
|
| - while(true) {
|
| - var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement;
|
| - if (combinator(type, content)) {
|
| - while(cc.length && cc[cc.length - 1].lex)
|
| - cc.pop()();
|
| - if (cx.marked) return cx.marked;
|
| - if (type == "variable" && inScope(state, content)) return "variable-2";
|
| - return style;
|
| - }
|
| - }
|
| - }
|
| -
|
| - // Combinator utils
|
| -
|
| - var cx = {state: null, column: null, marked: null, cc: null};
|
| - function pass() {
|
| - for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
|
| - }
|
| - function cont() {
|
| - pass.apply(null, arguments);
|
| - return true;
|
| - }
|
| - function register(varname) {
|
| - function inList(list) {
|
| - for (var v = list; v; v = v.next)
|
| - if (v.name == varname) return true;
|
| - return false;
|
| - }
|
| - var state = cx.state;
|
| - if (state.context) {
|
| - cx.marked = "def";
|
| - if (inList(state.localVars)) return;
|
| - state.localVars = {name: varname, next: state.localVars};
|
| - } else {
|
| - if (inList(state.globalVars)) return;
|
| - state.globalVars = {name: varname, next: state.globalVars};
|
| - }
|
| - }
|
| -
|
| - // Combinators
|
| -
|
| - var defaultVars = {name: "this", next: {name: "arguments"}};
|
| - function pushcontext() {
|
| - cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
|
| - cx.state.localVars = defaultVars;
|
| - }
|
| - function popcontext() {
|
| - cx.state.localVars = cx.state.context.vars;
|
| - cx.state.context = cx.state.context.prev;
|
| - }
|
| - function pushlex(type, info) {
|
| - var result = function() {
|
| - var state = cx.state;
|
| - state.lexical = new JSLexical(state.indented, cx.stream.column(), type, null, state.lexical, info);
|
| - };
|
| - result.lex = true;
|
| - return result;
|
| - }
|
| - function poplex() {
|
| - var state = cx.state;
|
| - if (state.lexical.prev) {
|
| - if (state.lexical.type == ")")
|
| - state.indented = state.lexical.indented;
|
| - state.lexical = state.lexical.prev;
|
| - }
|
| - }
|
| - poplex.lex = true;
|
| -
|
| - function expect(wanted) {
|
| - return function expecting(type) {
|
| - if (type == wanted) return cont();
|
| - else if (wanted == ";") return pass();
|
| - else return cont(arguments.callee);
|
| - };
|
| - }
|
| -
|
| - function statement(type) {
|
| - if (type == "var") return cont(pushlex("vardef"), vardef1, expect(";"), poplex);
|
| - if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex);
|
| - if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
|
| - if (type == "{") return cont(pushlex("}"), block, poplex);
|
| - if (type == ";") return cont();
|
| - if (type == "function") return cont(functiondef);
|
| - if (type == "for") return cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"),
|
| - poplex, statement, poplex);
|
| - if (type == "variable") return cont(pushlex("stat"), maybelabel);
|
| - if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
|
| - block, poplex, poplex);
|
| - if (type == "case") return cont(expression, expect(":"));
|
| - if (type == "default") return cont(expect(":"));
|
| - if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
|
| - statement, poplex, popcontext);
|
| - return pass(pushlex("stat"), expression, expect(";"), poplex);
|
| - }
|
| - function expression(type) {
|
| - if (atomicTypes.hasOwnProperty(type)) return cont(maybeoperator);
|
| - if (type == "function") return cont(functiondef);
|
| - if (type == "keyword c") return cont(maybeexpression);
|
| - if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeoperator);
|
| - if (type == "operator") return cont(expression);
|
| - if (type == "[") return cont(pushlex("]"), commasep(expression, "]"), poplex, maybeoperator);
|
| - if (type == "{") return cont(pushlex("}"), commasep(objprop, "}"), poplex, maybeoperator);
|
| - return cont();
|
| - }
|
| - function maybeexpression(type) {
|
| - if (type.match(/[;\}\)\],]/)) return pass();
|
| - return pass(expression);
|
| - }
|
| -
|
| - function maybeoperator(type, value) {
|
| - if (type == "operator" && /\+\+|--/.test(value)) return cont(maybeoperator);
|
| - if (type == "operator" && value == "?") return cont(expression, expect(":"), expression);
|
| - if (type == ";") return;
|
| - if (type == "(") return cont(pushlex(")"), commasep(expression, ")"), poplex, maybeoperator);
|
| - if (type == ".") return cont(property, maybeoperator);
|
| - if (type == "[") return cont(pushlex("]"), expression, expect("]"), poplex, maybeoperator);
|
| - }
|
| - function maybelabel(type) {
|
| - if (type == ":") return cont(poplex, statement);
|
| - return pass(maybeoperator, expect(";"), poplex);
|
| - }
|
| - function property(type) {
|
| - if (type == "variable") {cx.marked = "property"; return cont();}
|
| - }
|
| - function objprop(type) {
|
| - if (type == "variable") cx.marked = "property";
|
| - if (atomicTypes.hasOwnProperty(type)) return cont(expect(":"), expression);
|
| - }
|
| - function commasep(what, end) {
|
| - function proceed(type) {
|
| - if (type == ",") return cont(what, proceed);
|
| - if (type == end) return cont();
|
| - return cont(expect(end));
|
| - }
|
| - return function commaSeparated(type) {
|
| - if (type == end) return cont();
|
| - else return pass(what, proceed);
|
| - };
|
| - }
|
| - function block(type) {
|
| - if (type == "}") return cont();
|
| - return pass(statement, block);
|
| - }
|
| - function maybetype(type) {
|
| - if (type == ":") return cont(typedef);
|
| - return pass();
|
| - }
|
| - function typedef(type) {
|
| - if (type == "variable"){cx.marked = "variable-3"; return cont();}
|
| - return pass();
|
| - }
|
| - function vardef1(type, value) {
|
| - if (type == "variable") {
|
| - register(value);
|
| - return isTS ? cont(maybetype, vardef2) : cont(vardef2);
|
| - }
|
| - return pass();
|
| - }
|
| - function vardef2(type, value) {
|
| - if (value == "=") return cont(expression, vardef2);
|
| - if (type == ",") return cont(vardef1);
|
| - }
|
| - function forspec1(type) {
|
| - if (type == "var") return cont(vardef1, expect(";"), forspec2);
|
| - if (type == ";") return cont(forspec2);
|
| - if (type == "variable") return cont(formaybein);
|
| - return cont(forspec2);
|
| - }
|
| - function formaybein(_type, value) {
|
| - if (value == "in") return cont(expression);
|
| - return cont(maybeoperator, forspec2);
|
| - }
|
| - function forspec2(type, value) {
|
| - if (type == ";") return cont(forspec3);
|
| - if (value == "in") return cont(expression);
|
| - return cont(expression, expect(";"), forspec3);
|
| - }
|
| - function forspec3(type) {
|
| - if (type != ")") cont(expression);
|
| - }
|
| - function functiondef(type, value) {
|
| - if (type == "variable") {register(value); return cont(functiondef);}
|
| - if (type == "(") return cont(pushlex(")"), pushcontext, commasep(funarg, ")"), poplex, statement, popcontext);
|
| - }
|
| - function funarg(type, value) {
|
| - if (type == "variable") {register(value); return isTS ? cont(maybetype) : cont();}
|
| - }
|
| -
|
| - // Interface
|
| -
|
| - return {
|
| - startState: function(basecolumn) {
|
| - return {
|
| - tokenize: jsTokenBase,
|
| - lastType: null,
|
| - cc: [],
|
| - lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
|
| - localVars: parserConfig.localVars,
|
| - globalVars: parserConfig.globalVars,
|
| - context: parserConfig.localVars && {vars: parserConfig.localVars},
|
| - indented: 0
|
| - };
|
| - },
|
| -
|
| - token: function(stream, state) {
|
| - if (stream.sol()) {
|
| - if (!state.lexical.hasOwnProperty("align"))
|
| - state.lexical.align = false;
|
| - state.indented = stream.indentation();
|
| - }
|
| - if (stream.eatSpace()) return null;
|
| - var style = state.tokenize(stream, state);
|
| - if (type == "comment") return style;
|
| - state.lastType = type;
|
| - return parseJS(state, style, type, content, stream);
|
| - },
|
| -
|
| - indent: function(state, textAfter) {
|
| - if (state.tokenize == jsTokenComment) return CodeMirror.Pass;
|
| - if (state.tokenize != jsTokenBase) return 0;
|
| - var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical;
|
| - if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev;
|
| - var type = lexical.type, closing = firstChar == type;
|
| - if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? 4 : 0);
|
| - else if (type == "form" && firstChar == "{") return lexical.indented;
|
| - else if (type == "form") return lexical.indented + indentUnit;
|
| - else if (type == "stat")
|
| - return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? indentUnit : 0);
|
| - else if (lexical.info == "switch" && !closing)
|
| - return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
|
| - else if (lexical.align) return lexical.column + (closing ? 0 : 1);
|
| - else return lexical.indented + (closing ? 0 : indentUnit);
|
| - },
|
| -
|
| - electricChars: ":{}",
|
| -
|
| - jsonMode: jsonMode
|
| - };
|
| -});
|
| -
|
| -CodeMirror.defineMIME("text/javascript", "javascript");
|
| -CodeMirror.defineMIME("application/json", {name: "javascript", json: true});
|
| -CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true });
|
| -CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true });
|
| -;
|
| -CodeMirror.defineMode("xml", function(config, parserConfig) {
|
| - var indentUnit = config.indentUnit;
|
| - var Kludges = parserConfig.htmlMode ? {
|
| - autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true,
|
| - 'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true,
|
| - 'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true,
|
| - 'track': true, 'wbr': true},
|
| - implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true,
|
| - 'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true,
|
| - 'th': true, 'tr': true},
|
| - contextGrabbers: {
|
| - 'dd': {'dd': true, 'dt': true},
|
| - 'dt': {'dd': true, 'dt': true},
|
| - 'li': {'li': true},
|
| - 'option': {'option': true, 'optgroup': true},
|
| - 'optgroup': {'optgroup': true},
|
| - 'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true,
|
| - 'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true,
|
| - 'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true,
|
| - 'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true,
|
| - 'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true},
|
| - 'rp': {'rp': true, 'rt': true},
|
| - 'rt': {'rp': true, 'rt': true},
|
| - 'tbody': {'tbody': true, 'tfoot': true},
|
| - 'td': {'td': true, 'th': true},
|
| - 'tfoot': {'tbody': true},
|
| - 'th': {'td': true, 'th': true},
|
| - 'thead': {'tbody': true, 'tfoot': true},
|
| - 'tr': {'tr': true}
|
| - },
|
| - doNotIndent: {"pre": true},
|
| - allowUnquoted: true,
|
| - allowMissing: true
|
| - } : {
|
| - autoSelfClosers: {},
|
| - implicitlyClosed: {},
|
| - contextGrabbers: {},
|
| - doNotIndent: {},
|
| - allowUnquoted: false,
|
| - allowMissing: false
|
| - };
|
| - var alignCDATA = parserConfig.alignCDATA;
|
| -
|
| - // Return variables for tokenizers
|
| - var tagName, type;
|
| -
|
| - function inText(stream, state) {
|
| - function chain(parser) {
|
| - state.tokenize = parser;
|
| - return parser(stream, state);
|
| - }
|
| -
|
| - var ch = stream.next();
|
| - if (ch == "<") {
|
| - if (stream.eat("!")) {
|
| - if (stream.eat("[")) {
|
| - if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>"));
|
| - else return null;
|
| - }
|
| - else if (stream.match("--")) return chain(inBlock("comment", "-->"));
|
| - else if (stream.match("DOCTYPE", true, true)) {
|
| - stream.eatWhile(/[\w\._\-]/);
|
| - return chain(doctype(1));
|
| - }
|
| - else return null;
|
| - }
|
| - else if (stream.eat("?")) {
|
| - stream.eatWhile(/[\w\._\-]/);
|
| - state.tokenize = inBlock("meta", "?>");
|
| - return "meta";
|
| - }
|
| - else {
|
| - var isClose = stream.eat("/");
|
| - tagName = "";
|
| - var c;
|
| - while ((c = stream.eat(/[^\s\u00a0=<>\"\'\/?]/))) tagName += c;
|
| - if (!tagName) return "error";
|
| - type = isClose ? "closeTag" : "openTag";
|
| - state.tokenize = inTag;
|
| - return "tag";
|
| - }
|
| - }
|
| - else if (ch == "&") {
|
| - var ok;
|
| - if (stream.eat("#")) {
|
| - if (stream.eat("x")) {
|
| - ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";");
|
| - } else {
|
| - ok = stream.eatWhile(/[\d]/) && stream.eat(";");
|
| - }
|
| - } else {
|
| - ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";");
|
| - }
|
| - return ok ? "atom" : "error";
|
| - }
|
| - else {
|
| - stream.eatWhile(/[^&<]/);
|
| - return null;
|
| - }
|
| - }
|
| -
|
| - function inTag(stream, state) {
|
| - var ch = stream.next();
|
| - if (ch == ">" || (ch == "/" && stream.eat(">"))) {
|
| - state.tokenize = inText;
|
| - type = ch == ">" ? "endTag" : "selfcloseTag";
|
| - return "tag";
|
| - }
|
| - else if (ch == "=") {
|
| - type = "equals";
|
| - return null;
|
| - }
|
| - else if (/[\'\"]/.test(ch)) {
|
| - state.tokenize = inAttribute(ch);
|
| - return state.tokenize(stream, state);
|
| - }
|
| - else {
|
| - stream.eatWhile(/[^\s\u00a0=<>\"\']/);
|
| - return "word";
|
| - }
|
| - }
|
| -
|
| - function inAttribute(quote) {
|
| - return function(stream, state) {
|
| - while (!stream.eol()) {
|
| - if (stream.next() == quote) {
|
| - state.tokenize = inTag;
|
| - break;
|
| - }
|
| - }
|
| - return "string";
|
| - };
|
| - }
|
| -
|
| - function inBlock(style, terminator) {
|
| - return function(stream, state) {
|
| - while (!stream.eol()) {
|
| - if (stream.match(terminator)) {
|
| - state.tokenize = inText;
|
| - break;
|
| - }
|
| - stream.next();
|
| - }
|
| - return style;
|
| - };
|
| - }
|
| - function doctype(depth) {
|
| - return function(stream, state) {
|
| - var ch;
|
| - while ((ch = stream.next()) != null) {
|
| - if (ch == "<") {
|
| - state.tokenize = doctype(depth + 1);
|
| - return state.tokenize(stream, state);
|
| - } else if (ch == ">") {
|
| - if (depth == 1) {
|
| - state.tokenize = inText;
|
| - break;
|
| - } else {
|
| - state.tokenize = doctype(depth - 1);
|
| - return state.tokenize(stream, state);
|
| - }
|
| - }
|
| - }
|
| - return "meta";
|
| - };
|
| - }
|
| -
|
| - var curState, setStyle;
|
| - function pass() {
|
| - for (var i = arguments.length - 1; i >= 0; i--) curState.cc.push(arguments[i]);
|
| - }
|
| - function cont() {
|
| - pass.apply(null, arguments);
|
| - return true;
|
| - }
|
| -
|
| - function pushContext(tagName, startOfLine) {
|
| - var noIndent = Kludges.doNotIndent.hasOwnProperty(tagName) || (curState.context && curState.context.noIndent);
|
| - curState.context = {
|
| - prev: curState.context,
|
| - tagName: tagName,
|
| - indent: curState.indented,
|
| - startOfLine: startOfLine,
|
| - noIndent: noIndent
|
| - };
|
| - }
|
| - function popContext() {
|
| - if (curState.context) curState.context = curState.context.prev;
|
| - }
|
| -
|
| - function element(type) {
|
| - if (type == "openTag") {
|
| - curState.tagName = tagName;
|
| - return cont(attributes, endtag(curState.startOfLine));
|
| - } else if (type == "closeTag") {
|
| - var err = false;
|
| - if (curState.context) {
|
| - if (curState.context.tagName != tagName) {
|
| - if (Kludges.implicitlyClosed.hasOwnProperty(curState.context.tagName.toLowerCase())) {
|
| - popContext();
|
| - }
|
| - err = !curState.context || curState.context.tagName != tagName;
|
| - }
|
| - } else {
|
| - err = true;
|
| - }
|
| - if (err) setStyle = "error";
|
| - return cont(endclosetag(err));
|
| - }
|
| - return cont();
|
| - }
|
| - function endtag(startOfLine) {
|
| - return function(type) {
|
| - var tagName = curState.tagName;
|
| - curState.tagName = null;
|
| - if (type == "selfcloseTag" ||
|
| - (type == "endTag" && Kludges.autoSelfClosers.hasOwnProperty(tagName.toLowerCase()))) {
|
| - maybePopContext(tagName.toLowerCase());
|
| - return cont();
|
| - }
|
| - if (type == "endTag") {
|
| - maybePopContext(tagName.toLowerCase());
|
| - pushContext(tagName, startOfLine);
|
| - return cont();
|
| - }
|
| - return cont();
|
| - };
|
| - }
|
| - function endclosetag(err) {
|
| - return function(type) {
|
| - if (err) setStyle = "error";
|
| - if (type == "endTag") { popContext(); return cont(); }
|
| - setStyle = "error";
|
| - return cont(arguments.callee);
|
| - };
|
| - }
|
| - function maybePopContext(nextTagName) {
|
| - var parentTagName;
|
| - while (true) {
|
| - if (!curState.context) {
|
| - return;
|
| - }
|
| - parentTagName = curState.context.tagName.toLowerCase();
|
| - if (!Kludges.contextGrabbers.hasOwnProperty(parentTagName) ||
|
| - !Kludges.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) {
|
| - return;
|
| - }
|
| - popContext();
|
| - }
|
| - }
|
| -
|
| - function attributes(type) {
|
| - if (type == "word") {setStyle = "attribute"; return cont(attribute, attributes);}
|
| - if (type == "endTag" || type == "selfcloseTag") return pass();
|
| - setStyle = "error";
|
| - return cont(attributes);
|
| - }
|
| - function attribute(type) {
|
| - if (type == "equals") return cont(attvalue, attributes);
|
| - if (!Kludges.allowMissing) setStyle = "error";
|
| - else if (type == "word") setStyle = "attribute";
|
| - return (type == "endTag" || type == "selfcloseTag") ? pass() : cont();
|
| - }
|
| - function attvalue(type) {
|
| - if (type == "string") return cont(attvaluemaybe);
|
| - if (type == "word" && Kludges.allowUnquoted) {setStyle = "string"; return cont();}
|
| - setStyle = "error";
|
| - return (type == "endTag" || type == "selfCloseTag") ? pass() : cont();
|
| - }
|
| - function attvaluemaybe(type) {
|
| - if (type == "string") return cont(attvaluemaybe);
|
| - else return pass();
|
| - }
|
| -
|
| - return {
|
| - startState: function() {
|
| - return {tokenize: inText, cc: [], indented: 0, startOfLine: true, tagName: null, context: null};
|
| - },
|
| -
|
| - token: function(stream, state) {
|
| - if (stream.sol()) {
|
| - state.startOfLine = true;
|
| - state.indented = stream.indentation();
|
| - }
|
| - if (stream.eatSpace()) return null;
|
| -
|
| - setStyle = type = tagName = null;
|
| - var style = state.tokenize(stream, state);
|
| - state.type = type;
|
| - if ((style || type) && style != "comment") {
|
| - curState = state;
|
| - while (true) {
|
| - var comb = state.cc.pop() || element;
|
| - if (comb(type || style)) break;
|
| - }
|
| - }
|
| - state.startOfLine = false;
|
| - return setStyle || style;
|
| - },
|
| -
|
| - indent: function(state, textAfter, fullLine) {
|
| - var context = state.context;
|
| - if ((state.tokenize != inTag && state.tokenize != inText) ||
|
| - context && context.noIndent)
|
| - return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0;
|
| - if (alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0;
|
| - if (context && /^<\//.test(textAfter))
|
| - context = context.prev;
|
| - while (context && !context.startOfLine)
|
| - context = context.prev;
|
| - if (context) return context.indent + indentUnit;
|
| - else return 0;
|
| - },
|
| -
|
| - electricChars: "/",
|
| -
|
| - configuration: parserConfig.htmlMode ? "html" : "xml"
|
| - };
|
| -});
|
| -
|
| -CodeMirror.defineMIME("text/xml", "xml");
|
| -CodeMirror.defineMIME("application/xml", "xml");
|
| -if (!CodeMirror.mimeModes.hasOwnProperty("text/html"))
|
| - CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true});
|
| -;
|
| -CodeMirror.defineMode("htmlmixed", function(config) {
|
| - var htmlMode = CodeMirror.getMode(config, {name: "xml", htmlMode: true});
|
| - var jsMode = CodeMirror.getMode(config, "javascript");
|
| - var cssMode = CodeMirror.getMode(config, "css");
|
| -
|
| - function html(stream, state) {
|
| - var style = htmlMode.token(stream, state.htmlState);
|
| - if (/(?:^|\s)tag(?:\s|$)/.test(style) && stream.current() == ">" && state.htmlState.context) {
|
| - if (/^script$/i.test(state.htmlState.context.tagName)) {
|
| - state.token = javascript;
|
| - state.localState = jsMode.startState(htmlMode.indent(state.htmlState, ""));
|
| - }
|
| - else if (/^style$/i.test(state.htmlState.context.tagName)) {
|
| - state.token = css;
|
| - state.localState = cssMode.startState(htmlMode.indent(state.htmlState, ""));
|
| - }
|
| - }
|
| - return style;
|
| - }
|
| - function maybeBackup(stream, pat, style) {
|
| - var cur = stream.current();
|
| - var close = cur.search(pat), m;
|
| - if (close > -1) stream.backUp(cur.length - close);
|
| - else if (m = cur.match(/<\/?$/)) {
|
| - stream.backUp(cur.length);
|
| - if (!stream.match(pat, false)) stream.match(cur[0]);
|
| - }
|
| - return style;
|
| - }
|
| - function javascript(stream, state) {
|
| - if (stream.match(/^<\/\s*script\s*>/i, false)) {
|
| - state.token = html;
|
| - state.localState = null;
|
| - return html(stream, state);
|
| - }
|
| - return maybeBackup(stream, /<\/\s*script\s*>/,
|
| - jsMode.token(stream, state.localState));
|
| - }
|
| - function css(stream, state) {
|
| - if (stream.match(/^<\/\s*style\s*>/i, false)) {
|
| - state.token = html;
|
| - state.localState = null;
|
| - return html(stream, state);
|
| - }
|
| - return maybeBackup(stream, /<\/\s*style\s*>/,
|
| - cssMode.token(stream, state.localState));
|
| - }
|
| -
|
| - return {
|
| - startState: function() {
|
| - var state = htmlMode.startState();
|
| - return {token: html, localState: null, mode: "html", htmlState: state};
|
| - },
|
| -
|
| - copyState: function(state) {
|
| - if (state.localState)
|
| - var local = CodeMirror.copyState(state.token == css ? cssMode : jsMode, state.localState);
|
| - return {token: state.token, localState: local, mode: state.mode,
|
| - htmlState: CodeMirror.copyState(htmlMode, state.htmlState)};
|
| - },
|
| -
|
| - token: function(stream, state) {
|
| - return state.token(stream, state);
|
| - },
|
| -
|
| - indent: function(state, textAfter) {
|
| - if (state.token == html || /^\s*<\//.test(textAfter))
|
| - return htmlMode.indent(state.htmlState, textAfter);
|
| - else if (state.token == javascript)
|
| - return jsMode.indent(state.localState, textAfter);
|
| - else
|
| - return cssMode.indent(state.localState, textAfter);
|
| - },
|
| -
|
| - electricChars: "/{}:",
|
| -
|
| - innerMode: function(state) {
|
| - var mode = state.token == html ? htmlMode : state.token == javascript ? jsMode : cssMode;
|
| - return {state: state.localState || state.htmlState, mode: mode};
|
| - }
|
| - };
|
| -}, "xml", "javascript", "css");
|
| -
|
| -CodeMirror.defineMIME("text/html", "htmlmixed");
|
| -;
|
| -(function() {
|
| - var ie_lt8 = /MSIE \d/.test(navigator.userAgent) &&
|
| - (document.documentMode == null || document.documentMode < 8);
|
| -
|
| - var Pos = CodeMirror.Pos;
|
| - // Disable brace matching in long lines, since it'll cause hugely slow updates
|
| - var maxLineLen = 1000;
|
| -
|
| - var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<"};
|
| - function findMatchingBracket(cm) {
|
| - var cur = cm.getCursor(), line = cm.getLineHandle(cur.line), pos = cur.ch - 1;
|
| - var match = (pos >= 0 && matching[line.text.charAt(pos)]) || matching[line.text.charAt(++pos)];
|
| - if (!match) return null;
|
| - var forward = match.charAt(1) == ">", d = forward ? 1 : -1;
|
| - var style = cm.getTokenAt(Pos(cur.line, pos + 1)).type;
|
| -
|
| - var stack = [line.text.charAt(pos)], re = /[(){}[\]]/;
|
| - function scan(line, lineNo, start) {
|
| - if (!line.text) return;
|
| - var pos = forward ? 0 : line.text.length - 1, end = forward ? line.text.length : -1;
|
| - if (start != null) pos = start + d;
|
| - for (; pos != end; pos += d) {
|
| - var ch = line.text.charAt(pos);
|
| - if (re.test(ch) && cm.getTokenAt(Pos(lineNo, pos + 1)).type == style) {
|
| - var match = matching[ch];
|
| - if (match.charAt(1) == ">" == forward) stack.push(ch);
|
| - else if (stack.pop() != match.charAt(0)) return {pos: pos, match: false};
|
| - else if (!stack.length) return {pos: pos, match: true};
|
| - }
|
| - }
|
| - }
|
| - for (var i = cur.line, found, e = forward ? Math.min(i + 100, cm.lineCount()) : Math.max(-1, i - 100); i != e; i+=d) {
|
| - if (i == cur.line) found = scan(line, i, pos);
|
| - else found = scan(cm.getLineHandle(i), i);
|
| - if (found) break;
|
| - }
|
| - return {from: Pos(cur.line, pos), to: found && Pos(i, found.pos), match: found && found.match};
|
| - }
|
| -
|
| - function matchBrackets(cm, autoclear) {
|
| - var found = findMatchingBracket(cm);
|
| - if (!found || cm.getLine(found.from.line).length > maxLineLen ||
|
| - found.to && cm.getLine(found.to.line).length > maxLineLen)
|
| - return;
|
| -
|
| - var style = found.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket";
|
| - var one = cm.markText(found.from, Pos(found.from.line, found.from.ch + 1), {className: style});
|
| - var two = found.to && cm.markText(found.to, Pos(found.to.line, found.to.ch + 1), {className: style});
|
| - // Kludge to work around the IE bug from issue #1193, where text
|
| - // input stops going to the textare whever this fires.
|
| - if (ie_lt8 && cm.state.focused) cm.display.input.focus();
|
| - var clear = function() {
|
| - cm.operation(function() { one.clear(); two && two.clear(); });
|
| - };
|
| - if (autoclear) setTimeout(clear, 800);
|
| - else return clear;
|
| - }
|
| -
|
| - var currentlyHighlighted = null;
|
| - function doMatchBrackets(cm) {
|
| - cm.operation(function() {
|
| - if (currentlyHighlighted) {currentlyHighlighted(); currentlyHighlighted = null;}
|
| - if (!cm.somethingSelected()) currentlyHighlighted = matchBrackets(cm, false);
|
| - });
|
| - }
|
| -
|
| - CodeMirror.defineOption("matchBrackets", false, function(cm, val) {
|
| - if (val) cm.on("cursorActivity", doMatchBrackets);
|
| - else cm.off("cursorActivity", doMatchBrackets);
|
| - });
|
| -
|
| - CodeMirror.defineExtension("matchBrackets", function() {matchBrackets(this, true);});
|
| - CodeMirror.defineExtension("findMatchingBracket", function(){return findMatchingBracket(this);});
|
| -})();
|
| -;
|
| -(function() {
|
| - var DEFAULT_BRACKETS = "()[]{}''\"\"";
|
| - var SPACE_CHAR_REGEX = /\s/;
|
| -
|
| - CodeMirror.defineOption("autoCloseBrackets", false, function(cm, val, old) {
|
| - var wasOn = old && old != CodeMirror.Init;
|
| - if (val && !wasOn)
|
| - cm.addKeyMap(buildKeymap(typeof val == "string" ? val : DEFAULT_BRACKETS));
|
| - else if (!val && wasOn)
|
| - cm.removeKeyMap("autoCloseBrackets");
|
| - });
|
| -
|
| - function buildKeymap(pairs) {
|
| - var map = {
|
| - name : "autoCloseBrackets",
|
| - Backspace: function(cm) {
|
| - if (cm.somethingSelected()) return CodeMirror.Pass;
|
| - var cur = cm.getCursor(), line = cm.getLine(cur.line);
|
| - if (cur.ch && cur.ch < line.length &&
|
| - pairs.indexOf(line.slice(cur.ch - 1, cur.ch + 1)) % 2 == 0)
|
| - cm.replaceRange("", CodeMirror.Pos(cur.line, cur.ch - 1), CodeMirror.Pos(cur.line, cur.ch + 1));
|
| - else
|
| - return CodeMirror.Pass;
|
| - }
|
| - };
|
| - var closingBrackets = [];
|
| - for (var i = 0; i < pairs.length; i += 2) (function(left, right) {
|
| - if (left != right) closingBrackets.push(right);
|
| - function surround(cm) {
|
| - var selection = cm.getSelection();
|
| - cm.replaceSelection(left + selection + right);
|
| - }
|
| - function maybeOverwrite(cm) {
|
| - var cur = cm.getCursor(), ahead = cm.getRange(cur, CodeMirror.Pos(cur.line, cur.ch + 1));
|
| - if (ahead != right || cm.somethingSelected()) return CodeMirror.Pass;
|
| - else cm.execCommand("goCharRight");
|
| - }
|
| - map["'" + left + "'"] = function(cm) {
|
| - if (cm.somethingSelected()) return surround(cm);
|
| - if (left == right && maybeOverwrite(cm) != CodeMirror.Pass) return;
|
| - var cur = cm.getCursor(), ahead = CodeMirror.Pos(cur.line, cur.ch + 1);
|
| - var line = cm.getLine(cur.line), nextChar = line.charAt(cur.ch);
|
| - if (line.length == cur.ch || closingBrackets.indexOf(nextChar) >= 0 || SPACE_CHAR_REGEX.test(nextChar))
|
| - cm.replaceSelection(left + right, {head: ahead, anchor: ahead});
|
| - else
|
| - return CodeMirror.Pass;
|
| - };
|
| - if (left != right) map["'" + right + "'"] = maybeOverwrite;
|
| - })(pairs.charAt(i), pairs.charAt(i + 1));
|
| - return map;
|
| - }
|
| -})();
|
| -;
|
| -// Because sometimes you need to mark the selected *text*.
|
| -//
|
| -// Adds an option 'styleSelectedText' which, when enabled, gives
|
| -// selected text the CSS class "CodeMirror-selectedtext".
|
| -
|
| -(function() {
|
| - "use strict";
|
| -
|
| - CodeMirror.defineOption("styleSelectedText", false, function(cm, val, old) {
|
| - var prev = old && old != CodeMirror.Init;
|
| - if (val && !prev) {
|
| - updateSelectedText(cm);
|
| - cm.on("cursorActivity", updateSelectedText);
|
| - } else if (!val && prev) {
|
| - cm.off("cursorActivity", updateSelectedText);
|
| - clearSelectedText(cm);
|
| - delete cm._selectionMark;
|
| - }
|
| - });
|
| -
|
| - function clearSelectedText(cm) {
|
| - if (cm._selectionMark) cm._selectionMark.clear();
|
| - }
|
| -
|
| - function updateSelectedText(cm) {
|
| - clearSelectedText(cm);
|
| -
|
| - if (cm.somethingSelected())
|
| - cm._selectionMark = cm.markText(cm.getCursor("start"), cm.getCursor("end"),
|
| - {className: "CodeMirror-selectedtext"});
|
| - else
|
| - cm._selectionMark = null;
|
| - }
|
| -})();
|
| -;
|
| -
|
| -/**
|
| - * @constructor
|
| - * @extends {WebInspector.View}
|
| - * @implements {WebInspector.TextEditor}
|
| - * @param {?string} url
|
| - * @param {WebInspector.TextEditorDelegate} delegate
|
| - */
|
| -WebInspector.CodeMirrorTextEditor = function(url, delegate)
|
| -{
|
| - WebInspector.View.call(this);
|
| - this._delegate = delegate;
|
| - this._url = url;
|
| -
|
| - this.registerRequiredCSS("cm/codemirror.css");
|
| - this.registerRequiredCSS("cm/cmdevtools.css");
|
| -
|
| - this._codeMirror = window.CodeMirror(this.element, {
|
| - lineNumbers: true,
|
| - gutters: ["CodeMirror-linenumbers"],
|
| - matchBrackets: true,
|
| - smartIndent: false,
|
| - styleSelectedText: true,
|
| - electricChars: false,
|
| - autoCloseBrackets: true
|
| - });
|
| -
|
| - var extraKeys = {};
|
| - var indent = WebInspector.settings.textEditorIndent.get();
|
| - if (indent === WebInspector.TextUtils.Indent.TabCharacter) {
|
| - this._codeMirror.setOption("indentWithTabs", true);
|
| - this._codeMirror.setOption("indentUnit", 4);
|
| - } else {
|
| - this._codeMirror.setOption("indentWithTabs", false);
|
| - this._codeMirror.setOption("indentUnit", indent.length);
|
| - extraKeys.Tab = function(codeMirror)
|
| - {
|
| - if (codeMirror.somethingSelected())
|
| - return CodeMirror.Pass;
|
| - codeMirror.replaceRange(indent, codeMirror.getCursor());
|
| - }
|
| - }
|
| - this._codeMirror.setOption("extraKeys", extraKeys);
|
| -
|
| - this._tokenHighlighter = new WebInspector.CodeMirrorTextEditor.TokenHighlighter(this._codeMirror);
|
| - this._blockIndentController = new WebInspector.CodeMirrorTextEditor.BlockIndentController(this._codeMirror);
|
| - this._fixWordMovement = new WebInspector.CodeMirrorTextEditor.FixWordMovement(this._codeMirror);
|
| -
|
| - this._codeMirror.on("change", this._change.bind(this));
|
| - this._codeMirror.on("gutterClick", this._gutterClick.bind(this));
|
| - this._codeMirror.on("cursorActivity", this._cursorActivity.bind(this));
|
| - this._codeMirror.on("scroll", this._scroll.bind(this));
|
| - this.element.addEventListener("contextmenu", this._contextMenu.bind(this));
|
| -
|
| - this._lastRange = this.range();
|
| -
|
| - this.element.firstChild.addStyleClass("source-code");
|
| - this.element.firstChild.addStyleClass("fill");
|
| - this._elementToWidget = new Map();
|
| - this._nestedUpdatesCounter = 0;
|
| -
|
| - this.element.addEventListener("focus", this._handleElementFocus.bind(this), false);
|
| - this.element.tabIndex = 0;
|
| - this._setupSelectionColor();
|
| -}
|
| -
|
| -WebInspector.CodeMirrorTextEditor.prototype = {
|
| -
|
| - undo: function()
|
| - {
|
| - this._codeMirror.undo();
|
| - },
|
| -
|
| - redo: function()
|
| - {
|
| - this._codeMirror.redo();
|
| - },
|
| -
|
| - _setupSelectionColor: function()
|
| - {
|
| - if (WebInspector.CodeMirrorTextEditor._selectionStyleInjected)
|
| - return;
|
| - WebInspector.CodeMirrorTextEditor._selectionStyleInjected = true;
|
| - var backgroundColor = WebInspector.getSelectionBackgroundColor();
|
| - var backgroundColorRule = backgroundColor ? ".CodeMirror .CodeMirror-selected { background-color: " + backgroundColor + ";}" : "";
|
| - var foregroundColor = WebInspector.getSelectionForegroundColor();
|
| - var foregroundColorRule = foregroundColor ? ".CodeMirror .CodeMirror-selectedtext { color: " + foregroundColor + "!important;}" : "";
|
| - if (!foregroundColorRule && !backgroundColorRule)
|
| - return;
|
| -
|
| - var style = document.createElement("style");
|
| - style.textContent = backgroundColorRule + foregroundColorRule;
|
| - document.head.appendChild(style);
|
| - },
|
| -
|
| - /**
|
| - * @param {number} lineNumber
|
| - * @param {number} column
|
| - * @return {?{x: number, y: number, height: number}}
|
| - */
|
| - cursorPositionToCoordinates: function(lineNumber, column)
|
| - {
|
| - if (lineNumber >= this._codeMirror.lineCount || column > this._codeMirror.getLine(lineNumber).length || lineNumber < 0 || column < 0)
|
| - return null;
|
| -
|
| - var metrics = this._codeMirror.cursorCoords(new CodeMirror.Pos(lineNumber, column));
|
| -
|
| - return {
|
| - x: metrics.left,
|
| - y: metrics.top,
|
| - height: metrics.bottom - metrics.top
|
| - };
|
| - },
|
| -
|
| - /**
|
| - * @param {number} x
|
| - * @param {number} y
|
| - * @return {?WebInspector.TextRange}
|
| - */
|
| - coordinatesToCursorPosition: function(x, y)
|
| - {
|
| - var element = document.elementFromPoint(x, y);
|
| - if (!element || !element.isSelfOrDescendant(this._codeMirror.getWrapperElement()))
|
| - return null;
|
| - var gutterBox = this._codeMirror.getGutterElement().boxInWindow();
|
| - if (x >= gutterBox.x && x <= gutterBox.x + gutterBox.width &&
|
| - y >= gutterBox.y && y <= gutterBox.y + gutterBox.height)
|
| - return null;
|
| - var coords = this._codeMirror.coordsChar({left: x, top: y});
|
| - ++coords.ch;
|
| - return this._toRange(coords, coords);
|
| - },
|
| -
|
| - _convertTokenType: function(tokenType)
|
| - {
|
| - if (tokenType.startsWith("variable") || tokenType.startsWith("property") || tokenType === "def")
|
| - return "javascript-ident";
|
| - if (tokenType === "string-2")
|
| - return "javascript-regexp";
|
| - if (tokenType === "number" || tokenType === "comment" || tokenType === "string")
|
| - return "javascript-" + tokenType;
|
| - return null;
|
| - },
|
| -
|
| - /**
|
| - * @param {number} lineNumber
|
| - * @param {number} column
|
| - * @return {?{startColumn: number, endColumn: number, type: string}}
|
| - */
|
| - tokenAtTextPosition: function(lineNumber, column)
|
| - {
|
| - if (lineNumber < 0 || lineNumber >= this._codeMirror.lineCount())
|
| - return null;
|
| - var token = this._codeMirror.getTokenAt(new CodeMirror.Pos(lineNumber, column || 1));
|
| - if (!token || !token.type)
|
| - return null;
|
| - var convertedType = this._convertTokenType(token.type);
|
| - if (!convertedType)
|
| - return null;
|
| - return {
|
| - startColumn: token.start,
|
| - endColumn: token.end - 1,
|
| - type: convertedType
|
| - };
|
| - },
|
| -
|
| - /**
|
| - * @param {WebInspector.TextRange} textRange
|
| - * @return {string}
|
| - */
|
| - copyRange: function(textRange)
|
| - {
|
| - var pos = this._toPos(textRange);
|
| - return this._codeMirror.getRange(pos.start, pos.end);
|
| - },
|
| -
|
| - /**
|
| - * @return {boolean}
|
| - */
|
| - isClean: function()
|
| - {
|
| - return this._codeMirror.isClean();
|
| - },
|
| -
|
| - markClean: function()
|
| - {
|
| - this._codeMirror.markClean();
|
| - },
|
| -
|
| - /**
|
| - * @param {string} mimeType
|
| - */
|
| - set mimeType(mimeType)
|
| - {
|
| - this._codeMirror.setOption("mode", mimeType);
|
| - switch(mimeType) {
|
| - case "text/html": this._codeMirror.setOption("theme", "web-inspector-html"); break;
|
| - case "text/css": this._codeMirror.setOption("theme", "web-inspector-css"); break;
|
| - case "text/javascript": this._codeMirror.setOption("theme", "web-inspector-js"); break;
|
| - }
|
| - },
|
| -
|
| - /**
|
| - * @param {boolean} readOnly
|
| - */
|
| - setReadOnly: function(readOnly)
|
| - {
|
| - this._codeMirror.setOption("readOnly", readOnly ? "nocursor" : false);
|
| - },
|
| -
|
| - /**
|
| - * @return {boolean}
|
| - */
|
| - readOnly: function()
|
| - {
|
| - return !!this._codeMirror.getOption("readOnly");
|
| - },
|
| -
|
| - /**
|
| - * @param {Object} highlightDescriptor
|
| - */
|
| - removeHighlight: function(highlightDescriptor)
|
| - {
|
| - highlightDescriptor.clear();
|
| - },
|
| -
|
| - /**
|
| - * @param {WebInspector.TextRange} range
|
| - * @param {string} cssClass
|
| - * @return {Object}
|
| - */
|
| - highlightRange: function(range, cssClass)
|
| - {
|
| - var pos = this._toPos(range);
|
| - ++pos.end.ch;
|
| - return this._codeMirror.markText(pos.start, pos.end, {
|
| - className: cssClass,
|
| - startStyle: cssClass + "-start",
|
| - endStyle: cssClass + "-end"
|
| - });
|
| - },
|
| -
|
| - /**
|
| - * @param {string} regex
|
| - * @param {string} cssClass
|
| - * @return {Object}
|
| - */
|
| - highlightRegex: function(regex, cssClass) { },
|
| -
|
| - /**
|
| - * @return {Element}
|
| - */
|
| - defaultFocusedElement: function()
|
| - {
|
| - return this.element;
|
| - },
|
| -
|
| - focus: function()
|
| - {
|
| - this._codeMirror.focus();
|
| - },
|
| -
|
| - _handleElementFocus: function()
|
| - {
|
| - this._codeMirror.focus();
|
| - },
|
| -
|
| - beginUpdates: function()
|
| - {
|
| - ++this._nestedUpdatesCounter;
|
| - },
|
| -
|
| - endUpdates: function()
|
| - {
|
| - if (!--this._nestedUpdatesCounter)
|
| - this._codeMirror.refresh();
|
| - },
|
| -
|
| - /**
|
| - * @param {number} lineNumber
|
| - */
|
| - revealLine: function(lineNumber)
|
| - {
|
| - var pos = new CodeMirror.Pos(lineNumber, 0);
|
| - var topLine = this._topScrolledLine();
|
| - var bottomLine = this._bottomScrolledLine();
|
| -
|
| - var margin = null;
|
| - var lineMargin = 3;
|
| - var scrollInfo = this._codeMirror.getScrollInfo();
|
| - if ((lineNumber < topLine + lineMargin) || (lineNumber >= bottomLine - lineMargin)) {
|
| - // scrollIntoView could get into infinite loop if margin exceeds half of the clientHeight.
|
| - margin = (scrollInfo.clientHeight*0.9/2) >>> 0;
|
| - }
|
| - this._codeMirror.scrollIntoView(pos, margin);
|
| - },
|
| -
|
| - _gutterClick: function(instance, lineNumber, gutter, event)
|
| - {
|
| - this.dispatchEventToListeners(WebInspector.TextEditor.Events.GutterClick, { lineNumber: lineNumber, event: event });
|
| - },
|
| -
|
| - _contextMenu: function(event)
|
| - {
|
| - var contextMenu = new WebInspector.ContextMenu(event);
|
| - var target = event.target.enclosingNodeOrSelfWithClass("CodeMirror-gutter-elt");
|
| - if (target)
|
| - this._delegate.populateLineGutterContextMenu(contextMenu, parseInt(target.textContent, 10) - 1);
|
| - else
|
| - this._delegate.populateTextAreaContextMenu(contextMenu, 0);
|
| - contextMenu.show();
|
| - },
|
| -
|
| - /**
|
| - * @param {number} lineNumber
|
| - * @param {boolean} disabled
|
| - * @param {boolean} conditional
|
| - */
|
| - addBreakpoint: function(lineNumber, disabled, conditional)
|
| - {
|
| - var className = "cm-breakpoint" + (conditional ? " cm-breakpoint-conditional" : "") + (disabled ? " cm-breakpoint-disabled" : "");
|
| - this._codeMirror.addLineClass(lineNumber, "wrap", className);
|
| - },
|
| -
|
| - /**
|
| - * @param {number} lineNumber
|
| - */
|
| - removeBreakpoint: function(lineNumber)
|
| - {
|
| - var wrapClasses = this._codeMirror.getLineHandle(lineNumber).wrapClass;
|
| - if (!wrapClasses)
|
| - return;
|
| - var classes = wrapClasses.split(" ");
|
| - for(var i = 0; i < classes.length; ++i) {
|
| - if (classes[i].startsWith("cm-breakpoint"))
|
| - this._codeMirror.removeLineClass(lineNumber, "wrap", classes[i]);
|
| - }
|
| - },
|
| -
|
| - /**
|
| - * @param {number} lineNumber
|
| - */
|
| - setExecutionLine: function(lineNumber)
|
| - {
|
| - this._executionLine = this._codeMirror.getLineHandle(lineNumber);
|
| - this._codeMirror.addLineClass(this._executionLine, "wrap", "cm-execution-line");
|
| - },
|
| -
|
| - clearExecutionLine: function()
|
| - {
|
| - if (this._executionLine)
|
| - this._codeMirror.removeLineClass(this._executionLine, "wrap", "cm-execution-line");
|
| - delete this._executionLine;
|
| - },
|
| -
|
| - /**
|
| - * @param {number} lineNumber
|
| - * @param {Element} element
|
| - */
|
| - addDecoration: function(lineNumber, element)
|
| - {
|
| - var widget = this._codeMirror.addLineWidget(lineNumber, element);
|
| - this._elementToWidget.put(element, widget);
|
| - },
|
| -
|
| - /**
|
| - * @param {number} lineNumber
|
| - * @param {Element} element
|
| - */
|
| - removeDecoration: function(lineNumber, element)
|
| - {
|
| - var widget = this._elementToWidget.remove(element);
|
| - if (widget)
|
| - this._codeMirror.removeLineWidget(widget);
|
| - },
|
| -
|
| - /**
|
| - * @param {WebInspector.TextRange} range
|
| - */
|
| - markAndRevealRange: function(range)
|
| - {
|
| - if (range)
|
| - this.setSelection(range);
|
| - },
|
| -
|
| - /**
|
| - * @param {number} lineNumber
|
| - */
|
| - highlightLine: function(lineNumber)
|
| - {
|
| - this.clearLineHighlight();
|
| - this._highlightedLine = this._codeMirror.getLineHandle(lineNumber);
|
| - if (!this._highlightedLine)
|
| - return;
|
| - this.revealLine(lineNumber);
|
| - this._codeMirror.addLineClass(this._highlightedLine, null, "cm-highlight");
|
| - this._clearHighlightTimeout = setTimeout(this.clearLineHighlight.bind(this), 2000);
|
| - },
|
| -
|
| - clearLineHighlight: function()
|
| - {
|
| - if (this._clearHighlightTimeout)
|
| - clearTimeout(this._clearHighlightTimeout);
|
| - delete this._clearHighlightTimeout;
|
| -
|
| - if (this._highlightedLine)
|
| - this._codeMirror.removeLineClass(this._highlightedLine, null, "cm-highlight");
|
| - delete this._highlightedLine;
|
| - },
|
| -
|
| - /**
|
| - * @return {Array.<Element>}
|
| - */
|
| - elementsToRestoreScrollPositionsFor: function()
|
| - {
|
| - return [];
|
| - },
|
| -
|
| - /**
|
| - * @param {WebInspector.TextEditor} textEditor
|
| - */
|
| - inheritScrollPositions: function(textEditor)
|
| - {
|
| - },
|
| -
|
| - onResize: function()
|
| - {
|
| - this._codeMirror.refresh();
|
| - },
|
| -
|
| - /**
|
| - * @param {WebInspector.TextRange} range
|
| - * @param {string} text
|
| - * @return {WebInspector.TextRange}
|
| - */
|
| - editRange: function(range, text)
|
| - {
|
| - var pos = this._toPos(range);
|
| - this._codeMirror.replaceRange(text, pos.start, pos.end);
|
| - var newRange = this._toRange(pos.start, this._codeMirror.posFromIndex(this._codeMirror.indexFromPos(pos.start) + text.length));
|
| - this._delegate.onTextChanged(range, newRange);
|
| - return newRange;
|
| - },
|
| -
|
| - _change: function()
|
| - {
|
| - var widgets = this._elementToWidget.values();
|
| - for (var i = 0; i < widgets.length; ++i)
|
| - this._codeMirror.removeLineWidget(widgets[i]);
|
| - this._elementToWidget.clear();
|
| -
|
| - var newRange = this.range();
|
| - if (!this._muteTextChangedEvent)
|
| - this._delegate.onTextChanged(this._lastRange, newRange);
|
| - this._lastRange = newRange;
|
| - },
|
| -
|
| - _cursorActivity: function()
|
| - {
|
| - var start = this._codeMirror.getCursor("anchor");
|
| - var end = this._codeMirror.getCursor("head");
|
| - this._delegate.selectionChanged(this._toRange(start, end));
|
| - },
|
| -
|
| - _coordsCharLocal: function(coords)
|
| - {
|
| - var top = coords.top;
|
| - var totalLines = this._codeMirror.lineCount();
|
| - var begin = 0;
|
| - var end = totalLines - 1;
|
| - while (end - begin > 1) {
|
| - var middle = (begin + end) >> 1;
|
| - coords = this._codeMirror.charCoords(new CodeMirror.Pos(middle, 0), "local");
|
| - if (coords.top >= top)
|
| - end = middle;
|
| - else
|
| - begin = middle;
|
| - }
|
| -
|
| - return end;
|
| - },
|
| -
|
| - _topScrolledLine: function()
|
| - {
|
| - var scrollInfo = this._codeMirror.getScrollInfo();
|
| - // Workaround for CodeMirror's coordsChar incorrect result for "local" mode.
|
| - return this._coordsCharLocal(scrollInfo);
|
| - },
|
| -
|
| - _bottomScrolledLine: function()
|
| - {
|
| - var scrollInfo = this._codeMirror.getScrollInfo();
|
| - scrollInfo.top += scrollInfo.clientHeight;
|
| - // Workaround for CodeMirror's coordsChar incorrect result for "local" mode.
|
| - return this._coordsCharLocal(scrollInfo);
|
| - },
|
| -
|
| - _scroll: function()
|
| - {
|
| - this._delegate.scrollChanged(this._topScrolledLine());
|
| - },
|
| -
|
| - /**
|
| - * @param {number} lineNumber
|
| - */
|
| - scrollToLine: function(lineNumber)
|
| - {
|
| - function performScroll()
|
| - {
|
| - var pos = new CodeMirror.Pos(lineNumber, 0);
|
| - var coords = this._codeMirror.charCoords(pos, "local");
|
| - this._codeMirror.scrollTo(0, coords.top);
|
| - }
|
| -
|
| - setTimeout(performScroll.bind(this), 0);
|
| - },
|
| -
|
| - /**
|
| - * @return {WebInspector.TextRange}
|
| - */
|
| - selection: function()
|
| - {
|
| - var start = this._codeMirror.getCursor(true);
|
| - var end = this._codeMirror.getCursor(false);
|
| -
|
| - if (start.line > end.line || (start.line == end.line && start.ch > end.ch))
|
| - return this._toRange(end, start);
|
| -
|
| - return this._toRange(start, end);
|
| - },
|
| -
|
| - /**
|
| - * @return {WebInspector.TextRange?}
|
| - */
|
| - lastSelection: function()
|
| - {
|
| - return this._lastSelection;
|
| - },
|
| -
|
| - /**
|
| - * @param {WebInspector.TextRange} textRange
|
| - */
|
| - setSelection: function(textRange)
|
| - {
|
| - function performSelectionSet()
|
| - {
|
| - this._lastSelection = textRange;
|
| - var pos = this._toPos(textRange);
|
| - this._codeMirror.setSelection(pos.start, pos.end);
|
| - }
|
| -
|
| - setTimeout(performSelectionSet.bind(this), 0);
|
| - },
|
| -
|
| - /**
|
| - * @param {string} text
|
| - */
|
| - setText: function(text)
|
| - {
|
| - this._muteTextChangedEvent = true;
|
| - this._codeMirror.setValue(text);
|
| - this._codeMirror.clearHistory();
|
| - delete this._muteTextChangedEvent;
|
| - },
|
| -
|
| - /**
|
| - * @return {string}
|
| - */
|
| - text: function()
|
| - {
|
| - return this._codeMirror.getValue();
|
| - },
|
| -
|
| - /**
|
| - * @return {WebInspector.TextRange}
|
| - */
|
| - range: function()
|
| - {
|
| - var lineCount = this.linesCount;
|
| - var lastLine = this._codeMirror.getLine(lineCount - 1);
|
| - return this._toRange(new CodeMirror.Pos(0, 0), new CodeMirror.Pos(lineCount - 1, lastLine.length));
|
| - },
|
| -
|
| - /**
|
| - * @param {number} lineNumber
|
| - * @return {string}
|
| - */
|
| - line: function(lineNumber)
|
| - {
|
| - return this._codeMirror.getLine(lineNumber);
|
| - },
|
| -
|
| - /**
|
| - * @return {number}
|
| - */
|
| - get linesCount()
|
| - {
|
| - return this._codeMirror.lineCount();
|
| - },
|
| -
|
| - /**
|
| - * @param {number} line
|
| - * @param {string} name
|
| - * @param {Object?} value
|
| - */
|
| - setAttribute: function(line, name, value)
|
| - {
|
| - var handle = this._codeMirror.getLineHandle(line);
|
| - if (handle.attributes === undefined) handle.attributes = {};
|
| - handle.attributes[name] = value;
|
| - },
|
| -
|
| - /**
|
| - * @param {number} line
|
| - * @param {string} name
|
| - * @return {Object|null} value
|
| - */
|
| - getAttribute: function(line, name)
|
| - {
|
| - var handle = this._codeMirror.getLineHandle(line);
|
| - return handle.attributes && handle.attributes[name] !== undefined ? handle.attributes[name] : null;
|
| - },
|
| -
|
| - /**
|
| - * @param {number} line
|
| - * @param {string} name
|
| - */
|
| - removeAttribute: function(line, name)
|
| - {
|
| - var handle = this._codeMirror.getLineHandle(line);
|
| - if (handle && handle.attributes)
|
| - delete handle.attributes[name];
|
| - },
|
| -
|
| - /**
|
| - * @param {WebInspector.TextRange} range
|
| - * @return {{start: CodeMirror.Pos, end: CodeMirror.Pos}}
|
| - */
|
| - _toPos: function(range)
|
| - {
|
| - return {
|
| - start: new CodeMirror.Pos(range.startLine, range.startColumn),
|
| - end: new CodeMirror.Pos(range.endLine, range.endColumn)
|
| - }
|
| - },
|
| -
|
| - _toRange: function(start, end)
|
| - {
|
| - return new WebInspector.TextRange(start.line, start.ch, end.line, end.ch);
|
| - },
|
| -
|
| - __proto__: WebInspector.View.prototype
|
| -}
|
| -
|
| -/**
|
| - * @constructor
|
| - * @param {CodeMirror} codeMirror
|
| - */
|
| -WebInspector.CodeMirrorTextEditor.TokenHighlighter = function(codeMirror)
|
| -{
|
| - this._codeMirror = codeMirror;
|
| - this._codeMirror.on("cursorActivity", this._cursorChange.bind(this));
|
| -}
|
| -
|
| -WebInspector.CodeMirrorTextEditor.TokenHighlighter.prototype = {
|
| - _cursorChange: function()
|
| - {
|
| - this._codeMirror.operation(this._removeHighlight.bind(this));
|
| - var selectionStart = this._codeMirror.getCursor("start");
|
| - var selectionEnd = this._codeMirror.getCursor("end");
|
| - if (selectionStart.line !== selectionEnd.line)
|
| - return;
|
| - if (selectionStart.ch === selectionEnd.ch)
|
| - return;
|
| -
|
| - var selectedText = this._codeMirror.getSelection();
|
| - if (this._isWord(selectedText, selectionStart.line, selectionStart.ch, selectionEnd.ch))
|
| - this._codeMirror.operation(this._addHighlight.bind(this, selectedText, selectionStart));
|
| - },
|
| -
|
| - _isWord: function(selectedText, lineNumber, startColumn, endColumn)
|
| - {
|
| - var line = this._codeMirror.getLine(lineNumber);
|
| - var leftBound = startColumn === 0 || !WebInspector.TextUtils.isWordChar(line.charAt(startColumn - 1));
|
| - var rightBound = endColumn === line.length || !WebInspector.TextUtils.isWordChar(line.charAt(endColumn));
|
| - return leftBound && rightBound && WebInspector.TextUtils.isWord(selectedText);
|
| - },
|
| -
|
| - _removeHighlight: function()
|
| - {
|
| - if (this._highlightDescriptor) {
|
| - this._codeMirror.removeOverlay(this._highlightDescriptor.overlay);
|
| - this._codeMirror.removeLineClass(this._highlightDescriptor.selectionStart.line, "wrap", "cm-line-with-selection");
|
| - delete this._highlightDescriptor;
|
| - }
|
| - },
|
| -
|
| - _addHighlight: function(token, selectionStart)
|
| - {
|
| - const tokenFirstChar = token.charAt(0);
|
| - /**
|
| - * @param {CodeMirror.StringStream} stream
|
| - */
|
| - function nextToken(stream)
|
| - {
|
| - if (stream.match(token) && (stream.eol() || !WebInspector.TextUtils.isWordChar(stream.peek())))
|
| - return stream.column() === selectionStart.ch ? "token-highlight column-with-selection" : "token-highlight";
|
| -
|
| - var eatenChar;
|
| - do {
|
| - eatenChar = stream.next();
|
| - } while (eatenChar && (WebInspector.TextUtils.isWordChar(eatenChar) || stream.peek() !== tokenFirstChar));
|
| - }
|
| -
|
| - var overlayMode = {
|
| - token: nextToken
|
| - };
|
| - this._codeMirror.addOverlay(overlayMode);
|
| - this._codeMirror.addLineClass(selectionStart.line, "wrap", "cm-line-with-selection")
|
| - this._highlightDescriptor = {
|
| - overlay: overlayMode,
|
| - selectionStart: selectionStart
|
| - };
|
| - }
|
| -}
|
| -
|
| -/**
|
| - * @constructor
|
| - * @param {CodeMirror} codeMirror
|
| - */
|
| -WebInspector.CodeMirrorTextEditor.BlockIndentController = function(codeMirror)
|
| -{
|
| - codeMirror.addKeyMap(this);
|
| -}
|
| -
|
| -WebInspector.CodeMirrorTextEditor.BlockIndentController.prototype = {
|
| - name: "blockIndentKeymap",
|
| -
|
| - Enter: function(codeMirror)
|
| - {
|
| - if (codeMirror.somethingSelected())
|
| - return CodeMirror.Pass;
|
| - var cursor = codeMirror.getCursor();
|
| - var line = codeMirror.getLine(cursor.line);
|
| - if (line.substr(cursor.ch - 1, 2) === "{}") {
|
| - codeMirror.execCommand("newlineAndIndent");
|
| - codeMirror.setCursor(cursor);
|
| - codeMirror.execCommand("newlineAndIndent");
|
| - codeMirror.execCommand("indentMore");
|
| - } else if (line.substr(cursor.ch-1, 1) === "{") {
|
| - codeMirror.execCommand("newlineAndIndent");
|
| - codeMirror.execCommand("indentMore");
|
| - } else
|
| - return CodeMirror.Pass;
|
| - },
|
| -
|
| - "'}'": function(codeMirror)
|
| - {
|
| - var cursor = codeMirror.getCursor();
|
| - var line = codeMirror.getLine(cursor.line);
|
| - for(var i = 0 ; i < line.length; ++i)
|
| - if (!WebInspector.TextUtils.isSpaceChar(line.charAt(i)))
|
| - return CodeMirror.Pass;
|
| -
|
| - codeMirror.replaceRange("}", cursor);
|
| - var matchingBracket = codeMirror.findMatchingBracket();
|
| - if (!matchingBracket.match)
|
| - return;
|
| -
|
| - line = codeMirror.getLine(matchingBracket.to.line);
|
| - var desiredIndentation = 0;
|
| - while (desiredIndentation < line.length && WebInspector.TextUtils.isSpaceChar(line.charAt(desiredIndentation)))
|
| - ++desiredIndentation;
|
| -
|
| - codeMirror.replaceRange(line.substr(0, desiredIndentation) + "}", new CodeMirror.Pos(cursor.line, 0), new CodeMirror.Pos(cursor.line, cursor.ch + 1));
|
| - }
|
| -}
|
| -
|
| -/**
|
| - * @constructor
|
| - * @param {CodeMirror} codeMirror
|
| - */
|
| -WebInspector.CodeMirrorTextEditor.FixWordMovement = function(codeMirror)
|
| -{
|
| - function moveLeft(shift, codeMirror)
|
| - {
|
| - var cursor = codeMirror.getCursor("head");
|
| - if (cursor.ch !== 0 || cursor.line === 0)
|
| - return CodeMirror.Pass;
|
| - codeMirror.setExtending(shift);
|
| - codeMirror.execCommand("goLineUp");
|
| - codeMirror.execCommand("goLineEnd")
|
| - codeMirror.setExtending(false);
|
| - }
|
| - function moveRight(shift, codeMirror)
|
| - {
|
| - var cursor = codeMirror.getCursor("head");
|
| - var line = codeMirror.getLine(cursor.line);
|
| - if (cursor.ch !== line.length || cursor.line + 1 === codeMirror.lineCount())
|
| - return CodeMirror.Pass;
|
| - codeMirror.setExtending(shift);
|
| - codeMirror.execCommand("goLineDown");
|
| - codeMirror.execCommand("goLineStart");
|
| - codeMirror.setExtending(false);
|
| - }
|
| -
|
| - var modifierKey = WebInspector.isMac() ? "Alt" : "Ctrl";
|
| - var leftKey = modifierKey + "-Left";
|
| - var rightKey = modifierKey + "-Right";
|
| - var keyMap = {};
|
| - keyMap[leftKey] = moveLeft.bind(this, false);
|
| - keyMap[rightKey] = moveRight.bind(this, false);
|
| - keyMap["Shift-" + leftKey] = moveLeft.bind(this, true);
|
| - keyMap["Shift-" + rightKey] = moveRight.bind(this, true);
|
| - codeMirror.addKeyMap(keyMap);
|
| -}
|
| +window.CodeMirror=(function(){"use strict";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);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]);if(opera_version&&opera_version>=15){opera=false;webkit=true;}
|
| +var flipCtrlCmd=mac&&(qtwebkit||opera&&(opera_version==null||opera_version<12.11));var captureMiddleClick=gecko||(ie&&!ie_lt9);var sawReadOnlySpans=false,sawCollapsedSpans=false;function CodeMirror(place,options){if(!(this instanceof CodeMirror))return new CodeMirror(place,options);this.options=options=options||{};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);if(ie)setTimeout(bind(resetInput,this,true),20);registerEventHandlers(this);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);})();}
|
| +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(ios)input.style.border="1px solid black";input.setAttribute("autocorrect","off");input.setAttribute("autocapitalize","off");input.setAttribute("spellcheck","false");d.inputDiv=elt("div",[input],null,"overflow: hidden; position: relative; width: 3px; height: 0px;");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");d.gutterFiller=elt("div",null,"CodeMirror-gutter-filler");d.lineDiv=elt("div",null,"CodeMirror-code");d.selectionDiv=elt("div",null,null,"position: relative; z-index: 1");d.cursor=elt("div","\u00a0","CodeMirror-cursor");d.otherCursor=elt("div","\u00a0","CodeMirror-cursor CodeMirror-secondarycursor");d.measure=elt("div",null,"CodeMirror-measure");d.lineSpace=elt("div",[d.measure,d.selectionDiv,d.lineDiv,d.cursor,d.otherCursor],null,"position: relative; outline: none");d.mover=elt("div",[elt("div",[d.lineSpace],"CodeMirror-lines")],null,"position: relative");d.sizer=elt("div",[d.mover],"CodeMirror-sizer");d.heightForcer=elt("div",null,null,"position: absolute; height: "+scrollerCutOff+"px; width: 1px;");d.gutters=elt("div",null,"CodeMirror-gutters");d.lineGutter=null;d.scroller=elt("div",[d.sizer,d.heightForcer,d.gutters],"CodeMirror-scroll");d.scroller.setAttribute("tabIndex","-1");d.wrapper=elt("div",[d.inputDiv,d.scrollbarH,d.scrollbarV,d.scrollbarFiller,d.gutterFiller,d.scroller],"CodeMirror");if(ie_lt8){d.gutters.style.zIndex=-1;d.scroller.style.paddingRight=0;}
|
| +if(place.appendChild)place.appendChild(d.wrapper);else place(d.wrapper);if(ios)input.style.width="0px";if(!webkit)d.scroller.draggable=true;if(khtml){d.inputDiv.style.height="1px";d.inputDiv.style.position="absolute";}
|
| +else if(ie_lt8)d.scrollbarH.style.minWidth=d.scrollbarV.style.minWidth="18px";d.viewOffset=d.lastSizeC=0;d.showingFrom=d.showingTo=docStart;d.lineNumWidth=d.lineNumInnerWidth=d.lineNumChars=null;d.prevInput="";d.alignWidgets=false;d.pollingFast=false;d.poll=new Delayed();d.cachedCharWidth=d.cachedTextHeight=null;d.measureLineCache=[];d.measureLineCachePos=0;d.inaccurateSelection=false;d.maxLine=null;d.maxLineLength=0;d.maxLineChanged=false;d.wheelDX=d.wheelDY=d.wheelStartX=d.wheelStartY=null;return d;}
|
| +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);setTimeout(function(){updateScrollbars(cm);},100);}
|
| +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){var map=keyMap[cm.options.keyMap],style=map.style;cm.display.wrapper.className=cm.display.wrapper.className.replace(/\s*cm-keymap-\S+/g,"")+
|
| +(style?" cm-keymap-"+style:"");cm.state.disableInput=map.disableInput;}
|
| +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);setTimeout(function(){alignHorizontally(cm);},20);}
|
| +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;}});}
|
| +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");}
|
| +function updateScrollbars(cm){var d=cm.display,docHeight=cm.doc.height;var totalHeight=docHeight+paddingVert(d);d.sizer.style.minHeight=d.heightForcer.style.top=totalHeight+"px";d.gutters.style.height=Math.max(totalHeight,d.scroller.clientHeight-scrollerCutOff)+"px";var scrollHeight=Math.max(totalHeight,d.scroller.scrollHeight);var needsH=d.scroller.scrollWidth>(d.scroller.clientWidth+1);var needsV=scrollHeight>(d.scroller.clientHeight+1);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="";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="";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)};}
|
| +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;}
|
| +function updateDisplay(cm,changes,viewPort,forced){var oldFrom=cm.display.showingFrom,oldTo=cm.display.showingTo,updated;var visible=visibleLines(cm.display,cm.doc,viewPort);for(;;){if(!updateDisplayInner(cm,changes,visible,forced))break;forced=false;updated=true;updateSelection(cm);updateScrollbars(cm);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=[];}
|
| +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);}
|
| +return updated;}
|
| +function updateDisplayInner(cm,changes,visible,forced){var display=cm.display,doc=cm.doc;if(!display.wrapper.clientWidth){display.showingFrom=display.showingTo=doc.first;display.viewOffset=0;return;}
|
| +if(!forced&&changes.length==0&&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";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;}
|
| +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);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;}}}
|
| +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;}
|
| +if(!forced&&intactLines==to-from&&from==display.showingFrom&&to==display.showingTo){updateViewOffset(cm);return;}
|
| +intact.sort(function(a,b){return a.from-b.from;});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;if(different){display.lastSizeC=display.wrapper.clientHeight;startWorker(cm,400);}
|
| +display.showingFrom=from;display.showingTo=to;updateHeightsInViewport(cm);updateViewOffset(cm);return true;}
|
| +function updateHeightsInViewport(cm){var display=cm.display;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));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);if(line.widgets&&cur.previousSibling)for(var i=0;i<line.widgets.length;++i){var w=line.widgets[i];if(w.showIfHidden){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;}
|
| +var wnode=prev.appendChild(elt("div",[w.node],"CodeMirror-linewidget"));if(!w.handleMouseEvents)wnode.ignoreEvents=true;positionLineWidget(w,wnode,prev,dims);}}}else if(nextIntact&&nextIntact.from<=lineN&&nextIntact.to>lineN){while(cur.lineObj!=line)cur=rm(cur);if(lineNumbers&&updateNumbersFrom<=lineN&&cur.lineNumber)
|
| +setTextContent(cur.lineNumber,lineNumberFor(cm.options,lineN));cur=cur.nextSibling;}else{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;}
|
| +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;if(reuse){reuse.alignable=null;var isOk=true,widgetsSeen=0,insertBefore=null;for(var n=reuse.firstChild,next;n;n=next){next=n.nextSibling;if(!/\bCodeMirror-linewidget\b/.test(n.className)){reuse.removeChild(n);}else{for(var i=0;i<line.widgets.length;++i){var widget=line.widgets[i];if(widget.node==n.firstChild){if(!widget.above&&!insertBefore)insertBefore=n;positionLineWidget(widget,n,reuse,dims);++widgetsSeen;break;}}
|
| +if(i==line.widgets.length){isOk=false;break;}}}
|
| +reuse.insertBefore(lineElement,insertBefore);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);}
|
| +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");if(!widget.handleMouseEvents)node.ignoreEvents=true;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";}}
|
| +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";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";}}
|
| +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";}}
|
| +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"));}
|
| +function drawForLine(line,fromArg,toArg){var lineObj=getLine(doc,line);var lineLen=lineObj.text.length;var start,end;function coords(ch,bias){return charCoords(cm,Pos(line,ch),"div",lineObj,bias);}
|
| +iterateBidiSections(getOrder(lineObj),fromArg||0,toArg==null?lineLen:toArg,function(from,to,dir){var leftPos=coords(from,"left"),rightPos,left,right;if(from==to){rightPos=leftPos;left=right=leftPos.left;}else{rightPos=coords(to-1,"right");if(dir=="rtl"){var tmp=leftPos;leftPos=rightPos;rightPos=tmp;}
|
| +left=leftPos.left;right=rightPos.right;}
|
| +if(fromArg==null&&from==0)left=pl;if(rightPos.top-leftPos.top>3){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;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;if(left<pl+1)left=pl;add(left,rightPos.top,right-left,rightPos.bottom);});return{start:start,end:end};}
|
| +if(sel.from.line==sel.to.line){drawForLine(sel.from.line,sel.from.ch,sel.to.ch);}else{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);}}
|
| +if(leftEnd.bottom<rightStart.top)
|
| +add(pl,leftEnd.bottom,null,rightStart.top);}
|
| +removeChildrenAndAdd(display.selectionDiv,fragment);display.selectionDiv.style.display="";}
|
| +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);}
|
| +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){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);})();}
|
| +function findStartLine(cm,n,precise){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);if(line.stateAfter&&(!precise||search<=doc.frontier))return search;var indented=countColumn(line.text,null,cm.options.tabSize);if(minline==null||minindent>indented){minline=search-1;minindent=indented;}}
|
| +return minline;}
|
| +function getStateBefore(cm,n,precise){var doc=cm.doc,display=cm.display;if(!doc.mode.startState)return true;var pos=findStartLine(cm,n,precise),state=pos>doc.first&&getLine(doc,pos-1).stateAfter;if(!state)state=startState(doc.mode);else state=copyState(doc.mode,state);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;}
|
| +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;}
|
| +function measureChar(cm,line,ch,data,bias){var dir=-1;data=data||measureLine(cm,line);for(var pos=ch;;pos+=dir){var r=data.get(pos);if(r)break;if(dir<0&&pos==0)dir=1;}
|
| +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;return{left:pos<ch?r.right:r.left,right:pos>ch?r.left:r.right,top:r.top,bottom:r.bottom};}
|
| +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)
|
| +return memo;}}
|
| +function clearCachedMeasurement(cm,line){var exists=findCachedMeasurement(cm,line);if(exists)exists.text=exists.measure=exists.markedSpans=null;}
|
| +function measureLine(cm,line){var cached=findCachedMeasurement(cm,line);if(cached)return cached.measure;var measure=measureLineInner(cm,line,0,10);measure.get=function(num){if(this[num])return this[num];if(num<0||num>=line.text.length)return null;measureLineInner(cm,line,Math.max(num-50,0),Math.min(num+50,line.text.length),this);return this[num];};var 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);return measure;}
|
| +function measureLineInner(cm,line,from,to,oldMeasure){var display=cm.display,measure=emptyArray(line.text.length);var pre=lineContent(cm,line,measure,true,from,to);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=oldMeasure||emptyArray(line.text.length),maxBot=pre.offsetHeight;if(ie_lt9&&display.measure.first!=pre)
|
| +removeChildrenAndAdd(display.measure,pre);function measureRect(rect){var top=rect.top-outer.top,bot=rect.bottom-outer.top;if(bot>maxBot)bot=maxBot;if(top<0)top=0;for(var i=vranges.length-2;i>=0;i-=2){var rtop=vranges[i],rbot=vranges[i+1];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){vranges[i]=Math.min(top,rtop);vranges[i+1]=Math.max(bot,rbot);break;}}
|
| +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];}
|
| +for(var i=0,cur;i<measure.length;++i)if(cur=measure[i]){var node=cur,rect=null;if(/\bCodeMirror-widget\b/.test(cur.className)&&cur.getClientRects){if(cur.firstChild.nodeType==1)node=cur.firstChild;var rects=node.getClientRects();if(rects.length>1){rect=data[i]=measureRect(rects[0]);rect.rightSide=measureRect(rects[rects.length-1]);}}
|
| +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));}
|
| +for(var i=0,cur;i<data.length;++i)if(measure[i]&&(cur=data[i])){finishRect(cur);if(cur.leftSide)finishRect(cur.leftSide);if(cur.rightSide)finishRect(cur.rightSide);}
|
| +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);if(cached)return measureChar(cm,line,line.text.length,cached.measure,"right").right;var pre=lineContent(cm,line,null,true);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;}
|
| +function pageScrollX(){return window.pageXOffset||(document.documentElement||document.body).scrollLeft;}
|
| +function pageScrollY(){return window.pageYOffset||(document.documentElement||document.body).scrollTop;}
|
| +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);if(context=="local")yOff+=paddingTop(cm.display);else yOff-=cm.display.viewOffset;if(context=="page"||context=="window"){var lOff=getRect(cm.display.lineSpace);yOff+=lOff.top+(context=="window"?0:pageScrollY());var xOff=lOff.left+(context=="window"?0:pageScrollX());rect.left+=xOff;rect.right+=xOff;}
|
| +rect.top+=yOff;rect.bottom+=yOff;return rect;}
|
| +function fromCoordSystem(cm,coords,context){if(context=="div")return coords;var left=coords.left,top=coords.top;if(context=="page"){left-=pageScrollX();top-=pageScrollY();}else if(context=="local"||!context){var localBox=getRect(cm.display.sizer);left+=localBox.left;top+=localBox.top;}
|
| +var lineSpaceBox=getRect(cm.display.lineSpace);return{left:left-lineSpaceBox.left,top:top-lineSpaceBox.top};}
|
| +function charCoords(cm,pos,context,lineObj,bias){if(!lineObj)lineObj=getLine(cm.doc,pos.line);return intoCoordSystem(cm,lineObj,measureChar(cm,lineObj,pos.ch,null,bias),context);}
|
| +function cursorCoords(cm,pos,context,lineObj,measurement){lineObj=lineObj||getLine(cm.doc,pos.line);if(!measurement)measurement=measureLine(cm,lineObj);function get(ch,right){var m=measureChar(cm,lineObj,ch,measurement,right?"right":"left");if(right)m.left=m.right;else m.right=m.left;return intoCoordSystem(cm,lineObj,m,context);}
|
| +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);}
|
| +var order=getOrder(lineObj),ch=pos.ch;if(!order)return get(ch);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){var pos=new Pos(line,ch);pos.xRel=xRel;if(outside)pos.outside=true;return pos;}
|
| +function coordsChar(cm,x,y){var doc=cm.doc;y+=cm.display.viewOffset;if(y<0)return PosWithInfo(doc.first,0,true,-1);var lineNo=lineAtHeight(doc,y),last=doc.first+doc.size-1;if(lineNo>last)
|
| +return PosWithInfo(doc.first+doc.size-1,getLine(doc,last).text.length,true,1);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();if(merged&&(found.ch>mergedPos.from.ch||found.ch==mergedPos.from.ch&&found.xRel>0))
|
| +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;if(x>toX)return PosWithInfo(lineNo,to,toOutside,1);for(;;){if(bidi?to==from||to==moveVisually(lineObj,from,1):to-from<=1){var ch=x<fromX||x-fromX<=toX-x?from:to;var xDiff=x-(ch==from?fromX:toX);while(isExtendingChar.test(lineObj.text.charAt(ch)))++ch;var pos=PosWithInfo(lineNo,ch,ch==from?fromOutside:toOutside,xDiff<0?-1:xDiff?1:0);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");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;}
|
| +var nextOpId=0;function startOperation(cm){cm.curOp={changes:[],forceUpdate:false,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){var coords=cursorCoords(cm,doc.sel.head);newScrollPos=calculateScrollPos(cm,coords.left,coords.top,coords.left,coords.bottom);}
|
| +if(op.changes.length||op.forceUpdate||newScrollPos&&newScrollPos.scrollTop!=null){updated=updateDisplay(cm,op.changes,newScrollPos&&newScrollPos.scrollTop,op.forceUpdate);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]();}
|
| +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});}
|
| +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);}
|
| +function readInput(cm){var input=cm.display.input,prevInput=cm.display.prevInput,doc=cm.doc,sel=doc.sel;if(!cm.state.focused||hasSelection(input)||isReadOnly(cm)||cm.state.disableInput)return false;if(cm.state.pasteIncoming&&cm.state.fakedLastChar){input.value=input.value.substring(0,input.value.length-1);cm.state.fakedLastChar=false;}
|
| +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)));var updateInput=cm.curOp.updateInput;var changeEvent={from:from,to:to,text:splitLines(text.slice(same)),origin:cm.state.pasteIncoming?"paste":"+input"};makeChange(cm.doc,changeEvent,"end");cm.curOp.updateInput=updateInput;signalLater(cm,"inputRead",cm,changeEvent);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;}
|
| +function registerEventHandlers(cm){var d=cm.display;on(d.scroller,"mousedown",operation(cm,onMouseDown));if(ie)
|
| +on(d.scroller,"dblclick",operation(cm,function(e){if(signalDOMEvent(cm,e))return;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
|
| +on(d.scroller,"dblclick",function(e){signalDOMEvent(cm,e)||e_preventDefault(e);});on(d.lineSpace,"selectstart",function(e){if(!eventInWidget(d,e))e_preventDefault(e);});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);on(d.wrapper,"scroll",function(){d.wrapper.scrollTop=d.wrapper.scrollLeft=0;});var resizeTimer;function onResize(){if(resizeTimer==null)resizeTimer=setTimeout(function(){resizeTimer=null;d.cachedCharWidth=d.cachedTextHeight=knownScrollbarWidth=null;clearCaches(cm);runInOp(cm,bind(regChange,cm));},100);}
|
| +on(window,"resize",onResize);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){if(signalDOMEvent(cm,e)||cm.options.onKeyEvent&&cm.options.onKeyEvent(cm,addStop(e)))return;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));function drag_(e){if(signalDOMEvent(cm,e)||cm.options.onDragEvent&&cm.options.onDragEvent(cm,addStop(e)))return;e_stop(e);}
|
| +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(){if(webkit&&!cm.state.fakedLastChar){var start=d.input.selectionStart,end=d.input.selectionEnd;d.input.value+="$";d.input.selectionStart=start;d.input.selectionEnd=end;cm.state.fakedLastChar=true;}
|
| +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);if(khtml)on(d.sizer,"mouseup",function(){if(document.activeElement==d.input)d.input.blur();focusInput(cm);});}
|
| +function eventInWidget(display,e){for(var n=e_target(e);n!=display.wrapper;n=n.parentNode){if(!n||n.ignoreEvents||n.parentNode==display.sizer&&n!=display.mover)return true;}}
|
| +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||target==display.scrollbarFiller||target==display.gutterFiller)return null;}
|
| +var x,y,space=getRect(display.lineSpace);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){if(signalDOMEvent(this,e))return;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;}
|
| +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);}});if(webkit)display.scroller.draggable=true;cm.state.draggingText=dragEnd;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)));}}
|
| +var editorSize=getRect(display.wrapper);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);}}
|
| +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);}
|
| +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;}
|
| +var lastDrop=0;function onDrop(e){var cm=this;if(signalDOMEvent(cm,e)||eventInWidget(cm.display,e)||(cm.options.onDragEvent&&cm.options.onDragEvent(cm,addStop(e))))
|
| +return;e_preventDefault(e);if(ie)lastDrop=+new Date;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{if(cm.state.draggingText&&!(posLess(pos,cm.doc.sel.from)||posLess(cm.doc.sel.to,pos))){cm.state.draggingText(e);setTimeout(bind(focusInput,cm),20);return;}
|
| +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);}}
|
| +catch(e){}}}
|
| +function onDragStart(cm,e){if(ie&&(!cm.state.draggingText||+new Date-lastDrop<100)){e_stop(e);return;}
|
| +if(signalDOMEvent(cm,e)||eventInWidget(cm.display,e))return;var txt=cm.getSelection();e.dataTransfer.setData("Text",txt);if(e.dataTransfer.setDragImage&&!safari){var img=elt("img",null,null,"position: fixed; left: 0; top: 0;");if(opera){img.width=img.height=1;cm.display.wrapper.appendChild(img);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,[]);startWorker(cm,100);}
|
| +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;}
|
| +var wheelSamples=0,wheelPixelsPerUnit=null;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;if(!(dx&&scroll.scrollWidth>scroll.clientWidth||dy&&scroll.scrollHeight>scroll.clientHeight))return;if(dy&&mac&&webkit){for(var cur=e.target;cur!=scroll;cur=cur.parentNode){if(cur.lineObj){cm.display.currentWheelTarget=cur;break;}}}
|
| +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;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;}
|
| +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){var startMap=getKeyMap(cm.options.keyMap),next=startMap.auto;clearTimeout(maybeTransition);if(next&&!isModifierKey(e))maybeTransition=setTimeout(function(){if(getKeyMap(cm.options.keyMap)==startMap){cm.options.keyMap=(next.call?next.call(null,cm):next);keyMapChanged(cm);}},50);var name=keyName(e,true),handled=false;if(!name)return false;var keymaps=allKeyMaps(cm);if(e.shiftKey){handled=lookupKey("Shift-"+name,keymaps,function(b){return doHandleBinding(cm,b,true);})||lookupKey(name,keymaps,function(b){if(typeof b=="string"?/^go[A-Z]/.test(b):b.motion)
|
| +return doHandleBinding(cm,b);});}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;}
|
| +signalLater(cm,"keyHandled",cm,name,e);}
|
| +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);signalLater(cm,"keyHandled",cm,"'"+ch+"'",e);}
|
| +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;}
|
| +if(signalDOMEvent(cm,e)||cm.options.onKeyEvent&&cm.options.onKeyEvent(cm,addStop(e)))return;var code=e.keyCode;cm.doc.sel.shift=code==16||e.shiftKey;var handled=handleKeyBinding(cm,e);if(opera){lastStoppedKey=handled?code:null;if(!handled&&code==88&&!hasCopyEvent&&(mac?e.metaKey:e.ctrlKey))
|
| +cm.replaceSelection("");}}
|
| +function onKeyPress(e){var cm=this;if(signalDOMEvent(cm,e)||cm.options.onKeyEvent&&cm.options.onKeyEvent(cm,addStop(e)))return;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){if(signalDOMEvent(cm,e,"contextmenu"))return;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;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);if(posEq(sel.from,sel.to))display.input.value=display.prevInput=" ";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;}}
|
| +function rehide(){display.inputDiv.style.position="relative";display.input.style.cssText=oldCSS;if(ie_lt9)display.scrollbarV.scrollTop=display.scroller.scrollTop=scrollPos;slowPoll(cm);if(display.input.selectionStart!=null){if(!ie||ie_lt9)prepareSelectAllHack();clearTimeout(detectingSelectAll);var i=0,poll=function(){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);}}
|
| +if(ie&&!ie_lt9)prepareSelectAllHack();if(captureMiddleClick){e_stop(e);var mouseup=function(){off(window,"mouseup",mouseup);setTimeout(rehide,20);};on(window,"mouseup",mouseup);}else{setTimeout(rehide,50);}}
|
| +var changeEnd=CodeMirror.changeEnd=function(change){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));};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));}
|
| +function computeSelAfterChange(doc,change,hint){if(hint&&typeof hint=="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};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)};}
|
| +function filterChange(doc,change,update){var obj={canceled:false,from:change.from,to:change.to,text:change.text,origin:change.origin,cancel:function(){this.canceled=true;}};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;};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};}
|
| +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")){change=filterChange(doc,change,true);if(!change)return;}
|
| +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,anchorAfter:event.anchorBefore,headAfter:event.headBefore,generation:hist.generation};(type=="undo"?hist.undone:hist.done).push(anti);hist.generation=event.generation||++hist.maxGeneration;var filter=hasHandler(doc,"beforeChange")||doc.cm&&hasHandler(doc.cm,"beforeChange");for(var i=event.changes.length-1;i>=0;--i){var change=event.changes[i];change.origin=type;if(filter&&!filterChange(doc,change,false)){(type=="undo"?hist.done:hist.undone).length=0;return;}
|
| +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;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;}
|
| +doc.frontier=Math.min(doc.frontier,from.line);startWorker(cm,400);var lendiff=change.text.length-(to.line-from.line)-1;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);}
|
| +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);}
|
| +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;}
|
| +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;}}
|
| +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;}
|
| +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;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;}}}
|
| +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){if(!mayClear)return skipAtomic(doc,pos,bias,true);doc.cantEdit=true;return Pos(doc.first,0);}
|
| +flipped=true;newPos=pos;dir=-dir;}}
|
| +curPos=newPos;continue search;}}}
|
| +return curPos;}}
|
| +function scrollCursorIntoView(cm){var coords=scrollPosIntoView(cm,cm.doc.sel.head,cm.options.cursorScrollMargin);if(!cm.state.focused)return;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;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";}
|
| +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;}
|
| +if(scrollPos.scrollLeft!=null){setScrollLeft(cm,scrollPos.scrollLeft);if(Math.abs(cm.doc.scrollLeft-startLeft)>1)changed=true;}
|
| +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){var display=cm.display,snapMargin=textHeight(cm.display);if(y1<0)y1=0;var screen=display.scroller.clientHeight-scrollerCutOff,screentop=display.scroller.scrollTop,result={};var docBottom=cm.doc.height+paddingVert(display);var atTop=y1<snapMargin,atBottom=y2>docBottom-snapMargin;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));}
|
| +function indentLine(cm,n,how,aggressive){var doc=cm.doc;if(how==null)how="add";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";}}
|
| +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;}else if(typeof how=="number"){indentation=curSpace+how;}
|
| +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){var line=pos.line,ch=pos.ch,origDir=dir;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;return true;}
|
| +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;}
|
| +if(type)sawType=type;if(dir>0&&!moveOnce(!first))break;}}
|
| +var result=skipAtomic(doc,Pos(line,ch),origDir,true);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){if((pos.xRel<0||end==line.length)&&start)--start;else++end;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)));}
|
| +CodeMirror.prototype={constructor:CodeMirror,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)
|
| +if(maps[i]==map||(typeof maps[i]!="string"&&maps[i].name==map)){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){var cur=overlays[i].modeSpec;if(cur==spec||typeof spec=="string"&&cur.name==spec){overlays.splice(i,1);this.state.modeGen++;regChange(this);return;}}}),indentLine:operation(null,function(n,dir,aggressive){if(typeof dir!="string"&&typeof dir!="number"){if(dir==null)dir=this.options.smartIndent?"smart":"prev";else dir=dir?"add":"subtract";}
|
| +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);}),getTokenAt:function(pos,precise){var doc=this.doc;pos=clipPos(doc,pos);var state=getStateBefore(this,pos.line,precise),mode=this.doc.mode;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);}
|
| +return{start:stream.start,end:stream.pos,string:stream.current(),className:style||null,type:style||null,state:state};},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;if(ch==0)return styles[2];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];}},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];},getStateAfter:function(line,precise){var doc=this.doc;line=clipLine(doc,line==null?doc.first+doc.size-1:line);return getStateBefore(this,line+1,precise);},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);},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);},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;});}),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;}
|
| +++i;});}),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;else if(new RegExp("(?:^|\\s)"+cls+"(?:$|\\s)").test(line[prop]))return false;else line[prop]+=" "+cls;return true;});}),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{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;}
|
| +return true;});}),addLineWidget:operation(null,function(handle,node,options){return addLineWidget(this,handle,node,options);}),removeLineWidget:function(widget){widget.clear();},lineInfo:function(line){if(typeof line=="number"){if(!isLine(this.doc,line))return null;var n=line;line=getLine(this.doc,line);if(!line)return null;}else{var n=lineNo(line);if(n==null)return null;}
|
| +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);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;}
|
| +node.style.top=top+"px";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";}
|
| +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;}
|
| +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;}
|
| +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;}),toggleOverwrite:function(value){if(value!=null&&value==this.state.overwrite)return;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);}
|
| +var sPos=calculateScrollPos(this,coords.left,coords.top-margin,coords.right,coords.bottom+margin);updateScrollPos(this,sPos.scrollLeft,sPos.scrollTop);}),setSize:operation(null,function(width,height){function interpret(val){return typeof val=="number"||/^\d+$/.test(String(val))?val+"px":val;}
|
| +if(width!=null)this.display.wrapper.style.width=interpret(width);if(height!=null)this.display.wrapper.style.height=interpret(height);if(this.options.lineWrapping)
|
| +this.display.measureLineCache.length=this.display.measureLineCachePos=0;this.curOp.forceUpdate=true;}),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;}};eventMixin(CodeMirror);var optionHandlers=CodeMirror.optionHandlers={};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";}};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);option("coverGutterNextToScrollbar",false,updateScrollbars,true);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);option("cursorScrollMargin",0);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);var modes=CodeMirror.modes={},mimeModes=CodeMirror.mimeModes={};CodeMirror.defineMode=function(name,mode){if(!CodeMirror.defaults.mode&&name!="null")CodeMirror.defaults.mode=name;if(arguments.length>2){mode.dependencies=[];for(var i=2;i<arguments.length;++i)mode.dependencies.push(arguments[i]);}
|
| +modes[name]=mode;};CodeMirror.defineMIME=function(mime,spec){mimeModes[mime]=spec;};CodeMirror.resolveMode=function(spec){if(typeof spec=="string"&&mimeModes.hasOwnProperty(spec)){spec=mimeModes[spec];}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)){return CodeMirror.resolveMode("application/xml");}
|
| +if(typeof spec=="string")return{name:spec};else return spec||{name:"null"};};CodeMirror.getMode=function(options,spec){var spec=CodeMirror.resolveMode(spec);var mfactory=modes[spec.name];if(!mfactory)return CodeMirror.getMode(options,"text/plain");var modeObj=mfactory(options,spec);if(modeExtensions.hasOwnProperty(spec.name)){var exts=modeExtensions[spec.name];for(var prop in exts){if(!exts.hasOwnProperty(prop))continue;if(modeObj.hasOwnProperty(prop))modeObj["_"+prop]=modeObj[prop];modeObj[prop]=exts[prop];}}
|
| +modeObj.name=spec.name;return modeObj;};CodeMirror.defineMode("null",function(){return{token:function(stream){stream.skipToEnd();}};});CodeMirror.defineMIME("text/plain","null");var modeExtensions=CodeMirror.modeExtensions={};CodeMirror.extendMode=function(mode,properties){var exts=modeExtensions.hasOwnProperty(mode)?modeExtensions[mode]:(modeExtensions[mode]={});copyObj(properties,exts);};CodeMirror.defineExtension=function(name,func){CodeMirror.prototype[name]=func;};CodeMirror.defineDocExtension=function(name,func){Doc.prototype[name]=func;};CodeMirror.defineOption=option;var initHooks=[];CodeMirror.defineInitHook=function(f){initHooks.push(f);};var helpers=CodeMirror.helpers={};CodeMirror.registerHelper=function(type,name,value){if(!helpers.hasOwnProperty(type))helpers[type]=CodeMirror[type]={};helpers[type][name]=value;};CodeMirror.isWordChar=isWordChar;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;}
|
| +CodeMirror.copyState=copyState;function startState(mode,a1,a2){return mode.startState?mode.startState(a1,a2):true;}
|
| +CodeMirror.startState=startState;CodeMirror.innerMode=function(mode,state){while(mode.innerMode){var info=mode.innerMode(state);if(!info||info.mode==mode)break;state=info.state;mode=info.mode;}
|
| +return info||{mode:mode,state:state};};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");},delLineLeft:function(cm){var cur=cm.getCursor();cm.replaceRange("",Pos(cur.line,0),cur,"+delete");},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();}};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"};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","Cmd-[":"indentLess","Cmd-]":"indentMore","Cmd-Backspace":"delLineLeft",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"};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]);if(done)return done!="stop";}}
|
| +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;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;if(options.autofocus==null){var hasFocus=document.body;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);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;};function StringStream(string,tabSize){this.pos=this.start=0;this.string=string;this.tabSize=tabSize||8;this.lastColumnPos=this.lastColumnValue=0;}
|
| +StringStream.prototype={eol:function(){return this.pos>=this.string.length;},sol:function(){return this.pos==0;},peek:function(){return this.string.charAt(this.pos)||undefined;},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){var start=this.pos;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;},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;},indentation:function(){return countColumn(this.string,null,this.tabSize);},match:function(pattern,consume,caseInsensitive){if(typeof pattern=="string"){var cased=function(str){return caseInsensitive?str.toLowerCase():str;};var substr=this.string.substr(this.pos,pattern.length);if(cased(substr)==cased(pattern)){if(consume!==false)this.pos+=pattern.length;return true;}}else{var match=this.string.slice(this.pos).match(pattern);if(match&&match.index>0)return null;if(match&&consume!==false)this.pos+=match[0].length;return match;}},current:function(){return this.string.slice(this.start,this.pos);}};CodeMirror.StringStream=StringStream;function TextMarker(doc,type){this.lines=[];this.type=type;this.doc=doc;}
|
| +CodeMirror.TextMarker=TextMarker;eventMixin(TextMarker);TextMarker.prototype.clear=function(){if(this.explicitlyCleared)return;var cm=this.doc.cm,withOp=cm&&!cm.curOp;if(withOp)startOperation(cm);if(hasHandler(this,"clear")){var found=this.find();if(found)signalLater(this,"clear",found.from,found.to);}
|
| +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;if(this.atomic&&this.doc.cantEdit){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};};TextMarker.prototype.changed=function(){var pos=this.find(),cm=this.doc.cm;if(!pos||!cm)return;if(this.type!="bookmark")pos=pos.from;var line=getLine(this.doc,pos.line);clearCachedMeasurement(cm,line);if(pos.line>=cm.display.showingFrom&&pos.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;}
|
| +runInOp(cm,function(){cm.curOp.selectionChanged=cm.curOp.forceUpdate=cm.curOp.updateMaxLine=true;});}};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");if(!options.handleMouseEvents)marker.replacedWith.ignoreEvents=true;}
|
| +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;if(marker.className||marker.title||marker.startStyle||marker.endStyle||marker.collapsed)
|
| +regChange(cm,from.line,to.line+1);if(marker.atomic)reCheckSelection(cm);}
|
| +return marker;}
|
| +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;eventMixin(SharedTextMarker);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);}
|
| +function getMarkedSpanFor(spans,marker){if(spans)for(var i=0;i<spans.length;++i){var span=spans[i];if(span.marker==marker)return span;}}
|
| +function removeMarkedSpan(spans,span){for(var r,i=0;i<spans.length;++i)
|
| +if(spans[i]!=span)(r||(r=[])).push(spans[i]);return r;}
|
| +function addMarkedSpan(line,span){line.markedSpans=line.markedSpans?line.markedSpans.concat([span]):[span];span.marker.attachLine(line);}
|
| +function markedSpansBefore(old,startCh,isInsert){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);if(startsBefore||marker.type=="bookmark"&&span.from==startCh&&(!isInsert||!span.marker.insertLeft)){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});}}
|
| +return nw;}
|
| +function markedSpansAfter(old,endCh,isInsert){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);if(endsAfter||marker.type=="bookmark"&&span.from==endCh&&(!isInsert||span.marker.insertLeft)){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;}
|
| +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);var first=markedSpansBefore(oldFirst,startCh,isInsert);var last=markedSpansAfter(oldLast,endCh,isInsert);var sameLine=change.text.length==1,offset=lst(change.text).length+(sameLine?startCh:0);if(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;}}}
|
| +if(last){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);}}else{span.from+=offset;if(sameLine)(first||(first=[])).push(span);}}}
|
| +if(sameLine&&first){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;}
|
| +var newMarkers=[first];if(!sameLine){var gap=change.text.length-2,gapMarkers;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)
|
| +newMarkers.push(gapMarkers);newMarkers.push(last);}
|
| +return newMarkers;}
|
| +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;if(sp.marker.replacedWith)continue;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];if(sp.marker.collapsed&&!sp.marker.replacedWith&&sp.from==span.to&&(sp.marker.inclusiveLeft||span.marker.inclusiveRight)&&lineIsHiddenInner(doc,line,sp))return true;}}
|
| +function detachMarkedSpans(line){var spans=line.markedSpans;if(!spans)return;for(var i=0;i<spans.length;++i)
|
| +spans[i].marker.detachLine(line);line.markedSpans=null;}
|
| +function attachMarkedSpans(line,spans){if(!spans)return;for(var i=0;i<spans.length;++i)
|
| +spans[i].marker.attachLine(line);line.markedSpans=spans;}
|
| +var LineWidget=CodeMirror.LineWidget=function(cm,node,options){if(options)for(var opt in options)if(options.hasOwnProperty(opt))
|
| +this[opt]=options[opt];this.cm=cm;this.node=node;};eventMixin(LineWidget);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;var aboveVisible=heightAtLine(this.cm,this.line)<this.cm.doc.scrollTop;updateLineHeight(this.line,Math.max(0,this.line.height-widgetHeight(this)));if(aboveVisible)addToScrollPos(this.cm,0,-this.height);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){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);widget.line=line;if(!lineIsHidden(cm.doc,line)||widget.showIfHidden){var aboveVisible=heightAtLine(cm,line)<cm.doc.scrollTop;updateLineHeight(line,line.height+widgetHeight(widget));if(aboveVisible)addToScrollPos(cm,0,widget.height);}
|
| +return true;});return widget;}
|
| +var Line=CodeMirror.Line=function(text,markedSpans,estimateHeight){this.text=text;attachMarkedSpans(this,markedSpans);this.height=estimateHeight?estimateHeight(this):1;};eventMixin(Line);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);}
|
| +function runMode(cm,text,mode,state,f){var flattenSpans=mode.flattenSpans;if(flattenSpans==null)flattenSpans=cm.options.flattenSpans;var curStart=0,curStyle=null;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;stream.pos=Math.min(text.length,stream.start+50000);style=null;}else{style=mode.token(stream,state);}
|
| +if(!flattenSpans||curStyle!=style){if(curStart<stream.start)f(stream.start,curStyle);curStart=stream.start;curStyle=style;}
|
| +stream.start=stream.pos;}
|
| +if(curStart<stream.pos)f(stream.pos,curStyle);}
|
| +function highlightLine(cm,line,state){var st=[cm.state.modeGen];runMode(cm,line.text,cm.doc.mode,state,function(end,style){st.push(end,style);});for(var o=0;o<cm.state.overlays.length;++o){var overlay=cm.state.overlays[o],i=1,at=0;runMode(cm,line.text,overlay.mode,true,function(end,style){var start=i;while(at<end){var i_end=st[i];if(i_end>end)
|
| +st.splice(i,1,end,st[i+1],i_end);i+=2;at=Math.min(end,i_end);}
|
| +if(!style)return;if(overlay.opaque){st.splice(start,i-start,end,style);i=start+2;}else{for(;start<i;start+=2){var cur=st[start+1];st[start+1]=cur?cur+" "+style:style;}}});}
|
| +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;}
|
| +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-"));}
|
| +function lineContent(cm,realLine,measure,copyWidgets,from,to){var merged,line=realLine,empty=true;while(merged=collapsedSpanAtStart(line))
|
| +line=getLine(cm.doc,merged.find().from.line);var builder={pre:elt("pre"),col:0,pos:0,measure:null,measuredSomething:false,cm:cm,from:from,to:to,copyWidgets:copyWidgets};if(line.textClass)builder.pre.className=line.textClass;do{if(line.text)empty=false;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);var next=insertLineContent(line,builder,getLineStyles(cm,line));if(measure&&line==realLine&&!builder.measuredSomething){measure[0]=builder.pre.appendChild(zeroWidthElement(cm.display.measure));builder.measuredSomething=true;}
|
| +if(next)line=getLine(cm.doc,next.to.line);}while(next);if(measure&&!builder.measuredSomething&&!measure[0])
|
| +measure[0]=builder.pre.appendChild(empty?elt("span","\u00a0"):zeroWidthElement(cm.display.measure));if(!builder.pre.firstChild&&!lineIsHidden(cm.doc,realLine))
|
| +builder.pre.appendChild(document.createTextNode("\u00a0"));var order;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;function buildToken(builder,text,style,startStyle,endStyle,title){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;}
|
| +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;}}}
|
| +if(style||startStyle||endStyle||builder.measure){var fullStyle=style||"";if(startStyle)fullStyle+=startStyle;if(endStyle)fullStyle+=endStyle;var token=elt("span",[content],fullStyle);if(title)token.title=title;return builder.pre.appendChild(token);}
|
| +builder.pre.appendChild(content);}
|
| +function buildTokenMeasure(builder,text,style,startStyle,endStyle){if(builder.from||builder.to){if(builder.from>=builder.pos+text.length){buildToken(builder,text,style,startStyle,endStyle);builder.pos+=text.length;return;}}
|
| +var wrapping=builder.cm.options.lineWrapping;for(var i=0;i<text.length;++i){var ch=text.charAt(i),start=i==0;if(ch>="\ud800"&&ch<"\udbff"&&i<text.length-1){ch=text.slice(i,i+2);++i;}else if(i&&wrapping&&spanAffectsWrapping(text,i)){builder.pre.appendChild(elt("wbr"));}
|
| +var old=builder.measure[builder.pos];var span=builder.measure[builder.pos]=buildToken(builder,ch,style,start&&startStyle,i==text.length-1&&endStyle);if(old)span.leftSide=old.leftSide||old;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;}
|
| +if(text.length)builder.measuredSomething=true;}
|
| +function buildTokenSplitSpaces(inner){function split(old){var out=" ";for(var i=0;i<old.length-2;++i)out+=i%2?" ":"\u00a0";out+=" ";return out;}
|
| +return function(builder,text,style,startStyle,endStyle,title){return inner(builder,text.replace(/ {3,}/,split),style,startStyle,endStyle,title);};}
|
| +function buildCollapsedSpan(builder,size,marker,ignoreWidget){var widget=!ignoreWidget&&marker.replacedWith;if(widget){if(builder.copyWidgets)widget=widget.cloneNode(true);builder.pre.appendChild(widget);if(builder.measure){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);}
|
| +builder.measuredSomething=true;}}
|
| +builder.pos+=size;}
|
| +function insertLineContent(line,builder,styles){var spans=line.markedSpans,allText=line.text,at=0;if(!spans){if(builder.to||builder.from){for(var i=1;i<styles.length&&(!builder.to||builder.pos<builder.to);i+=2){var text=allText.slice(at,at=styles[i]);var textLength=text.length;var resolvedStyles=styleToClass(styles[i+1]);if(builder.pos+textLength<=builder.from){builder.addToken(builder,text,resolvedStyles);continue;}
|
| +if(builder.pos<builder.from&&builder.pos+textLength>builder.from){var overlap=builder.from-builder.pos;builder.addToken(builder,text.substring(0,overlap),resolvedStyles);text=text.substring(overlap);}
|
| +builder.addToken(builder,text.substr(0,Math.min(builder.to-builder.from,text.length)),resolvedStyles);}}else{for(var i=1;i<styles.length;i+=2)
|
| +builder.addToken(builder,allText.slice(at,at=styles[i]),styleToClass(styles[i+1]));}
|
| +return;}
|
| +var len=allText.length,pos=0,i=1,text="",style;var nextChange=0,spanStyle,spanEndStyle,spanStartStyle,title,collapsed;for(;;){if(nextChange==pos){spanStyle=spanEndStyle=spanStartStyle=title="";collapsed=null;nextChange=Infinity;var foundBookmarks=[];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;if(m.title&&!title)title=m.title;if(m.collapsed&&(!collapsed||collapsed.marker.size<m.size))
|
| +collapsed=sp;}else if(sp.from>pos&&nextChange>sp.from){nextChange=sp.from;}
|
| +if(m.type=="bookmark"&&sp.from==pos&&m.replacedWith)foundBookmarks.push(m);}
|
| +if(collapsed&&(collapsed.from||0)==pos){buildCollapsedSpan(builder,(collapsed.to==null?len:collapsed.to)-pos,collapsed.marker,collapsed.from==null);if(collapsed.to==null)return collapsed.marker.find();}
|
| +if(!collapsed&&foundBookmarks.length)for(var j=0;j<foundBookmarks.length;++j)
|
| +buildCollapsedSpan(builder,0,foundBookmarks[j]);}
|
| +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,spanStartStyle,pos+tokenText.length==nextChange?spanEndStyle:"",title);if(builder.to&&builder.pos>=builder.to)
|
| +return;}
|
| +if(end>=upto){text=text.slice(upto-pos);pos=upto;break;}
|
| +pos=end;spanStartStyle="";}
|
| +text=allText.slice(at,at=styles[i++]);style=styleToClass(styles[i++]);}}}
|
| +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;if(from.ch==0&&to.ch==0&&lastText==""){for(var i=0,e=text.length-1,added=[];i<e;++i)
|
| +added.push(new Line(text[i],spansFor(i),estimateHeight));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)
|
| +added.push(new Line(text[i],spansFor(i),estimateHeight));added.push(new Line(lastText+firstLine.text.slice(to.ch),lastSpans,estimateHeight));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)
|
| +added.push(new Line(text[i],spansFor(i),estimateHeight));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);}
|
| +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;}
|
| +LeafChunk.prototype={chunkSize:function(){return this.lines.length;},removeInner:function(at,n){for(var i=at,e=at+n;i<e;++i){var line=this.lines[i];this.height-=line.height;cleanUpLine(line);signalLater(line,"delete");}
|
| +this.lines.splice(at,n);},collapse:function(lines){lines.splice.apply(lines,[lines.length,0].concat(this.lines));},insertInner:function(at,lines,height){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;}};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;}
|
| +BranchChunk.prototype={chunkSize:function(){return this.size;},removeInner:function(at,n){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;child.removeInner(at,rm);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);},insertInner:function(at,lines,height){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){child.insertInner(at,lines,height);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){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;}}};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;BranchChunk.call(this,[new LeafChunk([new Line("",null)])]);this.first=firstLine;this.scrollTop=this.scrollLeft=0;this.cantEdit=false;this.history=makeHistory();this.cleanGeneration=1;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,{constructor:Doc,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);},getLineHandleVisualStart:function(line){if(typeof line=="number")line=getLine(this,line);return visualLine(this,line);},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};},clearHistory:function(){this.history=makeHistory(this.history.maxGeneration);},markClean:function(){this.cleanGeneration=this.changeGeneration();},changeGeneration:function(){this.history.lastOp=this.history.lastOrigin=null;return this.history.generation;},isClean:function(gen){return this.history.generation==(gen||this.cleanGeneration);},getHistory:function(){return{done:copyHistoryArray(this.history.done),undone:copyHistoryArray(this.history.undone)};},setHistory:function(histData){var hist=this.history=makeHistory(this.history.maxGeneration);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(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;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]);eventMixin(Doc);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);}
|
| +function getLine(chunk,n){n-=chunk.first;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];}
|
| +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;}
|
| +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){for(var i=0;;++i){if(chunk.children[i]==cur)break;no+=chunk.children[i].chunkSize();}}
|
| +return no+cur.first;}
|
| +function lineAtHeight(chunk,h){var n=chunk.first;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;}
|
| +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;}}
|
| +return h;}
|
| +function getOrder(line){var order=line.order;if(order==null)order=line.order=bidiOrdering(line.text);return order;}
|
| +function makeHistory(startGen){return{done:[],undone:[],undoDepth:Infinity,lastTime:0,lastOp:null,lastOrigin:null,generation:startGen||1,maxGeneration:startGen||1};}
|
| +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){var from={line:change.from.line,ch:change.from.ch};var histChange={from:from,to:changeEnd(change),text:getBetween(doc,change.from,change.to)};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)=="*"))){var last=lst(cur.changes);if(posEq(change.from,change.to)&&posEq(change.from,last.to)){last.to=changeEnd(change);}else{cur.changes.push(historyChangeFromChange(doc,change));}
|
| +cur.anchorAfter=selAfter.anchor;cur.headAfter=selAfter.head;}else{cur={changes:[historyChangeFromChange(doc,change)],generation:hist.generation,anchorBefore:doc.sel.anchor,headBefore:doc.sel.head,anchorAfter:selAfter.anchor,headAfter:selAfter.head};hist.done.push(cur);hist.generation=++hist.maxGeneration;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;}
|
| +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];}}}}
|
| +return copy;}
|
| +function rebaseHistSel(pos,from,to,diff){if(to<pos.line){pos.line+=diff;}else if(from<pos.line){pos.line=from;pos.ch=0;}}
|
| +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);}
|
| +function stopMethod(){e_stop(this);}
|
| +function addStop(event){if(!event.stop)event.stop=stopMethod;return event;}
|
| +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;}
|
| +function e_defaultPrevented(e){return e.defaultPrevented!=null?e.defaultPrevented:e.returnValue==false;}
|
| +function e_stop(e){e_preventDefault(e);e_stopPropagation(e);}
|
| +CodeMirror.e_stop=e_stop;CodeMirror.e_preventDefault=e_preventDefault;CodeMirror.e_stopPropagation=e_stopPropagation;function e_target(e){return e.target||e.srcElement;}
|
| +function e_button(e){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;}
|
| +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){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){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]));}
|
| +function signalDOMEvent(cm,e,override){signal(cm,override||e.type,cm,e);return e_defaultPrevented(e)||e.codemirrorIgnore;}
|
| +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;function eventMixin(ctor){ctor.prototype.on=function(type,f){on(this,type,f);};ctor.prototype.off=function(type,f){off(this,type,f);};}
|
| +var scrollerCutOff=30;var Pass=CodeMirror.Pass={toString:function(){return"CodeMirror.Pass";}};function Delayed(){this.id=null;}
|
| +Delayed.prototype={set:function(ms,f){clearTimeout(this.id);this.id=setTimeout(f,ms);}};function countColumn(string,end,tabSize,startIndex,startValue){if(end==null){end=string.search(/[^\s\u00a0]/);if(end==-1)end=string.length;}
|
| +for(var i=startIndex||0,n=startValue||0;i<end;++i){if(string.charAt(i)=="\t")n+=tabSize-(n%tabSize);else++n;}
|
| +return n;}
|
| +CodeMirror.countColumn=countColumn;var spaceStrs=[""];function spaceStr(n){while(spaceStrs.length<=n)
|
| +spaceStrs.push(lst(spaceStrs)+" ");return spaceStrs[n];}
|
| +function lst(arr){return arr[arr.length-1];}
|
| +function selectInput(node){if(ios){node.selectionStart=0;node.selectionEnd=node.value.length;}else{try{node.select();}
|
| +catch(_e){}}}
|
| +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);};}
|
| +var nonASCIISingleCaseWordChar=/[\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/;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]/;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;}
|
| +function removeChildren(e){for(var count=e.childNodes.length;count>0;--count)
|
| +e.removeChild(e.firstChild);return e;}
|
| +function removeChildrenAndAdd(parent,e){return removeChildren(parent).appendChild(e);}
|
| +function setTextContent(e,str){if(ie_lt9){e.innerHTML="";e.appendChild(document.createTextNode(str));}else e.textContent=str;}
|
| +function getRect(node){return node.getBoundingClientRect();}
|
| +CodeMirror.replaceGetRect=function(f){getRect=f;};var dragAndDrop=function(){if(ie_lt9)return false;var div=elt('div');return"draggable"in div||"dragDrop"in div;}();function spanAffectsWrapping(){return false;}
|
| +if(gecko)
|
| +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));};else if(webkit&&!/Chrome\/(?:29|[3-9]\d|\d\d\d)\./.test(navigator.userAgent))
|
| +spanAffectsWrapping=function(str,i){if(i>1&&str.charCodeAt(i-1)==45){if(/\w/.test(str.charAt(i-2))&&/[^\-?\.]/.test(str.charAt(i)))return true;if(i>2&&/[\d\.,]/.test(str.charAt(i-2))&&/[\d\.,]/.test(str.charAt(i)))return false;}
|
| +return/[~!#%&*)=+}\]|\"\.>,:;][({[<]|-[^\-?\.\u2010-\u201f\u2026]|\?[\w~`@#$%\^&*(_=+{[|><]|โฆ[\w~`@#$%\^&*(_=+{[><]/.test(str.slice(i-1,i+1));};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");}
|
| +var splitLines="\n\nb".split(/\n/).length!=3?function(string){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;}}
|
| +return result;}:function(string){return string.split(/\r\n?|\n/);};CodeMirror.splitLines=splitLines;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;};var hasCopyEvent=(function(){var e=elt("div");if("oncopy"in e)return true;e.setAttribute("oncopy","return;");return typeof e.oncopy=='function';})();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(){for(var i=0;i<10;i++)keyNames[i+48]=String(i);for(var i=65;i<=90;i++)keyNames[i]=String.fromCharCode(i);for(var i=1;i<=12;i++)keyNames[i+111]=keyNames[i+63235]="F"+i;})();function iterateBidiSections(order,from,to,f){if(!order)return f(from,to,"ltr");var found=false;for(var i=0;i<order.length;++i){var part=order[i];if(part.from<to&&part.to>from||from==to&&part.to==from){f(Math.max(part.from,from),Math.min(part.to,to),part.level==1?"rtl":"ltr");found=true;}}
|
| +if(!found)f(from,to,"ltr");}
|
| +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);}
|
| +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;}
|
| +function moveVisually(line,start,dir,byUnit){var bidi=getOrder(line);if(!bidi)return moveLogically(line,start,dir,byUnit);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;}else{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);}}}
|
| +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;}
|
| +var bidiOrdering=(function(){var lowTypes="bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLL";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]/;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)));for(var i=0,prev=outerType;i<len;++i){var type=types[i];if(type=="m")types[i]=prev;else prev=type;}
|
| +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";}}
|
| +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;}
|
| +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;}}
|
| +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;}
|
| +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;}}
|
| +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;};})();CodeMirror.version="3.15.1";return CodeMirror;})();;CodeMirror.defineMode("css",function(config){return CodeMirror.getMode(config,"text/css");});CodeMirror.defineMode("css-base",function(config,parserConfig){"use strict";var indentUnit=config.indentUnit,hooks=parserConfig.hooks||{},atMediaTypes=parserConfig.atMediaTypes||{},atMediaFeatures=parserConfig.atMediaFeatures||{},propertyKeywords=parserConfig.propertyKeywords||{},colorKeywords=parserConfig.colorKeywords||{},valueKeywords=parserConfig.valueKeywords||{},allowNested=!!parserConfig.allowNested,type=null;function ret(style,tp){type=tp;return style;}
|
| +function tokenBase(stream,state){var ch=stream.next();if(hooks[ch]){var result=hooks[ch](stream,state);if(result!==false)return result;}
|
| +if(ch=="@"){stream.eatWhile(/[\w\\\-]/);return ret("def",stream.current());}
|
| +else if(ch=="=")ret(null,"compare");else if((ch=="~"||ch=="|")&&stream.eat("="))return ret(null,"compare");else if(ch=="\""||ch=="'"){state.tokenize=tokenString(ch);return state.tokenize(stream,state);}
|
| +else if(ch=="#"){stream.eatWhile(/[\w\\\-]/);return ret("atom","hash");}
|
| +else if(ch=="!"){stream.match(/^\s*\w*/);return ret("keyword","important");}
|
| +else if(/\d/.test(ch)){stream.eatWhile(/[\w.%]/);return ret("number","unit");}
|
| +else if(ch==="-"){if(/\d/.test(stream.peek())){stream.eatWhile(/[\w.%]/);return ret("number","unit");}else if(stream.match(/^[^-]+-/)){return ret("meta","meta");}}
|
| +else if(/[,+>*\/]/.test(ch)){return ret(null,"select-op");}
|
| +else if(ch=="."&&stream.match(/^-?[_a-z][_a-z0-9-]*/i)){return ret("qualifier","qualifier");}
|
| +else if(ch==":"){return ret("operator",ch);}
|
| +else if(/[;{}\[\]\(\)]/.test(ch)){return ret(null,ch);}
|
| +else if(ch=="u"&&stream.match("rl(")){stream.backUp(1);state.tokenize=tokenParenthesized;return ret("property","variable");}
|
| +else{stream.eatWhile(/[\w\\\-]/);return ret("property","variable");}}
|
| +function tokenString(quote,nonInclusive){return function(stream,state){var escaped=false,ch;while((ch=stream.next())!=null){if(ch==quote&&!escaped)
|
| +break;escaped=!escaped&&ch=="\\";}
|
| +if(!escaped){if(nonInclusive)stream.backUp(1);state.tokenize=tokenBase;}
|
| +return ret("string","string");};}
|
| +function tokenParenthesized(stream,state){stream.next();if(!stream.match(/\s*[\"\']/,false))
|
| +state.tokenize=tokenString(")",true);else
|
| +state.tokenize=tokenBase;return ret(null,"(");}
|
| +return{startState:function(base){return{tokenize:tokenBase,baseIndent:base||0,stack:[],lastToken:null};},token:function(stream,state){state.tokenize=state.tokenize||tokenBase;if(state.tokenize==tokenBase&&stream.eatSpace())return null;var style=state.tokenize(stream,state);if(style&&typeof style!="string")style=ret(style[0],style[1]);var context=state.stack[state.stack.length-1];if(style=="variable"){if(type=="variable-definition")state.stack.push("propertyValue");return state.lastToken="variable-2";}else if(style=="property"){var word=stream.current().toLowerCase();if(context=="propertyValue"){if(valueKeywords.hasOwnProperty(word)){style="string-2";}else if(colorKeywords.hasOwnProperty(word)){style="keyword";}else{style="variable-2";}}else if(context=="rule"){if(!propertyKeywords.hasOwnProperty(word)){style+=" error";}}else if(context=="block"){if(propertyKeywords.hasOwnProperty(word)){style="property";}else if(colorKeywords.hasOwnProperty(word)){style="keyword";}else if(valueKeywords.hasOwnProperty(word)){style="string-2";}else{style="tag";}}else if(!context||context=="@media{"){style="tag";}else if(context=="@media"){if(atMediaTypes[stream.current()]){style="attribute";}else if(/^(only|not)$/.test(word)){style="keyword";}else if(word=="and"){style="error";}else if(atMediaFeatures.hasOwnProperty(word)){style="error";}else{style="attribute error";}}else if(context=="@mediaType"){if(atMediaTypes.hasOwnProperty(word)){style="attribute";}else if(word=="and"){style="operator";}else if(/^(only|not)$/.test(word)){style="error";}else{style="error";}}else if(context=="@mediaType("){if(propertyKeywords.hasOwnProperty(word)){}else if(atMediaTypes.hasOwnProperty(word)){style="error";}else if(word=="and"){style="operator";}else if(/^(only|not)$/.test(word)){style="error";}else{style+=" error";}}else if(context=="@import"){style="tag";}else{style="error";}}else if(style=="atom"){if(!context||context=="@media{"||context=="block"){style="builtin";}else if(context=="propertyValue"){if(!/^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/.test(stream.current())){style+=" error";}}else{style="error";}}else if(context=="@media"&&type=="{"){style="error";}
|
| +if(type=="{"){if(context=="@media"||context=="@mediaType"){state.stack.pop();state.stack[state.stack.length-1]="@media{";}
|
| +else{var newContext=allowNested?"block":"rule";state.stack.push(newContext);}}
|
| +else if(type=="}"){var lastState=state.stack[state.stack.length-1];if(lastState=="interpolation")style="operator";state.stack.pop();if(context=="propertyValue")state.stack.pop();}
|
| +else if(type=="interpolation")state.stack.push("interpolation");else if(type=="@media")state.stack.push("@media");else if(type=="@import")state.stack.push("@import");else if(context=="@media"&&/\b(keyword|attribute)\b/.test(style))
|
| +state.stack.push("@mediaType");else if(context=="@mediaType"&&stream.current()==",")state.stack.pop();else if(context=="@mediaType"&&type=="(")state.stack.push("@mediaType(");else if(context=="@mediaType("&&type==")")state.stack.pop();else if(type==":"&&state.lastToken=="property")state.stack.push("propertyValue");else if(context=="propertyValue"&&type==";")state.stack.pop();else if(context=="@import"&&type==";")state.stack.pop();return state.lastToken=style;},indent:function(state,textAfter){var n=state.stack.length;if(/^\}/.test(textAfter))
|
| +n-=state.stack[state.stack.length-1]=="propertyValue"?2:1;return state.baseIndent+n*indentUnit;},electricChars:"}",blockCommentStart:"/*",blockCommentEnd:"*/"};});(function(){function keySet(array){var keys={};for(var i=0;i<array.length;++i){keys[array[i]]=true;}
|
| +return keys;}
|
| +var atMediaTypes=keySet(["all","aural","braille","handheld","print","projection","screen","tty","tv","embossed"]);var atMediaFeatures=keySet(["width","min-width","max-width","height","min-height","max-height","device-width","min-device-width","max-device-width","device-height","min-device-height","max-device-height","aspect-ratio","min-aspect-ratio","max-aspect-ratio","device-aspect-ratio","min-device-aspect-ratio","max-device-aspect-ratio","color","min-color","max-color","color-index","min-color-index","max-color-index","monochrome","min-monochrome","max-monochrome","resolution","min-resolution","max-resolution","scan","grid"]);var propertyKeywords=keySet(["align-content","align-items","align-self","alignment-adjust","alignment-baseline","anchor-point","animation","animation-delay","animation-direction","animation-duration","animation-iteration-count","animation-name","animation-play-state","animation-timing-function","appearance","azimuth","backface-visibility","background","background-attachment","background-clip","background-color","background-image","background-origin","background-position","background-repeat","background-size","baseline-shift","binding","bleed","bookmark-label","bookmark-level","bookmark-state","bookmark-target","border","border-bottom","border-bottom-color","border-bottom-left-radius","border-bottom-right-radius","border-bottom-style","border-bottom-width","border-collapse","border-color","border-image","border-image-outset","border-image-repeat","border-image-slice","border-image-source","border-image-width","border-left","border-left-color","border-left-style","border-left-width","border-radius","border-right","border-right-color","border-right-style","border-right-width","border-spacing","border-style","border-top","border-top-color","border-top-left-radius","border-top-right-radius","border-top-style","border-top-width","border-width","bottom","box-decoration-break","box-shadow","box-sizing","break-after","break-before","break-inside","caption-side","clear","clip","color","color-profile","column-count","column-fill","column-gap","column-rule","column-rule-color","column-rule-style","column-rule-width","column-span","column-width","columns","content","counter-increment","counter-reset","crop","cue","cue-after","cue-before","cursor","direction","display","dominant-baseline","drop-initial-after-adjust","drop-initial-after-align","drop-initial-before-adjust","drop-initial-before-align","drop-initial-size","drop-initial-value","elevation","empty-cells","fit","fit-position","flex","flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","flex-wrap","float","float-offset","font","font-feature-settings","font-family","font-kerning","font-language-override","font-size","font-size-adjust","font-stretch","font-style","font-synthesis","font-variant","font-variant-alternates","font-variant-caps","font-variant-east-asian","font-variant-ligatures","font-variant-numeric","font-variant-position","font-weight","grid-cell","grid-column","grid-column-align","grid-column-sizing","grid-column-span","grid-columns","grid-flow","grid-row","grid-row-align","grid-row-sizing","grid-row-span","grid-rows","grid-template","hanging-punctuation","height","hyphens","icon","image-orientation","image-rendering","image-resolution","inline-box-align","justify-content","left","letter-spacing","line-break","line-height","line-stacking","line-stacking-ruby","line-stacking-shift","line-stacking-strategy","list-style","list-style-image","list-style-position","list-style-type","margin","margin-bottom","margin-left","margin-right","margin-top","marker-offset","marks","marquee-direction","marquee-loop","marquee-play-count","marquee-speed","marquee-style","max-height","max-width","min-height","min-width","move-to","nav-down","nav-index","nav-left","nav-right","nav-up","opacity","order","orphans","outline","outline-color","outline-offset","outline-style","outline-width","overflow","overflow-style","overflow-wrap","overflow-x","overflow-y","padding","padding-bottom","padding-left","padding-right","padding-top","page","page-break-after","page-break-before","page-break-inside","page-policy","pause","pause-after","pause-before","perspective","perspective-origin","pitch","pitch-range","play-during","position","presentation-level","punctuation-trim","quotes","rendering-intent","resize","rest","rest-after","rest-before","richness","right","rotation","rotation-point","ruby-align","ruby-overhang","ruby-position","ruby-span","size","speak","speak-as","speak-header","speak-numeral","speak-punctuation","speech-rate","stress","string-set","tab-size","table-layout","target","target-name","target-new","target-position","text-align","text-align-last","text-decoration","text-decoration-color","text-decoration-line","text-decoration-skip","text-decoration-style","text-emphasis","text-emphasis-color","text-emphasis-position","text-emphasis-style","text-height","text-indent","text-justify","text-outline","text-shadow","text-space-collapse","text-transform","text-underline-position","text-wrap","top","transform","transform-origin","transform-style","transition","transition-delay","transition-duration","transition-property","transition-timing-function","unicode-bidi","vertical-align","visibility","voice-balance","voice-duration","voice-family","voice-pitch","voice-range","voice-rate","voice-stress","voice-volume","volume","white-space","widows","width","word-break","word-spacing","word-wrap","z-index","clip-path","clip-rule","mask","enable-background","filter","flood-color","flood-opacity","lighting-color","stop-color","stop-opacity","pointer-events","color-interpolation","color-interpolation-filters","color-profile","color-rendering","fill","fill-opacity","fill-rule","image-rendering","marker","marker-end","marker-mid","marker-start","shape-rendering","stroke","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke-width","text-rendering","baseline-shift","dominant-baseline","glyph-orientation-horizontal","glyph-orientation-vertical","kerning","text-anchor","writing-mode"]);var colorKeywords=keySet(["aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgreen","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","green","greenyellow","honeydew","hotpink","indianred","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgray","lightgreen","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","snow","springgreen","steelblue","tan","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen"]);var valueKeywords=keySet(["above","absolute","activeborder","activecaption","afar","after-white-space","ahead","alias","all","all-scroll","alternate","always","amharic","amharic-abegede","antialiased","appworkspace","arabic-indic","armenian","asterisks","auto","avoid","background","backwards","baseline","below","bidi-override","binary","bengali","blink","block","block-axis","bold","bolder","border","border-box","both","bottom","break-all","break-word","button","button-bevel","buttonface","buttonhighlight","buttonshadow","buttontext","cambodian","capitalize","caps-lock-indicator","caption","captiontext","caret","cell","center","checkbox","circle","cjk-earthly-branch","cjk-heavenly-stem","cjk-ideographic","clear","clip","close-quote","col-resize","collapse","compact","condensed","contain","content","content-box","context-menu","continuous","copy","cover","crop","cross","crosshair","currentcolor","cursive","dashed","decimal","decimal-leading-zero","default","default-button","destination-atop","destination-in","destination-out","destination-over","devanagari","disc","discard","document","dot-dash","dot-dot-dash","dotted","double","down","e-resize","ease","ease-in","ease-in-out","ease-out","element","ellipsis","embed","end","ethiopic","ethiopic-abegede","ethiopic-abegede-am-et","ethiopic-abegede-gez","ethiopic-abegede-ti-er","ethiopic-abegede-ti-et","ethiopic-halehame-aa-er","ethiopic-halehame-aa-et","ethiopic-halehame-am-et","ethiopic-halehame-gez","ethiopic-halehame-om-et","ethiopic-halehame-sid-et","ethiopic-halehame-so-et","ethiopic-halehame-ti-er","ethiopic-halehame-ti-et","ethiopic-halehame-tig","ew-resize","expanded","extra-condensed","extra-expanded","fantasy","fast","fill","fixed","flat","footnotes","forwards","from","geometricPrecision","georgian","graytext","groove","gujarati","gurmukhi","hand","hangul","hangul-consonant","hebrew","help","hidden","hide","higher","highlight","highlighttext","hiragana","hiragana-iroha","horizontal","hsl","hsla","icon","ignore","inactiveborder","inactivecaption","inactivecaptiontext","infinite","infobackground","infotext","inherit","initial","inline","inline-axis","inline-block","inline-table","inset","inside","intrinsic","invert","italic","justify","kannada","katakana","katakana-iroha","khmer","landscape","lao","large","larger","left","level","lighter","line-through","linear","lines","list-item","listbox","listitem","local","logical","loud","lower","lower-alpha","lower-armenian","lower-greek","lower-hexadecimal","lower-latin","lower-norwegian","lower-roman","lowercase","ltr","malayalam","match","media-controls-background","media-current-time-display","media-fullscreen-button","media-mute-button","media-play-button","media-return-to-realtime-button","media-rewind-button","media-seek-back-button","media-seek-forward-button","media-slider","media-sliderthumb","media-time-remaining-display","media-volume-slider","media-volume-slider-container","media-volume-sliderthumb","medium","menu","menulist","menulist-button","menulist-text","menulist-textfield","menutext","message-box","middle","min-intrinsic","mix","mongolian","monospace","move","multiple","myanmar","n-resize","narrower","ne-resize","nesw-resize","no-close-quote","no-drop","no-open-quote","no-repeat","none","normal","not-allowed","nowrap","ns-resize","nw-resize","nwse-resize","oblique","octal","open-quote","optimizeLegibility","optimizeSpeed","oriya","oromo","outset","outside","overlay","overline","padding","padding-box","painted","paused","persian","plus-darker","plus-lighter","pointer","portrait","pre","pre-line","pre-wrap","preserve-3d","progress","push-button","radio","read-only","read-write","read-write-plaintext-only","relative","repeat","repeat-x","repeat-y","reset","reverse","rgb","rgba","ridge","right","round","row-resize","rtl","run-in","running","s-resize","sans-serif","scroll","scrollbar","se-resize","searchfield","searchfield-cancel-button","searchfield-decoration","searchfield-results-button","searchfield-results-decoration","semi-condensed","semi-expanded","separate","serif","show","sidama","single","skip-white-space","slide","slider-horizontal","slider-vertical","sliderthumb-horizontal","sliderthumb-vertical","slow","small","small-caps","small-caption","smaller","solid","somali","source-atop","source-in","source-out","source-over","space","square","square-button","start","static","status-bar","stretch","stroke","sub","subpixel-antialiased","super","sw-resize","table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row","table-row-group","telugu","text","text-bottom","text-top","textarea","textfield","thai","thick","thin","threeddarkshadow","threedface","threedhighlight","threedlightshadow","threedshadow","tibetan","tigre","tigrinya-er","tigrinya-er-abegede","tigrinya-et","tigrinya-et-abegede","to","top","transparent","ultra-condensed","ultra-expanded","underline","up","upper-alpha","upper-armenian","upper-greek","upper-hexadecimal","upper-latin","upper-norwegian","upper-roman","uppercase","urdu","url","vertical","vertical-text","visible","visibleFill","visiblePainted","visibleStroke","visual","w-resize","wait","wave","wider","window","windowframe","windowtext","x-large","x-small","xor","xx-large","xx-small"]);function tokenCComment(stream,state){var maybeEnd=false,ch;while((ch=stream.next())!=null){if(maybeEnd&&ch=="/"){state.tokenize=null;break;}
|
| +maybeEnd=(ch=="*");}
|
| +return["comment","comment"];}
|
| +CodeMirror.defineMIME("text/css",{atMediaTypes:atMediaTypes,atMediaFeatures:atMediaFeatures,propertyKeywords:propertyKeywords,colorKeywords:colorKeywords,valueKeywords:valueKeywords,hooks:{"<":function(stream,state){function tokenSGMLComment(stream,state){var dashes=0,ch;while((ch=stream.next())!=null){if(dashes>=2&&ch==">"){state.tokenize=null;break;}
|
| +dashes=(ch=="-")?dashes+1:0;}
|
| +return["comment","comment"];}
|
| +if(stream.eat("!")){state.tokenize=tokenSGMLComment;return tokenSGMLComment(stream,state);}},"/":function(stream,state){if(stream.eat("*")){state.tokenize=tokenCComment;return tokenCComment(stream,state);}
|
| +return false;}},name:"css-base"});CodeMirror.defineMIME("text/x-scss",{atMediaTypes:atMediaTypes,atMediaFeatures:atMediaFeatures,propertyKeywords:propertyKeywords,colorKeywords:colorKeywords,valueKeywords:valueKeywords,allowNested:true,hooks:{"$":function(stream){stream.match(/^[\w-]+/);if(stream.peek()==":"){return["variable","variable-definition"];}
|
| +return["variable","variable"];},"/":function(stream,state){if(stream.eat("/")){stream.skipToEnd();return["comment","comment"];}else if(stream.eat("*")){state.tokenize=tokenCComment;return tokenCComment(stream,state);}else{return["operator","operator"];}},"#":function(stream){if(stream.eat("{")){return["operator","interpolation"];}else{stream.eatWhile(/[\w\\\-]/);return["atom","hash"];}}},name:"css-base"});})();;CodeMirror.defineMode("javascript",function(config,parserConfig){var indentUnit=config.indentUnit;var jsonMode=parserConfig.json;var isTS=parserConfig.typescript;var keywords=function(){function kw(type){return{type:type,style:"keyword"};}
|
| +var A=kw("keyword a"),B=kw("keyword b"),C=kw("keyword c");var operator=kw("operator"),atom={type:"atom",style:"atom"};var jsKeywords={"if":kw("if"),"while":A,"with":A,"else":B,"do":B,"try":B,"finally":B,"return":C,"break":C,"continue":C,"new":C,"delete":C,"throw":C,"var":kw("var"),"const":kw("var"),"let":kw("var"),"function":kw("function"),"catch":kw("catch"),"for":kw("for"),"switch":kw("switch"),"case":kw("case"),"default":kw("default"),"in":operator,"typeof":operator,"instanceof":operator,"true":atom,"false":atom,"null":atom,"undefined":atom,"NaN":atom,"Infinity":atom,"this":kw("this")};if(isTS){var type={type:"variable",style:"variable-3"};var tsKeywords={"interface":kw("interface"),"class":kw("class"),"extends":kw("extends"),"constructor":kw("constructor"),"public":kw("public"),"private":kw("private"),"protected":kw("protected"),"static":kw("static"),"super":kw("super"),"string":type,"number":type,"bool":type,"any":type};for(var attr in tsKeywords){jsKeywords[attr]=tsKeywords[attr];}}
|
| +return jsKeywords;}();var isOperatorChar=/[+\-*&%=<>!?|~^]/;function chain(stream,state,f){state.tokenize=f;return f(stream,state);}
|
| +function nextUntilUnescaped(stream,end){var escaped=false,next;while((next=stream.next())!=null){if(next==end&&!escaped)
|
| +return false;escaped=!escaped&&next=="\\";}
|
| +return escaped;}
|
| +var type,content;function ret(tp,style,cont){type=tp;content=cont;return style;}
|
| +function jsTokenBase(stream,state){var ch=stream.next();if(ch=='"'||ch=="'")
|
| +return chain(stream,state,jsTokenString(ch));else if(/[\[\]{}\(\),;\:\.]/.test(ch))
|
| +return ret(ch);else if(ch=="0"&&stream.eat(/x/i)){stream.eatWhile(/[\da-f]/i);return ret("number","number");}
|
| +else if(/\d/.test(ch)||ch=="-"&&stream.eat(/\d/)){stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);return ret("number","number");}
|
| +else if(ch=="/"){if(stream.eat("*")){return chain(stream,state,jsTokenComment);}
|
| +else if(stream.eat("/")){stream.skipToEnd();return ret("comment","comment");}
|
| +else if(state.lastType=="operator"||state.lastType=="keyword c"||/^[\[{}\(,;:]$/.test(state.lastType)){nextUntilUnescaped(stream,"/");stream.eatWhile(/[gimy]/);return ret("regexp","string-2");}
|
| +else{stream.eatWhile(isOperatorChar);return ret("operator",null,stream.current());}}
|
| +else if(ch=="#"){stream.skipToEnd();return ret("error","error");}
|
| +else if(isOperatorChar.test(ch)){stream.eatWhile(isOperatorChar);return ret("operator",null,stream.current());}
|
| +else{stream.eatWhile(/[\w\$_]/);var word=stream.current(),known=keywords.propertyIsEnumerable(word)&&keywords[word];return(known&&state.lastType!=".")?ret(known.type,known.style,word):ret("variable","variable",word);}}
|
| +function jsTokenString(quote){return function(stream,state){if(!nextUntilUnescaped(stream,quote))
|
| +state.tokenize=jsTokenBase;return ret("string","string");};}
|
| +function jsTokenComment(stream,state){var maybeEnd=false,ch;while(ch=stream.next()){if(ch=="/"&&maybeEnd){state.tokenize=jsTokenBase;break;}
|
| +maybeEnd=(ch=="*");}
|
| +return ret("comment","comment");}
|
| +var atomicTypes={"atom":true,"number":true,"variable":true,"string":true,"regexp":true,"this":true};function JSLexical(indented,column,type,align,prev,info){this.indented=indented;this.column=column;this.type=type;this.prev=prev;this.info=info;if(align!=null)this.align=align;}
|
| +function inScope(state,varname){for(var v=state.localVars;v;v=v.next)
|
| +if(v.name==varname)return true;}
|
| +function parseJS(state,style,type,content,stream){var cc=state.cc;cx.state=state;cx.stream=stream;cx.marked=null,cx.cc=cc;if(!state.lexical.hasOwnProperty("align"))
|
| +state.lexical.align=true;while(true){var combinator=cc.length?cc.pop():jsonMode?expression:statement;if(combinator(type,content)){while(cc.length&&cc[cc.length-1].lex)
|
| +cc.pop()();if(cx.marked)return cx.marked;if(type=="variable"&&inScope(state,content))return"variable-2";return style;}}}
|
| +var cx={state:null,column:null,marked:null,cc:null};function pass(){for(var i=arguments.length-1;i>=0;i--)cx.cc.push(arguments[i]);}
|
| +function cont(){pass.apply(null,arguments);return true;}
|
| +function register(varname){function inList(list){for(var v=list;v;v=v.next)
|
| +if(v.name==varname)return true;return false;}
|
| +var state=cx.state;if(state.context){cx.marked="def";if(inList(state.localVars))return;state.localVars={name:varname,next:state.localVars};}else{if(inList(state.globalVars))return;state.globalVars={name:varname,next:state.globalVars};}}
|
| +var defaultVars={name:"this",next:{name:"arguments"}};function pushcontext(){cx.state.context={prev:cx.state.context,vars:cx.state.localVars};cx.state.localVars=defaultVars;}
|
| +function popcontext(){cx.state.localVars=cx.state.context.vars;cx.state.context=cx.state.context.prev;}
|
| +function pushlex(type,info){var result=function(){var state=cx.state;state.lexical=new JSLexical(state.indented,cx.stream.column(),type,null,state.lexical,info);};result.lex=true;return result;}
|
| +function poplex(){var state=cx.state;if(state.lexical.prev){if(state.lexical.type==")")
|
| +state.indented=state.lexical.indented;state.lexical=state.lexical.prev;}}
|
| +poplex.lex=true;function expect(wanted){return function(type){if(type==wanted)return cont();else if(wanted==";")return pass();else return cont(arguments.callee);};}
|
| +function statement(type){if(type=="var")return cont(pushlex("vardef"),vardef1,expect(";"),poplex);if(type=="keyword a")return cont(pushlex("form"),expression,statement,poplex);if(type=="keyword b")return cont(pushlex("form"),statement,poplex);if(type=="{")return cont(pushlex("}"),block,poplex);if(type==";")return cont();if(type=="if")return cont(pushlex("form"),expression,statement,poplex,maybeelse(cx.state.indented));if(type=="function")return cont(functiondef);if(type=="for")return cont(pushlex("form"),expect("("),pushlex(")"),forspec1,expect(")"),poplex,statement,poplex);if(type=="variable")return cont(pushlex("stat"),maybelabel);if(type=="switch")return cont(pushlex("form"),expression,pushlex("}","switch"),expect("{"),block,poplex,poplex);if(type=="case")return cont(expression,expect(":"));if(type=="default")return cont(expect(":"));if(type=="catch")return cont(pushlex("form"),pushcontext,expect("("),funarg,expect(")"),statement,poplex,popcontext);return pass(pushlex("stat"),expression,expect(";"),poplex);}
|
| +function expression(type){return expressionInner(type,maybeoperatorComma);}
|
| +function expressionNoComma(type){return expressionInner(type,maybeoperatorNoComma);}
|
| +function expressionInner(type,maybeop){if(atomicTypes.hasOwnProperty(type))return cont(maybeop);if(type=="function")return cont(functiondef);if(type=="keyword c")return cont(maybeexpression);if(type=="(")return cont(pushlex(")"),maybeexpression,expect(")"),poplex,maybeop);if(type=="operator")return cont(expression);if(type=="[")return cont(pushlex("]"),commasep(expressionNoComma,"]"),poplex,maybeop);if(type=="{")return cont(pushlex("}"),commasep(objprop,"}"),poplex,maybeop);return cont();}
|
| +function maybeexpression(type){if(type.match(/[;\}\)\],]/))return pass();return pass(expression);}
|
| +function maybeoperatorComma(type,value){if(type==",")return pass();return maybeoperatorNoComma(type,value,maybeoperatorComma);}
|
| +function maybeoperatorNoComma(type,value,me){if(!me)me=maybeoperatorNoComma;if(type=="operator"){if(/\+\+|--/.test(value))return cont(me);if(value=="?")return cont(expression,expect(":"),expression);return cont(expression);}
|
| +if(type==";")return;if(type=="(")return cont(pushlex(")","call"),commasep(expressionNoComma,")"),poplex,me);if(type==".")return cont(property,me);if(type=="[")return cont(pushlex("]"),expression,expect("]"),poplex,me);}
|
| +function maybelabel(type){if(type==":")return cont(poplex,statement);return pass(maybeoperatorComma,expect(";"),poplex);}
|
| +function property(type){if(type=="variable"){cx.marked="property";return cont();}}
|
| +function objprop(type,value){if(type=="variable"){cx.marked="property";if(value=="get"||value=="set")return cont(getterSetter);}else if(type=="number"||type=="string"){cx.marked=type+" property";}
|
| +if(atomicTypes.hasOwnProperty(type))return cont(expect(":"),expressionNoComma);}
|
| +function getterSetter(type){if(type==":")return cont(expression);if(type!="variable")return cont(expect(":"),expression);cx.marked="property";return cont(functiondef);}
|
| +function commasep(what,end){function proceed(type){if(type==","){var lex=cx.state.lexical;if(lex.info=="call")lex.pos=(lex.pos||0)+1;return cont(what,proceed);}
|
| +if(type==end)return cont();return cont(expect(end));}
|
| +return function(type){if(type==end)return cont();else return pass(what,proceed);};}
|
| +function block(type){if(type=="}")return cont();return pass(statement,block);}
|
| +function maybetype(type){if(type==":")return cont(typedef);return pass();}
|
| +function typedef(type){if(type=="variable"){cx.marked="variable-3";return cont();}
|
| +return pass();}
|
| +function vardef1(type,value){if(type=="variable"){register(value);return isTS?cont(maybetype,vardef2):cont(vardef2);}
|
| +return pass();}
|
| +function vardef2(type,value){if(value=="=")return cont(expressionNoComma,vardef2);if(type==",")return cont(vardef1);}
|
| +function maybeelse(indent){return function(type,value){if(type=="keyword b"&&value=="else"){cx.state.lexical=new JSLexical(indent,0,"form",null,cx.state.lexical);return cont(statement,poplex);}
|
| +return pass();};}
|
| +function forspec1(type){if(type=="var")return cont(vardef1,expect(";"),forspec2);if(type==";")return cont(forspec2);if(type=="variable")return cont(formaybein);return pass(expression,expect(";"),forspec2);}
|
| +function formaybein(_type,value){if(value=="in")return cont(expression);return cont(maybeoperatorComma,forspec2);}
|
| +function forspec2(type,value){if(type==";")return cont(forspec3);if(value=="in")return cont(expression);return pass(expression,expect(";"),forspec3);}
|
| +function forspec3(type){if(type!=")")cont(expression);}
|
| +function functiondef(type,value){if(type=="variable"){register(value);return cont(functiondef);}
|
| +if(type=="(")return cont(pushlex(")"),pushcontext,commasep(funarg,")"),poplex,statement,popcontext);}
|
| +function funarg(type,value){if(type=="variable"){register(value);return isTS?cont(maybetype):cont();}}
|
| +return{startState:function(basecolumn){return{tokenize:jsTokenBase,lastType:null,cc:[],lexical:new JSLexical((basecolumn||0)-indentUnit,0,"block",false),localVars:parserConfig.localVars,globalVars:parserConfig.globalVars,context:parserConfig.localVars&&{vars:parserConfig.localVars},indented:0};},token:function(stream,state){if(stream.sol()){if(!state.lexical.hasOwnProperty("align"))
|
| +state.lexical.align=false;state.indented=stream.indentation();}
|
| +if(state.tokenize!=jsTokenComment&&stream.eatSpace())return null;var style=state.tokenize(stream,state);if(type=="comment")return style;state.lastType=type=="operator"&&(content=="++"||content=="--")?"incdec":type;return parseJS(state,style,type,content,stream);},indent:function(state,textAfter){if(state.tokenize==jsTokenComment)return CodeMirror.Pass;if(state.tokenize!=jsTokenBase)return 0;var firstChar=textAfter&&textAfter.charAt(0),lexical=state.lexical;if(lexical.type=="stat"&&firstChar=="}")lexical=lexical.prev;var type=lexical.type,closing=firstChar==type;if(parserConfig.statementIndent!=null){if(type==")"&&lexical.prev&&lexical.prev.type=="stat")lexical=lexical.prev;if(lexical.type=="stat")return lexical.indented+parserConfig.statementIndent;}
|
| +if(type=="vardef")return lexical.indented+(state.lastType=="operator"||state.lastType==","?4:0);else if(type=="form"&&firstChar=="{")return lexical.indented;else if(type=="form")return lexical.indented+indentUnit;else if(type=="stat")
|
| +return lexical.indented+(state.lastType=="operator"||state.lastType==","?indentUnit:0);else if(lexical.info=="switch"&&!closing)
|
| +return lexical.indented+(/^(?:case|default)\b/.test(textAfter)?indentUnit:2*indentUnit);else if(lexical.align)return lexical.column+(closing?0:1);else return lexical.indented+(closing?0:indentUnit);},electricChars:":{}",blockCommentStart:jsonMode?null:"/*",blockCommentEnd:jsonMode?null:"*/",lineComment:jsonMode?null:"//",jsonMode:jsonMode};});CodeMirror.defineMIME("text/javascript","javascript");CodeMirror.defineMIME("text/ecmascript","javascript");CodeMirror.defineMIME("application/javascript","javascript");CodeMirror.defineMIME("application/ecmascript","javascript");CodeMirror.defineMIME("application/json",{name:"javascript",json:true});CodeMirror.defineMIME("application/x-json",{name:"javascript",json:true});CodeMirror.defineMIME("text/typescript",{name:"javascript",typescript:true});CodeMirror.defineMIME("application/typescript",{name:"javascript",typescript:true});;CodeMirror.defineMode("xml",function(config,parserConfig){var indentUnit=config.indentUnit;var multilineTagIndentFactor=parserConfig.multilineTagIndentFactor||1;var multilineTagIndentPastTag=parserConfig.multilineTagIndentPastTag||true;var Kludges=parserConfig.htmlMode?{autoSelfClosers:{'area':true,'base':true,'br':true,'col':true,'command':true,'embed':true,'frame':true,'hr':true,'img':true,'input':true,'keygen':true,'link':true,'meta':true,'param':true,'source':true,'track':true,'wbr':true},implicitlyClosed:{'dd':true,'li':true,'optgroup':true,'option':true,'p':true,'rp':true,'rt':true,'tbody':true,'td':true,'tfoot':true,'th':true,'tr':true},contextGrabbers:{'dd':{'dd':true,'dt':true},'dt':{'dd':true,'dt':true},'li':{'li':true},'option':{'option':true,'optgroup':true},'optgroup':{'optgroup':true},'p':{'address':true,'article':true,'aside':true,'blockquote':true,'dir':true,'div':true,'dl':true,'fieldset':true,'footer':true,'form':true,'h1':true,'h2':true,'h3':true,'h4':true,'h5':true,'h6':true,'header':true,'hgroup':true,'hr':true,'menu':true,'nav':true,'ol':true,'p':true,'pre':true,'section':true,'table':true,'ul':true},'rp':{'rp':true,'rt':true},'rt':{'rp':true,'rt':true},'tbody':{'tbody':true,'tfoot':true},'td':{'td':true,'th':true},'tfoot':{'tbody':true},'th':{'td':true,'th':true},'thead':{'tbody':true,'tfoot':true},'tr':{'tr':true}},doNotIndent:{"pre":true},allowUnquoted:true,allowMissing:true}:{autoSelfClosers:{},implicitlyClosed:{},contextGrabbers:{},doNotIndent:{},allowUnquoted:false,allowMissing:false};var alignCDATA=parserConfig.alignCDATA;var tagName,type;function inText(stream,state){function chain(parser){state.tokenize=parser;return parser(stream,state);}
|
| +var ch=stream.next();if(ch=="<"){if(stream.eat("!")){if(stream.eat("[")){if(stream.match("CDATA["))return chain(inBlock("atom","]]>"));else return null;}else if(stream.match("--")){return chain(inBlock("comment","-->"));}else if(stream.match("DOCTYPE",true,true)){stream.eatWhile(/[\w\._\-]/);return chain(doctype(1));}else{return null;}}else if(stream.eat("?")){stream.eatWhile(/[\w\._\-]/);state.tokenize=inBlock("meta","?>");return"meta";}else{var isClose=stream.eat("/");tagName="";var c;while((c=stream.eat(/[^\s\u00a0=<>\"\'\/?]/)))tagName+=c;if(!tagName)return"error";type=isClose?"closeTag":"openTag";state.tokenize=inTag;return"tag";}}else if(ch=="&"){var ok;if(stream.eat("#")){if(stream.eat("x")){ok=stream.eatWhile(/[a-fA-F\d]/)&&stream.eat(";");}else{ok=stream.eatWhile(/[\d]/)&&stream.eat(";");}}else{ok=stream.eatWhile(/[\w\.\-:]/)&&stream.eat(";");}
|
| +return ok?"atom":"error";}else{stream.eatWhile(/[^&<]/);return null;}}
|
| +function inTag(stream,state){var ch=stream.next();if(ch==">"||(ch=="/"&&stream.eat(">"))){state.tokenize=inText;type=ch==">"?"endTag":"selfcloseTag";return"tag";}else if(ch=="="){type="equals";return null;}else if(ch=="<"){return"error";}else if(/[\'\"]/.test(ch)){state.tokenize=inAttribute(ch);state.stringStartCol=stream.column();return state.tokenize(stream,state);}else{stream.eatWhile(/[^\s\u00a0=<>\"\']/);return"word";}}
|
| +function inAttribute(quote){var closure=function(stream,state){while(!stream.eol()){if(stream.next()==quote){state.tokenize=inTag;break;}}
|
| +return"string";};closure.isInAttribute=true;return closure;}
|
| +function inBlock(style,terminator){return function(stream,state){while(!stream.eol()){if(stream.match(terminator)){state.tokenize=inText;break;}
|
| +stream.next();}
|
| +return style;};}
|
| +function doctype(depth){return function(stream,state){var ch;while((ch=stream.next())!=null){if(ch=="<"){state.tokenize=doctype(depth+1);return state.tokenize(stream,state);}else if(ch==">"){if(depth==1){state.tokenize=inText;break;}else{state.tokenize=doctype(depth-1);return state.tokenize(stream,state);}}}
|
| +return"meta";};}
|
| +var curState,curStream,setStyle;function pass(){for(var i=arguments.length-1;i>=0;i--)curState.cc.push(arguments[i]);}
|
| +function cont(){pass.apply(null,arguments);return true;}
|
| +function pushContext(tagName,startOfLine){var noIndent=Kludges.doNotIndent.hasOwnProperty(tagName)||(curState.context&&curState.context.noIndent);curState.context={prev:curState.context,tagName:tagName,indent:curState.indented,startOfLine:startOfLine,noIndent:noIndent};}
|
| +function popContext(){if(curState.context)curState.context=curState.context.prev;}
|
| +function element(type){if(type=="openTag"){curState.tagName=tagName;curState.tagStart=curStream.column();return cont(attributes,endtag(curState.startOfLine));}else if(type=="closeTag"){var err=false;if(curState.context){if(curState.context.tagName!=tagName){if(Kludges.implicitlyClosed.hasOwnProperty(curState.context.tagName.toLowerCase())){popContext();}
|
| +err=!curState.context||curState.context.tagName!=tagName;}}else{err=true;}
|
| +if(err)setStyle="error";return cont(endclosetag(err));}
|
| +return cont();}
|
| +function endtag(startOfLine){return function(type){var tagName=curState.tagName;curState.tagName=curState.tagStart=null;if(type=="selfcloseTag"||(type=="endTag"&&Kludges.autoSelfClosers.hasOwnProperty(tagName.toLowerCase()))){maybePopContext(tagName.toLowerCase());return cont();}
|
| +if(type=="endTag"){maybePopContext(tagName.toLowerCase());pushContext(tagName,startOfLine);return cont();}
|
| +return cont();};}
|
| +function endclosetag(err){return function(type){if(err)setStyle="error";if(type=="endTag"){popContext();return cont();}
|
| +setStyle="error";return cont(arguments.callee);};}
|
| +function maybePopContext(nextTagName){var parentTagName;while(true){if(!curState.context){return;}
|
| +parentTagName=curState.context.tagName.toLowerCase();if(!Kludges.contextGrabbers.hasOwnProperty(parentTagName)||!Kludges.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)){return;}
|
| +popContext();}}
|
| +function attributes(type){if(type=="word"){setStyle="attribute";return cont(attribute,attributes);}
|
| +if(type=="endTag"||type=="selfcloseTag")return pass();setStyle="error";return cont(attributes);}
|
| +function attribute(type){if(type=="equals")return cont(attvalue,attributes);if(!Kludges.allowMissing)setStyle="error";else if(type=="word"){setStyle="attribute";return cont(attribute,attributes);}
|
| +return(type=="endTag"||type=="selfcloseTag")?pass():cont();}
|
| +function attvalue(type){if(type=="string")return cont(attvaluemaybe);if(type=="word"&&Kludges.allowUnquoted){setStyle="string";return cont();}
|
| +setStyle="error";return(type=="endTag"||type=="selfCloseTag")?pass():cont();}
|
| +function attvaluemaybe(type){if(type=="string")return cont(attvaluemaybe);else return pass();}
|
| +return{startState:function(){return{tokenize:inText,cc:[],indented:0,startOfLine:true,tagName:null,tagStart:null,context:null};},token:function(stream,state){if(!state.tagName&&stream.sol()){state.startOfLine=true;state.indented=stream.indentation();}
|
| +if(stream.eatSpace())return null;setStyle=type=tagName=null;var style=state.tokenize(stream,state);state.type=type;if((style||type)&&style!="comment"){curState=state;curStream=stream;while(true){var comb=state.cc.pop()||element;if(comb(type||style))break;}}
|
| +state.startOfLine=false;return setStyle||style;},indent:function(state,textAfter,fullLine){var context=state.context;if(state.tokenize.isInAttribute){return state.stringStartCol+1;}
|
| +if((state.tokenize!=inTag&&state.tokenize!=inText)||context&&context.noIndent)
|
| +return fullLine?fullLine.match(/^(\s*)/)[0].length:0;if(state.tagName){if(multilineTagIndentPastTag)
|
| +return state.tagStart+state.tagName.length+2;else
|
| +return state.tagStart+indentUnit*multilineTagIndentFactor;}
|
| +if(alignCDATA&&/<!\[CDATA\[/.test(textAfter))return 0;if(context&&/^<\//.test(textAfter))
|
| +context=context.prev;while(context&&!context.startOfLine)
|
| +context=context.prev;if(context)return context.indent+indentUnit;else return 0;},electricChars:"/",blockCommentStart:"<!--",blockCommentEnd:"-->",configuration:parserConfig.htmlMode?"html":"xml",helperType:parserConfig.htmlMode?"html":"xml"};});CodeMirror.defineMIME("text/xml","xml");CodeMirror.defineMIME("application/xml","xml");if(!CodeMirror.mimeModes.hasOwnProperty("text/html"))
|
| +CodeMirror.defineMIME("text/html",{name:"xml",htmlMode:true});;CodeMirror.defineMode("htmlmixed",function(config,parserConfig){var htmlMode=CodeMirror.getMode(config,{name:"xml",htmlMode:true});var cssMode=CodeMirror.getMode(config,"css");var scriptTypes=[],scriptTypesConf=parserConfig&&parserConfig.scriptTypes;scriptTypes.push({matches:/^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^$/i,mode:CodeMirror.getMode(config,"javascript")});if(scriptTypesConf)for(var i=0;i<scriptTypesConf.length;++i){var conf=scriptTypesConf[i];scriptTypes.push({matches:conf.matches,mode:conf.mode&&CodeMirror.getMode(config,conf.mode)});}
|
| +scriptTypes.push({matches:/./,mode:CodeMirror.getMode(config,"text/plain")});function html(stream,state){var tagName=state.htmlState.tagName;var style=htmlMode.token(stream,state.htmlState);if(tagName=="script"&&/\btag\b/.test(style)&&stream.current()==">"){var scriptType=stream.string.slice(Math.max(0,stream.pos-100),stream.pos).match(/\btype\s*=\s*("[^"]+"|'[^']+'|\S+)[^<]*$/i);scriptType=scriptType?scriptType[1]:"";if(scriptType&&/[\"\']/.test(scriptType.charAt(0)))scriptType=scriptType.slice(1,scriptType.length-1);for(var i=0;i<scriptTypes.length;++i){var tp=scriptTypes[i];if(typeof tp.matches=="string"?scriptType==tp.matches:tp.matches.test(scriptType)){if(tp.mode){state.token=script;state.localMode=tp.mode;state.localState=tp.mode.startState&&tp.mode.startState(htmlMode.indent(state.htmlState,""));}
|
| +break;}}}else if(tagName=="style"&&/\btag\b/.test(style)&&stream.current()==">"){state.token=css;state.localMode=cssMode;state.localState=cssMode.startState(htmlMode.indent(state.htmlState,""));}
|
| +return style;}
|
| +function maybeBackup(stream,pat,style){var cur=stream.current();var close=cur.search(pat),m;if(close>-1)stream.backUp(cur.length-close);else if(m=cur.match(/<\/?$/)){stream.backUp(cur.length);if(!stream.match(pat,false))stream.match(cur[0]);}
|
| +return style;}
|
| +function script(stream,state){if(stream.match(/^<\/\s*script\s*>/i,false)){state.token=html;state.localState=state.localMode=null;return html(stream,state);}
|
| +return maybeBackup(stream,/<\/\s*script\s*>/,state.localMode.token(stream,state.localState));}
|
| +function css(stream,state){if(stream.match(/^<\/\s*style\s*>/i,false)){state.token=html;state.localState=state.localMode=null;return html(stream,state);}
|
| +return maybeBackup(stream,/<\/\s*style\s*>/,cssMode.token(stream,state.localState));}
|
| +return{startState:function(){var state=htmlMode.startState();return{token:html,localMode:null,localState:null,htmlState:state};},copyState:function(state){if(state.localState)
|
| +var local=CodeMirror.copyState(state.localMode,state.localState);return{token:state.token,localMode:state.localMode,localState:local,htmlState:CodeMirror.copyState(htmlMode,state.htmlState)};},token:function(stream,state){return state.token(stream,state);},indent:function(state,textAfter){if(!state.localMode||/^\s*<\//.test(textAfter))
|
| +return htmlMode.indent(state.htmlState,textAfter);else if(state.localMode.indent)
|
| +return state.localMode.indent(state.localState,textAfter);else
|
| +return CodeMirror.Pass;},electricChars:"/{}:",innerMode:function(state){return{state:state.localState||state.htmlState,mode:state.localMode||htmlMode};}};},"xml","javascript","css");CodeMirror.defineMIME("text/html","htmlmixed");;(function(){var ie_lt8=/MSIE \d/.test(navigator.userAgent)&&(document.documentMode==null||document.documentMode<8);var Pos=CodeMirror.Pos;var matching={"(":")>",")":"(<","[":"]>","]":"[<","{":"}>","}":"{<"};function findMatchingBracket(cm,where,strict){var state=cm.state.matchBrackets;var maxScanLen=(state&&state.maxScanLineLength)||10000;var cur=where||cm.getCursor(),line=cm.getLineHandle(cur.line),pos=cur.ch-1;var match=(pos>=0&&matching[line.text.charAt(pos)])||matching[line.text.charAt(++pos)];if(!match)return null;var forward=match.charAt(1)==">",d=forward?1:-1;if(strict&&forward!=(pos==cur.ch))return null;var style=cm.getTokenTypeAt(Pos(cur.line,pos+1));var stack=[line.text.charAt(pos)],re=/[(){}[\]]/;function scan(line,lineNo,start){if(!line.text)return;var pos=forward?0:line.text.length-1,end=forward?line.text.length:-1;if(line.text.length>maxScanLen)return null;if(start!=null)pos=start+d;for(;pos!=end;pos+=d){var ch=line.text.charAt(pos);if(re.test(ch)&&cm.getTokenTypeAt(Pos(lineNo,pos+1))==style){var match=matching[ch];if(match.charAt(1)==">"==forward)stack.push(ch);else if(stack.pop()!=match.charAt(0))return{pos:pos,match:false};else if(!stack.length)return{pos:pos,match:true};}}}
|
| +for(var i=cur.line,found,e=forward?Math.min(i+100,cm.lineCount()):Math.max(-1,i-100);i!=e;i+=d){if(i==cur.line)found=scan(line,i,pos);else found=scan(cm.getLineHandle(i),i);if(found)break;}
|
| +return{from:Pos(cur.line,pos),to:found&&Pos(i,found.pos),match:found&&found.match,forward:forward};}
|
| +function matchBrackets(cm,autoclear){var maxHighlightLen=cm.state.matchBrackets.maxHighlightLineLength||1000;var found=findMatchingBracket(cm);if(!found||cm.getLine(found.from.line).length>maxHighlightLen||found.to&&cm.getLine(found.to.line).length>maxHighlightLen)
|
| +return;var style=found.match?"CodeMirror-matchingbracket":"CodeMirror-nonmatchingbracket";var one=cm.markText(found.from,Pos(found.from.line,found.from.ch+1),{className:style});var two=found.to&&cm.markText(found.to,Pos(found.to.line,found.to.ch+1),{className:style});if(ie_lt8&&cm.state.focused)cm.display.input.focus();var clear=function(){cm.operation(function(){one.clear();two&&two.clear();});};if(autoclear)setTimeout(clear,800);else return clear;}
|
| +var currentlyHighlighted=null;function doMatchBrackets(cm){cm.operation(function(){if(currentlyHighlighted){currentlyHighlighted();currentlyHighlighted=null;}
|
| +if(!cm.somethingSelected())currentlyHighlighted=matchBrackets(cm,false);});}
|
| +CodeMirror.defineOption("matchBrackets",false,function(cm,val,old){if(old&&old!=CodeMirror.Init)
|
| +cm.off("cursorActivity",doMatchBrackets);if(val){cm.state.matchBrackets=typeof val=="object"?val:{};cm.on("cursorActivity",doMatchBrackets);}});CodeMirror.defineExtension("matchBrackets",function(){matchBrackets(this,true);});CodeMirror.defineExtension("findMatchingBracket",function(pos,strict){return findMatchingBracket(this,pos,strict);});})();;(function(){var DEFAULT_BRACKETS="()[]{}''\"\"";var DEFAULT_EXPLODE_ON_ENTER="[]{}";var SPACE_CHAR_REGEX=/\s/;CodeMirror.defineOption("autoCloseBrackets",false,function(cm,val,old){if(old!=CodeMirror.Init&&old)
|
| +cm.removeKeyMap("autoCloseBrackets");if(!val)return;var pairs=DEFAULT_BRACKETS,explode=DEFAULT_EXPLODE_ON_ENTER;if(typeof val=="string")pairs=val;else if(typeof val=="object"){if(val.pairs!=null)pairs=val.pairs;if(val.explode!=null)explode=val.explode;}
|
| +var map=buildKeymap(pairs);if(explode)map.Enter=buildExplodeHandler(explode);cm.addKeyMap(map);});function charsAround(cm,pos){var str=cm.getRange(CodeMirror.Pos(pos.line,pos.ch-1),CodeMirror.Pos(pos.line,pos.ch+1));return str.length==2?str:null;}
|
| +function buildKeymap(pairs){var map={name:"autoCloseBrackets",Backspace:function(cm){if(cm.somethingSelected())return CodeMirror.Pass;var cur=cm.getCursor(),around=charsAround(cm,cur);if(around&&pairs.indexOf(around)%2==0)
|
| +cm.replaceRange("",CodeMirror.Pos(cur.line,cur.ch-1),CodeMirror.Pos(cur.line,cur.ch+1));else
|
| +return CodeMirror.Pass;}};var closingBrackets="";for(var i=0;i<pairs.length;i+=2)(function(left,right){if(left!=right)closingBrackets+=right;function surround(cm){var selection=cm.getSelection();cm.replaceSelection(left+selection+right);}
|
| +function maybeOverwrite(cm){var cur=cm.getCursor(),ahead=cm.getRange(cur,CodeMirror.Pos(cur.line,cur.ch+1));if(ahead!=right||cm.somethingSelected())return CodeMirror.Pass;else cm.execCommand("goCharRight");}
|
| +map["'"+left+"'"]=function(cm){if(left=="'"&&cm.getTokenAt(cm.getCursor()).type=="comment")
|
| +return CodeMirror.Pass;if(cm.somethingSelected())return surround(cm);if(left==right&&maybeOverwrite(cm)!=CodeMirror.Pass)return;var cur=cm.getCursor(),ahead=CodeMirror.Pos(cur.line,cur.ch+1);var line=cm.getLine(cur.line),nextChar=line.charAt(cur.ch),curChar=cur.ch>0?line.charAt(cur.ch-1):"";if(left==right&&CodeMirror.isWordChar(curChar))
|
| +return CodeMirror.Pass;if(line.length==cur.ch||closingBrackets.indexOf(nextChar)>=0||SPACE_CHAR_REGEX.test(nextChar))
|
| +cm.replaceSelection(left+right,{head:ahead,anchor:ahead});else
|
| +return CodeMirror.Pass;};if(left!=right)map["'"+right+"'"]=maybeOverwrite;})(pairs.charAt(i),pairs.charAt(i+1));return map;}
|
| +function buildExplodeHandler(pairs){return function(cm){var cur=cm.getCursor(),around=charsAround(cm,cur);if(!around||pairs.indexOf(around)%2!=0)return CodeMirror.Pass;cm.operation(function(){var newPos=CodeMirror.Pos(cur.line+1,0);cm.replaceSelection("\n\n",{anchor:newPos,head:newPos},"+input");cm.indentLine(cur.line+1,null,true);cm.indentLine(cur.line+2,null,true);});};}})();;(function(){"use strict";CodeMirror.defineOption("styleSelectedText",false,function(cm,val,old){var prev=old&&old!=CodeMirror.Init;if(val&&!prev){cm.state.markedSelection=[];cm.state.markedSelectionStyle=typeof val=="string"?val:"CodeMirror-selectedtext";reset(cm);cm.on("cursorActivity",onCursorActivity);cm.on("change",onChange);}else if(!val&&prev){cm.off("cursorActivity",onCursorActivity);cm.off("change",onChange);clear(cm);cm.state.markedSelection=cm.state.markedSelectionStyle=null;}});function onCursorActivity(cm){cm.operation(function(){update(cm);});}
|
| +function onChange(cm){if(cm.state.markedSelection.length)
|
| +cm.operation(function(){clear(cm);});}
|
| +var CHUNK_SIZE=8;var Pos=CodeMirror.Pos;function cmp(pos1,pos2){return pos1.line-pos2.line||pos1.ch-pos2.ch;}
|
| +function coverRange(cm,from,to,addAt){if(cmp(from,to)==0)return;var array=cm.state.markedSelection;var cls=cm.state.markedSelectionStyle;for(var line=from.line;;){var start=line==from.line?from:Pos(line,0);var endLine=line+CHUNK_SIZE,atEnd=endLine>=to.line;var end=atEnd?to:Pos(endLine,0);var mark=cm.markText(start,end,{className:cls});if(addAt==null)array.push(mark);else array.splice(addAt++,0,mark);if(atEnd)break;line=endLine;}}
|
| +function clear(cm){var array=cm.state.markedSelection;for(var i=0;i<array.length;++i)array[i].clear();array.length=0;}
|
| +function reset(cm){clear(cm);var from=cm.getCursor("start"),to=cm.getCursor("end");coverRange(cm,from,to);}
|
| +function update(cm){var from=cm.getCursor("start"),to=cm.getCursor("end");if(cmp(from,to)==0)return clear(cm);var array=cm.state.markedSelection;if(!array.length)return coverRange(cm,from,to);var coverStart=array[0].find(),coverEnd=array[array.length-1].find();if(!coverStart||!coverEnd||to.line-from.line<CHUNK_SIZE||cmp(from,coverEnd.to)>=0||cmp(to,coverStart.from)<=0)
|
| +return reset(cm);while(cmp(from,coverStart.from)>0){array.shift().clear();coverStart=array[0].find();}
|
| +if(cmp(from,coverStart.from)<0){if(coverStart.to.line-from.line<CHUNK_SIZE){array.shift().clear();coverRange(cm,from,coverStart.to,0);}else{coverRange(cm,from,coverStart.from,0);}}
|
| +while(cmp(to,coverEnd.to)<0){array.pop().clear();coverEnd=array[array.length-1].find();}
|
| +if(cmp(to,coverEnd.to)>0){if(to.line-coverEnd.from.line<CHUNK_SIZE){array.pop().clear();coverRange(cm,coverEnd.from,to);}else{coverRange(cm,coverEnd.to,to);}}}})();;(function(){"use strict";var noOptions={};var nonWS=/[^\s\u00a0]/;var Pos=CodeMirror.Pos;function firstNonWS(str){var found=str.search(nonWS);return found==-1?0:found;}
|
| +CodeMirror.commands.toggleComment=function(cm){var from=cm.getCursor("start"),to=cm.getCursor("end");cm.uncomment(from,to)||cm.lineComment(from,to);};CodeMirror.defineExtension("lineComment",function(from,to,options){if(!options)options=noOptions;var self=this,mode=CodeMirror.innerMode(self.getMode(),self.getTokenAt(from).state).mode;var commentString=options.lineComment||mode.lineComment;if(!commentString){if(options.blockCommentStart||mode.blockCommentStart){options.fullLines=true;self.blockComment(from,to,options);}
|
| +return;}
|
| +var firstLine=self.getLine(from.line);if(firstLine==null)return;var end=Math.min(to.ch!=0||to.line==from.line?to.line+1:to.line,self.lastLine()+1);var pad=options.padding==null?" ":options.padding;var blankLines=options.commentBlankLines;self.operation(function(){if(options.indent){var baseString=firstLine.slice(0,firstNonWS(firstLine));for(var i=from.line;i<end;++i){var line=self.getLine(i),cut=baseString.length;if(!blankLines&&!nonWS.test(line))continue;if(line.slice(0,cut)!=baseString)cut=firstNonWS(line);self.replaceRange(baseString+commentString+pad,Pos(i,0),Pos(i,cut));}}else{for(var i=from.line;i<end;++i){if(blankLines||nonWS.test(self.getLine(i)))
|
| +self.replaceRange(commentString+pad,Pos(i,0));}}});});CodeMirror.defineExtension("blockComment",function(from,to,options){if(!options)options=noOptions;var self=this,mode=CodeMirror.innerMode(self.getMode(),self.getTokenAt(from).state).mode;var startString=options.blockCommentStart||mode.blockCommentStart;var endString=options.blockCommentEnd||mode.blockCommentEnd;if(!startString||!endString){if((options.lineComment||mode.lineComment)&&options.fullLines!=false)
|
| +self.lineComment(from,to,options);return;}
|
| +var end=Math.min(to.line,self.lastLine());if(end!=from.line&&to.ch==0&&nonWS.test(self.getLine(end)))--end;var pad=options.padding==null?" ":options.padding;if(from.line>end)return;self.operation(function(){if(options.fullLines!=false){var lastLineHasText=nonWS.test(self.getLine(end));self.replaceRange(pad+endString,Pos(end));self.replaceRange(startString+pad,Pos(from.line,0));var lead=options.blockCommentLead||mode.blockCommentLead;if(lead!=null)for(var i=from.line+1;i<=end;++i)
|
| +if(i!=end||lastLineHasText)
|
| +self.replaceRange(lead+pad,Pos(i,0));}else{self.replaceRange(endString,to);self.replaceRange(startString,from);}});});CodeMirror.defineExtension("uncomment",function(from,to,options){if(!options)options=noOptions;var self=this,mode=CodeMirror.innerMode(self.getMode(),self.getTokenAt(from).state).mode;var end=Math.min(to.line,self.lastLine()),start=Math.min(from.line,end);var lineString=options.lineComment||mode.lineComment,lines=[];var pad=options.padding==null?" ":options.padding;lineComment:for(;;){if(!lineString)break;for(var i=start;i<=end;++i){var line=self.getLine(i);var found=line.indexOf(lineString);if(found==-1&&(i!=end||i==start)&&nonWS.test(line))break lineComment;if(i!=start&&found>-1&&nonWS.test(line.slice(0,found)))break lineComment;lines.push(line);}
|
| +self.operation(function(){for(var i=start;i<=end;++i){var line=lines[i-start];var pos=line.indexOf(lineString),endPos=pos+lineString.length;if(pos<0)continue;if(line.slice(endPos,endPos+pad.length)==pad)endPos+=pad.length;self.replaceRange("",Pos(i,pos),Pos(i,endPos));}});return true;}
|
| +var startString=options.blockCommentStart||mode.blockCommentStart;var endString=options.blockCommentEnd||mode.blockCommentEnd;if(!startString||!endString)return false;var lead=options.blockCommentLead||mode.blockCommentLead;var startLine=self.getLine(start),endLine=end==start?startLine:self.getLine(end);var open=startLine.indexOf(startString),close=endLine.lastIndexOf(endString);if(close==-1&&start!=end){endLine=self.getLine(--end);close=endLine.lastIndexOf(endString);}
|
| +if(open==-1||close==-1)return false;self.operation(function(){self.replaceRange("",Pos(end,close-(pad&&endLine.slice(close-pad.length,close)==pad?pad.length:0)),Pos(end,close+endString.length));var openEnd=open+startString.length;if(pad&&startLine.slice(openEnd,openEnd+pad.length)==pad)openEnd+=pad.length;self.replaceRange("",Pos(start,open),Pos(start,openEnd));if(lead)for(var i=start+1;i<=end;++i){var line=self.getLine(i),found=line.indexOf(lead);if(found==-1||nonWS.test(line.slice(0,found)))continue;var foundEnd=found+lead.length;if(pad&&line.slice(foundEnd,foundEnd+pad.length)==pad)foundEnd+=pad.length;self.replaceRange("",Pos(i,found),Pos(i,foundEnd));}});return true;});})();;CodeMirror.overlayMode=CodeMirror.overlayParser=function(base,overlay,combine){return{startState:function(){return{base:CodeMirror.startState(base),overlay:CodeMirror.startState(overlay),basePos:0,baseCur:null,overlayPos:0,overlayCur:null};},copyState:function(state){return{base:CodeMirror.copyState(base,state.base),overlay:CodeMirror.copyState(overlay,state.overlay),basePos:state.basePos,baseCur:null,overlayPos:state.overlayPos,overlayCur:null};},token:function(stream,state){if(stream.start==state.basePos){state.baseCur=base.token(stream,state.base);state.basePos=stream.pos;}
|
| +if(stream.start==state.overlayPos){stream.pos=stream.start;state.overlayCur=overlay.token(stream,state.overlay);state.overlayPos=stream.pos;}
|
| +stream.pos=Math.min(state.basePos,state.overlayPos);if(stream.eol())state.basePos=state.overlayPos=0;if(state.overlayCur==null)return state.baseCur;if(state.baseCur!=null&&combine)return state.baseCur+" "+state.overlayCur;else return state.overlayCur;},indent:base.indent&&function(state,textAfter){return base.indent(state.base,textAfter);},electricChars:base.electricChars,innerMode:function(state){return{state:state.base,mode:base};},blankLine:function(state){if(base.blankLine)base.blankLine(state.base);if(overlay.blankLine)overlay.blankLine(state.overlay);}};};;CodeMirror.defineMode("htmlembedded",function(config,parserConfig){var scriptStartRegex=parserConfig.scriptStartRegex||/^<%/i,scriptEndRegex=parserConfig.scriptEndRegex||/^%>/i;var scriptingMode,htmlMixedMode;function htmlDispatch(stream,state){if(stream.match(scriptStartRegex,false)){state.token=scriptingDispatch;return scriptingMode.token(stream,state.scriptState);}
|
| +else
|
| +return htmlMixedMode.token(stream,state.htmlState);}
|
| +function scriptingDispatch(stream,state){if(stream.match(scriptEndRegex,false)){state.token=htmlDispatch;return htmlMixedMode.token(stream,state.htmlState);}
|
| +else
|
| +return scriptingMode.token(stream,state.scriptState);}
|
| +return{startState:function(){scriptingMode=scriptingMode||CodeMirror.getMode(config,parserConfig.scriptingModeSpec);htmlMixedMode=htmlMixedMode||CodeMirror.getMode(config,"htmlmixed");return{token:parserConfig.startOpen?scriptingDispatch:htmlDispatch,htmlState:CodeMirror.startState(htmlMixedMode),scriptState:CodeMirror.startState(scriptingMode)};},token:function(stream,state){return state.token(stream,state);},indent:function(state,textAfter){if(state.token==htmlDispatch)
|
| +return htmlMixedMode.indent(state.htmlState,textAfter);else if(scriptingMode.indent)
|
| +return scriptingMode.indent(state.scriptState,textAfter);},copyState:function(state){return{token:state.token,htmlState:CodeMirror.copyState(htmlMixedMode,state.htmlState),scriptState:CodeMirror.copyState(scriptingMode,state.scriptState)};},electricChars:"/{}:",innerMode:function(state){if(state.token==scriptingDispatch)return{state:state.scriptState,mode:scriptingMode};else return{state:state.htmlState,mode:htmlMixedMode};}};},"htmlmixed");CodeMirror.defineMIME("application/x-ejs",{name:"htmlembedded",scriptingModeSpec:"javascript"});CodeMirror.defineMIME("application/x-aspx",{name:"htmlembedded",scriptingModeSpec:"text/x-csharp"});CodeMirror.defineMIME("application/x-jsp",{name:"htmlembedded",scriptingModeSpec:"text/x-java"});CodeMirror.defineMIME("application/x-erb",{name:"htmlembedded",scriptingModeSpec:"ruby"});;CodeMirror.defineMode("clike",function(config,parserConfig){var indentUnit=config.indentUnit,statementIndentUnit=parserConfig.statementIndentUnit||indentUnit,dontAlignCalls=parserConfig.dontAlignCalls,keywords=parserConfig.keywords||{},builtin=parserConfig.builtin||{},blockKeywords=parserConfig.blockKeywords||{},atoms=parserConfig.atoms||{},hooks=parserConfig.hooks||{},multiLineStrings=parserConfig.multiLineStrings;var isOperatorChar=/[+\-*&%=<>!?|\/]/;var curPunc;function tokenBase(stream,state){var ch=stream.next();if(hooks[ch]){var result=hooks[ch](stream,state);if(result!==false)return result;}
|
| +if(ch=='"'||ch=="'"){state.tokenize=tokenString(ch);return state.tokenize(stream,state);}
|
| +if(/[\[\]{}\(\),;\:\.]/.test(ch)){curPunc=ch;return null;}
|
| +if(/\d/.test(ch)){stream.eatWhile(/[\w\.]/);return"number";}
|
| +if(ch=="/"){if(stream.eat("*")){state.tokenize=tokenComment;return tokenComment(stream,state);}
|
| +if(stream.eat("/")){stream.skipToEnd();return"comment";}}
|
| +if(isOperatorChar.test(ch)){stream.eatWhile(isOperatorChar);return"operator";}
|
| +stream.eatWhile(/[\w\$_]/);var cur=stream.current();if(keywords.propertyIsEnumerable(cur)){if(blockKeywords.propertyIsEnumerable(cur))curPunc="newstatement";return"keyword";}
|
| +if(builtin.propertyIsEnumerable(cur)){if(blockKeywords.propertyIsEnumerable(cur))curPunc="newstatement";return"builtin";}
|
| +if(atoms.propertyIsEnumerable(cur))return"atom";return"variable";}
|
| +function tokenString(quote){return function(stream,state){var escaped=false,next,end=false;while((next=stream.next())!=null){if(next==quote&&!escaped){end=true;break;}
|
| +escaped=!escaped&&next=="\\";}
|
| +if(end||!(escaped||multiLineStrings))
|
| +state.tokenize=null;return"string";};}
|
| +function tokenComment(stream,state){var maybeEnd=false,ch;while(ch=stream.next()){if(ch=="/"&&maybeEnd){state.tokenize=null;break;}
|
| +maybeEnd=(ch=="*");}
|
| +return"comment";}
|
| +function Context(indented,column,type,align,prev){this.indented=indented;this.column=column;this.type=type;this.align=align;this.prev=prev;}
|
| +function pushContext(state,col,type){var indent=state.indented;if(state.context&&state.context.type=="statement")
|
| +indent=state.context.indented;return state.context=new Context(indent,col,type,null,state.context);}
|
| +function popContext(state){var t=state.context.type;if(t==")"||t=="]"||t=="}")
|
| +state.indented=state.context.indented;return state.context=state.context.prev;}
|
| +return{startState:function(basecolumn){return{tokenize:null,context:new Context((basecolumn||0)-indentUnit,0,"top",false),indented:0,startOfLine:true};},token:function(stream,state){var ctx=state.context;if(stream.sol()){if(ctx.align==null)ctx.align=false;state.indented=stream.indentation();state.startOfLine=true;}
|
| +if(stream.eatSpace())return null;curPunc=null;var style=(state.tokenize||tokenBase)(stream,state);if(style=="comment"||style=="meta")return style;if(ctx.align==null)ctx.align=true;if((curPunc==";"||curPunc==":"||curPunc==",")&&ctx.type=="statement")popContext(state);else if(curPunc=="{")pushContext(state,stream.column(),"}");else if(curPunc=="[")pushContext(state,stream.column(),"]");else if(curPunc=="(")pushContext(state,stream.column(),")");else if(curPunc=="}"){while(ctx.type=="statement")ctx=popContext(state);if(ctx.type=="}")ctx=popContext(state);while(ctx.type=="statement")ctx=popContext(state);}
|
| +else if(curPunc==ctx.type)popContext(state);else if(((ctx.type=="}"||ctx.type=="top")&&curPunc!=';')||(ctx.type=="statement"&&curPunc=="newstatement"))
|
| +pushContext(state,stream.column(),"statement");state.startOfLine=false;return style;},indent:function(state,textAfter){if(state.tokenize!=tokenBase&&state.tokenize!=null)return CodeMirror.Pass;var ctx=state.context,firstChar=textAfter&&textAfter.charAt(0);if(ctx.type=="statement"&&firstChar=="}")ctx=ctx.prev;var closing=firstChar==ctx.type;if(ctx.type=="statement")return ctx.indented+(firstChar=="{"?0:statementIndentUnit);else if(ctx.align&&(!dontAlignCalls||ctx.type!=")"))return ctx.column+(closing?0:1);else if(ctx.type==")"&&!closing)return ctx.indented+statementIndentUnit;else return ctx.indented+(closing?0:indentUnit);},electricChars:"{}",blockCommentStart:"/*",blockCommentEnd:"*/",lineComment:"//"};});(function(){function words(str){var obj={},words=str.split(" ");for(var i=0;i<words.length;++i)obj[words[i]]=true;return obj;}
|
| +var cKeywords="auto if break int case long char register continue return default short do sizeof "+"double static else struct entry switch extern typedef float union for unsigned "+"goto while enum void const signed volatile";function cppHook(stream,state){if(!state.startOfLine)return false;for(;;){if(stream.skipTo("\\")){stream.next();if(stream.eol()){state.tokenize=cppHook;break;}}else{stream.skipToEnd();state.tokenize=null;break;}}
|
| +return"meta";}
|
| +function tokenAtString(stream,state){var next;while((next=stream.next())!=null){if(next=='"'&&!stream.eat('"')){state.tokenize=null;break;}}
|
| +return"string";}
|
| +function mimes(ms,mode){for(var i=0;i<ms.length;++i)CodeMirror.defineMIME(ms[i],mode);}
|
| +mimes(["text/x-csrc","text/x-c","text/x-chdr"],{name:"clike",keywords:words(cKeywords),blockKeywords:words("case do else for if switch while struct"),atoms:words("null"),hooks:{"#":cppHook}});mimes(["text/x-c++src","text/x-c++hdr"],{name:"clike",keywords:words(cKeywords+" asm dynamic_cast namespace reinterpret_cast try bool explicit new "+"static_cast typeid catch operator template typename class friend private "+"this using const_cast inline public throw virtual delete mutable protected "+"wchar_t"),blockKeywords:words("catch class do else finally for if struct switch try while"),atoms:words("true false null"),hooks:{"#":cppHook}});CodeMirror.defineMIME("text/x-java",{name:"clike",keywords:words("abstract assert boolean break byte case catch char class const continue default "+"do double else enum extends final finally float for goto if implements import "+"instanceof int interface long native new package private protected public "+"return short static strictfp super switch synchronized this throw throws transient "+"try void volatile while"),blockKeywords:words("catch class do else finally for if switch try while"),atoms:words("true false null"),hooks:{"@":function(stream){stream.eatWhile(/[\w\$_]/);return"meta";}}});CodeMirror.defineMIME("text/x-csharp",{name:"clike",keywords:words("abstract as base break case catch checked class const continue"+" default delegate do else enum event explicit extern finally fixed for"+" foreach goto if implicit in interface internal is lock namespace new"+" operator out override params private protected public readonly ref return sealed"+" sizeof stackalloc static struct switch this throw try typeof unchecked"+" unsafe using virtual void volatile while add alias ascending descending dynamic from get"+" global group into join let orderby partial remove select set value var yield"),blockKeywords:words("catch class do else finally for foreach if struct switch try while"),builtin:words("Boolean Byte Char DateTime DateTimeOffset Decimal Double"+" Guid Int16 Int32 Int64 Object SByte Single String TimeSpan UInt16 UInt32"+" UInt64 bool byte char decimal double short int long object"+" sbyte float string ushort uint ulong"),atoms:words("true false null"),hooks:{"@":function(stream,state){if(stream.eat('"')){state.tokenize=tokenAtString;return tokenAtString(stream,state);}
|
| +stream.eatWhile(/[\w\$_]/);return"meta";}}});CodeMirror.defineMIME("text/x-scala",{name:"clike",keywords:words("abstract case catch class def do else extends false final finally for forSome if "+"implicit import lazy match new null object override package private protected return "+"sealed super this throw trait try trye type val var while with yield _ : = => <- <: "+"<% >: # @ "+"assert assume require print println printf readLine readBoolean readByte readShort "+"readChar readInt readLong readFloat readDouble "+"AnyVal App Application Array BufferedIterator BigDecimal BigInt Char Console Either "+"Enumeration Equiv Error Exception Fractional Function IndexedSeq Integral Iterable "+"Iterator List Map Numeric Nil NotNull Option Ordered Ordering PartialFunction PartialOrdering "+"Product Proxy Range Responder Seq Serializable Set Specializable Stream StringBuilder "+"StringContext Symbol Throwable Traversable TraversableOnce Tuple Unit Vector :: #:: "+"Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable "+"Compiler Double Exception Float Integer Long Math Number Object Package Pair Process "+"Runtime Runnable SecurityManager Short StackTraceElement StrictMath String "+"StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void"),blockKeywords:words("catch class do else finally for forSome if match switch try while"),atoms:words("true false null"),hooks:{"@":function(stream){stream.eatWhile(/[\w\$_]/);return"meta";}}});mimes(["x-shader/x-vertex","x-shader/x-fragment"],{name:"clike",keywords:words("float int bool void "+"vec2 vec3 vec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4 "+"mat2 mat3 mat4 "+"sampler1D sampler2D sampler3D samplerCube "+"sampler1DShadow sampler2DShadow"+"const attribute uniform varying "+"break continue discard return "+"for while do if else struct "+"in out inout"),blockKeywords:words("for while do if else struct"),builtin:words("radians degrees sin cos tan asin acos atan "+"pow exp log exp2 sqrt inversesqrt "+"abs sign floor ceil fract mod min max clamp mix step smootstep "+"length distance dot cross normalize ftransform faceforward "+"reflect refract matrixCompMult "+"lessThan lessThanEqual greaterThan greaterThanEqual "+"equal notEqual any all not "+"texture1D texture1DProj texture1DLod texture1DProjLod "+"texture2D texture2DProj texture2DLod texture2DProjLod "+"texture3D texture3DProj texture3DLod texture3DProjLod "+"textureCube textureCubeLod "+"shadow1D shadow2D shadow1DProj shadow2DProj "+"shadow1DLod shadow2DLod shadow1DProjLod shadow2DProjLod "+"dFdx dFdy fwidth "+"noise1 noise2 noise3 noise4"),atoms:words("true false "+"gl_FragColor gl_SecondaryColor gl_Normal gl_Vertex "+"gl_MultiTexCoord0 gl_MultiTexCoord1 gl_MultiTexCoord2 gl_MultiTexCoord3 "+"gl_MultiTexCoord4 gl_MultiTexCoord5 gl_MultiTexCoord6 gl_MultiTexCoord7 "+"gl_FogCoord "+"gl_Position gl_PointSize gl_ClipVertex "+"gl_FrontColor gl_BackColor gl_FrontSecondaryColor gl_BackSecondaryColor "+"gl_TexCoord gl_FogFragCoord "+"gl_FragCoord gl_FrontFacing "+"gl_FragColor gl_FragData gl_FragDepth "+"gl_ModelViewMatrix gl_ProjectionMatrix gl_ModelViewProjectionMatrix "+"gl_TextureMatrix gl_NormalMatrix gl_ModelViewMatrixInverse "+"gl_ProjectionMatrixInverse gl_ModelViewProjectionMatrixInverse "+"gl_TexureMatrixTranspose gl_ModelViewMatrixInverseTranspose "+"gl_ProjectionMatrixInverseTranspose "+"gl_ModelViewProjectionMatrixInverseTranspose "+"gl_TextureMatrixInverseTranspose "+"gl_NormalScale gl_DepthRange gl_ClipPlane "+"gl_Point gl_FrontMaterial gl_BackMaterial gl_LightSource gl_LightModel "+"gl_FrontLightModelProduct gl_BackLightModelProduct "+"gl_TextureColor gl_EyePlaneS gl_EyePlaneT gl_EyePlaneR gl_EyePlaneQ "+"gl_FogParameters "+"gl_MaxLights gl_MaxClipPlanes gl_MaxTextureUnits gl_MaxTextureCoords "+"gl_MaxVertexAttribs gl_MaxVertexUniformComponents gl_MaxVaryingFloats "+"gl_MaxVertexTextureImageUnits gl_MaxTextureImageUnits "+"gl_MaxFragmentUniformComponents gl_MaxCombineTextureImageUnits "+"gl_MaxDrawBuffers"),hooks:{"#":cppHook}});}());;CodeMirror.defineMode('coffeescript',function(conf){var ERRORCLASS='error';function wordRegexp(words){return new RegExp("^(("+words.join(")|(")+"))\\b");}
|
| +var singleOperators=new RegExp("^[\\+\\-\\*/%&|\\^~<>!\?]");var singleDelimiters=new RegExp('^[\\(\\)\\[\\]\\{\\},:`=;\\.]');var doubleOperators=new RegExp("^((\->)|(\=>)|(\\+\\+)|(\\+\\=)|(\\-\\-)|(\\-\\=)|(\\*\\*)|(\\*\\=)|(\\/\\/)|(\\/\\=)|(==)|(!=)|(<=)|(>=)|(<>)|(<<)|(>>)|(//))");var doubleDelimiters=new RegExp("^((\\.\\.)|(\\+=)|(\\-=)|(\\*=)|(%=)|(/=)|(&=)|(\\|=)|(\\^=))");var tripleDelimiters=new RegExp("^((\\.\\.\\.)|(//=)|(>>=)|(<<=)|(\\*\\*=))");var identifiers=new RegExp("^[_A-Za-z$][_A-Za-z$0-9]*");var properties=new RegExp("^(@|this\.)[_A-Za-z$][_A-Za-z$0-9]*");var wordOperators=wordRegexp(['and','or','not','is','isnt','in','instanceof','typeof']);var indentKeywords=['for','while','loop','if','unless','else','switch','try','catch','finally','class'];var commonKeywords=['break','by','continue','debugger','delete','do','in','of','new','return','then','this','throw','when','until'];var keywords=wordRegexp(indentKeywords.concat(commonKeywords));indentKeywords=wordRegexp(indentKeywords);var stringPrefixes=new RegExp("^('{3}|\"{3}|['\"])");var regexPrefixes=new RegExp("^(/{3}|/)");var commonConstants=['Infinity','NaN','undefined','null','true','false','on','off','yes','no'];var constants=wordRegexp(commonConstants);function tokenBase(stream,state){if(stream.sol()){var scopeOffset=state.scopes[0].offset;if(stream.eatSpace()){var lineOffset=stream.indentation();if(lineOffset>scopeOffset){return'indent';}else if(lineOffset<scopeOffset){return'dedent';}
|
| +return null;}else{if(scopeOffset>0){dedent(stream,state);}}}
|
| +if(stream.eatSpace()){return null;}
|
| +var ch=stream.peek();if(stream.match("####")){stream.skipToEnd();return'comment';}
|
| +if(stream.match("###")){state.tokenize=longComment;return state.tokenize(stream,state);}
|
| +if(ch==='#'){stream.skipToEnd();return'comment';}
|
| +if(stream.match(/^-?[0-9\.]/,false)){var floatLiteral=false;if(stream.match(/^-?\d*\.\d+(e[\+\-]?\d+)?/i)){floatLiteral=true;}
|
| +if(stream.match(/^-?\d+\.\d*/)){floatLiteral=true;}
|
| +if(stream.match(/^-?\.\d+/)){floatLiteral=true;}
|
| +if(floatLiteral){if(stream.peek()=="."){stream.backUp(1);}
|
| +return'number';}
|
| +var intLiteral=false;if(stream.match(/^-?0x[0-9a-f]+/i)){intLiteral=true;}
|
| +if(stream.match(/^-?[1-9]\d*(e[\+\-]?\d+)?/)){intLiteral=true;}
|
| +if(stream.match(/^-?0(?![\dx])/i)){intLiteral=true;}
|
| +if(intLiteral){return'number';}}
|
| +if(stream.match(stringPrefixes)){state.tokenize=tokenFactory(stream.current(),'string');return state.tokenize(stream,state);}
|
| +if(stream.match(regexPrefixes)){if(stream.current()!='/'||stream.match(/^.*\//,false)){state.tokenize=tokenFactory(stream.current(),'string-2');return state.tokenize(stream,state);}else{stream.backUp(1);}}
|
| +if(stream.match(tripleDelimiters)||stream.match(doubleDelimiters)){return'punctuation';}
|
| +if(stream.match(doubleOperators)||stream.match(singleOperators)||stream.match(wordOperators)){return'operator';}
|
| +if(stream.match(singleDelimiters)){return'punctuation';}
|
| +if(stream.match(constants)){return'atom';}
|
| +if(stream.match(keywords)){return'keyword';}
|
| +if(stream.match(identifiers)){return'variable';}
|
| +if(stream.match(properties)){return'property';}
|
| +stream.next();return ERRORCLASS;}
|
| +function tokenFactory(delimiter,outclass){var singleline=delimiter.length==1;return function(stream,state){while(!stream.eol()){stream.eatWhile(/[^'"\/\\]/);if(stream.eat('\\')){stream.next();if(singleline&&stream.eol()){return outclass;}}else if(stream.match(delimiter)){state.tokenize=tokenBase;return outclass;}else{stream.eat(/['"\/]/);}}
|
| +if(singleline){if(conf.mode.singleLineStringErrors){outclass=ERRORCLASS;}else{state.tokenize=tokenBase;}}
|
| +return outclass;};}
|
| +function longComment(stream,state){while(!stream.eol()){stream.eatWhile(/[^#]/);if(stream.match("###")){state.tokenize=tokenBase;break;}
|
| +stream.eatWhile("#");}
|
| +return"comment";}
|
| +function indent(stream,state,type){type=type||'coffee';var indentUnit=0;if(type==='coffee'){for(var i=0;i<state.scopes.length;i++){if(state.scopes[i].type==='coffee'){indentUnit=state.scopes[i].offset+conf.indentUnit;break;}}}else{indentUnit=stream.column()+stream.current().length;}
|
| +state.scopes.unshift({offset:indentUnit,type:type});}
|
| +function dedent(stream,state){if(state.scopes.length==1)return;if(state.scopes[0].type==='coffee'){var _indent=stream.indentation();var _indent_index=-1;for(var i=0;i<state.scopes.length;++i){if(_indent===state.scopes[i].offset){_indent_index=i;break;}}
|
| +if(_indent_index===-1){return true;}
|
| +while(state.scopes[0].offset!==_indent){state.scopes.shift();}
|
| +return false;}else{state.scopes.shift();return false;}}
|
| +function tokenLexer(stream,state){var style=state.tokenize(stream,state);var current=stream.current();if(current==='.'){style=state.tokenize(stream,state);current=stream.current();if(style==='variable'){return'variable';}else{return ERRORCLASS;}}
|
| +if(current==='return'){state.dedent+=1;}
|
| +if(((current==='->'||current==='=>')&&!state.lambda&&state.scopes[0].type=='coffee'&&stream.peek()==='')||style==='indent'){indent(stream,state);}
|
| +var delimiter_index='[({'.indexOf(current);if(delimiter_index!==-1){indent(stream,state,'])}'.slice(delimiter_index,delimiter_index+1));}
|
| +if(indentKeywords.exec(current)){indent(stream,state);}
|
| +if(current=='then'){dedent(stream,state);}
|
| +if(style==='dedent'){if(dedent(stream,state)){return ERRORCLASS;}}
|
| +delimiter_index='])}'.indexOf(current);if(delimiter_index!==-1){if(dedent(stream,state)){return ERRORCLASS;}}
|
| +if(state.dedent>0&&stream.eol()&&state.scopes[0].type=='coffee'){if(state.scopes.length>1)state.scopes.shift();state.dedent-=1;}
|
| +return style;}
|
| +var external={startState:function(basecolumn){return{tokenize:tokenBase,scopes:[{offset:basecolumn||0,type:'coffee'}],lastToken:null,lambda:false,dedent:0};},token:function(stream,state){var style=tokenLexer(stream,state);state.lastToken={style:style,content:stream.current()};if(stream.eol()&&stream.lambda){state.lambda=false;}
|
| +return style;},indent:function(state){if(state.tokenize!=tokenBase){return 0;}
|
| +return state.scopes[0].offset;},lineComment:"#"};return external;});CodeMirror.defineMIME('text/x-coffeescript','coffeescript');;(function(){function keywords(str){var obj={},words=str.split(" ");for(var i=0;i<words.length;++i)obj[words[i]]=true;return obj;}
|
| +function heredoc(delim){return function(stream,state){if(stream.match(delim))state.tokenize=null;else stream.skipToEnd();return"string";};}
|
| +var phpConfig={name:"clike",keywords:keywords("abstract and array as break case catch class clone const continue declare default "+"do else elseif enddeclare endfor endforeach endif endswitch endwhile extends final "+"for foreach function global goto if implements interface instanceof namespace "+"new or private protected public static switch throw trait try use var while xor "+"die echo empty exit eval include include_once isset list require require_once return "+"print unset __halt_compiler self static parent"),blockKeywords:keywords("catch do else elseif for foreach if switch try while"),atoms:keywords("true false null TRUE FALSE NULL __CLASS__ __DIR__ __FILE__ __LINE__ __METHOD__ __FUNCTION__ __NAMESPACE__"),builtin:keywords("func_num_args func_get_arg func_get_args strlen strcmp strncmp strcasecmp strncasecmp each error_reporting define defined trigger_error user_error set_error_handler restore_error_handler get_declared_classes get_loaded_extensions extension_loaded get_extension_funcs debug_backtrace constant bin2hex sleep usleep time mktime gmmktime strftime gmstrftime strtotime date gmdate getdate localtime checkdate flush wordwrap htmlspecialchars htmlentities html_entity_decode md5 md5_file crc32 getimagesize image_type_to_mime_type phpinfo phpversion phpcredits strnatcmp strnatcasecmp substr_count strspn strcspn strtok strtoupper strtolower strpos strrpos strrev hebrev hebrevc nl2br basename dirname pathinfo stripslashes stripcslashes strstr stristr strrchr str_shuffle str_word_count strcoll substr substr_replace quotemeta ucfirst ucwords strtr addslashes addcslashes rtrim str_replace str_repeat count_chars chunk_split trim ltrim strip_tags similar_text explode implode setlocale localeconv parse_str str_pad chop strchr sprintf printf vprintf vsprintf sscanf fscanf parse_url urlencode urldecode rawurlencode rawurldecode readlink linkinfo link unlink exec system escapeshellcmd escapeshellarg passthru shell_exec proc_open proc_close rand srand getrandmax mt_rand mt_srand mt_getrandmax base64_decode base64_encode abs ceil floor round is_finite is_nan is_infinite bindec hexdec octdec decbin decoct dechex base_convert number_format fmod ip2long long2ip getenv putenv getopt microtime gettimeofday getrusage uniqid quoted_printable_decode set_time_limit get_cfg_var magic_quotes_runtime set_magic_quotes_runtime get_magic_quotes_gpc get_magic_quotes_runtime import_request_variables error_log serialize unserialize memory_get_usage var_dump var_export debug_zval_dump print_r highlight_file show_source highlight_string ini_get ini_get_all ini_set ini_alter ini_restore get_include_path set_include_path restore_include_path setcookie header headers_sent connection_aborted connection_status ignore_user_abort parse_ini_file is_uploaded_file move_uploaded_file intval floatval doubleval strval gettype settype is_null is_resource is_bool is_long is_float is_int is_integer is_double is_real is_numeric is_string is_array is_object is_scalar ereg ereg_replace eregi eregi_replace split spliti join sql_regcase dl pclose popen readfile rewind rmdir umask fclose feof fgetc fgets fgetss fread fopen fpassthru ftruncate fstat fseek ftell fflush fwrite fputs mkdir rename copy tempnam tmpfile file file_get_contents stream_select stream_context_create stream_context_set_params stream_context_set_option stream_context_get_options stream_filter_prepend stream_filter_append fgetcsv flock get_meta_tags stream_set_write_buffer set_file_buffer set_socket_blocking stream_set_blocking socket_set_blocking stream_get_meta_data stream_register_wrapper stream_wrapper_register stream_set_timeout socket_set_timeout socket_get_status realpath fnmatch fsockopen pfsockopen pack unpack get_browser crypt opendir closedir chdir getcwd rewinddir readdir dir glob fileatime filectime filegroup fileinode filemtime fileowner fileperms filesize filetype file_exists is_writable is_writeable is_readable is_executable is_file is_dir is_link stat lstat chown touch clearstatcache mail ob_start ob_flush ob_clean ob_end_flush ob_end_clean ob_get_flush ob_get_clean ob_get_length ob_get_level ob_get_status ob_get_contents ob_implicit_flush ob_list_handlers ksort krsort natsort natcasesort asort arsort sort rsort usort uasort uksort shuffle array_walk count end prev next reset current key min max in_array array_search extract compact array_fill range array_multisort array_push array_pop array_shift array_unshift array_splice array_slice array_merge array_merge_recursive array_keys array_values array_count_values array_reverse array_reduce array_pad array_flip array_change_key_case array_rand array_unique array_intersect array_intersect_assoc array_diff array_diff_assoc array_sum array_filter array_map array_chunk array_key_exists pos sizeof key_exists assert assert_options version_compare ftok str_rot13 aggregate session_name session_module_name session_save_path session_id session_regenerate_id session_decode session_register session_unregister session_is_registered session_encode session_start session_destroy session_unset session_set_save_handler session_cache_limiter session_cache_expire session_set_cookie_params session_get_cookie_params session_write_close preg_match preg_match_all preg_replace preg_replace_callback preg_split preg_quote preg_grep overload ctype_alnum ctype_alpha ctype_cntrl ctype_digit ctype_lower ctype_graph ctype_print ctype_punct ctype_space ctype_upper ctype_xdigit virtual apache_request_headers apache_note apache_lookup_uri apache_child_terminate apache_setenv apache_response_headers apache_get_version getallheaders mysql_connect mysql_pconnect mysql_close mysql_select_db mysql_create_db mysql_drop_db mysql_query mysql_unbuffered_query mysql_db_query mysql_list_dbs mysql_list_tables mysql_list_fields mysql_list_processes mysql_error mysql_errno mysql_affected_rows mysql_insert_id mysql_result mysql_num_rows mysql_num_fields mysql_fetch_row mysql_fetch_array mysql_fetch_assoc mysql_fetch_object mysql_data_seek mysql_fetch_lengths mysql_fetch_field mysql_field_seek mysql_free_result mysql_field_name mysql_field_table mysql_field_len mysql_field_type mysql_field_flags mysql_escape_string mysql_real_escape_string mysql_stat mysql_thread_id mysql_client_encoding mysql_get_client_info mysql_get_host_info mysql_get_proto_info mysql_get_server_info mysql_info mysql mysql_fieldname mysql_fieldtable mysql_fieldlen mysql_fieldtype mysql_fieldflags mysql_selectdb mysql_createdb mysql_dropdb mysql_freeresult mysql_numfields mysql_numrows mysql_listdbs mysql_listtables mysql_listfields mysql_db_name mysql_dbname mysql_tablename mysql_table_name pg_connect pg_pconnect pg_close pg_connection_status pg_connection_busy pg_connection_reset pg_host pg_dbname pg_port pg_tty pg_options pg_ping pg_query pg_send_query pg_cancel_query pg_fetch_result pg_fetch_row pg_fetch_assoc pg_fetch_array pg_fetch_object pg_fetch_all pg_affected_rows pg_get_result pg_result_seek pg_result_status pg_free_result pg_last_oid pg_num_rows pg_num_fields pg_field_name pg_field_num pg_field_size pg_field_type pg_field_prtlen pg_field_is_null pg_get_notify pg_get_pid pg_result_error pg_last_error pg_last_notice pg_put_line pg_end_copy pg_copy_to pg_copy_from pg_trace pg_untrace pg_lo_create pg_lo_unlink pg_lo_open pg_lo_close pg_lo_read pg_lo_write pg_lo_read_all pg_lo_import pg_lo_export pg_lo_seek pg_lo_tell pg_escape_string pg_escape_bytea pg_unescape_bytea pg_client_encoding pg_set_client_encoding pg_meta_data pg_convert pg_insert pg_update pg_delete pg_select pg_exec pg_getlastoid pg_cmdtuples pg_errormessage pg_numrows pg_numfields pg_fieldname pg_fieldsize pg_fieldtype pg_fieldnum pg_fieldprtlen pg_fieldisnull pg_freeresult pg_result pg_loreadall pg_locreate pg_lounlink pg_loopen pg_loclose pg_loread pg_lowrite pg_loimport pg_loexport echo print global static exit array empty eval isset unset die include require include_once require_once"),multiLineStrings:true,hooks:{"$":function(stream){stream.eatWhile(/[\w\$_]/);return"variable-2";},"<":function(stream,state){if(stream.match(/<</)){stream.eatWhile(/[\w\.]/);state.tokenize=heredoc(stream.current().slice(3));return state.tokenize(stream,state);}
|
| +return false;},"#":function(stream){while(!stream.eol()&&!stream.match("?>",false))stream.next();return"comment";},"/":function(stream){if(stream.eat("/")){while(!stream.eol()&&!stream.match("?>",false))stream.next();return"comment";}
|
| +return false;}}};CodeMirror.defineMode("php",function(config,parserConfig){var htmlMode=CodeMirror.getMode(config,"text/html");var phpMode=CodeMirror.getMode(config,phpConfig);function dispatch(stream,state){var isPHP=state.curMode==phpMode;if(stream.sol()&&state.pending!='"')state.pending=null;if(!isPHP){if(stream.match(/^<\?\w*/)){state.curMode=phpMode;state.curState=state.php;return"meta";}
|
| +if(state.pending=='"'){while(!stream.eol()&&stream.next()!='"'){}
|
| +var style="string";}else if(state.pending&&stream.pos<state.pending.end){stream.pos=state.pending.end;var style=state.pending.style;}else{var style=htmlMode.token(stream,state.curState);}
|
| +state.pending=null;var cur=stream.current(),openPHP=cur.search(/<\?/);if(openPHP!=-1){if(style=="string"&&/\"$/.test(cur)&&!/\?>/.test(cur))state.pending='"';else state.pending={end:stream.pos,style:style};stream.backUp(cur.length-openPHP);}
|
| +return style;}else if(isPHP&&state.php.tokenize==null&&stream.match("?>")){state.curMode=htmlMode;state.curState=state.html;return"meta";}else{return phpMode.token(stream,state.curState);}}
|
| +return{startState:function(){var html=CodeMirror.startState(htmlMode),php=CodeMirror.startState(phpMode);return{html:html,php:php,curMode:parserConfig.startOpen?phpMode:htmlMode,curState:parserConfig.startOpen?php:html,pending:null};},copyState:function(state){var html=state.html,htmlNew=CodeMirror.copyState(htmlMode,html),php=state.php,phpNew=CodeMirror.copyState(phpMode,php),cur;if(state.curMode==htmlMode)cur=htmlNew;else cur=phpNew;return{html:htmlNew,php:phpNew,curMode:state.curMode,curState:cur,pending:state.pending};},token:dispatch,indent:function(state,textAfter){if((state.curMode!=phpMode&&/^\s*<\//.test(textAfter))||(state.curMode==phpMode&&/^\?>/.test(textAfter)))
|
| +return htmlMode.indent(state.html,textAfter);return state.curMode.indent(state.curState,textAfter);},electricChars:"/{}:",blockCommentStart:"/*",blockCommentEnd:"*/",lineComment:"//",innerMode:function(state){return{state:state.curState,mode:state.curMode};}};},"htmlmixed","clike");CodeMirror.defineMIME("application/x-httpd-php","php");CodeMirror.defineMIME("application/x-httpd-php-open",{name:"php",startOpen:true});CodeMirror.defineMIME("text/x-php",phpConfig);})();;CodeMirror.defineMode("python",function(conf,parserConf){var ERRORCLASS='error';function wordRegexp(words){return new RegExp("^(("+words.join(")|(")+"))\\b");}
|
| +var singleOperators=parserConf.singleOperators||new RegExp("^[\\+\\-\\*/%&|\\^~<>!]");var singleDelimiters=parserConf.singleDelimiters||new RegExp('^[\\(\\)\\[\\]\\{\\}@,:`=;\\.]');var doubleOperators=parserConf.doubleOperators||new RegExp("^((==)|(!=)|(<=)|(>=)|(<>)|(<<)|(>>)|(//)|(\\*\\*))");var doubleDelimiters=parserConf.doubleDelimiters||new RegExp("^((\\+=)|(\\-=)|(\\*=)|(%=)|(/=)|(&=)|(\\|=)|(\\^=))");var tripleDelimiters=parserConf.tripleDelimiters||new RegExp("^((//=)|(>>=)|(<<=)|(\\*\\*=))");var identifiers=parserConf.identifiers||new RegExp("^[_A-Za-z][_A-Za-z0-9]*");var wordOperators=wordRegexp(['and','or','not','is','in']);var commonkeywords=['as','assert','break','class','continue','def','del','elif','else','except','finally','for','from','global','if','import','lambda','pass','raise','return','try','while','with','yield'];var commonBuiltins=['abs','all','any','bin','bool','bytearray','callable','chr','classmethod','compile','complex','delattr','dict','dir','divmod','enumerate','eval','filter','float','format','frozenset','getattr','globals','hasattr','hash','help','hex','id','input','int','isinstance','issubclass','iter','len','list','locals','map','max','memoryview','min','next','object','oct','open','ord','pow','property','range','repr','reversed','round','set','setattr','slice','sorted','staticmethod','str','sum','super','tuple','type','vars','zip','__import__','NotImplemented','Ellipsis','__debug__'];var py2={'builtins':['apply','basestring','buffer','cmp','coerce','execfile','file','intern','long','raw_input','reduce','reload','unichr','unicode','xrange','False','True','None'],'keywords':['exec','print']};var py3={'builtins':['ascii','bytes','exec','print'],'keywords':['nonlocal','False','True','None']};if(!!parserConf.version&&parseInt(parserConf.version,10)===3){commonkeywords=commonkeywords.concat(py3.keywords);commonBuiltins=commonBuiltins.concat(py3.builtins);var stringPrefixes=new RegExp("^(([rb]|(br))?('{3}|\"{3}|['\"]))","i");}else{commonkeywords=commonkeywords.concat(py2.keywords);commonBuiltins=commonBuiltins.concat(py2.builtins);var stringPrefixes=new RegExp("^(([rub]|(ur)|(br))?('{3}|\"{3}|['\"]))","i");}
|
| +var keywords=wordRegexp(commonkeywords);var builtins=wordRegexp(commonBuiltins);var indentInfo=null;function tokenBase(stream,state){if(stream.sol()){var scopeOffset=state.scopes[0].offset;if(stream.eatSpace()){var lineOffset=stream.indentation();if(lineOffset>scopeOffset){indentInfo='indent';}else if(lineOffset<scopeOffset){indentInfo='dedent';}
|
| +return null;}else{if(scopeOffset>0){dedent(stream,state);}}}
|
| +if(stream.eatSpace()){return null;}
|
| +var ch=stream.peek();if(ch==='#'){stream.skipToEnd();return'comment';}
|
| +if(stream.match(/^[0-9\.]/,false)){var floatLiteral=false;if(stream.match(/^\d*\.\d+(e[\+\-]?\d+)?/i)){floatLiteral=true;}
|
| +if(stream.match(/^\d+\.\d*/)){floatLiteral=true;}
|
| +if(stream.match(/^\.\d+/)){floatLiteral=true;}
|
| +if(floatLiteral){stream.eat(/J/i);return'number';}
|
| +var intLiteral=false;if(stream.match(/^0x[0-9a-f]+/i)){intLiteral=true;}
|
| +if(stream.match(/^0b[01]+/i)){intLiteral=true;}
|
| +if(stream.match(/^0o[0-7]+/i)){intLiteral=true;}
|
| +if(stream.match(/^[1-9]\d*(e[\+\-]?\d+)?/)){stream.eat(/J/i);intLiteral=true;}
|
| +if(stream.match(/^0(?![\dx])/i)){intLiteral=true;}
|
| +if(intLiteral){stream.eat(/L/i);return'number';}}
|
| +if(stream.match(stringPrefixes)){state.tokenize=tokenStringFactory(stream.current());return state.tokenize(stream,state);}
|
| +if(stream.match(tripleDelimiters)||stream.match(doubleDelimiters)){return null;}
|
| +if(stream.match(doubleOperators)||stream.match(singleOperators)||stream.match(wordOperators)){return'operator';}
|
| +if(stream.match(singleDelimiters)){return null;}
|
| +if(stream.match(keywords)){return'keyword';}
|
| +if(stream.match(builtins)){return'builtin';}
|
| +if(stream.match(identifiers)){return'variable';}
|
| +stream.next();return ERRORCLASS;}
|
| +function tokenStringFactory(delimiter){while('rub'.indexOf(delimiter.charAt(0).toLowerCase())>=0){delimiter=delimiter.substr(1);}
|
| +var singleline=delimiter.length==1;var OUTCLASS='string';function tokenString(stream,state){while(!stream.eol()){stream.eatWhile(/[^'"\\]/);if(stream.eat('\\')){stream.next();if(singleline&&stream.eol()){return OUTCLASS;}}else if(stream.match(delimiter)){state.tokenize=tokenBase;return OUTCLASS;}else{stream.eat(/['"]/);}}
|
| +if(singleline){if(parserConf.singleLineStringErrors){return ERRORCLASS;}else{state.tokenize=tokenBase;}}
|
| +return OUTCLASS;}
|
| +tokenString.isString=true;return tokenString;}
|
| +function indent(stream,state,type){type=type||'py';var indentUnit=0;if(type==='py'){if(state.scopes[0].type!=='py'){state.scopes[0].offset=stream.indentation();return;}
|
| +for(var i=0;i<state.scopes.length;++i){if(state.scopes[i].type==='py'){indentUnit=state.scopes[i].offset+conf.indentUnit;break;}}}else{indentUnit=stream.column()+stream.current().length;}
|
| +state.scopes.unshift({offset:indentUnit,type:type});}
|
| +function dedent(stream,state,type){type=type||'py';if(state.scopes.length==1)return;if(state.scopes[0].type==='py'){var _indent=stream.indentation();var _indent_index=-1;for(var i=0;i<state.scopes.length;++i){if(_indent===state.scopes[i].offset){_indent_index=i;break;}}
|
| +if(_indent_index===-1){return true;}
|
| +while(state.scopes[0].offset!==_indent){state.scopes.shift();}
|
| +return false;}else{if(type==='py'){state.scopes[0].offset=stream.indentation();return false;}else{if(state.scopes[0].type!=type){return true;}
|
| +state.scopes.shift();return false;}}}
|
| +function tokenLexer(stream,state){indentInfo=null;var style=state.tokenize(stream,state);var current=stream.current();if(current==='.'){style=stream.match(identifiers,false)?null:ERRORCLASS;if(style===null&&state.lastToken==='meta'){style='meta';}
|
| +return style;}
|
| +if(current==='@'){return stream.match(identifiers,false)?'meta':ERRORCLASS;}
|
| +if((style==='variable'||style==='builtin')&&state.lastToken==='meta'){style='meta';}
|
| +if(current==='pass'||current==='return'){state.dedent+=1;}
|
| +if(current==='lambda')state.lambda=true;if((current===':'&&!state.lambda&&state.scopes[0].type=='py')||indentInfo==='indent'){indent(stream,state);}
|
| +var delimiter_index='[({'.indexOf(current);if(delimiter_index!==-1){indent(stream,state,'])}'.slice(delimiter_index,delimiter_index+1));}
|
| +if(indentInfo==='dedent'){if(dedent(stream,state)){return ERRORCLASS;}}
|
| +delimiter_index='])}'.indexOf(current);if(delimiter_index!==-1){if(dedent(stream,state,current)){return ERRORCLASS;}}
|
| +if(state.dedent>0&&stream.eol()&&state.scopes[0].type=='py'){if(state.scopes.length>1)state.scopes.shift();state.dedent-=1;}
|
| +return style;}
|
| +var external={startState:function(basecolumn){return{tokenize:tokenBase,scopes:[{offset:basecolumn||0,type:'py'}],lastToken:null,lambda:false,dedent:0};},token:function(stream,state){var style=tokenLexer(stream,state);state.lastToken=style;if(stream.eol()&&stream.lambda){state.lambda=false;}
|
| +return style;},indent:function(state){if(state.tokenize!=tokenBase){return state.tokenize.isString?CodeMirror.Pass:0;}
|
| +return state.scopes[0].offset;},lineComment:"#"};return external;});CodeMirror.defineMIME("text/x-python","python");;CodeMirror.defineMode('shell',function(){var words={};function define(style,string){var split=string.split(' ');for(var i=0;i<split.length;i++){words[split[i]]=style;}};define('atom','true false');define('keyword','if then do else elif while until for in esac fi fin '+'fil done exit set unset export function');define('builtin','ab awk bash beep cat cc cd chown chmod chroot clear cp '+'curl cut diff echo find gawk gcc get git grep kill killall ln ls make '+'mkdir openssl mv nc node npm ping ps restart rm rmdir sed service sh '+'shopt shred source sort sleep ssh start stop su sudo tee telnet top '+'touch vi vim wall wc wget who write yes zsh');function tokenBase(stream,state){var sol=stream.sol();var ch=stream.next();if(ch==='\''||ch==='"'||ch==='`'){state.tokens.unshift(tokenString(ch));return tokenize(stream,state);}
|
| +if(ch==='#'){if(sol&&stream.eat('!')){stream.skipToEnd();return'meta';}
|
| +stream.skipToEnd();return'comment';}
|
| +if(ch==='$'){state.tokens.unshift(tokenDollar);return tokenize(stream,state);}
|
| +if(ch==='+'||ch==='='){return'operator';}
|
| +if(ch==='-'){stream.eat('-');stream.eatWhile(/\w/);return'attribute';}
|
| +if(/\d/.test(ch)){stream.eatWhile(/\d/);if(!/\w/.test(stream.peek())){return'number';}}
|
| +stream.eatWhile(/[\w-]/);var cur=stream.current();if(stream.peek()==='='&&/\w+/.test(cur))return'def';return words.hasOwnProperty(cur)?words[cur]:null;}
|
| +function tokenString(quote){return function(stream,state){var next,end=false,escaped=false;while((next=stream.next())!=null){if(next===quote&&!escaped){end=true;break;}
|
| +if(next==='$'&&!escaped&"e!=='\''){escaped=true;stream.backUp(1);state.tokens.unshift(tokenDollar);break;}
|
| +escaped=!escaped&&next==='\\';}
|
| +if(end||!escaped){state.tokens.shift();}
|
| +return(quote==='`'||quote===')'?'quote':'string');};};var tokenDollar=function(stream,state){if(state.tokens.length>1)stream.eat('$');var ch=stream.next(),hungry=/\w/;if(ch==='{')hungry=/[^}]/;if(ch==='('){state.tokens[0]=tokenString(')');return tokenize(stream,state);}
|
| +if(!/\d/.test(ch)){stream.eatWhile(hungry);stream.eat('}');}
|
| +state.tokens.shift();return'def';};function tokenize(stream,state){return(state.tokens[0]||tokenBase)(stream,state);};return{startState:function(){return{tokens:[]};},token:function(stream,state){if(stream.eatSpace())return null;return tokenize(stream,state);}};});CodeMirror.defineMIME('text/x-sh','shell');;WebInspector.CodeMirrorUtils={createTokenizer:function(mimeType)
|
| +{var mode=CodeMirror.getMode({indentUnit:2},mimeType);var state=CodeMirror.startState(mode);function tokenize(line,callback)
|
| +{var stream=new CodeMirror.StringStream(line);while(!stream.eol()){var style=mode.token(stream,state);var value=stream.current();callback(value,style,stream.start,stream.start+value.length);stream.start=stream.pos;}}
|
| +return tokenize;},convertTokenType:function(tokenType)
|
| +{if(tokenType.startsWith("js-variable")||tokenType.startsWith("js-property")||tokenType==="js-def")
|
| +return"javascript-ident";if(tokenType==="js-string-2")
|
| +return"javascript-regexp";if(tokenType==="js-number"||tokenType==="js-comment"||tokenType==="js-string"||tokenType==="js-keyword")
|
| +return"javascript-"+tokenType.substring("js-".length);return null;},overrideModeWithPrefixedTokens:function(modeName,tokenPrefix)
|
| +{var oldModeName=modeName+"-old";if(CodeMirror.modes[oldModeName])
|
| +return;CodeMirror.defineMode(oldModeName,CodeMirror.modes[modeName]);CodeMirror.defineMode(modeName,modeConstructor);function modeConstructor(config,parserConfig)
|
| +{var innerConfig={};for(var i in parserConfig)
|
| +innerConfig[i]=parserConfig[i];innerConfig.name=oldModeName;var codeMirrorMode=CodeMirror.getMode(config,innerConfig);codeMirrorMode.name=modeName;codeMirrorMode.token=tokenOverride.bind(this,codeMirrorMode.token);return codeMirrorMode;}
|
| +function tokenOverride(superToken,stream,state)
|
| +{var token=superToken(stream,state);return token?tokenPrefix+token:token;}}}
|
| +WebInspector.CodeMirrorUtils.overrideModeWithPrefixedTokens("css-base","css-");WebInspector.CodeMirrorUtils.overrideModeWithPrefixedTokens("javascript","js-");WebInspector.CodeMirrorUtils.overrideModeWithPrefixedTokens("xml","xml-");;WebInspector.CodeMirrorTextEditor=function(url,delegate)
|
| +{WebInspector.View.call(this);this._delegate=delegate;this._url=url;this.registerRequiredCSS("cm/codemirror.css");this.registerRequiredCSS("cm/cmdevtools.css");this._codeMirror=window.CodeMirror(this.element,{lineNumbers:true,gutters:["CodeMirror-linenumbers"],matchBrackets:true,smartIndent:false,styleSelectedText:true,electricChars:false,autoCloseBrackets:{explode:false}});this._codeMirror._codeMirrorTextEditor=this;CodeMirror.keyMap["devtools-common"]={"Left":"goCharLeft","Right":"goCharRight","Up":"goLineUp","Down":"goLineDown","End":"goLineEnd","Home":"goLineStartSmart","PageUp":"goPageUp","PageDown":"goPageDown","Delete":"delCharAfter","Backspace":"delCharBefore","Tab":"defaultTab","Shift-Tab":"indentLess","Enter":"smartNewlineAndIndent","Ctrl-Space":"autocomplete"};CodeMirror.keyMap["devtools-pc"]={"Ctrl-A":"selectAll","Ctrl-Z":"undoAndReveal","Shift-Ctrl-Z":"redoAndReveal","Ctrl-Y":"redo","Ctrl-Home":"goDocStart","Ctrl-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-/":"toggleComment",fallthrough:"devtools-common"};CodeMirror.keyMap["devtools-mac"]={"Cmd-A":"selectAll","Cmd-Z":"undoAndReveal","Shift-Cmd-Z":"redoAndReveal","Cmd-Up":"goDocStart","Cmd-Down":"goDocEnd","Alt-Left":"goGroupLeft","Alt-Right":"goGroupRight","Cmd-Left":"goLineStartSmart","Cmd-Right":"goLineEnd","Alt-Backspace":"delGroupBefore","Alt-Delete":"delGroupAfter","Cmd-/":"toggleComment",fallthrough:"devtools-common"};WebInspector.settings.textEditorIndent.addChangeListener(this._updateEditorIndentation,this);this._updateEditorIndentation();WebInspector.settings.showWhitespacesInEditor.addChangeListener(this._updateCodeMirrorMode,this);this._codeMirror.setOption("keyMap",WebInspector.isMac()?"devtools-mac":"devtools-pc");this._codeMirror.setOption("flattenSpans",false);this._codeMirror.setOption("maxHighlightLength",1000);this._codeMirror.setOption("mode",null);this._shouldClearHistory=true;this._lineSeparator="\n";this._tokenHighlighter=new WebInspector.CodeMirrorTextEditor.TokenHighlighter(this._codeMirror);this._blockIndentController=new WebInspector.CodeMirrorTextEditor.BlockIndentController(this._codeMirror);this._fixWordMovement=new WebInspector.CodeMirrorTextEditor.FixWordMovement(this._codeMirror);this._autocompleteController=new WebInspector.CodeMirrorTextEditor.AutocompleteController(this,this._codeMirror);this._codeMirror.on("change",this._change.bind(this));this._codeMirror.on("beforeChange",this._beforeChange.bind(this));this._codeMirror.on("gutterClick",this._gutterClick.bind(this));this._codeMirror.on("cursorActivity",this._cursorActivity.bind(this));this._codeMirror.on("scroll",this._scroll.bind(this));this._codeMirror.on("focus",this._focus.bind(this));this._codeMirror.on("blur",this._blur.bind(this));this.element.addEventListener("contextmenu",this._contextMenu.bind(this),false);this.element.addStyleClass("fill");this.element.style.overflow="hidden";this.element.firstChild.addStyleClass("source-code");this.element.firstChild.addStyleClass("fill");this._elementToWidget=new Map();this._nestedUpdatesCounter=0;this.element.addEventListener("focus",this._handleElementFocus.bind(this),false);this.element.addEventListener("keydown",this._handleKeyDown.bind(this),true);this.element.tabIndex=0;this._setupSelectionColor();this._setupWhitespaceHighlight();}
|
| +WebInspector.CodeMirrorTextEditor.autocompleteCommand=function(codeMirror)
|
| +{codeMirror._codeMirrorTextEditor._autocompleteController.autocomplete();}
|
| +CodeMirror.commands.autocomplete=WebInspector.CodeMirrorTextEditor.autocompleteCommand;CodeMirror.commands.smartNewlineAndIndent=function(codeMirror)
|
| +{codeMirror.operation(innerSmartNewlineAndIndent.bind(this,codeMirror));function countIndent(line)
|
| +{for(var i=0;i<line.length;++i){if(!WebInspector.TextUtils.isSpaceChar(line[i]))
|
| +return i;}
|
| +return line.length;}
|
| +function innerSmartNewlineAndIndent(codeMirror)
|
| +{var cur=codeMirror.getCursor("start");var line=codeMirror.getLine(cur.line);var indent=cur.line>0?countIndent(line):0;if(cur.ch<=indent){codeMirror.replaceSelection("\n"+line.substring(0,cur.ch),"end","+input");codeMirror.setSelection(new CodeMirror.Pos(cur.line+1,cur.ch));}else
|
| +codeMirror.execCommand("newlineAndIndent");}}
|
| +CodeMirror.commands.undoAndReveal=function(codemirror)
|
| +{var scrollInfo=codemirror.getScrollInfo();codemirror.execCommand("undo");var cursor=codemirror.getCursor("start");codemirror._codeMirrorTextEditor._innerRevealLine(cursor.line,scrollInfo);}
|
| +CodeMirror.commands.redoAndReveal=function(codemirror)
|
| +{var scrollInfo=codemirror.getScrollInfo();codemirror.execCommand("redo");var cursor=codemirror.getCursor("start");codemirror._codeMirrorTextEditor._innerRevealLine(cursor.line,scrollInfo);}
|
| +WebInspector.CodeMirrorTextEditor.LongLineModeLineLengthThreshold=2000;WebInspector.CodeMirrorTextEditor.MaximumNumberOfWhitespacesPerSingleSpan=16;WebInspector.CodeMirrorTextEditor.prototype={wasShown:function()
|
| +{this._codeMirror.refresh();},_guessIndentationLevel:function()
|
| +{var tabRegex=/^\t+/;var tabLines=0;var indents={};function processLine(lineHandle)
|
| +{var text=lineHandle.text;if(text.length===0||!WebInspector.TextUtils.isSpaceChar(text[0]))
|
| +return;if(tabRegex.test(text)){++tabLines;return;}
|
| +var i=0;while(i<text.length&&WebInspector.TextUtils.isSpaceChar(text[i]))
|
| +++i;if(i%2!==0)
|
| +return;indents[i]=1+(indents[i]||0);}
|
| +this._codeMirror.eachLine(processLine);var onePercentFilterThreshold=this.linesCount/100;if(tabLines&&tabLines>onePercentFilterThreshold)
|
| +return"\t";var minimumIndent=Infinity;for(var i in indents){if(indents[i]<onePercentFilterThreshold)
|
| +continue;var indent=parseInt(i,10);if(minimumIndent>indent)
|
| +minimumIndent=indent;}
|
| +if(minimumIndent===Infinity)
|
| +return WebInspector.TextUtils.Indent.FourSpaces;return new Array(minimumIndent+1).join(" ");},_updateEditorIndentation:function()
|
| +{var extraKeys={};var indent=WebInspector.settings.textEditorIndent.get();if(WebInspector.settings.textEditorAutoDetectIndent.get())
|
| +indent=this._guessIndentationLevel();if(indent===WebInspector.TextUtils.Indent.TabCharacter){this._codeMirror.setOption("indentWithTabs",true);this._codeMirror.setOption("indentUnit",4);}else{this._codeMirror.setOption("indentWithTabs",false);this._codeMirror.setOption("indentUnit",indent.length);extraKeys.Tab=function(codeMirror)
|
| +{if(codeMirror.somethingSelected())
|
| +return CodeMirror.Pass;var pos=codeMirror.getCursor("head");codeMirror.replaceRange(indent.substring(pos.ch%indent.length),codeMirror.getCursor());}}
|
| +this._codeMirror.setOption("extraKeys",extraKeys);this._indentationLevel=indent;},indent:function()
|
| +{return this._indentationLevel;},highlightSearchResults:function(regex,range)
|
| +{function innerHighlightRegex()
|
| +{if(range){this.revealLine(range.startLine);this.setSelection(WebInspector.TextRange.createFromLocation(range.startLine,range.startColumn));}else{this.setSelection(this.selection().collapseToEnd());}
|
| +this._tokenHighlighter.highlightSearchResults(regex,range);}
|
| +this._codeMirror.operation(innerHighlightRegex.bind(this));},cancelSearchResultsHighlight:function()
|
| +{this._codeMirror.operation(this._tokenHighlighter.highlightSelectedTokens.bind(this._tokenHighlighter));},undo:function()
|
| +{this._codeMirror.undo();},redo:function()
|
| +{this._codeMirror.redo();},_setupSelectionColor:function()
|
| +{if(WebInspector.CodeMirrorTextEditor._selectionStyleInjected)
|
| +return;WebInspector.CodeMirrorTextEditor._selectionStyleInjected=true;var backgroundColor=WebInspector.getSelectionBackgroundColor();var backgroundColorRule=backgroundColor?".CodeMirror .CodeMirror-selected { background-color: "+backgroundColor+";}":"";var foregroundColor=WebInspector.getSelectionForegroundColor();var foregroundColorRule=foregroundColor?".CodeMirror .CodeMirror-selectedtext:not(.CodeMirror-persist-highlight) { color: "+foregroundColor+"!important;}":"";if(!foregroundColorRule&&!backgroundColorRule)
|
| +return;var style=document.createElement("style");style.textContent=backgroundColorRule+foregroundColorRule;document.head.appendChild(style);},_setupWhitespaceHighlight:function()
|
| +{if(WebInspector.CodeMirrorTextEditor._whitespaceStyleInjected||!WebInspector.settings.showWhitespacesInEditor.get())
|
| +return;WebInspector.CodeMirrorTextEditor._whitespaceStyleInjected=true;const classBase=".cm-whitespace-";const spaceChar="ยท";var spaceChars="";var rules="";for(var i=1;i<=WebInspector.CodeMirrorTextEditor.MaximumNumberOfWhitespacesPerSingleSpan;++i){spaceChars+=spaceChar;var rule=classBase+i+"::before { content: '"+spaceChars+"';}\n";rules+=rule;}
|
| +rules+=".cm-tab:before { display: block !important; }\n";var style=document.createElement("style");style.textContent=rules;document.head.appendChild(style);},_handleKeyDown:function(e)
|
| +{if(this._autocompleteController.keyDown(e))
|
| +e.consume(true);},_shouldProcessWordForAutocompletion:function(word)
|
| +{return word.length&&(word[0]<'0'||word[0]>'9');},_addTextToCompletionDictionary:function(text)
|
| +{var words=WebInspector.TextUtils.textToWords(text);for(var i=0;i<words.length;++i){if(this._shouldProcessWordForAutocompletion(words[i]))
|
| +this._dictionary.addWord(words[i]);}},_removeTextFromCompletionDictionary:function(text)
|
| +{var words=WebInspector.TextUtils.textToWords(text);for(var i=0;i<words.length;++i){if(this._shouldProcessWordForAutocompletion(words[i]))
|
| +this._dictionary.removeWord(words[i]);}},setCompletionDictionary:function(dictionary)
|
| +{this._dictionary=dictionary;this._addTextToCompletionDictionary(this.text());},cursorPositionToCoordinates:function(lineNumber,column)
|
| +{if(lineNumber>=this._codeMirror.lineCount()||lineNumber<0||column<0||column>this._codeMirror.getLine(lineNumber).length)
|
| +return null;var metrics=this._codeMirror.cursorCoords(new CodeMirror.Pos(lineNumber,column));return{x:metrics.left,y:metrics.top,height:metrics.bottom-metrics.top};},coordinatesToCursorPosition:function(x,y)
|
| +{var element=document.elementFromPoint(x,y);if(!element||!element.isSelfOrDescendant(this._codeMirror.getWrapperElement()))
|
| +return null;var gutterBox=this._codeMirror.getGutterElement().boxInWindow();if(x>=gutterBox.x&&x<=gutterBox.x+gutterBox.width&&y>=gutterBox.y&&y<=gutterBox.y+gutterBox.height)
|
| +return null;var coords=this._codeMirror.coordsChar({left:x,top:y});return this._toRange(coords,coords);},tokenAtTextPosition:function(lineNumber,column)
|
| +{if(lineNumber<0||lineNumber>=this._codeMirror.lineCount())
|
| +return null;var token=this._codeMirror.getTokenAt(new CodeMirror.Pos(lineNumber,(column||0)+1));if(!token||!token.type)
|
| +return null;var convertedType=WebInspector.CodeMirrorUtils.convertTokenType(token.type);if(!convertedType)
|
| +return null;return{startColumn:token.start,endColumn:token.end-1,type:convertedType};},copyRange:function(textRange)
|
| +{var pos=this._toPos(textRange.normalize());return this._codeMirror.getRange(pos.start,pos.end);},isClean:function()
|
| +{return this._codeMirror.isClean();},markClean:function()
|
| +{this._codeMirror.markClean();},_hasLongLines:function()
|
| +{function lineIterator(lineHandle)
|
| +{if(lineHandle.text.length>WebInspector.CodeMirrorTextEditor.LongLineModeLineLengthThreshold)
|
| +hasLongLines=true;return hasLongLines;}
|
| +var hasLongLines=false;this._codeMirror.eachLine(lineIterator);return hasLongLines;},_whitespaceOverlayMode:function(mimeType)
|
| +{var modeName=CodeMirror.mimeModes[mimeType]+"+whitespaces";if(CodeMirror.modes[modeName])
|
| +return modeName;function modeConstructor(config,parserConfig)
|
| +{function nextToken(stream)
|
| +{if(stream.peek()===" "){var spaces=0;while(spaces<WebInspector.CodeMirrorTextEditor.MaximumNumberOfWhitespacesPerSingleSpan&&stream.peek()===" "){++spaces;stream.next();}
|
| +return"whitespace whitespace-"+spaces;}
|
| +while(!stream.eol()&&stream.peek()!==" ")
|
| +stream.next();return null;}
|
| +var whitespaceMode={token:nextToken};return CodeMirror.overlayMode(CodeMirror.getMode(config,mimeType),whitespaceMode,false);}
|
| +CodeMirror.defineMode(modeName,modeConstructor);return modeName;},_enableLongLinesMode:function()
|
| +{this._codeMirror.setOption("styleSelectedText",false);this._longLinesMode=true;},_disableLongLinesMode:function()
|
| +{this._codeMirror.setOption("styleSelectedText",true);this._longLinesMode=false;},_updateCodeMirrorMode:function()
|
| +{var showWhitespaces=WebInspector.settings.showWhitespacesInEditor.get();this._codeMirror.setOption("mode",showWhitespaces?this._whitespaceOverlayMode(this._mimeType):this._mimeType);},setMimeType:function(mimeType)
|
| +{this._mimeType=mimeType;if(this._hasLongLines())
|
| +this._enableLongLinesMode();else
|
| +this._disableLongLinesMode();this._updateCodeMirrorMode();},setReadOnly:function(readOnly)
|
| +{this.element.enableStyleClass("CodeMirror-readonly",readOnly)
|
| +this._codeMirror.setOption("readOnly",readOnly);},readOnly:function()
|
| +{return!!this._codeMirror.getOption("readOnly");},removeHighlight:function(highlightDescriptor)
|
| +{highlightDescriptor.clear();},highlightRange:function(range,cssClass)
|
| +{cssClass="CodeMirror-persist-highlight "+cssClass;var pos=this._toPos(range);++pos.end.ch;return this._codeMirror.markText(pos.start,pos.end,{className:cssClass,startStyle:cssClass+"-start",endStyle:cssClass+"-end"});},highlightRegex:function(regex,cssClass){},defaultFocusedElement:function()
|
| +{return this.element;},focus:function()
|
| +{this._codeMirror.focus();},_handleElementFocus:function()
|
| +{this._codeMirror.focus();},beginUpdates:function()
|
| +{++this._nestedUpdatesCounter;},endUpdates:function()
|
| +{if(!--this._nestedUpdatesCounter)
|
| +this._codeMirror.refresh();},revealLine:function(lineNumber)
|
| +{this._innerRevealLine(lineNumber,this._codeMirror.getScrollInfo());},_innerRevealLine:function(lineNumber,scrollInfo)
|
| +{var topLine=this._codeMirror.lineAtHeight(scrollInfo.top,"local");var bottomLine=this._codeMirror.lineAtHeight(scrollInfo.top+scrollInfo.clientHeight,"local");var linesPerScreen=bottomLine-topLine+1;if(lineNumber<topLine){var topLineToReveal=Math.max(lineNumber-(linesPerScreen/2)+1,0)|0;this._codeMirror.scrollIntoView(new CodeMirror.Pos(topLineToReveal,0));}else if(lineNumber>bottomLine){var bottomLineToReveal=Math.min(lineNumber+(linesPerScreen/2)-1,this.linesCount-1)|0;this._codeMirror.scrollIntoView(new CodeMirror.Pos(bottomLineToReveal,0));}},_gutterClick:function(instance,lineNumber,gutter,event)
|
| +{this.dispatchEventToListeners(WebInspector.TextEditor.Events.GutterClick,{lineNumber:lineNumber,event:event});},_contextMenu:function(event)
|
| +{var contextMenu=new WebInspector.ContextMenu(event);var target=event.target.enclosingNodeOrSelfWithClass("CodeMirror-gutter-elt");if(target)
|
| +this._delegate.populateLineGutterContextMenu(contextMenu,parseInt(target.textContent,10)-1);else
|
| +this._delegate.populateTextAreaContextMenu(contextMenu,0);contextMenu.show();},addBreakpoint:function(lineNumber,disabled,conditional)
|
| +{if(lineNumber<0||lineNumber>=this._codeMirror.lineCount())
|
| +return;var className="cm-breakpoint"+(conditional?" cm-breakpoint-conditional":"")+(disabled?" cm-breakpoint-disabled":"");this._codeMirror.addLineClass(lineNumber,"wrap",className);},removeBreakpoint:function(lineNumber)
|
| +{if(lineNumber<0||lineNumber>=this._codeMirror.lineCount())
|
| +return;var wrapClasses=this._codeMirror.getLineHandle(lineNumber).wrapClass;if(!wrapClasses)
|
| +return;var classes=wrapClasses.split(" ");for(var i=0;i<classes.length;++i){if(classes[i].startsWith("cm-breakpoint"))
|
| +this._codeMirror.removeLineClass(lineNumber,"wrap",classes[i]);}},setExecutionLine:function(lineNumber)
|
| +{this._executionLine=this._codeMirror.getLineHandle(lineNumber);this._codeMirror.addLineClass(this._executionLine,"wrap","cm-execution-line");},clearExecutionLine:function()
|
| +{if(this._executionLine)
|
| +this._codeMirror.removeLineClass(this._executionLine,"wrap","cm-execution-line");delete this._executionLine;},addDecoration:function(lineNumber,element)
|
| +{var widget=this._codeMirror.addLineWidget(lineNumber,element);this._elementToWidget.put(element,widget);},removeDecoration:function(lineNumber,element)
|
| +{var widget=this._elementToWidget.remove(element);if(widget)
|
| +this._codeMirror.removeLineWidget(widget);},highlightPosition:function(lineNumber,columnNumber)
|
| +{if(lineNumber<0)
|
| +return;lineNumber=Math.min(lineNumber,this._codeMirror.lineCount()-1);if(typeof columnNumber!=="number"||columnNumber<0||columnNumber>this._codeMirror.getLine(lineNumber).length)
|
| +columnNumber=0;this.clearPositionHighlight();this._highlightedLine=this._codeMirror.getLineHandle(lineNumber);if(!this._highlightedLine)
|
| +return;this.revealLine(lineNumber);this._codeMirror.addLineClass(this._highlightedLine,null,"cm-highlight");this._clearHighlightTimeout=setTimeout(this.clearPositionHighlight.bind(this),2000);if(!this.readOnly())
|
| +this._codeMirror.setSelection(new CodeMirror.Pos(lineNumber,columnNumber));},clearPositionHighlight:function()
|
| +{if(this._clearHighlightTimeout)
|
| +clearTimeout(this._clearHighlightTimeout);delete this._clearHighlightTimeout;if(this._highlightedLine)
|
| +this._codeMirror.removeLineClass(this._highlightedLine,null,"cm-highlight");delete this._highlightedLine;},elementsToRestoreScrollPositionsFor:function()
|
| +{return[];},inheritScrollPositions:function(textEditor)
|
| +{},_updatePaddingBottom:function(width,height)
|
| +{var scrollInfo=this._codeMirror.getScrollInfo();var newPaddingBottom;var linesElement=this.element.firstChild.querySelector(".CodeMirror-lines");var lineCount=this._codeMirror.lineCount();if(lineCount<=1)
|
| +newPaddingBottom=0;else
|
| +newPaddingBottom=Math.max(scrollInfo.clientHeight-this._codeMirror.getLineHandle(this._codeMirror.lastLine()).height,0);newPaddingBottom+="px";linesElement.style.paddingBottom=newPaddingBottom;this._codeMirror.setSize(width,height);},_resizeEditor:function()
|
| +{var parentElement=this.element.parentElement;if(!parentElement||!this.isShowing())
|
| +return;var scrollInfo=this._codeMirror.getScrollInfo();var width=parentElement.offsetWidth;var height=parentElement.offsetHeight;this._codeMirror.setSize(width,height);this._updatePaddingBottom(width,height);this._codeMirror.scrollTo(scrollInfo.left,scrollInfo.top);},onResize:function()
|
| +{this._resizeEditor();},editRange:function(range,text)
|
| +{var pos=this._toPos(range);this._codeMirror.replaceRange(text,pos.start,pos.end);var newRange=this._toRange(pos.start,this._codeMirror.posFromIndex(this._codeMirror.indexFromPos(pos.start)+text.length));this._delegate.onTextChanged(range,newRange);if(WebInspector.settings.textEditorAutoDetectIndent.get())
|
| +this._updateEditorIndentation();return newRange;},_wordRangeForCursorPosition:function(lineNumber,column,prefixOnly)
|
| +{var line=this.line(lineNumber);if(column===0||!WebInspector.TextUtils.isWordChar(line.charAt(column-1)))
|
| +return null;var wordStart=column-1;while(wordStart>0&&WebInspector.TextUtils.isWordChar(line.charAt(wordStart-1)))
|
| +--wordStart;if(prefixOnly)
|
| +return new WebInspector.TextRange(lineNumber,wordStart,lineNumber,column);var wordEnd=column;while(wordEnd<line.length&&WebInspector.TextUtils.isWordChar(line.charAt(wordEnd)))
|
| +++wordEnd;return new WebInspector.TextRange(lineNumber,wordStart,lineNumber,wordEnd);},_beforeChange:function(codeMirror,changeObject)
|
| +{if(!this._dictionary)
|
| +return;this._updatedLines=this._updatedLines||{};for(var i=changeObject.from.line;i<=changeObject.to.line;++i)
|
| +this._updatedLines[i]=this.line(i);},_change:function(codeMirror,changeObject)
|
| +{var hasOneLine=this._codeMirror.lineCount()===1;if(hasOneLine!==this._hasOneLine)
|
| +this._resizeEditor();this._hasOneLine=hasOneLine;var widgets=this._elementToWidget.values();for(var i=0;i<widgets.length;++i)
|
| +this._codeMirror.removeLineWidget(widgets[i]);this._elementToWidget.clear();if(this._updatedLines){for(var lineNumber in this._updatedLines)
|
| +this._removeTextFromCompletionDictionary(this._updatedLines[lineNumber]);delete this._updatedLines;}
|
| +var linesToUpdate={};var singleCharInput=false;do{var oldRange=this._toRange(changeObject.from,changeObject.to);var newRange=oldRange.clone();var linesAdded=changeObject.text.length;singleCharInput=(changeObject.origin==="+input"&&changeObject.text.length===1&&changeObject.text[0].length===1)||(changeObject.origin==="+delete"&&changeObject.removed.length===1&&changeObject.removed[0].length===1);if(linesAdded===0){newRange.endLine=newRange.startLine;newRange.endColumn=newRange.startColumn;}else if(linesAdded===1){newRange.endLine=newRange.startLine;newRange.endColumn=newRange.startColumn+changeObject.text[0].length;}else{newRange.endLine=newRange.startLine+linesAdded-1;newRange.endColumn=changeObject.text[linesAdded-1].length;}
|
| +if(!this._muteTextChangedEvent)
|
| +this._delegate.onTextChanged(oldRange,newRange);for(var i=newRange.startLine;i<=newRange.endLine;++i){linesToUpdate[i]=true;}
|
| +if(this._dictionary){for(var i=newRange.startLine;i<=newRange.endLine;++i)
|
| +linesToUpdate[i]=this.line(i);}}while(changeObject=changeObject.next);if(this._dictionary){for(var lineNumber in linesToUpdate)
|
| +this._addTextToCompletionDictionary(linesToUpdate[lineNumber]);}
|
| +if(singleCharInput)
|
| +this._autocompleteController.autocomplete();},_cursorActivity:function()
|
| +{var start=this._codeMirror.getCursor("anchor");var end=this._codeMirror.getCursor("head");this._delegate.selectionChanged(this._toRange(start,end));if(!this._tokenHighlighter.highlightedRegex())
|
| +this._codeMirror.operation(this._tokenHighlighter.highlightSelectedTokens.bind(this._tokenHighlighter));},_scroll:function()
|
| +{if(this._scrollTimer)
|
| +clearTimeout(this._scrollTimer);var topmostLineNumber=this._codeMirror.lineAtHeight(this._codeMirror.getScrollInfo().top,"local");this._scrollTimer=setTimeout(this._delegate.scrollChanged.bind(this._delegate,topmostLineNumber),100);},_focus:function()
|
| +{this._delegate.editorFocused();},_blur:function()
|
| +{this._autocompleteController.finishAutocomplete();},scrollToLine:function(lineNumber)
|
| +{var pos=new CodeMirror.Pos(lineNumber,0);var coords=this._codeMirror.charCoords(pos,"local");this._codeMirror.scrollTo(0,coords.top);},firstVisibleLine:function()
|
| +{return this._codeMirror.lineAtHeight(this._codeMirror.getScrollInfo().top,"local");},lastVisibleLine:function()
|
| +{var scrollInfo=this._codeMirror.getScrollInfo();return this._codeMirror.lineAtHeight(scrollInfo.top+scrollInfo.clientHeight,"local");},selection:function()
|
| +{var start=this._codeMirror.getCursor("anchor");var end=this._codeMirror.getCursor("head");return this._toRange(start,end);},lastSelection:function()
|
| +{return this._lastSelection;},setSelection:function(textRange)
|
| +{this._lastSelection=textRange;var pos=this._toPos(textRange);this._codeMirror.setSelection(pos.start,pos.end);},_detectLineSeparator:function(text)
|
| +{this._lineSeparator=text.indexOf("\r\n")>=0?"\r\n":"\n";},setText:function(text)
|
| +{this._muteTextChangedEvent=true;this._codeMirror.setValue(text);this._updateEditorIndentation();if(this._shouldClearHistory){this._codeMirror.clearHistory();this._shouldClearHistory=false;}
|
| +this._detectLineSeparator(text);delete this._muteTextChangedEvent;},text:function()
|
| +{return this._codeMirror.getValue().replace(/\n/g,this._lineSeparator);},range:function()
|
| +{var lineCount=this.linesCount;var lastLine=this._codeMirror.getLine(lineCount-1);return this._toRange(new CodeMirror.Pos(0,0),new CodeMirror.Pos(lineCount-1,lastLine.length));},line:function(lineNumber)
|
| +{return this._codeMirror.getLine(lineNumber);},get linesCount()
|
| +{return this._codeMirror.lineCount();},setAttribute:function(line,name,value)
|
| +{if(line<0||line>=this._codeMirror.lineCount())
|
| +return;var handle=this._codeMirror.getLineHandle(line);if(handle.attributes===undefined)handle.attributes={};handle.attributes[name]=value;},getAttribute:function(line,name)
|
| +{if(line<0||line>=this._codeMirror.lineCount())
|
| +return null;var handle=this._codeMirror.getLineHandle(line);return handle.attributes&&handle.attributes[name]!==undefined?handle.attributes[name]:null;},removeAttribute:function(line,name)
|
| +{if(line<0||line>=this._codeMirror.lineCount())
|
| +return;var handle=this._codeMirror.getLineHandle(line);if(handle&&handle.attributes)
|
| +delete handle.attributes[name];},_toPos:function(range)
|
| +{return{start:new CodeMirror.Pos(range.startLine,range.startColumn),end:new CodeMirror.Pos(range.endLine,range.endColumn)}},_toRange:function(start,end)
|
| +{return new WebInspector.TextRange(start.line,start.ch,end.line,end.ch);},__proto__:WebInspector.View.prototype}
|
| +WebInspector.CodeMirrorTextEditor.TokenHighlighter=function(codeMirror)
|
| +{this._codeMirror=codeMirror;}
|
| +WebInspector.CodeMirrorTextEditor.TokenHighlighter.prototype={highlightSearchResults:function(regex,range)
|
| +{var oldRegex=this._highlightRegex;this._highlightRegex=regex;this._highlightRange=range;if(this._searchResultMarker){this._searchResultMarker.clear();delete this._searchResultMarker;}
|
| +if(this._highlightDescriptor&&this._highlightDescriptor.selectionStart)
|
| +this._codeMirror.removeLineClass(this._highlightDescriptor.selectionStart.line,"wrap","cm-line-with-selection");var selectionStart=this._highlightRange?new CodeMirror.Pos(this._highlightRange.startLine,this._highlightRange.startColumn):null;if(selectionStart)
|
| +this._codeMirror.addLineClass(selectionStart.line,"wrap","cm-line-with-selection");if(this._highlightRegex===oldRegex){if(this._highlightDescriptor)
|
| +this._highlightDescriptor.selectionStart=selectionStart;}else{this._removeHighlight();this._setHighlighter(this._searchHighlighter.bind(this,this._highlightRegex,this._highlightRange),selectionStart);}
|
| +if(selectionStart){var pos=WebInspector.CodeMirrorTextEditor.prototype._toPos(this._highlightRange);this._searchResultMarker=this._codeMirror.markText(pos.start,pos.end,{className:"cm-column-with-selection"});}},highlightedRegex:function()
|
| +{return this._highlightRegex;},highlightSelectedTokens:function()
|
| +{delete this._highlightRegex;delete this._highlightRange;if(this._highlightDescriptor&&this._highlightDescriptor.selectionStart)
|
| +this._codeMirror.removeLineClass(this._highlightDescriptor.selectionStart.line,"wrap","cm-line-with-selection");this._removeHighlight();var selectionStart=this._codeMirror.getCursor("start");var selectionEnd=this._codeMirror.getCursor("end");if(selectionStart.line!==selectionEnd.line)
|
| +return;if(selectionStart.ch===selectionEnd.ch)
|
| +return;var selectedText=this._codeMirror.getSelection();if(this._isWord(selectedText,selectionStart.line,selectionStart.ch,selectionEnd.ch)){if(selectionStart)
|
| +this._codeMirror.addLineClass(selectionStart.line,"wrap","cm-line-with-selection")
|
| +this._setHighlighter(this._tokenHighlighter.bind(this,selectedText,selectionStart),selectionStart);}},_isWord:function(selectedText,lineNumber,startColumn,endColumn)
|
| +{var line=this._codeMirror.getLine(lineNumber);var leftBound=startColumn===0||!WebInspector.TextUtils.isWordChar(line.charAt(startColumn-1));var rightBound=endColumn===line.length||!WebInspector.TextUtils.isWordChar(line.charAt(endColumn));return leftBound&&rightBound&&WebInspector.TextUtils.isWord(selectedText);},_removeHighlight:function()
|
| +{if(this._highlightDescriptor){this._codeMirror.removeOverlay(this._highlightDescriptor.overlay);delete this._highlightDescriptor;}},_searchHighlighter:function(regex,range,stream)
|
| +{if(stream.column()===0)
|
| +delete this._searchMatchLength;if(this._searchMatchLength){if(this._searchMatchLength>1){for(var i=0;i<this._searchMatchLength-2;++i)
|
| +stream.next();this._searchMatchLength=1;return"search-highlight";}else{stream.next();delete this._searchMatchLength;return"search-highlight search-highlight-end";}}
|
| +var match=stream.match(regex,false);if(match){stream.next();var matchLength=match[0].length;if(matchLength===1)
|
| +return"search-highlight search-highlight-full";this._searchMatchLength=matchLength;return"search-highlight search-highlight-start";}
|
| +while(!stream.match(regex,false)&&stream.next()){};},_tokenHighlighter:function(token,selectionStart,stream)
|
| +{var tokenFirstChar=token.charAt(0);if(stream.match(token)&&(stream.eol()||!WebInspector.TextUtils.isWordChar(stream.peek())))
|
| +return stream.column()===selectionStart.ch?"token-highlight column-with-selection":"token-highlight";var eatenChar;do{eatenChar=stream.next();}while(eatenChar&&(WebInspector.TextUtils.isWordChar(eatenChar)||stream.peek()!==tokenFirstChar));},_setHighlighter:function(highlighter,selectionStart)
|
| +{var overlayMode={token:highlighter};this._codeMirror.addOverlay(overlayMode);this._highlightDescriptor={overlay:overlayMode,selectionStart:selectionStart};}}
|
| +WebInspector.CodeMirrorTextEditor.BlockIndentController=function(codeMirror)
|
| +{codeMirror.addKeyMap(this);}
|
| +WebInspector.CodeMirrorTextEditor.BlockIndentController.prototype={name:"blockIndentKeymap",Enter:function(codeMirror)
|
| +{if(codeMirror.somethingSelected())
|
| +return CodeMirror.Pass;var cursor=codeMirror.getCursor();if(cursor.ch===0)
|
| +return CodeMirror.Pass;var line=codeMirror.getLine(cursor.line);if(line.substr(cursor.ch-1,2)==="{}"){codeMirror.execCommand("newlineAndIndent");codeMirror.setCursor(cursor);codeMirror.execCommand("newlineAndIndent");codeMirror.execCommand("indentMore");}else if(line.substr(cursor.ch-1,1)==="{"){codeMirror.execCommand("newlineAndIndent");codeMirror.execCommand("indentMore");}else
|
| +return CodeMirror.Pass;},"'}'":function(codeMirror)
|
| +{var cursor=codeMirror.getCursor();var line=codeMirror.getLine(cursor.line);for(var i=0;i<line.length;++i)
|
| +if(!WebInspector.TextUtils.isSpaceChar(line.charAt(i)))
|
| +return CodeMirror.Pass;codeMirror.replaceRange("}",cursor);var matchingBracket=codeMirror.findMatchingBracket();if(!matchingBracket||!matchingBracket.match)
|
| +return;line=codeMirror.getLine(matchingBracket.to.line);var desiredIndentation=0;while(desiredIndentation<line.length&&WebInspector.TextUtils.isSpaceChar(line.charAt(desiredIndentation)))
|
| +++desiredIndentation;codeMirror.replaceRange(line.substr(0,desiredIndentation)+"}",new CodeMirror.Pos(cursor.line,0),new CodeMirror.Pos(cursor.line,cursor.ch+1));}}
|
| +WebInspector.CodeMirrorTextEditor.FixWordMovement=function(codeMirror)
|
| +{function moveLeft(shift,codeMirror)
|
| +{var cursor=codeMirror.getCursor("head");if(cursor.ch!==0||cursor.line===0)
|
| +return CodeMirror.Pass;codeMirror.setExtending(shift);codeMirror.execCommand("goLineUp");codeMirror.execCommand("goLineEnd")
|
| +codeMirror.setExtending(false);}
|
| +function moveRight(shift,codeMirror)
|
| +{var cursor=codeMirror.getCursor("head");var line=codeMirror.getLine(cursor.line);if(cursor.ch!==line.length||cursor.line+1===codeMirror.lineCount())
|
| +return CodeMirror.Pass;codeMirror.setExtending(shift);codeMirror.execCommand("goLineDown");codeMirror.execCommand("goLineStart");codeMirror.setExtending(false);}
|
| +function delWordBack(codeMirror)
|
| +{if(codeMirror.somethingSelected())
|
| +return CodeMirror.Pass;var cursor=codeMirror.getCursor("head");if(cursor.ch===0)
|
| +codeMirror.execCommand("delCharBefore");else
|
| +return CodeMirror.Pass;}
|
| +var modifierKey=WebInspector.isMac()?"Alt":"Ctrl";var leftKey=modifierKey+"-Left";var rightKey=modifierKey+"-Right";var keyMap={};keyMap[leftKey]=moveLeft.bind(this,false);keyMap[rightKey]=moveRight.bind(this,false);keyMap["Shift-"+leftKey]=moveLeft.bind(this,true);keyMap["Shift-"+rightKey]=moveRight.bind(this,true);keyMap[modifierKey+"-Backspace"]=delWordBack.bind(this);codeMirror.addKeyMap(keyMap);}
|
| +WebInspector.CodeMirrorTextEditor.AutocompleteController=function(textEditor,codeMirror)
|
| +{this._textEditor=textEditor;this._codeMirror=codeMirror;this._codeMirror.on("scroll",this._onScroll.bind(this));this._codeMirror.on("cursorActivity",this._onCursorActivity.bind(this));}
|
| +WebInspector.CodeMirrorTextEditor.AutocompleteController.prototype={autocomplete:function()
|
| +{var dictionary=this._textEditor._dictionary;if(!dictionary||this._codeMirror.somethingSelected()){this.finishAutocomplete();return;}
|
| +var cursor=this._codeMirror.getCursor();var substituteRange=this._textEditor._wordRangeForCursorPosition(cursor.line,cursor.ch,false);if(!substituteRange||substituteRange.startColumn===cursor.ch){this.finishAutocomplete();return;}
|
| +var prefixRange=substituteRange.clone();prefixRange.endColumn=cursor.ch;var substituteWord=this._textEditor.copyRange(substituteRange);var hasPrefixInDictionary=dictionary.hasWord(substituteWord);if(hasPrefixInDictionary)
|
| +dictionary.removeWord(substituteWord);var wordsWithPrefix=dictionary.wordsWithPrefix(this._textEditor.copyRange(prefixRange));if(hasPrefixInDictionary)
|
| +dictionary.addWord(substituteWord);function sortSuggestions(a,b)
|
| +{return dictionary.wordCount(b)-dictionary.wordCount(a)||a.length-b.length;}
|
| +wordsWithPrefix.sort(sortSuggestions);if(!this._suggestBox){this._suggestBox=new WebInspector.SuggestBox(this,this._textEditor.element,"generic-suggest",6);this._anchorBox=this._anchorBoxForPosition(cursor.line,cursor.ch);}
|
| +this._suggestBox.updateSuggestions(this._anchorBox,wordsWithPrefix,0,true,this._textEditor.copyRange(prefixRange));this._prefixRange=prefixRange;if(!this._suggestBox.visible())
|
| +this.finishAutocomplete();},finishAutocomplete:function()
|
| +{if(!this._suggestBox)
|
| +return;this._suggestBox.hide();this._suggestBox=null;this._prefixRange=null;this._anchorBox=null;},keyDown:function(e)
|
| +{if(!this._suggestBox)
|
| +return false;if(e.keyCode===WebInspector.KeyboardShortcut.Keys.Esc.code){this.finishAutocomplete();return true;}
|
| +if(e.keyCode===WebInspector.KeyboardShortcut.Keys.Tab.code){this._suggestBox.acceptSuggestion();this.finishAutocomplete();return true;}
|
| +return this._suggestBox.keyPressed(e);},applySuggestion:function(suggestion,isIntermediateSuggestion)
|
| +{this._currentSuggestion=suggestion;},acceptSuggestion:function()
|
| +{if(this._prefixRange.endColumn-this._prefixRange.startColumn!==this._currentSuggestion.length){var pos=this._textEditor._toPos(this._prefixRange);this._codeMirror.replaceRange(this._currentSuggestion,pos.start,pos.end,"+autocomplete");}},_onScroll:function()
|
| +{if(!this._suggestBox)
|
| +return;var cursor=this._codeMirror.getCursor();var scrollInfo=this._codeMirror.getScrollInfo();var topmostLineNumber=this._codeMirror.lineAtHeight(scrollInfo.top,"local");var bottomLine=this._codeMirror.lineAtHeight(scrollInfo.top+scrollInfo.clientHeight,"local");if(cursor.line<topmostLineNumber||cursor.line>bottomLine)
|
| +this.finishAutocomplete();else{this._anchorBox=this._anchorBoxForPosition(cursor.line,cursor.ch);this._suggestBox.setPosition(this._anchorBox);}},_onCursorActivity:function()
|
| +{if(!this._suggestBox)
|
| +return;var cursor=this._codeMirror.getCursor();if(cursor.line!==this._prefixRange.startLine||cursor.ch>this._prefixRange.endColumn||cursor.ch<this._prefixRange.startColumn)
|
| +this.finishAutocomplete();},_anchorBoxForPosition:function(line,column)
|
| +{var metrics=this._textEditor.cursorPositionToCoordinates(line,column);return metrics?new AnchorBox(metrics.x,metrics.y,0,metrics.height):null;},}
|
|
|