erp_app 3.0.10 → 3.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/erp_app/version.rb +1 -1
- data/public/javascripts/erp_app/codemirror/README.md +1 -1
- data/public/javascripts/erp_app/codemirror/doc/compress.html +11 -3
- data/public/javascripts/erp_app/codemirror/doc/docs.css +16 -5
- data/public/javascripts/erp_app/codemirror/doc/internals.html +6 -3
- data/public/javascripts/erp_app/codemirror/doc/manual.html +103 -41
- data/public/javascripts/erp_app/codemirror/doc/oldrelease.html +43 -5
- data/public/javascripts/erp_app/codemirror/doc/reporting.html +6 -3
- data/public/javascripts/erp_app/codemirror/doc/upgrade_v2.2.html +7 -4
- data/public/javascripts/erp_app/codemirror/keymap/vim.js +10 -6
- data/public/javascripts/erp_app/codemirror/lib/codemirror.css +16 -12
- data/public/javascripts/erp_app/codemirror/lib/codemirror.js +699 -787
- data/public/javascripts/erp_app/codemirror/lib/util/closetag.js +35 -35
- data/public/javascripts/erp_app/codemirror/lib/util/dialog.js +4 -1
- data/public/javascripts/erp_app/codemirror/lib/util/formatting.js +147 -253
- data/public/javascripts/erp_app/codemirror/lib/util/javascript-hint.js +3 -3
- data/public/javascripts/erp_app/codemirror/lib/util/loadmode.js +1 -1
- data/public/javascripts/erp_app/codemirror/lib/util/multiplex.js +5 -9
- data/public/javascripts/erp_app/codemirror/lib/util/overlay.js +3 -1
- data/public/javascripts/erp_app/codemirror/lib/util/pig-hint.js +1 -1
- data/public/javascripts/erp_app/codemirror/lib/util/runmode-standalone.js +90 -0
- data/public/javascripts/erp_app/codemirror/lib/util/runmode.js +8 -4
- data/public/javascripts/erp_app/codemirror/lib/util/search.js +4 -4
- data/public/javascripts/erp_app/codemirror/lib/util/searchcursor.js +13 -11
- data/public/javascripts/erp_app/codemirror/lib/util/simple-hint.js +89 -68
- data/public/javascripts/erp_app/codemirror/lib/util/xml-hint.js +8 -8
- data/public/javascripts/erp_app/codemirror/mode/clike/clike.js +6 -2
- data/public/javascripts/erp_app/codemirror/mode/clike/index.html +1 -0
- data/public/javascripts/erp_app/codemirror/mode/clike/scala.html +1 -0
- data/public/javascripts/erp_app/codemirror/mode/clojure/clojure.js +8 -9
- data/public/javascripts/erp_app/codemirror/mode/clojure/index.html +1 -0
- data/public/javascripts/erp_app/codemirror/mode/coffeescript/coffeescript.js +3 -3
- data/public/javascripts/erp_app/codemirror/mode/coffeescript/index.html +1 -0
- data/public/javascripts/erp_app/codemirror/mode/commonlisp/commonlisp.js +101 -0
- data/public/javascripts/erp_app/codemirror/mode/commonlisp/index.html +165 -0
- data/public/javascripts/erp_app/codemirror/mode/css/css.js +339 -15
- data/public/javascripts/erp_app/codemirror/mode/css/index.html +3 -0
- data/public/javascripts/erp_app/codemirror/mode/css/test.js +501 -0
- data/public/javascripts/erp_app/codemirror/mode/diff/index.html +1 -0
- data/public/javascripts/erp_app/codemirror/mode/ecl/ecl.js +1 -1
- data/public/javascripts/erp_app/codemirror/mode/erlang/index.html +1 -0
- data/public/javascripts/erp_app/codemirror/mode/gfm/gfm.js +10 -4
- data/public/javascripts/erp_app/codemirror/mode/gfm/index.html +1 -0
- data/public/javascripts/erp_app/codemirror/mode/go/go.js +2 -2
- data/public/javascripts/erp_app/codemirror/mode/go/index.html +1 -0
- data/public/javascripts/erp_app/codemirror/mode/groovy/groovy.js +1 -1
- data/public/javascripts/erp_app/codemirror/mode/groovy/index.html +1 -0
- data/public/javascripts/erp_app/codemirror/mode/haskell/haskell.js +2 -2
- data/public/javascripts/erp_app/codemirror/mode/haskell/index.html +1 -0
- data/public/javascripts/erp_app/codemirror/mode/haxe/haxe.js +4 -7
- data/public/javascripts/erp_app/codemirror/mode/haxe/index.html +1 -0
- data/public/javascripts/erp_app/codemirror/mode/htmlembedded/htmlembedded.js +8 -4
- data/public/javascripts/erp_app/codemirror/mode/htmlembedded/index.html +1 -0
- data/public/javascripts/erp_app/codemirror/mode/htmlmixed/htmlmixed.js +12 -13
- data/public/javascripts/erp_app/codemirror/mode/htmlmixed/index.html +1 -0
- data/public/javascripts/erp_app/codemirror/mode/javascript/index.html +1 -0
- data/public/javascripts/erp_app/codemirror/mode/javascript/javascript.js +3 -3
- data/public/javascripts/erp_app/codemirror/mode/jinja2/index.html +1 -0
- data/public/javascripts/erp_app/codemirror/mode/less/index.html +124 -2
- data/public/javascripts/erp_app/codemirror/mode/less/less.js +94 -60
- data/public/javascripts/erp_app/codemirror/mode/lua/index.html +1 -0
- data/public/javascripts/erp_app/codemirror/mode/markdown/index.html +3 -0
- data/public/javascripts/erp_app/codemirror/mode/markdown/markdown.js +134 -20
- data/public/javascripts/erp_app/codemirror/mode/markdown/test.js +1084 -0
- data/public/javascripts/erp_app/codemirror/mode/mysql/index.html +1 -0
- data/public/javascripts/erp_app/codemirror/mode/ntriples/index.html +1 -0
- data/public/javascripts/erp_app/codemirror/mode/ntriples/ntriples.js +4 -4
- data/public/javascripts/erp_app/codemirror/mode/ocaml/ocaml.js +1 -1
- data/public/javascripts/erp_app/codemirror/mode/pascal/index.html +1 -0
- data/public/javascripts/erp_app/codemirror/mode/pascal/pascal.js +1 -1
- data/public/javascripts/erp_app/codemirror/mode/perl/index.html +1 -0
- data/public/javascripts/erp_app/codemirror/mode/perl/perl.js +71 -71
- data/public/javascripts/erp_app/codemirror/mode/php/index.html +1 -0
- data/public/javascripts/erp_app/codemirror/mode/php/php.js +7 -9
- data/public/javascripts/erp_app/codemirror/mode/pig/index.html +1 -0
- data/public/javascripts/erp_app/codemirror/mode/pig/pig.js +3 -3
- data/public/javascripts/erp_app/codemirror/mode/plsql/index.html +1 -0
- data/public/javascripts/erp_app/codemirror/mode/properties/index.html +1 -0
- data/public/javascripts/erp_app/codemirror/mode/python/index.html +1 -0
- data/public/javascripts/erp_app/codemirror/mode/python/python.js +1 -1
- data/public/javascripts/erp_app/codemirror/mode/r/index.html +1 -0
- data/public/javascripts/erp_app/codemirror/mode/rpm/changes/index.html +1 -0
- data/public/javascripts/erp_app/codemirror/mode/rpm/spec/index.html +1 -0
- data/public/javascripts/erp_app/codemirror/mode/rst/index.html +1 -0
- data/public/javascripts/erp_app/codemirror/mode/ruby/index.html +1 -0
- data/public/javascripts/erp_app/codemirror/mode/rust/index.html +1 -0
- data/public/javascripts/erp_app/codemirror/mode/scheme/index.html +1 -0
- data/public/javascripts/erp_app/codemirror/mode/scheme/scheme.js +1 -1
- data/public/javascripts/erp_app/codemirror/mode/shell/shell.js +2 -2
- data/public/javascripts/erp_app/codemirror/mode/sieve/LICENSE +23 -0
- data/public/javascripts/erp_app/codemirror/mode/sieve/index.html +81 -0
- data/public/javascripts/erp_app/codemirror/mode/sieve/sieve.js +156 -0
- data/public/javascripts/erp_app/codemirror/mode/smalltalk/index.html +1 -0
- data/public/javascripts/erp_app/codemirror/mode/smalltalk/smalltalk.js +2 -2
- data/public/javascripts/erp_app/codemirror/mode/smarty/index.html +1 -0
- data/public/javascripts/erp_app/codemirror/mode/smarty/smarty.js +2 -2
- data/public/javascripts/erp_app/codemirror/mode/sparql/index.html +1 -0
- data/public/javascripts/erp_app/codemirror/mode/stex/index.html +3 -0
- data/public/javascripts/erp_app/codemirror/mode/stex/stex.js +1 -1
- data/public/javascripts/erp_app/codemirror/mode/stex/test.js +343 -0
- data/public/javascripts/erp_app/codemirror/mode/tiddlywiki/index.html +1 -0
- data/public/javascripts/erp_app/codemirror/mode/tiki/index.html +1 -0
- data/public/javascripts/erp_app/codemirror/mode/tiki/tiki.js +4 -11
- data/public/javascripts/erp_app/codemirror/mode/vb/index.html +1 -0
- data/public/javascripts/erp_app/codemirror/mode/vb/vb.js +2 -2
- data/public/javascripts/erp_app/codemirror/mode/vbscript/index.html +1 -0
- data/public/javascripts/erp_app/codemirror/mode/velocity/index.html +1 -0
- data/public/javascripts/erp_app/codemirror/mode/velocity/velocity.js +1 -1
- data/public/javascripts/erp_app/codemirror/mode/verilog/index.html +1 -0
- data/public/javascripts/erp_app/codemirror/mode/verilog/verilog.js +1 -1
- data/public/javascripts/erp_app/codemirror/mode/xml/index.html +2 -1
- data/public/javascripts/erp_app/codemirror/mode/xml/xml.js +2 -10
- data/public/javascripts/erp_app/codemirror/mode/xquery/index.html +3 -2
- data/public/javascripts/erp_app/codemirror/mode/xquery/xquery.js +7 -4
- data/public/javascripts/erp_app/codemirror/mode/yaml/index.html +1 -0
- data/public/javascripts/erp_app/codemirror/package.json +15 -23
- data/public/javascripts/erp_app/codemirror/test/driver.js +109 -22
- data/public/javascripts/erp_app/codemirror/test/index.html +129 -16
- data/public/javascripts/erp_app/codemirror/test/lint/lint.js +120 -0
- data/public/javascripts/erp_app/codemirror/test/lint/parse-js.js +1372 -0
- data/public/javascripts/erp_app/codemirror/test/mode_test.css +0 -12
- data/public/javascripts/erp_app/codemirror/test/mode_test.js +66 -27
- data/public/javascripts/erp_app/codemirror/test/phantom_driver.js +30 -0
- data/public/javascripts/erp_app/codemirror/test/run.js +32 -0
- data/public/javascripts/erp_app/codemirror/test/test.js +213 -8
- data/public/javascripts/erp_app/shared/dynamic_editable_grid.js +33 -27
- data/public/javascripts/erp_app/shared/dynamic_editable_grid_loader_panel.js +2 -1
- metadata +15 -3
- data/public/javascripts/erp_app/codemirror/mode/stex/test.html +0 -263
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
// CodeMirror version 2.
|
|
2
|
-
|
|
1
|
+
// CodeMirror version 2.34
|
|
2
|
+
|
|
3
3
|
// All functions that need access to the editor's state live inside
|
|
4
4
|
// the CodeMirror function. Below that, at the bottom of the file,
|
|
5
5
|
// some utilities are defined.
|
|
6
6
|
|
|
7
7
|
// CodeMirror is the only global var we claim
|
|
8
|
-
|
|
8
|
+
window.CodeMirror = (function() {
|
|
9
|
+
"use strict";
|
|
9
10
|
// This is the function that produces an editor instance. Its
|
|
10
11
|
// closure is used to store the editor state.
|
|
11
12
|
function CodeMirror(place, givenOptions) {
|
|
@@ -15,38 +16,33 @@ var CodeMirror = (function() {
|
|
|
15
16
|
if (defaults.hasOwnProperty(opt))
|
|
16
17
|
options[opt] = (givenOptions && givenOptions.hasOwnProperty(opt) ? givenOptions : defaults)[opt];
|
|
17
18
|
|
|
19
|
+
var input = elt("textarea", null, null, "position: absolute; padding: 0; width: 1px; height: 1em");
|
|
20
|
+
input.setAttribute("wrap", "off"); input.setAttribute("autocorrect", "off"); input.setAttribute("autocapitalize", "off");
|
|
21
|
+
// Wraps and hides input textarea
|
|
22
|
+
var inputDiv = elt("div", [input], null, "overflow: hidden; position: relative; width: 3px; height: 0px;");
|
|
23
|
+
// The empty scrollbar content, used solely for managing the scrollbar thumb.
|
|
24
|
+
var scrollbarInner = elt("div", null, "CodeMirror-scrollbar-inner");
|
|
25
|
+
// The vertical scrollbar. Horizontal scrolling is handled by the scroller itself.
|
|
26
|
+
var scrollbar = elt("div", [scrollbarInner], "CodeMirror-scrollbar");
|
|
27
|
+
// DIVs containing the selection and the actual code
|
|
28
|
+
var lineDiv = elt("div"), selectionDiv = elt("div", null, null, "position: relative; z-index: -1");
|
|
29
|
+
// Blinky cursor, and element used to ensure cursor fits at the end of a line
|
|
30
|
+
var cursor = elt("pre", "\u00a0", "CodeMirror-cursor"), widthForcer = elt("pre", "\u00a0", "CodeMirror-cursor", "visibility: hidden");
|
|
31
|
+
// Used to measure text size
|
|
32
|
+
var measure = elt("div", null, null, "position: absolute; width: 100%; height: 0px; overflow: hidden; visibility: hidden;");
|
|
33
|
+
var lineSpace = elt("div", [measure, cursor, widthForcer, selectionDiv, lineDiv], null, "position: relative; z-index: 0");
|
|
34
|
+
var gutterText = elt("div", null, "CodeMirror-gutter-text"), gutter = elt("div", [gutterText], "CodeMirror-gutter");
|
|
35
|
+
// Moved around its parent to cover visible view
|
|
36
|
+
var mover = elt("div", [gutter, elt("div", [lineSpace], "CodeMirror-lines")], null, "position: relative");
|
|
37
|
+
// Set to the height of the text, causes scrolling
|
|
38
|
+
var sizer = elt("div", [mover], null, "position: relative");
|
|
39
|
+
// Provides scrolling
|
|
40
|
+
var scroller = elt("div", [sizer], "CodeMirror-scroll");
|
|
41
|
+
scroller.setAttribute("tabIndex", "-1");
|
|
18
42
|
// The element in which the editor lives.
|
|
19
|
-
var wrapper =
|
|
20
|
-
wrapper.className = "CodeMirror" + (options.lineWrapping ? " CodeMirror-wrap" : "");
|
|
21
|
-
// This mess creates the base DOM structure for the editor.
|
|
22
|
-
wrapper.innerHTML =
|
|
23
|
-
'<div style="overflow: hidden; position: relative; width: 3px; height: 0px;">' + // Wraps and hides input textarea
|
|
24
|
-
'<textarea style="position: absolute; padding: 0; width: 1px; height: 1em" wrap="off" ' +
|
|
25
|
-
'autocorrect="off" autocapitalize="off"></textarea></div>' +
|
|
26
|
-
'<div class="CodeMirror-scrollbar">' + // The vertical scrollbar. Horizontal scrolling is handled by the scroller itself.
|
|
27
|
-
'<div class="CodeMirror-scrollbar-inner">' + // The empty scrollbar content, used solely for managing the scrollbar thumb.
|
|
28
|
-
'</div></div>' + // This must be before the scroll area because it's float-right.
|
|
29
|
-
'<div class="CodeMirror-scroll" tabindex="-1">' +
|
|
30
|
-
'<div style="position: relative">' + // Set to the height of the text, causes scrolling
|
|
31
|
-
'<div style="position: relative">' + // Moved around its parent to cover visible view
|
|
32
|
-
'<div class="CodeMirror-gutter"><div class="CodeMirror-gutter-text"></div></div>' +
|
|
33
|
-
// Provides positioning relative to (visible) text origin
|
|
34
|
-
'<div class="CodeMirror-lines"><div style="position: relative; z-index: 0">' +
|
|
35
|
-
// Used to measure text size
|
|
36
|
-
'<div style="position: absolute; width: 100%; height: 0px; overflow: hidden; visibility: hidden;"></div>' +
|
|
37
|
-
'<pre class="CodeMirror-cursor"> </pre>' + // Absolutely positioned blinky cursor
|
|
38
|
-
'<pre class="CodeMirror-cursor" style="visibility: hidden"> </pre>' + // Used to force a width
|
|
39
|
-
'<div style="position: relative; z-index: -1"></div><div></div>' + // DIVs containing the selection and the actual code
|
|
40
|
-
'</div></div></div></div></div>';
|
|
43
|
+
var wrapper = elt("div", [inputDiv, scrollbar, scroller], "CodeMirror" + (options.lineWrapping ? " CodeMirror-wrap" : ""));
|
|
41
44
|
if (place.appendChild) place.appendChild(wrapper); else place(wrapper);
|
|
42
|
-
|
|
43
|
-
var inputDiv = wrapper.firstChild, input = inputDiv.firstChild,
|
|
44
|
-
scroller = wrapper.lastChild, code = scroller.firstChild,
|
|
45
|
-
mover = code.firstChild, gutter = mover.firstChild, gutterText = gutter.firstChild,
|
|
46
|
-
lineSpace = gutter.nextSibling.firstChild, measure = lineSpace.firstChild,
|
|
47
|
-
cursor = measure.nextSibling, widthForcer = cursor.nextSibling,
|
|
48
|
-
selectionDiv = widthForcer.nextSibling, lineDiv = selectionDiv.nextSibling,
|
|
49
|
-
scrollbar = inputDiv.nextSibling, scrollbarInner = scrollbar.firstChild;
|
|
45
|
+
|
|
50
46
|
themeChanged(); keyMapChanged();
|
|
51
47
|
// Needed to hide big blue blinking cursor on Mobile Safari
|
|
52
48
|
if (ios) input.style.width = "0px";
|
|
@@ -58,33 +54,21 @@ var CodeMirror = (function() {
|
|
|
58
54
|
// Needed to handle Tab key in KHTML
|
|
59
55
|
if (khtml) inputDiv.style.height = "1px", inputDiv.style.position = "absolute";
|
|
60
56
|
|
|
61
|
-
// Check for OS X >= 10.7.
|
|
62
|
-
//
|
|
63
|
-
//
|
|
64
|
-
//
|
|
65
|
-
if (mac_geLion) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
// Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8).
|
|
69
|
-
scrollbar.className += " cm-sb-ie7";
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// Check for problem with IE innerHTML not working when we have a
|
|
73
|
-
// P (or similar) parent node.
|
|
74
|
-
try { stringWidth("x"); }
|
|
75
|
-
catch (e) {
|
|
76
|
-
if (e.message.match(/runtime/i))
|
|
77
|
-
e = new Error("A CodeMirror inside a P-style element does not work in Internet Explorer. (innerHTML bug)");
|
|
78
|
-
throw e;
|
|
79
|
-
}
|
|
57
|
+
// Check for OS X >= 10.7. This has transparent scrollbars, so the
|
|
58
|
+
// overlaying of one scrollbar with another won't work. This is a
|
|
59
|
+
// temporary hack to simply turn off the overlay scrollbar. See
|
|
60
|
+
// issue #727.
|
|
61
|
+
if (mac_geLion) { scrollbar.style.zIndex = -2; scrollbar.style.visibility = "hidden"; }
|
|
62
|
+
// Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8).
|
|
63
|
+
else if (ie_lt8) scrollbar.style.minWidth = "18px";
|
|
80
64
|
|
|
81
65
|
// Delayed object wrap timeouts, making sure only one is active. blinker holds an interval.
|
|
82
66
|
var poll = new Delayed(), highlight = new Delayed(), blinker;
|
|
83
67
|
|
|
84
68
|
// mode holds a mode API object. doc is the tree of Line objects,
|
|
85
|
-
//
|
|
86
|
-
// undo history (instance of History constructor).
|
|
87
|
-
var mode, doc = new BranchChunk([new LeafChunk([new Line("")])]),
|
|
69
|
+
// frontier is the point up to which the content has been parsed,
|
|
70
|
+
// and history the undo history (instance of History constructor).
|
|
71
|
+
var mode, doc = new BranchChunk([new LeafChunk([new Line("")])]), frontier = 0, focused;
|
|
88
72
|
loadMode();
|
|
89
73
|
// The selection. These are always maintained to point at valid
|
|
90
74
|
// positions. Inverted is used to remember that the user is
|
|
@@ -92,11 +76,11 @@ var CodeMirror = (function() {
|
|
|
92
76
|
var sel = {from: {line: 0, ch: 0}, to: {line: 0, ch: 0}, inverted: false};
|
|
93
77
|
// Selection-related flags. shiftSelecting obviously tracks
|
|
94
78
|
// whether the user is holding shift.
|
|
95
|
-
var shiftSelecting, lastClick, lastDoubleClick, lastScrollTop = 0,
|
|
79
|
+
var shiftSelecting, lastClick, lastDoubleClick, lastScrollTop = 0, draggingText,
|
|
96
80
|
overwrite = false, suppressEdits = false;
|
|
97
81
|
// Variables used by startOperation/endOperation to track what
|
|
98
82
|
// happened during the operation.
|
|
99
|
-
var updateInput, userSelChange, changes, textChanged, selectionChanged,
|
|
83
|
+
var updateInput, userSelChange, changes, textChanged, selectionChanged,
|
|
100
84
|
gutterDirty, callbacks;
|
|
101
85
|
// Current visible range (may be bigger than the view window).
|
|
102
86
|
var displayOffset = 0, showingFrom = 0, showingTo = 0, lastSizeC = 0;
|
|
@@ -105,8 +89,9 @@ var CodeMirror = (function() {
|
|
|
105
89
|
var bracketHighlighted;
|
|
106
90
|
// Tracks the maximum line length so that the horizontal scrollbar
|
|
107
91
|
// can be kept static when scrolling.
|
|
108
|
-
var maxLine =
|
|
109
|
-
var
|
|
92
|
+
var maxLine = getLine(0), updateMaxLine = false, maxLineChanged = true;
|
|
93
|
+
var pollingFast = false; // Ensures slowPoll doesn't cancel fastPoll
|
|
94
|
+
var goalColumn = null;
|
|
110
95
|
|
|
111
96
|
// Initialize the content.
|
|
112
97
|
operation(function(){setValue(options.value || ""); updateInput = false;})();
|
|
@@ -120,12 +105,13 @@ var CodeMirror = (function() {
|
|
|
120
105
|
// which point we can't mess with it anymore. Context menu is
|
|
121
106
|
// handled in onMouseDown for Gecko.
|
|
122
107
|
if (!gecko) connect(scroller, "contextmenu", onContextMenu);
|
|
123
|
-
connect(scroller, "scroll",
|
|
124
|
-
connect(scrollbar, "scroll",
|
|
108
|
+
connect(scroller, "scroll", onScrollMain);
|
|
109
|
+
connect(scrollbar, "scroll", onScrollBar);
|
|
125
110
|
connect(scrollbar, "mousedown", function() {if (focused) setTimeout(focusInput, 0);});
|
|
126
|
-
connect(
|
|
127
|
-
|
|
128
|
-
|
|
111
|
+
var resizeHandler = connect(window, "resize", function() {
|
|
112
|
+
if (wrapper.parentNode) updateDisplay(true);
|
|
113
|
+
else resizeHandler();
|
|
114
|
+
}, true);
|
|
129
115
|
connect(input, "keyup", operation(onKeyUp));
|
|
130
116
|
connect(input, "input", fastPoll);
|
|
131
117
|
connect(input, "keydown", operation(onKeyDown));
|
|
@@ -133,12 +119,12 @@ var CodeMirror = (function() {
|
|
|
133
119
|
connect(input, "focus", onFocus);
|
|
134
120
|
connect(input, "blur", onBlur);
|
|
135
121
|
|
|
122
|
+
function drag_(e) {
|
|
123
|
+
if (options.onDragEvent && options.onDragEvent(instance, addStop(e))) return;
|
|
124
|
+
e_stop(e);
|
|
125
|
+
}
|
|
136
126
|
if (options.dragDrop) {
|
|
137
127
|
connect(scroller, "dragstart", onDragStart);
|
|
138
|
-
function drag_(e) {
|
|
139
|
-
if (options.onDragEvent && options.onDragEvent(instance, addStop(e))) return;
|
|
140
|
-
e_stop(e);
|
|
141
|
-
}
|
|
142
128
|
connect(scroller, "dragenter", drag_);
|
|
143
129
|
connect(scroller, "dragover", drag_);
|
|
144
130
|
connect(scroller, "drop", operation(onDrop));
|
|
@@ -150,7 +136,7 @@ var CodeMirror = (function() {
|
|
|
150
136
|
}));
|
|
151
137
|
|
|
152
138
|
// Needed to handle Tab key in KHTML
|
|
153
|
-
if (khtml) connect(
|
|
139
|
+
if (khtml) connect(sizer, "mouseup", function() {
|
|
154
140
|
if (document.activeElement == input) input.blur();
|
|
155
141
|
focusInput();
|
|
156
142
|
});
|
|
@@ -183,12 +169,14 @@ var CodeMirror = (function() {
|
|
|
183
169
|
else if (option == "lineWrapping" && oldVal != value) operation(wrappingChanged)();
|
|
184
170
|
else if (option == "tabSize") updateDisplay(true);
|
|
185
171
|
else if (option == "keyMap") keyMapChanged();
|
|
186
|
-
if (option == "lineNumbers" || option == "gutter" || option == "firstLineNumber" ||
|
|
172
|
+
if (option == "lineNumbers" || option == "gutter" || option == "firstLineNumber" ||
|
|
173
|
+
option == "theme" || option == "lineNumberFormatter") {
|
|
187
174
|
gutterChanged();
|
|
188
175
|
updateDisplay(true);
|
|
189
176
|
}
|
|
190
177
|
},
|
|
191
178
|
getOption: function(option) {return options[option];},
|
|
179
|
+
getMode: function() {return mode;},
|
|
192
180
|
undo: operation(undo),
|
|
193
181
|
redo: operation(redo),
|
|
194
182
|
indentLine: operation(function(n, dir) {
|
|
@@ -207,13 +195,23 @@ var CodeMirror = (function() {
|
|
|
207
195
|
history.undone = histData.undone;
|
|
208
196
|
},
|
|
209
197
|
getHistory: function() {
|
|
210
|
-
|
|
211
|
-
|
|
198
|
+
function cp(arr) {
|
|
199
|
+
for (var i = 0, nw = [], nwelt; i < arr.length; ++i) {
|
|
200
|
+
nw.push(nwelt = []);
|
|
201
|
+
for (var j = 0, elt = arr[i]; j < elt.length; ++j) {
|
|
202
|
+
var old = [], cur = elt[j];
|
|
203
|
+
nwelt.push({start: cur.start, added: cur.added, old: old});
|
|
204
|
+
for (var k = 0; k < cur.old.length; ++k) old.push(hlText(cur.old[k]));
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
return nw;
|
|
208
|
+
}
|
|
209
|
+
return {done: cp(history.done), undone: cp(history.undone)};
|
|
212
210
|
},
|
|
213
211
|
matchBrackets: operation(function(){matchBrackets(true);}),
|
|
214
212
|
getTokenAt: operation(function(pos) {
|
|
215
213
|
pos = clipPos(pos);
|
|
216
|
-
return getLine(pos.line).getTokenAt(mode, getStateBefore(pos.line), pos.ch);
|
|
214
|
+
return getLine(pos.line).getTokenAt(mode, getStateBefore(pos.line), options.tabSize, pos.ch);
|
|
217
215
|
}),
|
|
218
216
|
getStateAfter: function(line) {
|
|
219
217
|
line = clipLine(line == null ? doc.size - 1: line);
|
|
@@ -250,15 +248,16 @@ var CodeMirror = (function() {
|
|
|
250
248
|
return line;
|
|
251
249
|
},
|
|
252
250
|
lineInfo: lineInfo,
|
|
251
|
+
getViewport: function() { return {from: showingFrom, to: showingTo};},
|
|
253
252
|
addWidget: function(pos, node, scroll, vert, horiz) {
|
|
254
253
|
pos = localCoords(clipPos(pos));
|
|
255
254
|
var top = pos.yBot, left = pos.x;
|
|
256
255
|
node.style.position = "absolute";
|
|
257
|
-
|
|
256
|
+
sizer.appendChild(node);
|
|
258
257
|
if (vert == "over") top = pos.y;
|
|
259
258
|
else if (vert == "near") {
|
|
260
259
|
var vspace = Math.max(scroller.offsetHeight, doc.height * textHeight()),
|
|
261
|
-
hspace = Math.max(
|
|
260
|
+
hspace = Math.max(sizer.clientWidth, lineSpace.clientWidth) - paddingLeft();
|
|
262
261
|
if (pos.yBot + node.offsetHeight > vspace && pos.y > node.offsetHeight)
|
|
263
262
|
top = pos.y - node.offsetHeight;
|
|
264
263
|
if (left + node.offsetWidth > hspace)
|
|
@@ -267,11 +266,11 @@ var CodeMirror = (function() {
|
|
|
267
266
|
node.style.top = (top + paddingTop()) + "px";
|
|
268
267
|
node.style.left = node.style.right = "";
|
|
269
268
|
if (horiz == "right") {
|
|
270
|
-
left =
|
|
269
|
+
left = sizer.clientWidth - node.offsetWidth;
|
|
271
270
|
node.style.right = "0px";
|
|
272
271
|
} else {
|
|
273
272
|
if (horiz == "left") left = 0;
|
|
274
|
-
else if (horiz == "middle") left = (
|
|
273
|
+
else if (horiz == "middle") left = (sizer.clientWidth - node.offsetWidth) / 2;
|
|
275
274
|
node.style.left = (left + paddingLeft()) + "px";
|
|
276
275
|
}
|
|
277
276
|
if (scroll)
|
|
@@ -339,7 +338,7 @@ var CodeMirror = (function() {
|
|
|
339
338
|
},
|
|
340
339
|
scrollTo: function(x, y) {
|
|
341
340
|
if (x != null) scroller.scrollLeft = x;
|
|
342
|
-
if (y != null) scrollbar.scrollTop = y;
|
|
341
|
+
if (y != null) scrollbar.scrollTop = scroller.scrollTop = y;
|
|
343
342
|
updateDisplay([]);
|
|
344
343
|
},
|
|
345
344
|
getScrollInfo: function() {
|
|
@@ -353,6 +352,7 @@ var CodeMirror = (function() {
|
|
|
353
352
|
}
|
|
354
353
|
if (width != null) wrapper.style.width = interpret(width);
|
|
355
354
|
if (height != null) scroller.style.height = interpret(height);
|
|
355
|
+
instance.refresh();
|
|
356
356
|
},
|
|
357
357
|
|
|
358
358
|
operation: function(f){return operation(f)();},
|
|
@@ -375,6 +375,12 @@ var CodeMirror = (function() {
|
|
|
375
375
|
for (var n = line; n; n = n.parent) n.height += diff;
|
|
376
376
|
}
|
|
377
377
|
|
|
378
|
+
function lineContent(line, wrapAt) {
|
|
379
|
+
if (!line.styles)
|
|
380
|
+
line.highlight(mode, line.stateAfter = getStateBefore(lineNo(line)), options.tabSize);
|
|
381
|
+
return line.getContent(options.tabSize, wrapAt, options.lineWrapping);
|
|
382
|
+
}
|
|
383
|
+
|
|
378
384
|
function setValue(code) {
|
|
379
385
|
var top = {line: 0, ch: 0};
|
|
380
386
|
updateLines(top, {line: doc.size - 1, ch: getLine(doc.size-1).text.length},
|
|
@@ -387,25 +393,30 @@ var CodeMirror = (function() {
|
|
|
387
393
|
return text.join(lineSep || "\n");
|
|
388
394
|
}
|
|
389
395
|
|
|
390
|
-
function
|
|
391
|
-
if (
|
|
392
|
-
|
|
393
|
-
|
|
396
|
+
function onScrollBar(e) {
|
|
397
|
+
if (scrollbar.scrollTop != lastScrollTop) {
|
|
398
|
+
lastScrollTop = scroller.scrollTop = scrollbar.scrollTop;
|
|
399
|
+
updateDisplay([]);
|
|
394
400
|
}
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
function onScrollMain(e) {
|
|
404
|
+
if (options.fixedGutter && gutter.style.left != scroller.scrollLeft + "px")
|
|
405
|
+
gutter.style.left = scroller.scrollLeft + "px";
|
|
406
|
+
if (scroller.scrollTop != lastScrollTop) {
|
|
407
|
+
lastScrollTop = scroller.scrollTop;
|
|
408
|
+
if (scrollbar.scrollTop != lastScrollTop)
|
|
409
|
+
scrollbar.scrollTop = lastScrollTop;
|
|
398
410
|
updateDisplay([]);
|
|
399
|
-
if (options.fixedGutter) gutter.style.left = scroller.scrollLeft + "px";
|
|
400
|
-
if (options.onScroll) options.onScroll(instance);
|
|
401
411
|
}
|
|
412
|
+
if (options.onScroll) options.onScroll(instance);
|
|
402
413
|
}
|
|
403
414
|
|
|
404
415
|
function onMouseDown(e) {
|
|
405
416
|
setShift(e_prop(e, "shiftKey"));
|
|
406
417
|
// Check whether this is a click in a widget
|
|
407
418
|
for (var n = e_target(e); n != wrapper; n = n.parentNode)
|
|
408
|
-
if (n.parentNode ==
|
|
419
|
+
if (n.parentNode == sizer && n != mover) return;
|
|
409
420
|
|
|
410
421
|
// See if this is a click in the gutter
|
|
411
422
|
for (var n = e_target(e); n != wrapper; n = n.parentNode)
|
|
@@ -448,21 +459,21 @@ var CodeMirror = (function() {
|
|
|
448
459
|
setSelectionUser(word.from, word.to);
|
|
449
460
|
} else { lastClick = {time: now, pos: start}; }
|
|
450
461
|
|
|
462
|
+
function dragEnd(e2) {
|
|
463
|
+
if (webkit) scroller.draggable = false;
|
|
464
|
+
draggingText = false;
|
|
465
|
+
up(); drop();
|
|
466
|
+
if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) {
|
|
467
|
+
e_preventDefault(e2);
|
|
468
|
+
setCursor(start.line, start.ch, true);
|
|
469
|
+
focusInput();
|
|
470
|
+
}
|
|
471
|
+
}
|
|
451
472
|
var last = start, going;
|
|
452
473
|
if (options.dragDrop && dragAndDrop && !options.readOnly && !posEq(sel.from, sel.to) &&
|
|
453
474
|
!posLess(start, sel.from) && !posLess(sel.to, start) && type == "single") {
|
|
454
475
|
// Let the drag handler handle this.
|
|
455
476
|
if (webkit) scroller.draggable = true;
|
|
456
|
-
function dragEnd(e2) {
|
|
457
|
-
if (webkit) scroller.draggable = false;
|
|
458
|
-
draggingText = false;
|
|
459
|
-
up(); drop();
|
|
460
|
-
if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) {
|
|
461
|
-
e_preventDefault(e2);
|
|
462
|
-
setCursor(start.line, start.ch, true);
|
|
463
|
-
focusInput();
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
477
|
var up = connect(document, "mouseup", operation(dragEnd), true);
|
|
467
478
|
var drop = connect(scroller, "drop", operation(dragEnd), true);
|
|
468
479
|
draggingText = true;
|
|
@@ -525,11 +536,12 @@ var CodeMirror = (function() {
|
|
|
525
536
|
}
|
|
526
537
|
function onDrop(e) {
|
|
527
538
|
if (options.onDragEvent && options.onDragEvent(instance, addStop(e))) return;
|
|
528
|
-
e
|
|
539
|
+
e_preventDefault(e);
|
|
529
540
|
var pos = posFromMouse(e, true), files = e.dataTransfer.files;
|
|
530
541
|
if (!pos || options.readOnly) return;
|
|
531
542
|
if (files && files.length && window.FileReader && window.File) {
|
|
532
|
-
|
|
543
|
+
var n = files.length, text = Array(n), read = 0;
|
|
544
|
+
var loadFile = function(file, i) {
|
|
533
545
|
var reader = new FileReader;
|
|
534
546
|
reader.onload = function() {
|
|
535
547
|
text[i] = reader.result;
|
|
@@ -542,8 +554,7 @@ var CodeMirror = (function() {
|
|
|
542
554
|
}
|
|
543
555
|
};
|
|
544
556
|
reader.readAsText(file);
|
|
545
|
-
}
|
|
546
|
-
var n = files.length, text = Array(n), read = 0;
|
|
557
|
+
};
|
|
547
558
|
for (var i = 0; i < n; ++i) loadFile(files[i], i);
|
|
548
559
|
} else {
|
|
549
560
|
// Don't do a replace if the drop happened inside of the selected text.
|
|
@@ -566,13 +577,10 @@ var CodeMirror = (function() {
|
|
|
566
577
|
function onDragStart(e) {
|
|
567
578
|
var txt = getSelection();
|
|
568
579
|
e.dataTransfer.setData("Text", txt);
|
|
569
|
-
|
|
580
|
+
|
|
570
581
|
// Use dummy image instead of default browsers image.
|
|
571
|
-
if (
|
|
572
|
-
|
|
573
|
-
img.scr = 'data:image/gif;base64,R0lGODdhAgACAIAAAAAAAP///ywAAAAAAgACAAACAoRRADs='; //1x1 image
|
|
574
|
-
e.dataTransfer.setDragImage(img, 0, 0);
|
|
575
|
-
}
|
|
582
|
+
if (e.dataTransfer.setDragImage)
|
|
583
|
+
e.dataTransfer.setDragImage(elt('img'), 0, 0);
|
|
576
584
|
}
|
|
577
585
|
|
|
578
586
|
function doHandleBinding(bound, dropShift) {
|
|
@@ -594,6 +602,7 @@ var CodeMirror = (function() {
|
|
|
594
602
|
}
|
|
595
603
|
return true;
|
|
596
604
|
}
|
|
605
|
+
var maybeTransition;
|
|
597
606
|
function handleKeyBinding(e) {
|
|
598
607
|
// Handle auto keymap transitions
|
|
599
608
|
var startMap = getKeyMap(options.keyMap), next = startMap.auto;
|
|
@@ -605,10 +614,11 @@ var CodeMirror = (function() {
|
|
|
605
614
|
}, 50);
|
|
606
615
|
|
|
607
616
|
var name = keyNames[e_prop(e, "keyCode")], handled = false;
|
|
617
|
+
var flipCtrlCmd = opera && mac;
|
|
608
618
|
if (name == null || e.altGraphKey) return false;
|
|
609
619
|
if (e_prop(e, "altKey")) name = "Alt-" + name;
|
|
610
|
-
if (e_prop(e, "ctrlKey")) name = "Ctrl-" + name;
|
|
611
|
-
if (e_prop(e, "metaKey")) name = "Cmd-" + name;
|
|
620
|
+
if (e_prop(e, flipCtrlCmd ? "metaKey" : "ctrlKey")) name = "Ctrl-" + name;
|
|
621
|
+
if (e_prop(e, flipCtrlCmd ? "ctrlKey" : "metaKey")) name = "Cmd-" + name;
|
|
612
622
|
|
|
613
623
|
var stopped = false;
|
|
614
624
|
function stop() { stopped = true; }
|
|
@@ -640,7 +650,7 @@ var CodeMirror = (function() {
|
|
|
640
650
|
return handled;
|
|
641
651
|
}
|
|
642
652
|
|
|
643
|
-
var lastStoppedKey = null
|
|
653
|
+
var lastStoppedKey = null;
|
|
644
654
|
function onKeyDown(e) {
|
|
645
655
|
if (!focused) onFocus();
|
|
646
656
|
if (ie && e.keyCode == 27) { e.returnValue = false; }
|
|
@@ -684,7 +694,6 @@ var CodeMirror = (function() {
|
|
|
684
694
|
focused = true;
|
|
685
695
|
if (scroller.className.search(/\bCodeMirror-focused\b/) == -1)
|
|
686
696
|
scroller.className += " CodeMirror-focused";
|
|
687
|
-
if (!leaveInputAlone) resetInput(true);
|
|
688
697
|
}
|
|
689
698
|
slowPoll();
|
|
690
699
|
restartBlink();
|
|
@@ -703,53 +712,20 @@ var CodeMirror = (function() {
|
|
|
703
712
|
setTimeout(function() {if (!focused) shiftSelecting = null;}, 150);
|
|
704
713
|
}
|
|
705
714
|
|
|
706
|
-
function chopDelta(delta) {
|
|
707
|
-
// Make sure we always scroll a little bit for any nonzero delta.
|
|
708
|
-
if (delta > 0.0 && delta < 1.0) return 1;
|
|
709
|
-
else if (delta > -1.0 && delta < 0.0) return -1;
|
|
710
|
-
else return Math.round(delta);
|
|
711
|
-
}
|
|
712
|
-
|
|
713
|
-
function onMouseWheel(e) {
|
|
714
|
-
var deltaX = 0, deltaY = 0;
|
|
715
|
-
if (e.type == "DOMMouseScroll") { // Firefox
|
|
716
|
-
var delta = -e.detail * 8.0;
|
|
717
|
-
if (e.axis == e.HORIZONTAL_AXIS) deltaX = delta;
|
|
718
|
-
else if (e.axis == e.VERTICAL_AXIS) deltaY = delta;
|
|
719
|
-
} else if (e.wheelDeltaX !== undefined && e.wheelDeltaY !== undefined) { // WebKit
|
|
720
|
-
deltaX = e.wheelDeltaX / 3.0;
|
|
721
|
-
deltaY = e.wheelDeltaY / 3.0;
|
|
722
|
-
} else if (e.wheelDelta !== undefined) { // IE or Opera
|
|
723
|
-
deltaY = e.wheelDelta / 3.0;
|
|
724
|
-
}
|
|
725
|
-
|
|
726
|
-
var scrolled = false;
|
|
727
|
-
deltaX = chopDelta(deltaX);
|
|
728
|
-
deltaY = chopDelta(deltaY);
|
|
729
|
-
if ((deltaX > 0 && scroller.scrollLeft > 0) ||
|
|
730
|
-
(deltaX < 0 && scroller.scrollLeft + scroller.clientWidth < scroller.scrollWidth)) {
|
|
731
|
-
scroller.scrollLeft -= deltaX;
|
|
732
|
-
scrolled = true;
|
|
733
|
-
}
|
|
734
|
-
if ((deltaY > 0 && scrollbar.scrollTop > 0) ||
|
|
735
|
-
(deltaY < 0 && scrollbar.scrollTop + scrollbar.clientHeight < scrollbar.scrollHeight)) {
|
|
736
|
-
scrollbar.scrollTop -= deltaY;
|
|
737
|
-
scrolled = true;
|
|
738
|
-
}
|
|
739
|
-
if (scrolled) e_stop(e);
|
|
740
|
-
}
|
|
741
|
-
|
|
742
715
|
// Replace the range from from to to by the strings in newText.
|
|
743
716
|
// Afterwards, set the selection to selFrom, selTo.
|
|
744
717
|
function updateLines(from, to, newText, selFrom, selTo) {
|
|
745
718
|
if (suppressEdits) return;
|
|
719
|
+
var old = [];
|
|
720
|
+
doc.iter(from.line, to.line + 1, function(line) {
|
|
721
|
+
old.push(newHL(line.text, line.markedSpans));
|
|
722
|
+
});
|
|
746
723
|
if (history) {
|
|
747
|
-
var old = [];
|
|
748
|
-
doc.iter(from.line, to.line + 1, function(line) { old.push(line.text); });
|
|
749
724
|
history.addChange(from.line, newText.length, old);
|
|
750
725
|
while (history.done.length > options.undoDepth) history.done.shift();
|
|
751
726
|
}
|
|
752
|
-
|
|
727
|
+
var lines = updateMarkedSpans(hlSpans(old[0]), hlSpans(lst(old)), from.ch, to.ch, newText);
|
|
728
|
+
updateLinesNoUndo(from, to, lines, selFrom, selTo);
|
|
753
729
|
}
|
|
754
730
|
function unredoHelper(from, to) {
|
|
755
731
|
if (!from.length) return;
|
|
@@ -757,11 +733,12 @@ var CodeMirror = (function() {
|
|
|
757
733
|
for (var i = set.length - 1; i >= 0; i -= 1) {
|
|
758
734
|
var change = set[i];
|
|
759
735
|
var replaced = [], end = change.start + change.added;
|
|
760
|
-
doc.iter(change.start, end, function(line) { replaced.push(line.text); });
|
|
736
|
+
doc.iter(change.start, end, function(line) { replaced.push(newHL(line.text, line.markedSpans)); });
|
|
761
737
|
out.push({start: change.start, added: change.old.length, old: replaced});
|
|
762
738
|
var pos = {line: change.start + change.old.length - 1,
|
|
763
|
-
ch: editEnd(replaced
|
|
764
|
-
updateLinesNoUndo({line: change.start, ch: 0}, {line: end - 1, ch: getLine(end-1).text.length},
|
|
739
|
+
ch: editEnd(hlText(lst(replaced)), hlText(lst(change.old)))};
|
|
740
|
+
updateLinesNoUndo({line: change.start, ch: 0}, {line: end - 1, ch: getLine(end-1).text.length},
|
|
741
|
+
change.old, pos, pos);
|
|
765
742
|
}
|
|
766
743
|
updateInput = true;
|
|
767
744
|
to.push(out);
|
|
@@ -769,95 +746,86 @@ var CodeMirror = (function() {
|
|
|
769
746
|
function undo() {unredoHelper(history.done, history.undone);}
|
|
770
747
|
function redo() {unredoHelper(history.undone, history.done);}
|
|
771
748
|
|
|
772
|
-
function updateLinesNoUndo(from, to,
|
|
749
|
+
function updateLinesNoUndo(from, to, lines, selFrom, selTo) {
|
|
773
750
|
if (suppressEdits) return;
|
|
774
|
-
var recomputeMaxLength = false, maxLineLength = maxLine.length;
|
|
751
|
+
var recomputeMaxLength = false, maxLineLength = maxLine.text.length;
|
|
775
752
|
if (!options.lineWrapping)
|
|
776
753
|
doc.iter(from.line, to.line + 1, function(line) {
|
|
777
754
|
if (!line.hidden && line.text.length == maxLineLength) {recomputeMaxLength = true; return true;}
|
|
778
755
|
});
|
|
779
|
-
if (from.line != to.line ||
|
|
756
|
+
if (from.line != to.line || lines.length > 1) gutterDirty = true;
|
|
780
757
|
|
|
781
758
|
var nlines = to.line - from.line, firstLine = getLine(from.line), lastLine = getLine(to.line);
|
|
782
|
-
|
|
783
|
-
|
|
759
|
+
var lastHL = lst(lines);
|
|
760
|
+
|
|
761
|
+
// First adjust the line structure
|
|
762
|
+
if (from.ch == 0 && to.ch == 0 && hlText(lastHL) == "") {
|
|
784
763
|
// This is a whole-line replace. Treated specially to make
|
|
785
764
|
// sure line objects move the way they are supposed to.
|
|
786
765
|
var added = [], prevLine = null;
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
} else lastLine.fixMarkStarts();
|
|
791
|
-
for (var i = 0, e = newText.length - 1; i < e; ++i)
|
|
792
|
-
added.push(Line.inheritMarks(newText[i], prevLine));
|
|
766
|
+
for (var i = 0, e = lines.length - 1; i < e; ++i)
|
|
767
|
+
added.push(new Line(hlText(lines[i]), hlSpans(lines[i])));
|
|
768
|
+
lastLine.update(lastLine.text, hlSpans(lastHL));
|
|
793
769
|
if (nlines) doc.remove(from.line, nlines, callbacks);
|
|
794
770
|
if (added.length) doc.insert(from.line, added);
|
|
795
771
|
} else if (firstLine == lastLine) {
|
|
796
|
-
if (
|
|
797
|
-
firstLine.
|
|
798
|
-
else {
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
firstLine.
|
|
802
|
-
|
|
803
|
-
for (var i = 1, e = newText.length - 1; i < e; ++i)
|
|
804
|
-
added.push(Line.inheritMarks(newText[i], firstLine));
|
|
805
|
-
added.push(lastLine);
|
|
772
|
+
if (lines.length == 1) {
|
|
773
|
+
firstLine.update(firstLine.text.slice(0, from.ch) + hlText(lines[0]) + firstLine.text.slice(to.ch), hlSpans(lines[0]));
|
|
774
|
+
} else {
|
|
775
|
+
for (var added = [], i = 1, e = lines.length - 1; i < e; ++i)
|
|
776
|
+
added.push(new Line(hlText(lines[i]), hlSpans(lines[i])));
|
|
777
|
+
added.push(new Line(hlText(lastHL) + firstLine.text.slice(to.ch), hlSpans(lastHL)));
|
|
778
|
+
firstLine.update(firstLine.text.slice(0, from.ch) + hlText(lines[0]), hlSpans(lines[0]));
|
|
806
779
|
doc.insert(from.line + 1, added);
|
|
807
780
|
}
|
|
808
|
-
} else if (
|
|
809
|
-
firstLine.
|
|
810
|
-
lastLine.replace(null, to.ch, "");
|
|
811
|
-
firstLine.append(lastLine);
|
|
781
|
+
} else if (lines.length == 1) {
|
|
782
|
+
firstLine.update(firstLine.text.slice(0, from.ch) + hlText(lines[0]) + lastLine.text.slice(to.ch), hlSpans(lines[0]));
|
|
812
783
|
doc.remove(from.line + 1, nlines, callbacks);
|
|
813
784
|
} else {
|
|
814
785
|
var added = [];
|
|
815
|
-
firstLine.
|
|
816
|
-
lastLine.
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
added.push(Line.inheritMarks(newText[i], firstLine));
|
|
786
|
+
firstLine.update(firstLine.text.slice(0, from.ch) + hlText(lines[0]), hlSpans(lines[0]));
|
|
787
|
+
lastLine.update(hlText(lastHL) + lastLine.text.slice(to.ch), hlSpans(lastHL));
|
|
788
|
+
for (var i = 1, e = lines.length - 1; i < e; ++i)
|
|
789
|
+
added.push(new Line(hlText(lines[i]), hlSpans(lines[i])));
|
|
820
790
|
if (nlines > 1) doc.remove(from.line + 1, nlines - 1, callbacks);
|
|
821
791
|
doc.insert(from.line + 1, added);
|
|
822
792
|
}
|
|
823
793
|
if (options.lineWrapping) {
|
|
824
794
|
var perLine = Math.max(5, scroller.clientWidth / charWidth() - 3);
|
|
825
|
-
doc.iter(from.line, from.line +
|
|
795
|
+
doc.iter(from.line, from.line + lines.length, function(line) {
|
|
826
796
|
if (line.hidden) return;
|
|
827
797
|
var guess = Math.ceil(line.text.length / perLine) || 1;
|
|
828
798
|
if (guess != line.height) updateLineHeight(line, guess);
|
|
829
799
|
});
|
|
830
800
|
} else {
|
|
831
|
-
doc.iter(from.line, from.line +
|
|
801
|
+
doc.iter(from.line, from.line + lines.length, function(line) {
|
|
832
802
|
var l = line.text;
|
|
833
803
|
if (!line.hidden && l.length > maxLineLength) {
|
|
834
|
-
maxLine =
|
|
804
|
+
maxLine = line; maxLineLength = l.length; maxLineChanged = true;
|
|
835
805
|
recomputeMaxLength = false;
|
|
836
806
|
}
|
|
837
807
|
});
|
|
838
808
|
if (recomputeMaxLength) updateMaxLine = true;
|
|
839
809
|
}
|
|
840
810
|
|
|
841
|
-
//
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
if (task < from.line) newWork.push(task);
|
|
847
|
-
else if (task > to.line) newWork.push(task + lendiff);
|
|
848
|
-
}
|
|
849
|
-
var hlEnd = from.line + Math.min(newText.length, 500);
|
|
850
|
-
highlightLines(from.line, hlEnd);
|
|
851
|
-
newWork.push(hlEnd);
|
|
852
|
-
work = newWork;
|
|
853
|
-
startWorker(100);
|
|
811
|
+
// Adjust frontier, schedule worker
|
|
812
|
+
frontier = Math.min(frontier, from.line);
|
|
813
|
+
startWorker(400);
|
|
814
|
+
|
|
815
|
+
var lendiff = lines.length - nlines - 1;
|
|
854
816
|
// Remember that these lines changed, for updating the display
|
|
855
817
|
changes.push({from: from.line, to: to.line + 1, diff: lendiff});
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
818
|
+
if (options.onChange) {
|
|
819
|
+
// Normalize lines to contain only strings, since that's what
|
|
820
|
+
// the change event handler expects
|
|
821
|
+
for (var i = 0; i < lines.length; ++i)
|
|
822
|
+
if (typeof lines[i] != "string") lines[i] = lines[i].text;
|
|
823
|
+
var changeObj = {from: from, to: to, text: lines};
|
|
824
|
+
if (textChanged) {
|
|
825
|
+
for (var cur = textChanged; cur.next; cur = cur.next) {}
|
|
826
|
+
cur.next = changeObj;
|
|
827
|
+
} else textChanged = changeObj;
|
|
828
|
+
}
|
|
861
829
|
|
|
862
830
|
// Update the selection
|
|
863
831
|
function updateLine(n) {return n <= Math.min(to.line, to.line + lendiff) ? n : n + lendiff;}
|
|
@@ -867,46 +835,43 @@ var CodeMirror = (function() {
|
|
|
867
835
|
|
|
868
836
|
function needsScrollbar() {
|
|
869
837
|
var realHeight = doc.height * textHeight() + 2 * paddingTop();
|
|
870
|
-
return realHeight
|
|
838
|
+
return realHeight * .99 > scroller.offsetHeight ? realHeight : false;
|
|
871
839
|
}
|
|
872
840
|
|
|
873
841
|
function updateVerticalScroll(scrollTop) {
|
|
874
842
|
var scrollHeight = needsScrollbar();
|
|
875
843
|
scrollbar.style.display = scrollHeight ? "block" : "none";
|
|
876
844
|
if (scrollHeight) {
|
|
877
|
-
scrollbarInner.style.height = scrollHeight + "px";
|
|
878
|
-
scrollbar.style.height = scroller.
|
|
879
|
-
if (scrollTop != null)
|
|
845
|
+
scrollbarInner.style.height = sizer.style.minHeight = scrollHeight + "px";
|
|
846
|
+
scrollbar.style.height = scroller.clientHeight + "px";
|
|
847
|
+
if (scrollTop != null) {
|
|
848
|
+
scrollbar.scrollTop = scroller.scrollTop = scrollTop;
|
|
849
|
+
// 'Nudge' the scrollbar to work around a Webkit bug where,
|
|
850
|
+
// in some situations, we'd end up with a scrollbar that
|
|
851
|
+
// reported its scrollTop (and looked) as expected, but
|
|
852
|
+
// *behaved* as if it was still in a previous state (i.e.
|
|
853
|
+
// couldn't scroll up, even though it appeared to be at the
|
|
854
|
+
// bottom).
|
|
855
|
+
if (webkit) setTimeout(function() {
|
|
856
|
+
if (scrollbar.scrollTop != scrollTop) return;
|
|
857
|
+
scrollbar.scrollTop = scrollTop + (scrollTop ? -1 : 1);
|
|
858
|
+
scrollbar.scrollTop = scrollTop;
|
|
859
|
+
}, 0);
|
|
860
|
+
}
|
|
861
|
+
} else {
|
|
862
|
+
sizer.style.minHeight = "";
|
|
880
863
|
}
|
|
881
864
|
// Position the mover div to align with the current virtual scroll position
|
|
882
|
-
mover.style.top =
|
|
883
|
-
}
|
|
884
|
-
|
|
885
|
-
// On Mac OS X Lion and up, detect whether the mouse is plugged in by measuring
|
|
886
|
-
// the width of a div with a scrollbar in it. If the width is <= 1, then
|
|
887
|
-
// the mouse isn't plugged in and scrollbars should overlap the content.
|
|
888
|
-
function overlapScrollbars() {
|
|
889
|
-
var tmpSb = document.createElement('div'),
|
|
890
|
-
tmpSbInner = document.createElement('div');
|
|
891
|
-
tmpSb.className = "CodeMirror-scrollbar";
|
|
892
|
-
tmpSb.style.cssText = "position: absolute; left: -9999px; height: 100px;";
|
|
893
|
-
tmpSbInner.className = "CodeMirror-scrollbar-inner";
|
|
894
|
-
tmpSbInner.style.height = "200px";
|
|
895
|
-
tmpSb.appendChild(tmpSbInner);
|
|
896
|
-
|
|
897
|
-
document.body.appendChild(tmpSb);
|
|
898
|
-
var result = (tmpSb.offsetWidth <= 1);
|
|
899
|
-
document.body.removeChild(tmpSb);
|
|
900
|
-
return result;
|
|
865
|
+
mover.style.top = displayOffset * textHeight() + "px";
|
|
901
866
|
}
|
|
902
867
|
|
|
903
868
|
function computeMaxLength() {
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
doc.iter(
|
|
869
|
+
maxLine = getLine(0); maxLineChanged = true;
|
|
870
|
+
var maxLineLength = maxLine.text.length;
|
|
871
|
+
doc.iter(1, doc.size, function(line) {
|
|
907
872
|
var l = line.text;
|
|
908
873
|
if (!line.hidden && l.length > maxLineLength) {
|
|
909
|
-
maxLineLength = l.length; maxLine =
|
|
874
|
+
maxLineLength = l.length; maxLine = line;
|
|
910
875
|
}
|
|
911
876
|
});
|
|
912
877
|
updateMaxLine = false;
|
|
@@ -922,7 +887,7 @@ var CodeMirror = (function() {
|
|
|
922
887
|
var line = pos.line + code.length - (to.line - from.line) - 1;
|
|
923
888
|
var ch = pos.ch;
|
|
924
889
|
if (pos.line == to.line)
|
|
925
|
-
ch += code
|
|
890
|
+
ch += lst(code).length - (to.ch - (to.line == from.line ? from.ch : 0));
|
|
926
891
|
return {line: line, ch: ch};
|
|
927
892
|
}
|
|
928
893
|
var end;
|
|
@@ -940,7 +905,7 @@ var CodeMirror = (function() {
|
|
|
940
905
|
});
|
|
941
906
|
}
|
|
942
907
|
function replaceRange1(code, from, to, computeSel) {
|
|
943
|
-
var endch = code.length == 1 ? code[0].length + from.ch : code
|
|
908
|
+
var endch = code.length == 1 ? code[0].length + from.ch : lst(code).length;
|
|
944
909
|
var newSel = computeSel({line: from.line + code.length - 1, ch: endch});
|
|
945
910
|
updateLines(from, to, code, newSel.from, newSel.to);
|
|
946
911
|
}
|
|
@@ -957,25 +922,20 @@ var CodeMirror = (function() {
|
|
|
957
922
|
return getRange(sel.from, sel.to, lineSep);
|
|
958
923
|
}
|
|
959
924
|
|
|
960
|
-
var pollingFast = false; // Ensures slowPoll doesn't cancel fastPoll
|
|
961
925
|
function slowPoll() {
|
|
962
926
|
if (pollingFast) return;
|
|
963
927
|
poll.set(options.pollInterval, function() {
|
|
964
|
-
startOperation();
|
|
965
928
|
readInput();
|
|
966
929
|
if (focused) slowPoll();
|
|
967
|
-
endOperation();
|
|
968
930
|
});
|
|
969
931
|
}
|
|
970
932
|
function fastPoll() {
|
|
971
933
|
var missed = false;
|
|
972
934
|
pollingFast = true;
|
|
973
935
|
function p() {
|
|
974
|
-
startOperation();
|
|
975
936
|
var changed = readInput();
|
|
976
937
|
if (!changed && !missed) {missed = true; poll.set(60, p);}
|
|
977
938
|
else {pollingFast = false; slowPoll();}
|
|
978
|
-
endOperation();
|
|
979
939
|
}
|
|
980
940
|
poll.set(20, p);
|
|
981
941
|
}
|
|
@@ -987,9 +947,10 @@ var CodeMirror = (function() {
|
|
|
987
947
|
// supported or compatible enough yet to rely on.)
|
|
988
948
|
var prevInput = "";
|
|
989
949
|
function readInput() {
|
|
990
|
-
if (
|
|
950
|
+
if (!focused || hasSelection(input) || options.readOnly) return false;
|
|
991
951
|
var text = input.value;
|
|
992
952
|
if (text == prevInput) return false;
|
|
953
|
+
if (!nestedOperation) startOperation();
|
|
993
954
|
shiftSelecting = null;
|
|
994
955
|
var same = 0, l = Math.min(prevInput.length, text.length);
|
|
995
956
|
while (same < l && prevInput[same] == text[same]) ++same;
|
|
@@ -1000,13 +961,14 @@ var CodeMirror = (function() {
|
|
|
1000
961
|
replaceSelection(text.slice(same), "end");
|
|
1001
962
|
if (text.length > 1000) { input.value = prevInput = ""; }
|
|
1002
963
|
else prevInput = text;
|
|
964
|
+
if (!nestedOperation) endOperation();
|
|
1003
965
|
return true;
|
|
1004
966
|
}
|
|
1005
967
|
function resetInput(user) {
|
|
1006
968
|
if (!posEq(sel.from, sel.to)) {
|
|
1007
969
|
prevInput = "";
|
|
1008
970
|
input.value = getSelection();
|
|
1009
|
-
selectInput(input);
|
|
971
|
+
if (focused) selectInput(input);
|
|
1010
972
|
} else if (user) prevInput = input.value = "";
|
|
1011
973
|
}
|
|
1012
974
|
|
|
@@ -1014,16 +976,23 @@ var CodeMirror = (function() {
|
|
|
1014
976
|
if (options.readOnly != "nocursor") input.focus();
|
|
1015
977
|
}
|
|
1016
978
|
|
|
1017
|
-
function scrollEditorIntoView() {
|
|
1018
|
-
var rect = cursor.getBoundingClientRect();
|
|
1019
|
-
// IE returns bogus coordinates when the instance sits inside of an iframe and the cursor is hidden
|
|
1020
|
-
if (ie && rect.top == rect.bottom) return;
|
|
1021
|
-
var winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight);
|
|
1022
|
-
if (rect.top < 0 || rect.bottom > winH) scrollCursorIntoView();
|
|
1023
|
-
}
|
|
1024
979
|
function scrollCursorIntoView() {
|
|
1025
980
|
var coords = calculateCursorCoords();
|
|
1026
|
-
|
|
981
|
+
scrollIntoView(coords.x, coords.y, coords.x, coords.yBot);
|
|
982
|
+
if (!focused) return;
|
|
983
|
+
var box = sizer.getBoundingClientRect(), doScroll = null;
|
|
984
|
+
if (coords.y + box.top < 0) doScroll = true;
|
|
985
|
+
else if (coords.y + box.top + textHeight() > (window.innerHeight || document.documentElement.clientHeight)) doScroll = false;
|
|
986
|
+
if (doScroll != null) {
|
|
987
|
+
var hidden = cursor.style.display == "none";
|
|
988
|
+
if (hidden) {
|
|
989
|
+
cursor.style.display = "";
|
|
990
|
+
cursor.style.left = coords.x + "px";
|
|
991
|
+
cursor.style.top = (coords.y - displayOffset) + "px";
|
|
992
|
+
}
|
|
993
|
+
cursor.scrollIntoView(doScroll);
|
|
994
|
+
if (hidden) cursor.style.display = "none";
|
|
995
|
+
}
|
|
1027
996
|
}
|
|
1028
997
|
function calculateCursorCoords() {
|
|
1029
998
|
var cursor = localCoords(sel.inverted ? sel.from : sel.to);
|
|
@@ -1031,17 +1000,16 @@ var CodeMirror = (function() {
|
|
|
1031
1000
|
return {x: x, y: cursor.y, yBot: cursor.yBot};
|
|
1032
1001
|
}
|
|
1033
1002
|
function scrollIntoView(x1, y1, x2, y2) {
|
|
1034
|
-
var scrollPos = calculateScrollPos(x1, y1, x2, y2)
|
|
1035
|
-
if (scrollPos.scrollLeft != null) {scroller.scrollLeft = scrollPos.scrollLeft;
|
|
1036
|
-
if (scrollPos.scrollTop != null) {scrollbar.scrollTop =
|
|
1037
|
-
if (scrolled && options.onScroll) options.onScroll(instance);
|
|
1003
|
+
var scrollPos = calculateScrollPos(x1, y1, x2, y2);
|
|
1004
|
+
if (scrollPos.scrollLeft != null) {scroller.scrollLeft = scrollPos.scrollLeft;}
|
|
1005
|
+
if (scrollPos.scrollTop != null) {scrollbar.scrollTop = scroller.scrollTop = scrollPos.scrollTop;}
|
|
1038
1006
|
}
|
|
1039
1007
|
function calculateScrollPos(x1, y1, x2, y2) {
|
|
1040
1008
|
var pl = paddingLeft(), pt = paddingTop();
|
|
1041
1009
|
y1 += pt; y2 += pt; x1 += pl; x2 += pl;
|
|
1042
1010
|
var screen = scroller.clientHeight, screentop = scrollbar.scrollTop, result = {};
|
|
1043
|
-
var docBottom =
|
|
1044
|
-
var atTop = y1 < pt + 10, atBottom = y2 + pt > docBottom - 10
|
|
1011
|
+
var docBottom = needsScrollbar() || Infinity;
|
|
1012
|
+
var atTop = y1 < pt + 10, atBottom = y2 + pt > docBottom - 10;
|
|
1045
1013
|
if (y1 < screentop) result.scrollTop = atTop ? 0 : Math.max(0, y1);
|
|
1046
1014
|
else if (y2 > screentop + screen) result.scrollTop = (atBottom ? docBottom : y2) - screen;
|
|
1047
1015
|
|
|
@@ -1113,8 +1081,13 @@ var CodeMirror = (function() {
|
|
|
1113
1081
|
// This is just a bogus formula that detects when the editor is
|
|
1114
1082
|
// resized or the font size changes.
|
|
1115
1083
|
if (different) lastSizeC = scroller.clientHeight + th;
|
|
1084
|
+
if (from != showingFrom || to != showingTo && options.onViewportChange)
|
|
1085
|
+
setTimeout(function(){
|
|
1086
|
+
if (options.onViewportChange) options.onViewportChange(instance, from, to);
|
|
1087
|
+
});
|
|
1116
1088
|
showingFrom = from; showingTo = to;
|
|
1117
1089
|
displayOffset = heightAtLine(doc, from);
|
|
1090
|
+
startWorker(100);
|
|
1118
1091
|
|
|
1119
1092
|
// Since this is all rather error prone, it is honoured with the
|
|
1120
1093
|
// only assertion in the whole file.
|
|
@@ -1125,6 +1098,10 @@ var CodeMirror = (function() {
|
|
|
1125
1098
|
function checkHeights() {
|
|
1126
1099
|
var curNode = lineDiv.firstChild, heightChanged = false;
|
|
1127
1100
|
doc.iter(showingFrom, showingTo, function(line) {
|
|
1101
|
+
// Work around bizarro IE7 bug where, sometimes, our curNode
|
|
1102
|
+
// is magically replaced with a new node in the DOM, leaving
|
|
1103
|
+
// us with a reference to an orphan (nextSibling-less) node.
|
|
1104
|
+
if (!curNode) return;
|
|
1128
1105
|
if (!line.hidden) {
|
|
1129
1106
|
var height = Math.round(curNode.offsetHeight / th) || 1;
|
|
1130
1107
|
if (line.height != height) {
|
|
@@ -1137,16 +1114,7 @@ var CodeMirror = (function() {
|
|
|
1137
1114
|
return heightChanged;
|
|
1138
1115
|
}
|
|
1139
1116
|
|
|
1140
|
-
if (options.lineWrapping)
|
|
1141
|
-
checkHeights();
|
|
1142
|
-
var scrollHeight = needsScrollbar();
|
|
1143
|
-
var shouldHaveScrollbar = scrollHeight ? "block" : "none";
|
|
1144
|
-
if (scrollbar.style.display != shouldHaveScrollbar) {
|
|
1145
|
-
scrollbar.style.display = shouldHaveScrollbar;
|
|
1146
|
-
if (scrollHeight) scrollbarInner.style.height = scrollHeight + "px";
|
|
1147
|
-
checkHeights();
|
|
1148
|
-
}
|
|
1149
|
-
}
|
|
1117
|
+
if (options.lineWrapping) checkHeights();
|
|
1150
1118
|
|
|
1151
1119
|
gutter.style.display = gutterDisplay;
|
|
1152
1120
|
if (different || gutterDirty) {
|
|
@@ -1183,14 +1151,14 @@ var CodeMirror = (function() {
|
|
|
1183
1151
|
}
|
|
1184
1152
|
|
|
1185
1153
|
function patchDisplay(from, to, intact) {
|
|
1154
|
+
function killNode(node) {
|
|
1155
|
+
var tmp = node.nextSibling;
|
|
1156
|
+
node.parentNode.removeChild(node);
|
|
1157
|
+
return tmp;
|
|
1158
|
+
}
|
|
1186
1159
|
// The first pass removes the DOM nodes that aren't intact.
|
|
1187
|
-
if (!intact.length) lineDiv
|
|
1160
|
+
if (!intact.length) removeChildren(lineDiv);
|
|
1188
1161
|
else {
|
|
1189
|
-
function killNode(node) {
|
|
1190
|
-
var tmp = node.nextSibling;
|
|
1191
|
-
node.parentNode.removeChild(node);
|
|
1192
|
-
return tmp;
|
|
1193
|
-
}
|
|
1194
1162
|
var domPos = 0, curNode = lineDiv.firstChild, n;
|
|
1195
1163
|
for (var i = 0; i < intact.length; ++i) {
|
|
1196
1164
|
var cur = intact[i];
|
|
@@ -1201,21 +1169,20 @@ var CodeMirror = (function() {
|
|
|
1201
1169
|
}
|
|
1202
1170
|
// This pass fills in the lines that actually changed.
|
|
1203
1171
|
var nextIntact = intact.shift(), curNode = lineDiv.firstChild, j = from;
|
|
1204
|
-
var scratch = document.createElement("div");
|
|
1205
1172
|
doc.iter(from, to, function(line) {
|
|
1206
1173
|
if (nextIntact && nextIntact.to == j) nextIntact = intact.shift();
|
|
1207
1174
|
if (!nextIntact || nextIntact.from > j) {
|
|
1208
|
-
if (line.hidden) var
|
|
1175
|
+
if (line.hidden) var lineElement = elt("pre");
|
|
1209
1176
|
else {
|
|
1210
|
-
var
|
|
1211
|
-
|
|
1177
|
+
var lineElement = lineContent(line);
|
|
1178
|
+
if (line.className) lineElement.className = line.className;
|
|
1212
1179
|
// Kludge to make sure the styled element lies behind the selection (by z-index)
|
|
1213
|
-
if (line.bgClassName)
|
|
1214
|
-
|
|
1215
|
-
|
|
1180
|
+
if (line.bgClassName) {
|
|
1181
|
+
var pre = elt("pre", "\u00a0", line.bgClassName, "position: absolute; left: 0; right: 0; top: 0; bottom: 0; z-index: -2");
|
|
1182
|
+
lineElement = elt("div", [pre, lineElement], null, "position: relative");
|
|
1183
|
+
}
|
|
1216
1184
|
}
|
|
1217
|
-
|
|
1218
|
-
lineDiv.insertBefore(scratch.firstChild, curNode);
|
|
1185
|
+
lineDiv.insertBefore(lineElement, curNode);
|
|
1219
1186
|
} else {
|
|
1220
1187
|
curNode = curNode.nextSibling;
|
|
1221
1188
|
}
|
|
@@ -1227,10 +1194,10 @@ var CodeMirror = (function() {
|
|
|
1227
1194
|
if (!options.gutter && !options.lineNumbers) return;
|
|
1228
1195
|
var hText = mover.offsetHeight, hEditor = scroller.clientHeight;
|
|
1229
1196
|
gutter.style.height = (hText - hEditor < 2 ? hEditor : hText) + "px";
|
|
1230
|
-
var
|
|
1197
|
+
var fragment = document.createDocumentFragment(), i = showingFrom, normalNode;
|
|
1231
1198
|
doc.iter(showingFrom, Math.max(showingTo, showingFrom + 1), function(line) {
|
|
1232
1199
|
if (line.hidden) {
|
|
1233
|
-
|
|
1200
|
+
fragment.appendChild(elt("pre"));
|
|
1234
1201
|
} else {
|
|
1235
1202
|
var marker = line.gutterMarker;
|
|
1236
1203
|
var text = options.lineNumbers ? options.lineNumberFormatter(i + options.firstLineNumber) : null;
|
|
@@ -1238,15 +1205,18 @@ var CodeMirror = (function() {
|
|
|
1238
1205
|
text = marker.text.replace("%N%", text != null ? text : "");
|
|
1239
1206
|
else if (text == null)
|
|
1240
1207
|
text = "\u00a0";
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1208
|
+
var markerElement = fragment.appendChild(elt("pre", null, marker && marker.style));
|
|
1209
|
+
markerElement.innerHTML = text;
|
|
1210
|
+
for (var j = 1; j < line.height; ++j) {
|
|
1211
|
+
markerElement.appendChild(elt("br"));
|
|
1212
|
+
markerElement.appendChild(document.createTextNode("\u00a0"));
|
|
1213
|
+
}
|
|
1244
1214
|
if (!marker) normalNode = i;
|
|
1245
1215
|
}
|
|
1246
1216
|
++i;
|
|
1247
1217
|
});
|
|
1248
1218
|
gutter.style.display = "none";
|
|
1249
|
-
gutterText
|
|
1219
|
+
removeChildrenAndAdd(gutterText, fragment);
|
|
1250
1220
|
// Make sure scrolling doesn't cause number gutter size to pop
|
|
1251
1221
|
if (normalNode != null && options.lineNumbers) {
|
|
1252
1222
|
var node = gutterText.childNodes[normalNode - showingFrom];
|
|
@@ -1274,15 +1244,15 @@ var CodeMirror = (function() {
|
|
|
1274
1244
|
cursor.style.display = "";
|
|
1275
1245
|
selectionDiv.style.display = "none";
|
|
1276
1246
|
} else {
|
|
1277
|
-
var sameLine = fromPos.y == toPos.y,
|
|
1247
|
+
var sameLine = fromPos.y == toPos.y, fragment = document.createDocumentFragment();
|
|
1278
1248
|
var clientWidth = lineSpace.clientWidth || lineSpace.offsetWidth;
|
|
1279
1249
|
var clientHeight = lineSpace.clientHeight || lineSpace.offsetHeight;
|
|
1280
|
-
|
|
1250
|
+
var add = function(left, top, right, height) {
|
|
1281
1251
|
var rstyle = quirksMode ? "width: " + (!right ? clientWidth : clientWidth - right - left) + "px"
|
|
1282
1252
|
: "right: " + right + "px";
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
}
|
|
1253
|
+
fragment.appendChild(elt("div", null, "CodeMirror-selected", "position: absolute; left: " + left +
|
|
1254
|
+
"px; top: " + top + "px; " + rstyle + "; height: " + height + "px"));
|
|
1255
|
+
};
|
|
1286
1256
|
if (sel.from.ch && fromPos.y >= 0) {
|
|
1287
1257
|
var right = sameLine ? clientWidth - toPos.x : 0;
|
|
1288
1258
|
add(fromPos.x, fromPos.y, right, th);
|
|
@@ -1293,7 +1263,7 @@ var CodeMirror = (function() {
|
|
|
1293
1263
|
add(0, middleStart, 0, middleHeight);
|
|
1294
1264
|
if ((!sameLine || !sel.from.ch) && toPos.y < clientHeight - .5 * th)
|
|
1295
1265
|
add(0, toPos.y, clientWidth - toPos.x, th);
|
|
1296
|
-
selectionDiv
|
|
1266
|
+
removeChildrenAndAdd(selectionDiv, fragment);
|
|
1297
1267
|
cursor.style.display = "none";
|
|
1298
1268
|
selectionDiv.style.display = "";
|
|
1299
1269
|
}
|
|
@@ -1425,13 +1395,16 @@ var CodeMirror = (function() {
|
|
|
1425
1395
|
else replaceRange("", sel.from, findPosH(dir, unit));
|
|
1426
1396
|
userSelChange = true;
|
|
1427
1397
|
}
|
|
1428
|
-
var goalColumn = null;
|
|
1429
1398
|
function moveV(dir, unit) {
|
|
1430
1399
|
var dist = 0, pos = localCoords(sel.inverted ? sel.from : sel.to, true);
|
|
1431
1400
|
if (goalColumn != null) pos.x = goalColumn;
|
|
1432
|
-
if (unit == "page")
|
|
1433
|
-
|
|
1434
|
-
|
|
1401
|
+
if (unit == "page") {
|
|
1402
|
+
var screen = Math.min(scroller.clientHeight, window.innerHeight || document.documentElement.clientHeight);
|
|
1403
|
+
var target = coordsChar(pos.x, pos.y + screen * dir);
|
|
1404
|
+
} else if (unit == "line") {
|
|
1405
|
+
var th = textHeight();
|
|
1406
|
+
var target = coordsChar(pos.x, pos.y + .5 * th + dir * th);
|
|
1407
|
+
}
|
|
1435
1408
|
if (unit == "page") scrollbar.scrollTop += localCoords(target, true).y - pos.y;
|
|
1436
1409
|
setCursor(target.line, target.ch, true);
|
|
1437
1410
|
goalColumn = pos.x;
|
|
@@ -1440,10 +1413,15 @@ var CodeMirror = (function() {
|
|
|
1440
1413
|
function findWordAt(pos) {
|
|
1441
1414
|
var line = getLine(pos.line).text;
|
|
1442
1415
|
var start = pos.ch, end = pos.ch;
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1416
|
+
if (line) {
|
|
1417
|
+
if (pos.after === false || end == line.length) --start; else ++end;
|
|
1418
|
+
var startChar = line.charAt(start);
|
|
1419
|
+
var check = isWordChar(startChar) ? isWordChar :
|
|
1420
|
+
/\s/.test(startChar) ? function(ch) {return /\s/.test(ch);} :
|
|
1421
|
+
function(ch) {return !/\s/.test(ch) && !isWordChar(ch);};
|
|
1422
|
+
while (start > 0 && check(line.charAt(start - 1))) --start;
|
|
1423
|
+
while (end < line.length && check(line.charAt(end))) ++end;
|
|
1424
|
+
}
|
|
1447
1425
|
return {from: {line: pos.line, ch: start}, to: {line: pos.line, ch: end}};
|
|
1448
1426
|
}
|
|
1449
1427
|
function selectLine(line) {
|
|
@@ -1480,16 +1458,17 @@ var CodeMirror = (function() {
|
|
|
1480
1458
|
var indentString = "", pos = 0;
|
|
1481
1459
|
if (options.indentWithTabs)
|
|
1482
1460
|
for (var i = Math.floor(indentation / options.tabSize); i; --i) {pos += options.tabSize; indentString += "\t";}
|
|
1483
|
-
|
|
1461
|
+
if (pos < indentation) indentString += spaceStr(indentation - pos);
|
|
1484
1462
|
|
|
1485
|
-
|
|
1463
|
+
if (indentString != curSpaceString)
|
|
1464
|
+
replaceRange(indentString, {line: n, ch: 0}, {line: n, ch: curSpaceString.length});
|
|
1486
1465
|
}
|
|
1487
1466
|
|
|
1488
1467
|
function loadMode() {
|
|
1489
1468
|
mode = CodeMirror.getMode(options, options.mode);
|
|
1490
1469
|
doc.iter(0, doc.size, function(line) { line.stateAfter = null; });
|
|
1491
|
-
|
|
1492
|
-
startWorker();
|
|
1470
|
+
frontier = 0;
|
|
1471
|
+
startWorker(100);
|
|
1493
1472
|
}
|
|
1494
1473
|
function gutterChanged() {
|
|
1495
1474
|
var visible = options.gutter || options.lineNumbers;
|
|
@@ -1506,24 +1485,16 @@ var CodeMirror = (function() {
|
|
|
1506
1485
|
var guess = Math.ceil(line.text.length / perLine) || 1;
|
|
1507
1486
|
if (guess != 1) updateLineHeight(line, guess);
|
|
1508
1487
|
});
|
|
1509
|
-
lineSpace.style.
|
|
1510
|
-
widthForcer.style.left = "";
|
|
1488
|
+
lineSpace.style.minWidth = widthForcer.style.left = "";
|
|
1511
1489
|
} else {
|
|
1512
1490
|
wrapper.className = wrapper.className.replace(" CodeMirror-wrap", "");
|
|
1513
|
-
|
|
1491
|
+
computeMaxLength();
|
|
1514
1492
|
doc.iter(0, doc.size, function(line) {
|
|
1515
1493
|
if (line.height != 1 && !line.hidden) updateLineHeight(line, 1);
|
|
1516
|
-
if (line.text.length > maxLine.length) maxLine = line.text;
|
|
1517
1494
|
});
|
|
1518
1495
|
}
|
|
1519
1496
|
changes.push({from: 0, to: doc.size});
|
|
1520
1497
|
}
|
|
1521
|
-
function makeTab(col) {
|
|
1522
|
-
var w = options.tabSize - col % options.tabSize, cached = tabCache[w];
|
|
1523
|
-
if (cached) return cached;
|
|
1524
|
-
for (var str = '<span class="cm-tab">', i = 0; i < w; ++i) str += " ";
|
|
1525
|
-
return (tabCache[w] = {html: str + "</span>", width: w});
|
|
1526
|
-
}
|
|
1527
1498
|
function themeChanged() {
|
|
1528
1499
|
scroller.className = scroller.className.replace(/\s*cm-s-\S+/g, "") +
|
|
1529
1500
|
options.theme.replace(/(^|\s)\s*/g, " cm-s-");
|
|
@@ -1534,74 +1505,71 @@ var CodeMirror = (function() {
|
|
|
1534
1505
|
(style ? " cm-keymap-" + style : "");
|
|
1535
1506
|
}
|
|
1536
1507
|
|
|
1537
|
-
function TextMarker() { this.
|
|
1508
|
+
function TextMarker(type, style) { this.lines = []; this.type = type; if (style) this.style = style; }
|
|
1538
1509
|
TextMarker.prototype.clear = operation(function() {
|
|
1539
1510
|
var min = Infinity, max = -Infinity;
|
|
1540
|
-
for (var i = 0
|
|
1541
|
-
var line = this.
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1511
|
+
for (var i = 0; i < this.lines.length; ++i) {
|
|
1512
|
+
var line = this.lines[i];
|
|
1513
|
+
var span = getMarkedSpanFor(line.markedSpans, this, true);
|
|
1514
|
+
if (span.from != null || span.to != null) {
|
|
1515
|
+
var lineN = lineNo(line);
|
|
1516
|
+
min = Math.min(min, lineN); max = Math.max(max, lineN);
|
|
1517
|
+
}
|
|
1547
1518
|
}
|
|
1548
1519
|
if (min != Infinity)
|
|
1549
1520
|
changes.push({from: min, to: max + 1});
|
|
1521
|
+
this.lines.length = 0;
|
|
1550
1522
|
});
|
|
1551
1523
|
TextMarker.prototype.find = function() {
|
|
1552
1524
|
var from, to;
|
|
1553
|
-
for (var i = 0
|
|
1554
|
-
var line = this.
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
if (found != null) {
|
|
1561
|
-
if (mark.from != null) from = {line: found, ch: mark.from};
|
|
1562
|
-
if (mark.to != null) to = {line: found, ch: mark.to};
|
|
1563
|
-
}
|
|
1564
|
-
}
|
|
1565
|
-
}
|
|
1525
|
+
for (var i = 0; i < this.lines.length; ++i) {
|
|
1526
|
+
var line = this.lines[i];
|
|
1527
|
+
var span = getMarkedSpanFor(line.markedSpans, this);
|
|
1528
|
+
if (span.from != null || span.to != null) {
|
|
1529
|
+
var found = lineNo(line);
|
|
1530
|
+
if (span.from != null) from = {line: found, ch: span.from};
|
|
1531
|
+
if (span.to != null) to = {line: found, ch: span.to};
|
|
1566
1532
|
}
|
|
1567
1533
|
}
|
|
1568
|
-
|
|
1534
|
+
if (this.type == "bookmark") return from;
|
|
1535
|
+
return from && {from: from, to: to};
|
|
1569
1536
|
};
|
|
1570
1537
|
|
|
1571
|
-
function markText(from, to, className) {
|
|
1538
|
+
function markText(from, to, className, options) {
|
|
1572
1539
|
from = clipPos(from); to = clipPos(to);
|
|
1573
|
-
var
|
|
1574
|
-
if (
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
}
|
|
1540
|
+
var marker = new TextMarker("range", className);
|
|
1541
|
+
if (options) for (var opt in options) if (options.hasOwnProperty(opt))
|
|
1542
|
+
marker[opt] = options[opt];
|
|
1543
|
+
var curLine = from.line;
|
|
1544
|
+
doc.iter(curLine, to.line + 1, function(line) {
|
|
1545
|
+
var span = {from: curLine == from.line ? from.ch : null,
|
|
1546
|
+
to: curLine == to.line ? to.ch : null,
|
|
1547
|
+
marker: marker};
|
|
1548
|
+
(line.markedSpans || (line.markedSpans = [])).push(span);
|
|
1549
|
+
marker.lines.push(line);
|
|
1550
|
+
++curLine;
|
|
1551
|
+
});
|
|
1585
1552
|
changes.push({from: from.line, to: to.line + 1});
|
|
1586
|
-
return
|
|
1553
|
+
return marker;
|
|
1587
1554
|
}
|
|
1588
1555
|
|
|
1589
1556
|
function setBookmark(pos) {
|
|
1590
1557
|
pos = clipPos(pos);
|
|
1591
|
-
var
|
|
1592
|
-
|
|
1593
|
-
|
|
1558
|
+
var marker = new TextMarker("bookmark"), line = getLine(pos.line);
|
|
1559
|
+
var span = {from: pos.ch, to: pos.ch, marker: marker};
|
|
1560
|
+
(line.markedSpans || (line.markedSpans = [])).push(span);
|
|
1561
|
+
marker.lines.push(line);
|
|
1562
|
+
return marker;
|
|
1594
1563
|
}
|
|
1595
1564
|
|
|
1596
1565
|
function findMarksAt(pos) {
|
|
1597
1566
|
pos = clipPos(pos);
|
|
1598
|
-
var markers = [],
|
|
1599
|
-
if (
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
markers.push(m.marker || m);
|
|
1567
|
+
var markers = [], spans = getLine(pos.line).markedSpans;
|
|
1568
|
+
if (spans) for (var i = 0; i < spans.length; ++i) {
|
|
1569
|
+
var span = spans[i];
|
|
1570
|
+
if ((span.from == null || span.from <= pos.ch) &&
|
|
1571
|
+
(span.to == null || span.to >= pos.ch))
|
|
1572
|
+
markers.push(span.marker);
|
|
1605
1573
|
}
|
|
1606
1574
|
return markers;
|
|
1607
1575
|
}
|
|
@@ -1641,11 +1609,10 @@ var CodeMirror = (function() {
|
|
|
1641
1609
|
if (line.hidden != hidden) {
|
|
1642
1610
|
line.hidden = hidden;
|
|
1643
1611
|
if (!options.lineWrapping) {
|
|
1644
|
-
|
|
1645
|
-
if (hidden && l.length == maxLine.length) {
|
|
1612
|
+
if (hidden && line.text.length == maxLine.text.length) {
|
|
1646
1613
|
updateMaxLine = true;
|
|
1647
|
-
} else if (!hidden &&
|
|
1648
|
-
maxLine =
|
|
1614
|
+
} else if (!hidden && line.text.length > maxLine.text.length) {
|
|
1615
|
+
maxLine = line; updateMaxLine = false;
|
|
1649
1616
|
}
|
|
1650
1617
|
}
|
|
1651
1618
|
updateLineHeight(line, hidden ? 0 : 1);
|
|
@@ -1677,53 +1644,18 @@ var CodeMirror = (function() {
|
|
|
1677
1644
|
markerClass: marker && marker.style, lineClass: line.className, bgClass: line.bgClassName};
|
|
1678
1645
|
}
|
|
1679
1646
|
|
|
1680
|
-
function stringWidth(str) {
|
|
1681
|
-
measure.innerHTML = "<pre><span>x</span></pre>";
|
|
1682
|
-
measure.firstChild.firstChild.firstChild.nodeValue = str;
|
|
1683
|
-
return measure.firstChild.firstChild.offsetWidth || 10;
|
|
1684
|
-
}
|
|
1685
|
-
// These are used to go from pixel positions to character
|
|
1686
|
-
// positions, taking varying character widths into account.
|
|
1687
|
-
function charFromX(line, x) {
|
|
1688
|
-
if (x <= 0) return 0;
|
|
1689
|
-
var lineObj = getLine(line), text = lineObj.text;
|
|
1690
|
-
function getX(len) {
|
|
1691
|
-
return measureLine(lineObj, len).left;
|
|
1692
|
-
}
|
|
1693
|
-
var from = 0, fromX = 0, to = text.length, toX;
|
|
1694
|
-
// Guess a suitable upper bound for our search.
|
|
1695
|
-
var estimated = Math.min(to, Math.ceil(x / charWidth()));
|
|
1696
|
-
for (;;) {
|
|
1697
|
-
var estX = getX(estimated);
|
|
1698
|
-
if (estX <= x && estimated < to) estimated = Math.min(to, Math.ceil(estimated * 1.2));
|
|
1699
|
-
else {toX = estX; to = estimated; break;}
|
|
1700
|
-
}
|
|
1701
|
-
if (x > toX) return to;
|
|
1702
|
-
// Try to guess a suitable lower bound as well.
|
|
1703
|
-
estimated = Math.floor(to * 0.8); estX = getX(estimated);
|
|
1704
|
-
if (estX < x) {from = estimated; fromX = estX;}
|
|
1705
|
-
// Do a binary search between these bounds.
|
|
1706
|
-
for (;;) {
|
|
1707
|
-
if (to - from <= 1) return (toX - x > x - fromX) ? from : to;
|
|
1708
|
-
var middle = Math.ceil((from + to) / 2), middleX = getX(middle);
|
|
1709
|
-
if (middleX > x) {to = middle; toX = middleX;}
|
|
1710
|
-
else {from = middle; fromX = middleX;}
|
|
1711
|
-
}
|
|
1712
|
-
}
|
|
1713
|
-
|
|
1714
|
-
var tempId = "CodeMirror-temp-" + Math.floor(Math.random() * 0xffffff).toString(16);
|
|
1715
1647
|
function measureLine(line, ch) {
|
|
1716
1648
|
if (ch == 0) return {top: 0, left: 0};
|
|
1717
1649
|
var wbr = options.lineWrapping && ch < line.text.length &&
|
|
1718
1650
|
spanAffectsWrapping.test(line.text.slice(ch - 1, ch + 1));
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
var
|
|
1651
|
+
var pre = lineContent(line, ch);
|
|
1652
|
+
removeChildrenAndAdd(measure, pre);
|
|
1653
|
+
var anchor = pre.anchor;
|
|
1654
|
+
var top = anchor.offsetTop, left = anchor.offsetLeft;
|
|
1722
1655
|
// Older IEs report zero offsets for spans directly after a wrap
|
|
1723
1656
|
if (ie && top == 0 && left == 0) {
|
|
1724
|
-
var backup =
|
|
1725
|
-
backup.
|
|
1726
|
-
elt.parentNode.insertBefore(backup, elt.nextSibling);
|
|
1657
|
+
var backup = elt("span", "x");
|
|
1658
|
+
anchor.parentNode.insertBefore(backup, anchor.nextSibling);
|
|
1727
1659
|
top = backup.offsetTop;
|
|
1728
1660
|
}
|
|
1729
1661
|
return {top: top, left: left};
|
|
@@ -1740,17 +1672,19 @@ var CodeMirror = (function() {
|
|
|
1740
1672
|
}
|
|
1741
1673
|
// Coords must be lineSpace-local
|
|
1742
1674
|
function coordsChar(x, y) {
|
|
1743
|
-
if (y < 0) y = 0;
|
|
1744
1675
|
var th = textHeight(), cw = charWidth(), heightPos = displayOffset + Math.floor(y / th);
|
|
1676
|
+
if (heightPos < 0) return {line: 0, ch: 0};
|
|
1745
1677
|
var lineNo = lineAtHeight(doc, heightPos);
|
|
1746
1678
|
if (lineNo >= doc.size) return {line: doc.size - 1, ch: getLine(doc.size - 1).text.length};
|
|
1747
1679
|
var lineObj = getLine(lineNo), text = lineObj.text;
|
|
1748
1680
|
var tw = options.lineWrapping, innerOff = tw ? heightPos - heightAtLine(doc, lineNo) : 0;
|
|
1749
1681
|
if (x <= 0 && innerOff == 0) return {line: lineNo, ch: 0};
|
|
1682
|
+
var wrongLine = false;
|
|
1750
1683
|
function getX(len) {
|
|
1751
1684
|
var sp = measureLine(lineObj, len);
|
|
1752
1685
|
if (tw) {
|
|
1753
1686
|
var off = Math.round(sp.top / th);
|
|
1687
|
+
wrongLine = off != innerOff;
|
|
1754
1688
|
return Math.max(0, sp.left + (off - innerOff) * scroller.clientWidth);
|
|
1755
1689
|
}
|
|
1756
1690
|
return sp.left;
|
|
@@ -1769,9 +1703,12 @@ var CodeMirror = (function() {
|
|
|
1769
1703
|
if (estX < x) {from = estimated; fromX = estX;}
|
|
1770
1704
|
// Do a binary search between these bounds.
|
|
1771
1705
|
for (;;) {
|
|
1772
|
-
if (to - from <= 1)
|
|
1706
|
+
if (to - from <= 1) {
|
|
1707
|
+
var after = x - fromX < toX - x;
|
|
1708
|
+
return {line: lineNo, ch: after ? from : to, after: after};
|
|
1709
|
+
}
|
|
1773
1710
|
var middle = Math.ceil((from + to) / 2), middleX = getX(middle);
|
|
1774
|
-
if (middleX > x) {to = middle; toX = middleX;}
|
|
1711
|
+
if (middleX > x) {to = middle; toX = middleX; if (wrongLine) toX += 1000; }
|
|
1775
1712
|
else {from = middle; fromX = middleX;}
|
|
1776
1713
|
}
|
|
1777
1714
|
}
|
|
@@ -1780,26 +1717,32 @@ var CodeMirror = (function() {
|
|
|
1780
1717
|
return {x: off.left + local.x, y: off.top + local.y, yBot: off.top + local.yBot};
|
|
1781
1718
|
}
|
|
1782
1719
|
|
|
1783
|
-
var cachedHeight, cachedHeightFor,
|
|
1720
|
+
var cachedHeight, cachedHeightFor, measurePre;
|
|
1784
1721
|
function textHeight() {
|
|
1785
|
-
if (
|
|
1786
|
-
|
|
1787
|
-
for (var i = 0; i < 49; ++i)
|
|
1788
|
-
|
|
1722
|
+
if (measurePre == null) {
|
|
1723
|
+
measurePre = elt("pre");
|
|
1724
|
+
for (var i = 0; i < 49; ++i) {
|
|
1725
|
+
measurePre.appendChild(document.createTextNode("x"));
|
|
1726
|
+
measurePre.appendChild(elt("br"));
|
|
1727
|
+
}
|
|
1728
|
+
measurePre.appendChild(document.createTextNode("x"));
|
|
1789
1729
|
}
|
|
1790
1730
|
var offsetHeight = lineDiv.clientHeight;
|
|
1791
1731
|
if (offsetHeight == cachedHeightFor) return cachedHeight;
|
|
1792
1732
|
cachedHeightFor = offsetHeight;
|
|
1793
|
-
measure.
|
|
1733
|
+
removeChildrenAndAdd(measure, measurePre.cloneNode(true));
|
|
1794
1734
|
cachedHeight = measure.firstChild.offsetHeight / 50 || 1;
|
|
1795
|
-
measure
|
|
1735
|
+
removeChildren(measure);
|
|
1796
1736
|
return cachedHeight;
|
|
1797
1737
|
}
|
|
1798
1738
|
var cachedWidth, cachedWidthFor = 0;
|
|
1799
1739
|
function charWidth() {
|
|
1800
1740
|
if (scroller.clientWidth == cachedWidthFor) return cachedWidth;
|
|
1801
1741
|
cachedWidthFor = scroller.clientWidth;
|
|
1802
|
-
|
|
1742
|
+
var anchor = elt("span", "x");
|
|
1743
|
+
var pre = elt("pre", [anchor]);
|
|
1744
|
+
removeChildrenAndAdd(measure, pre);
|
|
1745
|
+
return (cachedWidth = anchor.offsetWidth || 10);
|
|
1803
1746
|
}
|
|
1804
1747
|
function paddingTop() {return lineSpace.offsetTop;}
|
|
1805
1748
|
function paddingLeft() {return lineSpace.offsetLeft;}
|
|
@@ -1816,6 +1759,7 @@ var CodeMirror = (function() {
|
|
|
1816
1759
|
var offL = eltOffset(lineSpace, true);
|
|
1817
1760
|
return coordsChar(x - offL.left, y - offL.top);
|
|
1818
1761
|
}
|
|
1762
|
+
var detectingSelectAll;
|
|
1819
1763
|
function onContextMenu(e) {
|
|
1820
1764
|
var pos = posFromMouse(e), scrollPos = scrollbar.scrollTop;
|
|
1821
1765
|
if (!pos || opera) return; // Opera is difficult.
|
|
@@ -1827,19 +1771,30 @@ var CodeMirror = (function() {
|
|
|
1827
1771
|
input.style.cssText = "position: fixed; width: 30px; height: 30px; top: " + (e.clientY - 5) +
|
|
1828
1772
|
"px; left: " + (e.clientX - 5) + "px; z-index: 1000; background: white; " +
|
|
1829
1773
|
"border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);";
|
|
1830
|
-
leaveInputAlone = true;
|
|
1831
|
-
var val = input.value = getSelection();
|
|
1832
1774
|
focusInput();
|
|
1833
|
-
|
|
1775
|
+
resetInput(true);
|
|
1776
|
+
// Adds "Select all" to context menu in FF
|
|
1777
|
+
if (posEq(sel.from, sel.to)) input.value = prevInput = " ";
|
|
1778
|
+
|
|
1834
1779
|
function rehide() {
|
|
1835
|
-
var newVal = splitLines(input.value).join("\n");
|
|
1836
|
-
if (newVal != val && !options.readOnly) operation(replaceSelection)(newVal, "end");
|
|
1837
1780
|
inputDiv.style.position = "relative";
|
|
1838
1781
|
input.style.cssText = oldCSS;
|
|
1839
1782
|
if (ie_lt9) scrollbar.scrollTop = scrollPos;
|
|
1840
|
-
leaveInputAlone = false;
|
|
1841
|
-
resetInput(true);
|
|
1842
1783
|
slowPoll();
|
|
1784
|
+
|
|
1785
|
+
// Try to detect the user choosing select-all
|
|
1786
|
+
if (input.selectionStart != null) {
|
|
1787
|
+
clearTimeout(detectingSelectAll);
|
|
1788
|
+
var extval = input.value = " " + (posEq(sel.from, sel.to) ? "" : input.value), i = 0;
|
|
1789
|
+
prevInput = " ";
|
|
1790
|
+
input.selectionStart = 1; input.selectionEnd = extval.length;
|
|
1791
|
+
detectingSelectAll = setTimeout(function poll(){
|
|
1792
|
+
if (prevInput == " " && input.selectionStart == 0)
|
|
1793
|
+
operation(commands.selectAll)(instance);
|
|
1794
|
+
else if (i++ < 10) detectingSelectAll = setTimeout(poll, 500);
|
|
1795
|
+
else resetInput();
|
|
1796
|
+
}, 200);
|
|
1797
|
+
}
|
|
1843
1798
|
}
|
|
1844
1799
|
|
|
1845
1800
|
if (gecko) {
|
|
@@ -1860,7 +1815,7 @@ var CodeMirror = (function() {
|
|
|
1860
1815
|
cursor.style.visibility = "";
|
|
1861
1816
|
blinker = setInterval(function() {
|
|
1862
1817
|
cursor.style.visibility = (on = !on) ? "" : "hidden";
|
|
1863
|
-
},
|
|
1818
|
+
}, options.cursorBlinkRate);
|
|
1864
1819
|
}
|
|
1865
1820
|
|
|
1866
1821
|
var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<"};
|
|
@@ -1923,70 +1878,39 @@ var CodeMirror = (function() {
|
|
|
1923
1878
|
return minline;
|
|
1924
1879
|
}
|
|
1925
1880
|
function getStateBefore(n) {
|
|
1926
|
-
var
|
|
1881
|
+
var pos = findStartLine(n), state = pos && getLine(pos-1).stateAfter;
|
|
1927
1882
|
if (!state) state = startState(mode);
|
|
1928
1883
|
else state = copyState(mode, state);
|
|
1929
|
-
doc.iter(
|
|
1930
|
-
line.
|
|
1931
|
-
line.stateAfter = copyState(mode, state);
|
|
1884
|
+
doc.iter(pos, n, function(line) {
|
|
1885
|
+
line.process(mode, state, options.tabSize);
|
|
1886
|
+
line.stateAfter = (pos == n - 1 || pos % 5 == 0) ? copyState(mode, state) : null;
|
|
1932
1887
|
});
|
|
1933
|
-
if (start < n) changes.push({from: start, to: n});
|
|
1934
|
-
if (n < doc.size && !getLine(n).stateAfter) work.push(n);
|
|
1935
1888
|
return state;
|
|
1936
1889
|
}
|
|
1937
|
-
function highlightLines(start, end) {
|
|
1938
|
-
var state = getStateBefore(start);
|
|
1939
|
-
doc.iter(start, end, function(line) {
|
|
1940
|
-
line.highlight(mode, state, options.tabSize);
|
|
1941
|
-
line.stateAfter = copyState(mode, state);
|
|
1942
|
-
});
|
|
1943
|
-
}
|
|
1944
1890
|
function highlightWorker() {
|
|
1945
|
-
|
|
1946
|
-
var
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
var start = findStartLine(task), state = start && getLine(start-1).stateAfter;
|
|
1952
|
-
if (state) state = copyState(mode, state);
|
|
1953
|
-
else state = startState(mode);
|
|
1954
|
-
|
|
1955
|
-
var unchanged = 0, compare = mode.compareStates, realChange = false,
|
|
1956
|
-
i = start, bail = false;
|
|
1957
|
-
doc.iter(i, doc.size, function(line) {
|
|
1958
|
-
var hadState = line.stateAfter;
|
|
1959
|
-
if (+new Date > end) {
|
|
1960
|
-
work.push(i);
|
|
1961
|
-
startWorker(options.workDelay);
|
|
1962
|
-
if (realChange) changes.push({from: task, to: i + 1});
|
|
1963
|
-
return (bail = true);
|
|
1964
|
-
}
|
|
1965
|
-
var changed = line.highlight(mode, state, options.tabSize);
|
|
1966
|
-
if (changed) realChange = true;
|
|
1891
|
+
if (frontier >= showingTo) return;
|
|
1892
|
+
var end = +new Date + options.workTime, state = copyState(mode, getStateBefore(frontier));
|
|
1893
|
+
var startFrontier = frontier;
|
|
1894
|
+
doc.iter(frontier, showingTo, function(line) {
|
|
1895
|
+
if (frontier >= showingFrom) { // Visible
|
|
1896
|
+
line.highlight(mode, state, options.tabSize);
|
|
1967
1897
|
line.stateAfter = copyState(mode, state);
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
});
|
|
1981
|
-
if (bail) return;
|
|
1982
|
-
if (realChange) changes.push({from: task, to: i + 1});
|
|
1983
|
-
}
|
|
1984
|
-
if (foundWork && options.onHighlightComplete)
|
|
1985
|
-
options.onHighlightComplete(instance);
|
|
1898
|
+
} else {
|
|
1899
|
+
line.process(mode, state, options.tabSize);
|
|
1900
|
+
line.stateAfter = frontier % 5 == 0 ? copyState(mode, state) : null;
|
|
1901
|
+
}
|
|
1902
|
+
++frontier;
|
|
1903
|
+
if (+new Date > end) {
|
|
1904
|
+
startWorker(options.workDelay);
|
|
1905
|
+
return true;
|
|
1906
|
+
}
|
|
1907
|
+
});
|
|
1908
|
+
if (showingTo > startFrontier && frontier >= showingFrom)
|
|
1909
|
+
operation(function() {changes.push({from: startFrontier, to: frontier});})();
|
|
1986
1910
|
}
|
|
1987
1911
|
function startWorker(time) {
|
|
1988
|
-
if (
|
|
1989
|
-
|
|
1912
|
+
if (frontier < showingTo)
|
|
1913
|
+
highlight.set(time, highlightWorker);
|
|
1990
1914
|
}
|
|
1991
1915
|
|
|
1992
1916
|
// Operations are used to wrap changes in such a way that each
|
|
@@ -2000,9 +1924,11 @@ var CodeMirror = (function() {
|
|
|
2000
1924
|
function endOperation() {
|
|
2001
1925
|
if (updateMaxLine) computeMaxLength();
|
|
2002
1926
|
if (maxLineChanged && !options.lineWrapping) {
|
|
2003
|
-
var cursorWidth = widthForcer.offsetWidth, left =
|
|
2004
|
-
|
|
2005
|
-
|
|
1927
|
+
var cursorWidth = widthForcer.offsetWidth, left = measureLine(maxLine, maxLine.text.length).left;
|
|
1928
|
+
if (!ie_lt8) {
|
|
1929
|
+
widthForcer.style.left = left + "px";
|
|
1930
|
+
lineSpace.style.minWidth = (left + cursorWidth) + "px";
|
|
1931
|
+
}
|
|
2006
1932
|
maxLineChanged = false;
|
|
2007
1933
|
}
|
|
2008
1934
|
var newScrollPos, updated;
|
|
@@ -2010,16 +1936,16 @@ var CodeMirror = (function() {
|
|
|
2010
1936
|
var coords = calculateCursorCoords();
|
|
2011
1937
|
newScrollPos = calculateScrollPos(coords.x, coords.y, coords.x, coords.yBot);
|
|
2012
1938
|
}
|
|
2013
|
-
if (changes.length
|
|
2014
|
-
|
|
1939
|
+
if (changes.length || newScrollPos && newScrollPos.scrollTop != null)
|
|
1940
|
+
updated = updateDisplay(changes, true, newScrollPos && newScrollPos.scrollTop);
|
|
1941
|
+
if (!updated) {
|
|
2015
1942
|
if (selectionChanged) updateSelection();
|
|
2016
1943
|
if (gutterDirty) updateGutter();
|
|
2017
1944
|
}
|
|
2018
1945
|
if (newScrollPos) scrollCursorIntoView();
|
|
2019
|
-
if (selectionChanged)
|
|
1946
|
+
if (selectionChanged) restartBlink();
|
|
2020
1947
|
|
|
2021
|
-
if (focused &&
|
|
2022
|
-
(updateInput === true || (updateInput !== false && selectionChanged)))
|
|
1948
|
+
if (focused && (updateInput === true || (updateInput !== false && selectionChanged)))
|
|
2023
1949
|
resetInput(userSelChange);
|
|
2024
1950
|
|
|
2025
1951
|
if (selectionChanged && options.matchBrackets)
|
|
@@ -2081,11 +2007,12 @@ var CodeMirror = (function() {
|
|
|
2081
2007
|
dragDrop: true,
|
|
2082
2008
|
onChange: null,
|
|
2083
2009
|
onCursorActivity: null,
|
|
2010
|
+
onViewportChange: null,
|
|
2084
2011
|
onGutterClick: null,
|
|
2085
|
-
onHighlightComplete: null,
|
|
2086
2012
|
onUpdate: null,
|
|
2087
2013
|
onFocus: null, onBlur: null, onScroll: null,
|
|
2088
2014
|
matchBrackets: false,
|
|
2015
|
+
cursorBlinkRate: 530,
|
|
2089
2016
|
workTime: 100,
|
|
2090
2017
|
workDelay: 200,
|
|
2091
2018
|
pollInterval: 100,
|
|
@@ -2124,7 +2051,13 @@ var CodeMirror = (function() {
|
|
|
2124
2051
|
var spec = CodeMirror.resolveMode(spec);
|
|
2125
2052
|
var mfactory = modes[spec.name];
|
|
2126
2053
|
if (!mfactory) return CodeMirror.getMode(options, "text/plain");
|
|
2127
|
-
|
|
2054
|
+
var modeObj = mfactory(options, spec);
|
|
2055
|
+
if (modeExtensions.hasOwnProperty(spec.name)) {
|
|
2056
|
+
var exts = modeExtensions[spec.name];
|
|
2057
|
+
for (var prop in exts) if (exts.hasOwnProperty(prop)) modeObj[prop] = exts[prop];
|
|
2058
|
+
}
|
|
2059
|
+
modeObj.name = spec.name;
|
|
2060
|
+
return modeObj;
|
|
2128
2061
|
};
|
|
2129
2062
|
CodeMirror.listModes = function() {
|
|
2130
2063
|
var list = [];
|
|
@@ -2144,6 +2077,13 @@ var CodeMirror = (function() {
|
|
|
2144
2077
|
extensions[name] = func;
|
|
2145
2078
|
};
|
|
2146
2079
|
|
|
2080
|
+
var modeExtensions = CodeMirror.modeExtensions = {};
|
|
2081
|
+
CodeMirror.extendMode = function(mode, properties) {
|
|
2082
|
+
var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {});
|
|
2083
|
+
for (var prop in properties) if (properties.hasOwnProperty(prop))
|
|
2084
|
+
exts[prop] = properties[prop];
|
|
2085
|
+
};
|
|
2086
|
+
|
|
2147
2087
|
var commands = CodeMirror.commands = {
|
|
2148
2088
|
selectAll: function(cm) {cm.setSelection({line: 0, ch: 0}, {line: cm.lineCount() - 1});},
|
|
2149
2089
|
killLine: function(cm) {
|
|
@@ -2241,6 +2181,10 @@ var CodeMirror = (function() {
|
|
|
2241
2181
|
function lookup(map) {
|
|
2242
2182
|
map = getKeyMap(map);
|
|
2243
2183
|
var found = map[name];
|
|
2184
|
+
if (found === false) {
|
|
2185
|
+
if (stop) stop();
|
|
2186
|
+
return true;
|
|
2187
|
+
}
|
|
2244
2188
|
if (found != null && handle(found)) return true;
|
|
2245
2189
|
if (map.nofallthrough) {
|
|
2246
2190
|
if (stop) stop();
|
|
@@ -2268,8 +2212,15 @@ var CodeMirror = (function() {
|
|
|
2268
2212
|
options.value = textarea.value;
|
|
2269
2213
|
if (!options.tabindex && textarea.tabindex)
|
|
2270
2214
|
options.tabindex = textarea.tabindex;
|
|
2271
|
-
|
|
2272
|
-
|
|
2215
|
+
// Set autofocus to true if this textarea is focused, or if it has
|
|
2216
|
+
// autofocus and no other element is focused.
|
|
2217
|
+
if (options.autofocus == null) {
|
|
2218
|
+
var hasFocus = document.body;
|
|
2219
|
+
// doc.activeElement occasionally throws on IE
|
|
2220
|
+
try { hasFocus = document.activeElement; } catch(e) {}
|
|
2221
|
+
options.autofocus = hasFocus == textarea ||
|
|
2222
|
+
textarea.getAttribute("autofocus") != null && hasFocus == document.body;
|
|
2223
|
+
}
|
|
2273
2224
|
|
|
2274
2225
|
function save() {textarea.value = instance.getValue();}
|
|
2275
2226
|
if (textarea.form) {
|
|
@@ -2277,13 +2228,12 @@ var CodeMirror = (function() {
|
|
|
2277
2228
|
var rmSubmit = connect(textarea.form, "submit", save, true);
|
|
2278
2229
|
if (typeof textarea.form.submit == "function") {
|
|
2279
2230
|
var realSubmit = textarea.form.submit;
|
|
2280
|
-
function wrappedSubmit() {
|
|
2231
|
+
textarea.form.submit = function wrappedSubmit() {
|
|
2281
2232
|
save();
|
|
2282
2233
|
textarea.form.submit = realSubmit;
|
|
2283
2234
|
textarea.form.submit();
|
|
2284
2235
|
textarea.form.submit = wrappedSubmit;
|
|
2285
|
-
}
|
|
2286
|
-
textarea.form.submit = wrappedSubmit;
|
|
2236
|
+
};
|
|
2287
2237
|
}
|
|
2288
2238
|
}
|
|
2289
2239
|
|
|
@@ -2306,6 +2256,18 @@ var CodeMirror = (function() {
|
|
|
2306
2256
|
return instance;
|
|
2307
2257
|
};
|
|
2308
2258
|
|
|
2259
|
+
var gecko = /gecko\/\d{7}/i.test(navigator.userAgent);
|
|
2260
|
+
var ie = /MSIE \d/.test(navigator.userAgent);
|
|
2261
|
+
var ie_lt8 = /MSIE [1-7]\b/.test(navigator.userAgent);
|
|
2262
|
+
var ie_lt9 = /MSIE [1-8]\b/.test(navigator.userAgent);
|
|
2263
|
+
var quirksMode = ie && document.documentMode == 5;
|
|
2264
|
+
var webkit = /WebKit\//.test(navigator.userAgent);
|
|
2265
|
+
var chrome = /Chrome\//.test(navigator.userAgent);
|
|
2266
|
+
var opera = /Opera\//.test(navigator.userAgent);
|
|
2267
|
+
var safari = /Apple Computer/.test(navigator.vendor);
|
|
2268
|
+
var khtml = /KHTML\//.test(navigator.userAgent);
|
|
2269
|
+
var mac_geLion = /Mac OS X 10\D([7-9]|\d\d)\D/.test(navigator.userAgent);
|
|
2270
|
+
|
|
2309
2271
|
// Utility functions for working with state. Exported because modes
|
|
2310
2272
|
// sometimes need to do this.
|
|
2311
2273
|
function copyState(mode, state) {
|
|
@@ -2324,6 +2286,14 @@ var CodeMirror = (function() {
|
|
|
2324
2286
|
return mode.startState ? mode.startState(a1, a2) : true;
|
|
2325
2287
|
}
|
|
2326
2288
|
CodeMirror.startState = startState;
|
|
2289
|
+
CodeMirror.innerMode = function(mode, state) {
|
|
2290
|
+
while (mode.innerMode) {
|
|
2291
|
+
var info = mode.innerMode(state);
|
|
2292
|
+
state = info.state;
|
|
2293
|
+
mode = info.mode;
|
|
2294
|
+
}
|
|
2295
|
+
return info || {mode: mode, state: state};
|
|
2296
|
+
};
|
|
2327
2297
|
|
|
2328
2298
|
// The character stream used by a mode's parser.
|
|
2329
2299
|
function StringStream(string, tabSize) {
|
|
@@ -2334,7 +2304,7 @@ var CodeMirror = (function() {
|
|
|
2334
2304
|
StringStream.prototype = {
|
|
2335
2305
|
eol: function() {return this.pos >= this.string.length;},
|
|
2336
2306
|
sol: function() {return this.pos == 0;},
|
|
2337
|
-
peek: function() {return this.string.charAt(this.pos);},
|
|
2307
|
+
peek: function() {return this.string.charAt(this.pos) || undefined;},
|
|
2338
2308
|
next: function() {
|
|
2339
2309
|
if (this.pos < this.string.length)
|
|
2340
2310
|
return this.string.charAt(this.pos++);
|
|
@@ -2365,13 +2335,14 @@ var CodeMirror = (function() {
|
|
|
2365
2335
|
indentation: function() {return countColumn(this.string, null, this.tabSize);},
|
|
2366
2336
|
match: function(pattern, consume, caseInsensitive) {
|
|
2367
2337
|
if (typeof pattern == "string") {
|
|
2368
|
-
|
|
2338
|
+
var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;};
|
|
2369
2339
|
if (cased(this.string).indexOf(cased(pattern), this.pos) == this.pos) {
|
|
2370
2340
|
if (consume !== false) this.pos += pattern.length;
|
|
2371
2341
|
return true;
|
|
2372
2342
|
}
|
|
2373
2343
|
} else {
|
|
2374
2344
|
var match = this.string.slice(this.pos).match(pattern);
|
|
2345
|
+
if (match && match.index > 0) return null;
|
|
2375
2346
|
if (match && consume !== false) this.pos += match[0].length;
|
|
2376
2347
|
return match;
|
|
2377
2348
|
}
|
|
@@ -2380,210 +2351,162 @@ var CodeMirror = (function() {
|
|
|
2380
2351
|
};
|
|
2381
2352
|
CodeMirror.StringStream = StringStream;
|
|
2382
2353
|
|
|
2383
|
-
function
|
|
2384
|
-
this.from = from; this.to = to; this.
|
|
2354
|
+
function MarkedSpan(from, to, marker) {
|
|
2355
|
+
this.from = from; this.to = to; this.marker = marker;
|
|
2385
2356
|
}
|
|
2386
|
-
MarkedText.prototype = {
|
|
2387
|
-
attach: function(line) { this.marker.set.push(line); },
|
|
2388
|
-
detach: function(line) {
|
|
2389
|
-
var ix = indexOf(this.marker.set, line);
|
|
2390
|
-
if (ix > -1) this.marker.set.splice(ix, 1);
|
|
2391
|
-
},
|
|
2392
|
-
split: function(pos, lenBefore) {
|
|
2393
|
-
if (this.to <= pos && this.to != null) return null;
|
|
2394
|
-
var from = this.from < pos || this.from == null ? null : this.from - pos + lenBefore;
|
|
2395
|
-
var to = this.to == null ? null : this.to - pos + lenBefore;
|
|
2396
|
-
return new MarkedText(from, to, this.style, this.marker);
|
|
2397
|
-
},
|
|
2398
|
-
dup: function() { return new MarkedText(null, null, this.style, this.marker); },
|
|
2399
|
-
clipTo: function(fromOpen, from, toOpen, to, diff) {
|
|
2400
|
-
if (fromOpen && to > this.from && (to < this.to || this.to == null))
|
|
2401
|
-
this.from = null;
|
|
2402
|
-
else if (this.from != null && this.from >= from)
|
|
2403
|
-
this.from = Math.max(to, this.from) + diff;
|
|
2404
|
-
if (toOpen && (from < this.to || this.to == null) && (from > this.from || this.from == null))
|
|
2405
|
-
this.to = null;
|
|
2406
|
-
else if (this.to != null && this.to > from)
|
|
2407
|
-
this.to = to < this.to ? this.to + diff : from;
|
|
2408
|
-
},
|
|
2409
|
-
isDead: function() { return this.from != null && this.to != null && this.from >= this.to; },
|
|
2410
|
-
sameSet: function(x) { return this.marker == x.marker; }
|
|
2411
|
-
};
|
|
2412
2357
|
|
|
2413
|
-
function
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
split: function(pos, lenBefore) {
|
|
2420
|
-
if (pos < this.from) {
|
|
2421
|
-
this.from = this.to = (this.from - pos) + lenBefore;
|
|
2422
|
-
return this;
|
|
2423
|
-
}
|
|
2424
|
-
},
|
|
2425
|
-
isDead: function() { return this.from > this.to; },
|
|
2426
|
-
clipTo: function(fromOpen, from, toOpen, to, diff) {
|
|
2427
|
-
if ((fromOpen || from < this.from) && (toOpen || to > this.to)) {
|
|
2428
|
-
this.from = 0; this.to = -1;
|
|
2429
|
-
} else if (this.from > from) {
|
|
2430
|
-
this.from = this.to = Math.max(to, this.from) + diff;
|
|
2431
|
-
}
|
|
2432
|
-
},
|
|
2433
|
-
sameSet: function(x) { return false; },
|
|
2434
|
-
find: function() {
|
|
2435
|
-
if (!this.line || !this.line.parent) return null;
|
|
2436
|
-
return {line: lineNo(this.line), ch: this.from};
|
|
2437
|
-
},
|
|
2438
|
-
clear: function() {
|
|
2439
|
-
if (this.line) {
|
|
2440
|
-
var found = indexOf(this.line.marked, this);
|
|
2441
|
-
if (found != -1) this.line.marked.splice(found, 1);
|
|
2442
|
-
this.line = null;
|
|
2358
|
+
function getMarkedSpanFor(spans, marker, del) {
|
|
2359
|
+
if (spans) for (var i = 0; i < spans.length; ++i) {
|
|
2360
|
+
var span = spans[i];
|
|
2361
|
+
if (span.marker == marker) {
|
|
2362
|
+
if (del) spans.splice(i, 1);
|
|
2363
|
+
return span;
|
|
2443
2364
|
}
|
|
2444
2365
|
}
|
|
2445
|
-
};
|
|
2446
|
-
|
|
2447
|
-
// Line objects. These hold state related to a line, including
|
|
2448
|
-
// highlighting info (the styles array).
|
|
2449
|
-
function Line(text, styles) {
|
|
2450
|
-
this.styles = styles || [text, null];
|
|
2451
|
-
this.text = text;
|
|
2452
|
-
this.height = 1;
|
|
2453
|
-
this.marked = this.gutterMarker = this.className = this.bgClassName = this.handlers = null;
|
|
2454
|
-
this.stateAfter = this.parent = this.hidden = null;
|
|
2455
2366
|
}
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
if (
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2367
|
+
|
|
2368
|
+
function markedSpansBefore(old, startCh, endCh) {
|
|
2369
|
+
if (old) for (var i = 0, nw; i < old.length; ++i) {
|
|
2370
|
+
var span = old[i], marker = span.marker;
|
|
2371
|
+
var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh);
|
|
2372
|
+
if (startsBefore || marker.type == "bookmark" && span.from == startCh && span.from != endCh) {
|
|
2373
|
+
var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh);
|
|
2374
|
+
(nw || (nw = [])).push({from: span.from,
|
|
2375
|
+
to: endsAfter ? null : span.to,
|
|
2376
|
+
marker: marker});
|
|
2464
2377
|
}
|
|
2465
2378
|
}
|
|
2466
|
-
return
|
|
2379
|
+
return nw;
|
|
2467
2380
|
}
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
var
|
|
2472
|
-
|
|
2473
|
-
if (
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
if (mk) {
|
|
2479
|
-
var diff = text.length - (to - from);
|
|
2480
|
-
for (var i = 0; i < mk.length; ++i) {
|
|
2481
|
-
var mark = mk[i];
|
|
2482
|
-
mark.clipTo(from == null, from || 0, to_ == null, to, diff);
|
|
2483
|
-
if (mark.isDead()) {mark.detach(this); mk.splice(i--, 1);}
|
|
2484
|
-
}
|
|
2485
|
-
}
|
|
2486
|
-
},
|
|
2487
|
-
// Split a part off a line, keeping styles and markers intact.
|
|
2488
|
-
split: function(pos, textBefore) {
|
|
2489
|
-
var st = [textBefore, null], mk = this.marked;
|
|
2490
|
-
copyStyles(pos, this.text.length, this.styles, st);
|
|
2491
|
-
var taken = new Line(textBefore + this.text.slice(pos), st);
|
|
2492
|
-
if (mk) {
|
|
2493
|
-
for (var i = 0; i < mk.length; ++i) {
|
|
2494
|
-
var mark = mk[i];
|
|
2495
|
-
var newmark = mark.split(pos, textBefore.length);
|
|
2496
|
-
if (newmark) {
|
|
2497
|
-
if (!taken.marked) taken.marked = [];
|
|
2498
|
-
taken.marked.push(newmark); newmark.attach(taken);
|
|
2499
|
-
if (newmark == mark) mk.splice(i--, 1);
|
|
2500
|
-
}
|
|
2501
|
-
}
|
|
2381
|
+
|
|
2382
|
+
function markedSpansAfter(old, endCh) {
|
|
2383
|
+
if (old) for (var i = 0, nw; i < old.length; ++i) {
|
|
2384
|
+
var span = old[i], marker = span.marker;
|
|
2385
|
+
var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh);
|
|
2386
|
+
if (endsAfter || marker.type == "bookmark" && span.from == endCh) {
|
|
2387
|
+
var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh);
|
|
2388
|
+
(nw || (nw = [])).push({from: startsBefore ? null : span.from - endCh,
|
|
2389
|
+
to: span.to == null ? null : span.to - endCh,
|
|
2390
|
+
marker: marker});
|
|
2502
2391
|
}
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
mymark.detach(this);
|
|
2524
|
-
mk.splice(i--, 1);
|
|
2525
|
-
}
|
|
2526
|
-
continue outer;
|
|
2527
|
-
}
|
|
2528
|
-
}
|
|
2529
|
-
}
|
|
2530
|
-
mymk.push(mark);
|
|
2531
|
-
mark.attach(this);
|
|
2532
|
-
mark.from += mylen;
|
|
2533
|
-
if (mark.to != null) mark.to += mylen;
|
|
2392
|
+
}
|
|
2393
|
+
return nw;
|
|
2394
|
+
}
|
|
2395
|
+
|
|
2396
|
+
function updateMarkedSpans(oldFirst, oldLast, startCh, endCh, newText) {
|
|
2397
|
+
if (!oldFirst && !oldLast) return newText;
|
|
2398
|
+
// Get the spans that 'stick out' on both sides
|
|
2399
|
+
var first = markedSpansBefore(oldFirst, startCh);
|
|
2400
|
+
var last = markedSpansAfter(oldLast, endCh);
|
|
2401
|
+
|
|
2402
|
+
// Next, merge those two ends
|
|
2403
|
+
var sameLine = newText.length == 1, offset = lst(newText).length + (sameLine ? startCh : 0);
|
|
2404
|
+
if (first) {
|
|
2405
|
+
// Fix up .to properties of first
|
|
2406
|
+
for (var i = 0; i < first.length; ++i) {
|
|
2407
|
+
var span = first[i];
|
|
2408
|
+
if (span.to == null) {
|
|
2409
|
+
var found = getMarkedSpanFor(last, span.marker);
|
|
2410
|
+
if (!found) span.to = startCh;
|
|
2411
|
+
else if (sameLine) span.to = found.to == null ? null : found.to + offset;
|
|
2534
2412
|
}
|
|
2535
2413
|
}
|
|
2536
|
-
}
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
if (
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
if (
|
|
2547
|
-
omk.splice(j, 1);
|
|
2548
|
-
mk.splice(i--, 1);
|
|
2549
|
-
continue outer;
|
|
2550
|
-
} else {
|
|
2551
|
-
close = false; break;
|
|
2552
|
-
}
|
|
2414
|
+
}
|
|
2415
|
+
if (last) {
|
|
2416
|
+
// Fix up .from in last (or move them into first in case of sameLine)
|
|
2417
|
+
for (var i = 0; i < last.length; ++i) {
|
|
2418
|
+
var span = last[i];
|
|
2419
|
+
if (span.to != null) span.to += offset;
|
|
2420
|
+
if (span.from == null) {
|
|
2421
|
+
var found = getMarkedSpanFor(first, span.marker);
|
|
2422
|
+
if (!found) {
|
|
2423
|
+
span.from = offset;
|
|
2424
|
+
if (sameLine) (first || (first = [])).push(span);
|
|
2553
2425
|
}
|
|
2426
|
+
} else {
|
|
2427
|
+
span.from += offset;
|
|
2428
|
+
if (sameLine) (first || (first = [])).push(span);
|
|
2554
2429
|
}
|
|
2555
|
-
if (close) mark.to = this.text.length;
|
|
2556
2430
|
}
|
|
2557
|
-
}
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2431
|
+
}
|
|
2432
|
+
|
|
2433
|
+
var newMarkers = [newHL(newText[0], first)];
|
|
2434
|
+
if (!sameLine) {
|
|
2435
|
+
// Fill gap with whole-line-spans
|
|
2436
|
+
var gap = newText.length - 2, gapMarkers;
|
|
2437
|
+
if (gap > 0 && first)
|
|
2438
|
+
for (var i = 0; i < first.length; ++i)
|
|
2439
|
+
if (first[i].to == null)
|
|
2440
|
+
(gapMarkers || (gapMarkers = [])).push({from: null, to: null, marker: first[i].marker});
|
|
2441
|
+
for (var i = 0; i < gap; ++i)
|
|
2442
|
+
newMarkers.push(newHL(newText[i+1], gapMarkers));
|
|
2443
|
+
newMarkers.push(newHL(lst(newText), last));
|
|
2444
|
+
}
|
|
2445
|
+
return newMarkers;
|
|
2446
|
+
}
|
|
2447
|
+
|
|
2448
|
+
// hl stands for history-line, a data structure that can be either a
|
|
2449
|
+
// string (line without markers) or a {text, markedSpans} object.
|
|
2450
|
+
function hlText(val) { return typeof val == "string" ? val : val.text; }
|
|
2451
|
+
function hlSpans(val) { return typeof val == "string" ? null : val.markedSpans; }
|
|
2452
|
+
function newHL(text, spans) { return spans ? {text: text, markedSpans: spans} : text; }
|
|
2453
|
+
|
|
2454
|
+
function detachMarkedSpans(line) {
|
|
2455
|
+
var spans = line.markedSpans;
|
|
2456
|
+
if (!spans) return;
|
|
2457
|
+
for (var i = 0; i < spans.length; ++i) {
|
|
2458
|
+
var lines = spans[i].marker.lines;
|
|
2459
|
+
var ix = indexOf(lines, line);
|
|
2460
|
+
lines.splice(ix, 1);
|
|
2461
|
+
}
|
|
2462
|
+
line.markedSpans = null;
|
|
2463
|
+
}
|
|
2464
|
+
|
|
2465
|
+
function attachMarkedSpans(line, spans) {
|
|
2466
|
+
if (!spans) return;
|
|
2467
|
+
for (var i = 0; i < spans.length; ++i)
|
|
2468
|
+
var marker = spans[i].marker.lines.push(line);
|
|
2469
|
+
line.markedSpans = spans;
|
|
2470
|
+
}
|
|
2471
|
+
|
|
2472
|
+
// When measuring the position of the end of a line, different
|
|
2473
|
+
// browsers require different approaches. If an empty span is added,
|
|
2474
|
+
// many browsers report bogus offsets. Of those, some (Webkit,
|
|
2475
|
+
// recent IE) will accept a space without moving the whole span to
|
|
2476
|
+
// the next line when wrapping it, others work with a zero-width
|
|
2477
|
+
// space.
|
|
2478
|
+
var eolSpanContent = " ";
|
|
2479
|
+
if (gecko || (ie && !ie_lt8)) eolSpanContent = "\u200b";
|
|
2480
|
+
else if (opera) eolSpanContent = "";
|
|
2481
|
+
|
|
2482
|
+
// Line objects. These hold state related to a line, including
|
|
2483
|
+
// highlighting info (the styles array).
|
|
2484
|
+
function Line(text, markedSpans) {
|
|
2485
|
+
this.text = text;
|
|
2486
|
+
this.height = 1;
|
|
2487
|
+
attachMarkedSpans(this, markedSpans);
|
|
2488
|
+
}
|
|
2489
|
+
Line.prototype = {
|
|
2490
|
+
update: function(text, markedSpans) {
|
|
2491
|
+
this.text = text;
|
|
2492
|
+
this.stateAfter = this.styles = null;
|
|
2493
|
+
detachMarkedSpans(this);
|
|
2494
|
+
attachMarkedSpans(this, markedSpans);
|
|
2569
2495
|
},
|
|
2570
2496
|
// Run the given mode's parser over a line, update the styles
|
|
2571
2497
|
// array, which contains alternating fragments of text and CSS
|
|
2572
2498
|
// classes.
|
|
2573
2499
|
highlight: function(mode, state, tabSize) {
|
|
2574
|
-
var stream = new StringStream(this.text, tabSize), st = this.styles
|
|
2575
|
-
var
|
|
2500
|
+
var stream = new StringStream(this.text, tabSize), st = this.styles || (this.styles = []);
|
|
2501
|
+
var pos = st.length = 0;
|
|
2576
2502
|
if (this.text == "" && mode.blankLine) mode.blankLine(state);
|
|
2577
2503
|
while (!stream.eol()) {
|
|
2578
|
-
var style = mode.token(stream, state);
|
|
2579
|
-
var substr = this.text.slice(stream.start, stream.pos);
|
|
2504
|
+
var style = mode.token(stream, state), substr = stream.current();
|
|
2580
2505
|
stream.start = stream.pos;
|
|
2581
|
-
if (pos && st[pos-1] == style)
|
|
2506
|
+
if (pos && st[pos-1] == style) {
|
|
2582
2507
|
st[pos-2] += substr;
|
|
2583
|
-
else if (substr) {
|
|
2584
|
-
if (!changed && (st[pos+1] != style || (pos && st[pos-2] != prevWord))) changed = true;
|
|
2508
|
+
} else if (substr) {
|
|
2585
2509
|
st[pos++] = substr; st[pos++] = style;
|
|
2586
|
-
prevWord = curWord; curWord = st[pos];
|
|
2587
2510
|
}
|
|
2588
2511
|
// Give up when line is ridiculously long
|
|
2589
2512
|
if (stream.pos > 5000) {
|
|
@@ -2591,17 +2514,19 @@ var CodeMirror = (function() {
|
|
|
2591
2514
|
break;
|
|
2592
2515
|
}
|
|
2593
2516
|
}
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2517
|
+
},
|
|
2518
|
+
process: function(mode, state, tabSize) {
|
|
2519
|
+
var stream = new StringStream(this.text, tabSize);
|
|
2520
|
+
if (this.text == "" && mode.blankLine) mode.blankLine(state);
|
|
2521
|
+
while (!stream.eol() && stream.pos <= 5000) {
|
|
2522
|
+
mode.token(stream, state);
|
|
2523
|
+
stream.start = stream.pos;
|
|
2524
|
+
}
|
|
2600
2525
|
},
|
|
2601
2526
|
// Fetch the parser token for a given character. Useful for hacks
|
|
2602
2527
|
// that want to inspect the mode state (say, for completion).
|
|
2603
|
-
getTokenAt: function(mode, state, ch) {
|
|
2604
|
-
var txt = this.text, stream = new StringStream(txt);
|
|
2528
|
+
getTokenAt: function(mode, state, tabSize, ch) {
|
|
2529
|
+
var txt = this.text, stream = new StringStream(txt, tabSize);
|
|
2605
2530
|
while (stream.pos < ch && !stream.eol()) {
|
|
2606
2531
|
stream.start = stream.pos;
|
|
2607
2532
|
var style = mode.token(stream, state);
|
|
@@ -2615,94 +2540,98 @@ var CodeMirror = (function() {
|
|
|
2615
2540
|
indentation: function(tabSize) {return countColumn(this.text, null, tabSize);},
|
|
2616
2541
|
// Produces an HTML fragment for the line, taking selection,
|
|
2617
2542
|
// marking, and highlighting into account.
|
|
2618
|
-
|
|
2619
|
-
var
|
|
2620
|
-
|
|
2543
|
+
getContent: function(tabSize, wrapAt, compensateForWrapping) {
|
|
2544
|
+
var first = true, col = 0, specials = /[\t\u0000-\u0019\u200b\u2028\u2029\uFEFF]/g;
|
|
2545
|
+
var pre = elt("pre");
|
|
2546
|
+
function span_(html, text, style) {
|
|
2621
2547
|
if (!text) return;
|
|
2622
2548
|
// Work around a bug where, in some compat modes, IE ignores leading spaces
|
|
2623
2549
|
if (first && ie && text.charAt(0) == " ") text = "\u00a0" + text.slice(1);
|
|
2624
2550
|
first = false;
|
|
2625
|
-
if (
|
|
2551
|
+
if (!specials.test(text)) {
|
|
2626
2552
|
col += text.length;
|
|
2627
|
-
var
|
|
2553
|
+
var content = document.createTextNode(text);
|
|
2628
2554
|
} else {
|
|
2629
|
-
var
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2555
|
+
var content = document.createDocumentFragment(), pos = 0;
|
|
2556
|
+
while (true) {
|
|
2557
|
+
specials.lastIndex = pos;
|
|
2558
|
+
var m = specials.exec(text);
|
|
2559
|
+
var skipped = m ? m.index - pos : text.length - pos;
|
|
2560
|
+
if (skipped) {
|
|
2561
|
+
content.appendChild(document.createTextNode(text.slice(pos, pos + skipped)));
|
|
2562
|
+
col += skipped;
|
|
2563
|
+
}
|
|
2564
|
+
if (!m) break;
|
|
2565
|
+
pos += skipped + 1;
|
|
2566
|
+
if (m[0] == "\t") {
|
|
2567
|
+
var tabWidth = tabSize - col % tabSize;
|
|
2568
|
+
content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab"));
|
|
2569
|
+
col += tabWidth;
|
|
2636
2570
|
} else {
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
col +=
|
|
2641
|
-
pos = idx + 1;
|
|
2571
|
+
var token = elt("span", "\u2022", "cm-invalidchar");
|
|
2572
|
+
token.title = "\\u" + m[0].charCodeAt(0).toString(16);
|
|
2573
|
+
content.appendChild(token);
|
|
2574
|
+
col += 1;
|
|
2642
2575
|
}
|
|
2643
2576
|
}
|
|
2644
2577
|
}
|
|
2645
|
-
if (style) html.
|
|
2646
|
-
else html.
|
|
2578
|
+
if (style) html.appendChild(elt("span", [content], style));
|
|
2579
|
+
else html.appendChild(content);
|
|
2647
2580
|
}
|
|
2648
2581
|
var span = span_;
|
|
2649
2582
|
if (wrapAt != null) {
|
|
2650
|
-
var outPos = 0,
|
|
2651
|
-
span = function(text, style) {
|
|
2583
|
+
var outPos = 0, anchor = pre.anchor = elt("span");
|
|
2584
|
+
span = function(html, text, style) {
|
|
2652
2585
|
var l = text.length;
|
|
2653
2586
|
if (wrapAt >= outPos && wrapAt < outPos + l) {
|
|
2654
2587
|
if (wrapAt > outPos) {
|
|
2655
|
-
span_(text.slice(0, wrapAt - outPos), style);
|
|
2588
|
+
span_(html, text.slice(0, wrapAt - outPos), style);
|
|
2656
2589
|
// See comment at the definition of spanAffectsWrapping
|
|
2657
|
-
if (
|
|
2590
|
+
if (compensateForWrapping) html.appendChild(elt("wbr"));
|
|
2658
2591
|
}
|
|
2659
|
-
html.
|
|
2592
|
+
html.appendChild(anchor);
|
|
2660
2593
|
var cut = wrapAt - outPos;
|
|
2661
|
-
span_(opera ? text.slice(cut, cut + 1) : text.slice(cut), style);
|
|
2662
|
-
html.
|
|
2663
|
-
if (opera) span_(text.slice(cut + 1), style);
|
|
2594
|
+
span_(anchor, opera ? text.slice(cut, cut + 1) : text.slice(cut), style);
|
|
2595
|
+
if (opera) span_(html, text.slice(cut + 1), style);
|
|
2664
2596
|
wrapAt--;
|
|
2665
2597
|
outPos += l;
|
|
2666
2598
|
} else {
|
|
2667
2599
|
outPos += l;
|
|
2668
|
-
span_(text, style);
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
// to determine which to use.)
|
|
2674
|
-
if (outPos == wrapAt && outPos == len)
|
|
2675
|
-
html.push(open + (gecko || (ie && !ie_lt8) ? "​" : " ") + "</span>");
|
|
2600
|
+
span_(html, text, style);
|
|
2601
|
+
if (outPos == wrapAt && outPos == len) {
|
|
2602
|
+
setTextContent(anchor, eolSpanContent);
|
|
2603
|
+
html.appendChild(anchor);
|
|
2604
|
+
}
|
|
2676
2605
|
// Stop outputting HTML when gone sufficiently far beyond measure
|
|
2677
2606
|
else if (outPos > wrapAt + 10 && /\s/.test(text)) span = function(){};
|
|
2678
2607
|
}
|
|
2679
|
-
}
|
|
2608
|
+
};
|
|
2680
2609
|
}
|
|
2681
2610
|
|
|
2682
|
-
var st = this.styles, allText = this.text, marked = this.
|
|
2611
|
+
var st = this.styles, allText = this.text, marked = this.markedSpans;
|
|
2683
2612
|
var len = allText.length;
|
|
2684
2613
|
function styleToClass(style) {
|
|
2685
2614
|
if (!style) return null;
|
|
2686
2615
|
return "cm-" + style.replace(/ +/g, " cm-");
|
|
2687
2616
|
}
|
|
2688
|
-
|
|
2689
2617
|
if (!allText && wrapAt == null) {
|
|
2690
|
-
span(" ");
|
|
2618
|
+
span(pre, " ");
|
|
2691
2619
|
} else if (!marked || !marked.length) {
|
|
2692
2620
|
for (var i = 0, ch = 0; ch < len; i+=2) {
|
|
2693
2621
|
var str = st[i], style = st[i+1], l = str.length;
|
|
2694
2622
|
if (ch + l > len) str = str.slice(0, len - ch);
|
|
2695
2623
|
ch += l;
|
|
2696
|
-
span(str, styleToClass(style));
|
|
2624
|
+
span(pre, str, styleToClass(style));
|
|
2697
2625
|
}
|
|
2698
2626
|
} else {
|
|
2627
|
+
marked.sort(function(a, b) { return a.from - b.from; });
|
|
2699
2628
|
var pos = 0, i = 0, text = "", style, sg = 0;
|
|
2700
2629
|
var nextChange = marked[0].from || 0, marks = [], markpos = 0;
|
|
2701
|
-
|
|
2630
|
+
var advanceMarks = function() {
|
|
2702
2631
|
var m;
|
|
2703
2632
|
while (markpos < marked.length &&
|
|
2704
2633
|
((m = marked[markpos]).from == pos || m.from == null)) {
|
|
2705
|
-
if (m.
|
|
2634
|
+
if (m.marker.type == "range") marks.push(m);
|
|
2706
2635
|
++markpos;
|
|
2707
2636
|
}
|
|
2708
2637
|
nextChange = markpos < marked.length ? marked[markpos].from : Infinity;
|
|
@@ -2712,7 +2641,7 @@ var CodeMirror = (function() {
|
|
|
2712
2641
|
if (to == pos) marks.splice(i--, 1);
|
|
2713
2642
|
else nextChange = Math.min(to, nextChange);
|
|
2714
2643
|
}
|
|
2715
|
-
}
|
|
2644
|
+
};
|
|
2716
2645
|
var m = 0;
|
|
2717
2646
|
while (pos < len) {
|
|
2718
2647
|
if (nextChange == pos) advanceMarks();
|
|
@@ -2721,9 +2650,13 @@ var CodeMirror = (function() {
|
|
|
2721
2650
|
if (text) {
|
|
2722
2651
|
var end = pos + text.length;
|
|
2723
2652
|
var appliedStyle = style;
|
|
2724
|
-
for (var j = 0; j < marks.length; ++j)
|
|
2725
|
-
|
|
2726
|
-
|
|
2653
|
+
for (var j = 0; j < marks.length; ++j) {
|
|
2654
|
+
var mark = marks[j];
|
|
2655
|
+
appliedStyle = (appliedStyle ? appliedStyle + " " : "") + mark.marker.style;
|
|
2656
|
+
if (mark.marker.endStyle && mark.to === Math.min(end, upto)) appliedStyle += " " + mark.marker.endStyle;
|
|
2657
|
+
if (mark.marker.startStyle && mark.from === pos) appliedStyle += " " + mark.marker.startStyle;
|
|
2658
|
+
}
|
|
2659
|
+
span(pre, end > upto ? text.slice(0, upto - pos) : text, appliedStyle);
|
|
2727
2660
|
if (end >= upto) {text = text.slice(upto - pos); pos = upto; break;}
|
|
2728
2661
|
pos = end;
|
|
2729
2662
|
}
|
|
@@ -2731,28 +2664,13 @@ var CodeMirror = (function() {
|
|
|
2731
2664
|
}
|
|
2732
2665
|
}
|
|
2733
2666
|
}
|
|
2734
|
-
return
|
|
2667
|
+
return pre;
|
|
2735
2668
|
},
|
|
2736
2669
|
cleanUp: function() {
|
|
2737
2670
|
this.parent = null;
|
|
2738
|
-
|
|
2739
|
-
for (var i = 0, e = this.marked.length; i < e; ++i) this.marked[i].detach(this);
|
|
2671
|
+
detachMarkedSpans(this);
|
|
2740
2672
|
}
|
|
2741
2673
|
};
|
|
2742
|
-
// Utility used by replace and split above
|
|
2743
|
-
function copyStyles(from, to, source, dest) {
|
|
2744
|
-
for (var i = 0, pos = 0, state = 0; pos < to; i+=2) {
|
|
2745
|
-
var part = source[i], end = pos + part.length;
|
|
2746
|
-
if (state == 0) {
|
|
2747
|
-
if (end > from) dest.push(part.slice(from - pos, Math.min(part.length, to - pos)), source[i+1]);
|
|
2748
|
-
if (end >= from) state = 1;
|
|
2749
|
-
} else if (state == 1) {
|
|
2750
|
-
if (end > to) dest.push(part.slice(0, to - pos), source[i+1]);
|
|
2751
|
-
else dest.push(part, source[i+1]);
|
|
2752
|
-
}
|
|
2753
|
-
pos = end;
|
|
2754
|
-
}
|
|
2755
|
-
}
|
|
2756
2674
|
|
|
2757
2675
|
// Data structure that holds the sequence of lines.
|
|
2758
2676
|
function LeafChunk(lines) {
|
|
@@ -2953,7 +2871,7 @@ var CodeMirror = (function() {
|
|
|
2953
2871
|
History.prototype = {
|
|
2954
2872
|
addChange: function(start, added, old) {
|
|
2955
2873
|
this.undone.length = 0;
|
|
2956
|
-
var time = +new Date, cur = this.done
|
|
2874
|
+
var time = +new Date, cur = lst(this.done), last = cur && lst(cur);
|
|
2957
2875
|
var dtime = time - this.time;
|
|
2958
2876
|
|
|
2959
2877
|
if (this.compound && cur && !this.closed) {
|
|
@@ -3038,30 +2956,18 @@ var CodeMirror = (function() {
|
|
|
3038
2956
|
|
|
3039
2957
|
var Pass = CodeMirror.Pass = {toString: function(){return "CodeMirror.Pass";}};
|
|
3040
2958
|
|
|
3041
|
-
var gecko = /gecko\/\d{7}/i.test(navigator.userAgent);
|
|
3042
|
-
var ie = /MSIE \d/.test(navigator.userAgent);
|
|
3043
|
-
var ie_lt8 = /MSIE [1-7]\b/.test(navigator.userAgent);
|
|
3044
|
-
var ie_lt9 = /MSIE [1-8]\b/.test(navigator.userAgent);
|
|
3045
|
-
var quirksMode = ie && document.documentMode == 5;
|
|
3046
|
-
var webkit = /WebKit\//.test(navigator.userAgent);
|
|
3047
|
-
var chrome = /Chrome\//.test(navigator.userAgent);
|
|
3048
|
-
var opera = /Opera\//.test(navigator.userAgent);
|
|
3049
|
-
var safari = /Apple Computer/.test(navigator.vendor);
|
|
3050
|
-
var khtml = /KHTML\//.test(navigator.userAgent);
|
|
3051
|
-
var mac_geLion = /Mac OS X 10\D([7-9]|\d\d)\D/.test(navigator.userAgent);
|
|
3052
|
-
|
|
3053
2959
|
// Detect drag-and-drop
|
|
3054
2960
|
var dragAndDrop = function() {
|
|
3055
2961
|
// There is *some* kind of drag-and-drop support in IE6-8, but I
|
|
3056
2962
|
// couldn't get it to work yet.
|
|
3057
2963
|
if (ie_lt9) return false;
|
|
3058
|
-
var div =
|
|
2964
|
+
var div = elt('div');
|
|
3059
2965
|
return "draggable" in div || "dragDrop" in div;
|
|
3060
2966
|
}();
|
|
3061
2967
|
|
|
3062
2968
|
// Feature-detect whether newlines in textareas are converted to \r\n
|
|
3063
2969
|
var lineSep = function () {
|
|
3064
|
-
var te =
|
|
2970
|
+
var te = elt("textarea");
|
|
3065
2971
|
te.value = "foo\nbar";
|
|
3066
2972
|
if (te.value.indexOf("\r") > -1) return "\r\n";
|
|
3067
2973
|
return "\n";
|
|
@@ -3093,11 +2999,6 @@ var CodeMirror = (function() {
|
|
|
3093
2999
|
return n;
|
|
3094
3000
|
}
|
|
3095
3001
|
|
|
3096
|
-
function computedStyle(elt) {
|
|
3097
|
-
if (elt.currentStyle) return elt.currentStyle;
|
|
3098
|
-
return window.getComputedStyle(elt, null);
|
|
3099
|
-
}
|
|
3100
|
-
|
|
3101
3002
|
function eltOffset(node, screen) {
|
|
3102
3003
|
// Take the parts of bounding client rect that we are interested in so we are able to edit if need be,
|
|
3103
3004
|
// since the returned value cannot be changed externally (they are kept in sync as the element moves within the page)
|
|
@@ -3116,10 +3017,19 @@ var CodeMirror = (function() {
|
|
|
3116
3017
|
return box;
|
|
3117
3018
|
}
|
|
3118
3019
|
|
|
3119
|
-
// Get a node's text content.
|
|
3120
3020
|
function eltText(node) {
|
|
3121
3021
|
return node.textContent || node.innerText || node.nodeValue || "";
|
|
3122
3022
|
}
|
|
3023
|
+
|
|
3024
|
+
var spaceStrs = [""];
|
|
3025
|
+
function spaceStr(n) {
|
|
3026
|
+
while (spaceStrs.length <= n)
|
|
3027
|
+
spaceStrs.push(lst(spaceStrs) + " ");
|
|
3028
|
+
return spaceStrs[n];
|
|
3029
|
+
}
|
|
3030
|
+
|
|
3031
|
+
function lst(arr) { return arr[arr.length-1]; }
|
|
3032
|
+
|
|
3123
3033
|
function selectInput(node) {
|
|
3124
3034
|
if (ios) { // Mobile Safari apparently has a bug where select() is broken.
|
|
3125
3035
|
node.selectionStart = 0;
|
|
@@ -3132,27 +3042,27 @@ var CodeMirror = (function() {
|
|
|
3132
3042
|
function posLess(a, b) {return a.line < b.line || (a.line == b.line && a.ch < b.ch);}
|
|
3133
3043
|
function copyPos(x) {return {line: x.line, ch: x.ch};}
|
|
3134
3044
|
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3045
|
+
function elt(tag, content, className, style) {
|
|
3046
|
+
var e = document.createElement(tag);
|
|
3047
|
+
if (className) e.className = className;
|
|
3048
|
+
if (style) e.style.cssText = style;
|
|
3049
|
+
if (typeof content == "string") setTextContent(e, content);
|
|
3050
|
+
else if (content) for (var i = 0; i < content.length; ++i) e.appendChild(content[i]);
|
|
3051
|
+
return e;
|
|
3139
3052
|
}
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
return escapeElement.innerHTML;
|
|
3153
|
-
};
|
|
3053
|
+
function removeChildren(e) {
|
|
3054
|
+
e.innerHTML = "";
|
|
3055
|
+
return e;
|
|
3056
|
+
}
|
|
3057
|
+
function removeChildrenAndAdd(parent, e) {
|
|
3058
|
+
removeChildren(parent).appendChild(e);
|
|
3059
|
+
}
|
|
3060
|
+
function setTextContent(e, str) {
|
|
3061
|
+
if (ie_lt9) {
|
|
3062
|
+
e.innerHTML = "";
|
|
3063
|
+
e.appendChild(document.createTextNode(str));
|
|
3064
|
+
} else e.textContent = str;
|
|
3154
3065
|
}
|
|
3155
|
-
CodeMirror.htmlEscape = htmlEscape;
|
|
3156
3066
|
|
|
3157
3067
|
// Used to position the cursor after an undo/redo by finding the
|
|
3158
3068
|
// last edited character.
|
|
@@ -3227,5 +3137,7 @@ var CodeMirror = (function() {
|
|
|
3227
3137
|
for (var i = 1; i <= 12; i++) keyNames[i + 111] = keyNames[i + 63235] = "F" + i;
|
|
3228
3138
|
})();
|
|
3229
3139
|
|
|
3140
|
+
CodeMirror.version = "2.34";
|
|
3141
|
+
|
|
3230
3142
|
return CodeMirror;
|
|
3231
3143
|
})();
|