2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
language: node_js
node_js:
- 0.8
- 0.10
4 changes: 4 additions & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ Andy Kimball
Andy Li
angelozerr
angelo.zerr@gmail.com
Ankit
Ankit Ahuja
Ansel Santosa
Anthony Grimes
Expand Down Expand Up @@ -138,6 +139,7 @@ flack
ForbesLindesay
Forbes Lindesay
Ford_Lawnmower
Forrest Oliphant
Frank Wiegand
Gabriel Gheorghian
Gabriel Horner
Expand Down Expand Up @@ -256,6 +258,7 @@ Marcel Gerber
Marco Aurélio
Marco Munizaga
Marcus Bointon
Marek Rudnicki
Marijn Haverbeke
Mário Gonçalves
Mario Pietsch
Expand Down Expand Up @@ -383,6 +386,7 @@ stoskov
Taha Jahangir
Takuji Shimokawa
Tarmil
tel
tfjgeorge
Thaddee Tyl
TheHowl
Expand Down
21 changes: 14 additions & 7 deletions addon/edit/closetag.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,32 +94,32 @@
}
}

function autoCloseSlash(cm) {
if (cm.getOption("disableInput")) return CodeMirror.Pass;
function autoCloseCurrent(cm, typingSlash) {
var ranges = cm.listSelections(), replacements = [];
var head = typingSlash ? "/" : "</";
for (var i = 0; i < ranges.length; i++) {
if (!ranges[i].empty()) return CodeMirror.Pass;
var pos = ranges[i].head, tok = cm.getTokenAt(pos);
var inner = CodeMirror.innerMode(cm.getMode(), tok.state), state = inner.state;
if (tok.type == "string" || tok.string.charAt(0) != "<" ||
tok.start != pos.ch - 1)
if (typingSlash && (tok.type == "string" || tok.string.charAt(0) != "<" ||
tok.start != pos.ch - 1))
return CodeMirror.Pass;
// Kludge to get around the fact that we are not in XML mode
// when completing in JS/CSS snippet in htmlmixed mode. Does not
// work for other XML embedded languages (there is no general
// way to go from a mixed mode to its current XML state).
if (inner.mode.name != "xml") {
if (cm.getMode().name == "htmlmixed" && inner.mode.name == "javascript")
replacements[i] = "/script>";
replacements[i] = head + "script>";
else if (cm.getMode().name == "htmlmixed" && inner.mode.name == "css")
replacements[i] = "/style>";
replacements[i] = head + "style>";
else
return CodeMirror.Pass;
} else {
if (!state.context || !state.context.tagName ||
closingTagExists(cm, state.context.tagName, pos, state))
return CodeMirror.Pass;
replacements[i] = "/" + state.context.tagName + ">";
replacements[i] = head + state.context.tagName + ">";
}
}
cm.replaceSelections(replacements);
Expand All @@ -129,6 +129,13 @@
cm.indentLine(ranges[i].head.line);
}

function autoCloseSlash(cm) {
if (cm.getOption("disableInput")) return CodeMirror.Pass;
autoCloseCurrent(cm, true);
}

CodeMirror.commands.closeTag = function(cm) { return autoCloseCurrent(cm); };

function indexOf(collection, elt) {
if (collection.indexOf) return collection.indexOf(elt);
for (var i = 0, e = collection.length; i < e; ++i)
Expand Down
4 changes: 4 additions & 0 deletions addon/fold/foldcode.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,4 +142,8 @@
return editorOptions[name];
return defaultOptions[name];
}

CodeMirror.defineExtension("foldOption", function(options, name) {
return getOption(this, options, name);
});
});
6 changes: 4 additions & 2 deletions addon/fold/foldgutter.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,16 @@

function updateFoldInfo(cm, from, to) {
var opts = cm.state.foldGutter.options, cur = from;
var minSize = cm.foldOption(opts, "minFoldSize");
var func = cm.foldOption(opts, "rangeFinder");
cm.eachLine(from, to, function(line) {
var mark = null;
if (isFolded(cm, cur)) {
mark = marker(opts.indicatorFolded);
} else {
var pos = Pos(cur, 0), func = opts.rangeFinder || CodeMirror.fold.auto;
var pos = Pos(cur, 0);
var range = func && func(cm, pos);
if (range && range.from.line + 1 < range.to.line)
if (range && range.to.line - range.from.line >= minSize)
mark = marker(opts.indicatorOpen);
}
cm.setGutterMarker(line, opts.gutter, mark);
Expand Down
6 changes: 5 additions & 1 deletion addon/merge/merge.js
Original file line number Diff line number Diff line change
Expand Up @@ -259,11 +259,13 @@
function makeConnections(dv) {
if (!dv.showDifferences) return;

var align = dv.mv.options.connect == "align";
var align = dv.mv.options.connect == "align", oldScrollEdit, oldScrollOrig;
if (align) {
if (!dv.orig.curOp) return dv.orig.operation(function() {
makeConnections(dv);
});
oldScrollEdit = dv.edit.getScrollInfo().top;
oldScrollOrig = dv.orig.getScrollInfo().top;
for (var i = 0; i < dv.aligners.length; i++)
dv.aligners[i].clear();
dv.aligners.length = 0;
Expand Down Expand Up @@ -293,6 +295,8 @@
dv.aligners.push(padBelow(dv.edit, 0, extraSpaceAbove.edit));
if (extraSpaceAbove.orig)
dv.aligners.push(padBelow(dv.orig, 0, extraSpaceAbove.orig));
dv.edit.scrollTo(null, oldScrollEdit);
dv.orig.scrollTo(null, oldScrollOrig);
}
}

Expand Down
2 changes: 1 addition & 1 deletion addon/mode/simple.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@
var curState = states[state.state];
for (var i = 0; i < curState.length; i++) {
var rule = curState[i];
var matches = stream.match(rule.regex);
var matches = (!rule.data.sol || stream.sol()) && stream.match(rule.regex);
if (matches) {
if (rule.data.next) {
state.state = rule.data.next;
Expand Down
10 changes: 6 additions & 4 deletions addon/scroll/simplescrollbars.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,16 @@
CodeMirror.e_preventDefault(e);
var axis = self.orientation == "horizontal" ? "pageX" : "pageY";
var start = e[axis], startpos = self.pos;
function done() {
CodeMirror.off(document, "mousemove", move);
CodeMirror.off(document, "mouseup", done);
}
function move(e) {
if (e.which != 1) {
CodeMirror.off(document, "mousemove", move);
return;
}
if (e.which != 1) return done();
self.moveTo(startpos + (e[axis] - start) * (self.total / self.size));
}
CodeMirror.on(document, "mousemove", move);
CodeMirror.on(document, "mouseup", done);
});

CodeMirror.on(this.node, "click", function(e) {
Expand Down
95 changes: 95 additions & 0 deletions addon/selection/selection-pointer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";

CodeMirror.defineOption("selectionPointer", false, function(cm, val) {
var data = cm.state.selectionPointer;
if (data) {
CodeMirror.off(cm.getWrapperElement(), "mousemove", data.mousemove);
CodeMirror.off(cm.getWrapperElement(), "mouseout", data.mouseout);
cm.off("cursorActivity", reset);
cm.off("scroll", reset);
cm.state.selectionPointer = null;
cm.display.lineDiv.style.cursor = "";
}
if (val) {
data = cm.state.selectionPointer = {
value: typeof val == "string" ? val : "default",
mousemove: function(event) { mousemove(cm, event); },
mouseout: function(event) { mouseout(cm, event); },
rects: null,
mouseX: null, mouseY: null,
willUpdate: false
};
CodeMirror.on(cm.getWrapperElement(), "mousemove", data.mousemove);
CodeMirror.on(cm.getWrapperElement(), "mouseout", data.mouseout);
cm.on("cursorActivity", reset);
cm.on("scroll", reset);
}
});

function mousemove(cm, event) {
var data = cm.state.selectionPointer;
if (event.buttons == null ? event.which : event.buttons) {
data.mouseX = data.mouseY = null;
} else {
data.mouseX = event.clientX;
data.mouseY = event.clientY;
}
scheduleUpdate(cm);
}

function mouseout(cm, event) {
if (!cm.getWrapperElement().contains(event.relatedTarget)) {
var data = cm.state.selectionPointer;
data.mouseX = data.mouseY = null;
scheduleUpdate(cm);
}
}

function reset(cm) {
cm.state.selectionPointer.rects = null;
scheduleUpdate(cm);
}

function scheduleUpdate(cm) {
if (!cm.state.selectionPointer.willUpdate) {
cm.state.selectionPointer.willUpdate = true;
setTimeout(function() {
update(cm);
cm.state.selectionPointer.willUpdate = false;
}, 50);
}
}

function update(cm) {
var data = cm.state.selectionPointer;
if (!data) return;
if (data.rects == null && data.mouseX != null) {
data.rects = [];
if (cm.somethingSelected()) {
for (var sel = cm.display.selectionDiv.firstChild; sel; sel = sel.nextSibling)
data.rects.push(sel.getBoundingClientRect());
}
}
var inside = false;
if (data.mouseX != null) for (var i = 0; i < data.rects.length; i++) {
var rect = data.rects[i];
if (rect.left <= data.mouseX && rect.right >= data.mouseX &&
rect.top <= data.mouseY && rect.bottom >= data.mouseY)
inside = true;
}
var cursor = inside ? data.value : "";
if (cm.display.lineDiv.style.cursor != cursor)
cm.display.lineDiv.style.cursor = cursor;
}
});
15 changes: 1 addition & 14 deletions bin/lint
Original file line number Diff line number Diff line change
@@ -1,16 +1,3 @@
#!/usr/bin/env node

var lint = require("../test/lint/lint"),
path = require("path");

if (process.argv.length > 2) {
lint.checkDir(process.argv[2]);
} else {
process.chdir(path.resolve(__dirname, ".."));
lint.checkDir("lib");
lint.checkDir("mode");
lint.checkDir("addon");
lint.checkDir("keymap");
}

process.exit(lint.success() ? 0 : 1);
process.exit(require("../test/lint").ok ? 0 : 1);
2 changes: 1 addition & 1 deletion bower.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "codemirror",
"version":"4.11.0",
"version":"4.12.0",
"main": ["lib/codemirror.js", "lib/codemirror.css"],
"ignore": [
"**/.*",
Expand Down
5 changes: 5 additions & 0 deletions demo/simplemode.html
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ <h2>Simple Mode Demo</h2>
string (since JS provides no way to find out where a group matched),
and this property must hold an array of token styles that has one
style for each matched group.</dd>
<dt><code><strong>sol</strong></code>: boolean</dt>
<dd>When true, this token will only match at the start of the line.
(The <code>^</code> regexp marker doesn't work as you'd expect in
this context because of limitations in JavaScript's RegExp
API.)</dd>
<dt><code><strong>next</strong>: string</code></dt>
<dd>When a <code>next</code> property is present, the mode will
transfer to the state named by the property when the token is
Expand Down
1 change: 1 addition & 0 deletions doc/compress.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ <h2>Script compression helper</h2>
<input type="hidden" id="download" name="download" value="codemirror-compressed.js"/>
<p>Version: <select id="version" onchange="setVersion(this);" style="padding: 1px;">
<option value="http://codemirror.net/">HEAD</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=4.12.0;f=">4.12</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=4.11.0;f=">4.11</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=4.10.0;f=">4.10</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=4.9.0;f=">4.9</option>
Expand Down
37 changes: 27 additions & 10 deletions doc/manual.html
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
<section class=first id=overview>
<h2 style="position: relative">
User manual and reference guide
<span style="color: #888; font-size: 1rem; position: absolute; right: 0; bottom: 0">version 4.11.0</span>
<span style="color: #888; font-size: 1rem; position: absolute; right: 0; bottom: 0">version 4.12.0</span>
</h2>

<p>CodeMirror is a code-editor component that can be embedded in
Expand Down Expand Up @@ -1763,9 +1763,12 @@ <h3 id="api_sizing">Sizing, scrolling and positioning methods</h3>
If <code>mode</code> is <code>"local"</code>, they will be
relative to the top-left corner of the editable document. If it
is <code>"page"</code> or not given, they are relative to the
top-left corner of the page. <code>where</code> can be a boolean
indicating whether you want the start (<code>true</code>) or the
end (<code>false</code>) of the selection, or, if a <code>{line,
top-left corner of the page. If <code>mode</code>
is <code>"window"</code>, the coordinates are relative to the
top-left corner of the currently visible (scrolled)
window. <code>where</code> can be a boolean indicating whether
you want the start (<code>true</code>) or the end
(<code>false</code>) of the selection, or, if a <code>{line,
ch}</code> object is given, it specifies the precise position at
which you want to measure.</dd>
<dt id="charCoords"><code><strong>cm.charCoords</strong>(pos: {line, ch}, ?mode: string) → {left, right, top, bottom}</code></dt>
Expand Down Expand Up @@ -2229,8 +2232,12 @@ <h2 id="addons">Addons</h2>
squiggly underline style for this class.</dd>

<dt id="addon_closetag"><a href="../addon/edit/closetag.js"><code>edit/closetag.js</code></a></dt>
<dd>Provides utility functions for adding automatic tag closing
to XML modes. See
<dd>Defines an <code>autoCloseTags</code> option that will
auto-close XML tags when '<code>&gt;</code>' or '<code>/</code>'
is typed, and
a <code>closeTag</code> <a href="#commands">command</a> that
closes the nearest open tag. Depends on
the <code>fold/xml-fold.js</code> addon. See
the <a href="../demo/closetag.html">demo</a>.</dd>

<dt id="addon_continuelist"><a href="../addon/edit/continuelist.js"><code>edit/continuelist.js</code></a></dt>
Expand Down Expand Up @@ -2605,6 +2612,7 @@ <h2 id="addons">Addons</h2>
with pluggable warning sources
(see <a href="../addon/lint/json-lint.js"><code>json-lint.js</code></a>,
<a href="../addon/lint/javascript-lint.js"><code>javascript-lint.js</code></a>,
<a href="../addon/lint/coffeescript-lint.js"><code>coffeescript-lint.js</code></a>,
and <a href="../addon/lint/css-lint.js"><code>css-lint.js</code></a>
in the same directory). Defines a <code>lint</code> option that
can be set to a warning source (for
Expand All @@ -2627,6 +2635,14 @@ <h2 id="addons">Addons</h2>
and adds a background with the class <code>CodeMirror-activeline-background</code>.
is enabled. See the <a href="../demo/activeline.html">demo</a>.</dd>

<dt id="addon_selection-pointer"><a href="../addon/selection/selection-pointer.js"><code>selection/selection-pointer.js</code></a></dt>
<dd>Defines a <code>selectionPointer</code> option which you can
use to control the mouse cursor appearance when hovering over
the selection. It can be set to a string,
like <code>"pointer"</code>, or to true, in which case
the <code>"default"</code> (arrow) cursor will be used. You can
see a demo <a href="../mode/htmlmixed/index.html">here</a>.</dd>

<dt id="addon_loadmode"><a href="../addon/mode/loadmode.js"><code>mode/loadmode.js</code></a></dt>
<dd>Defines a <code>CodeMirror.requireMode(modename,
callback)</code> function that will try to load a given mode and
Expand All @@ -2651,12 +2667,13 @@ <h2 id="addons">Addons</h2>
properties <code>mimes</code>, which holds an array of MIME
types for modes with multiple MIMEs associated,
and <code>ext</code>, which holds an array of file extensions
associated with this mode. Three convenience
associated with this mode. Four convenience
functions, <code>CodeMirror.findModeByMIME</code>,
and <code>CodeMirror.findModeByExtension</code>,
<code>CodeMirror.findModeByExtension</code>,
<code>CodeMirror.findModeByFileName</code>
and <code>CodeMirror.findModeByName</code> are provided, which
return such an object given a MIME or extension string. Note
that, for historical reasons, this file resides in the
return such an object given a MIME, extension, file name or mode name
string. Note that, for historical reasons, this file resides in the
top-level <code>mode</code> directory, not
under <code>addon</code>. <a href="../demo/loadmode.html">Demo</a>.</dd>

Expand Down
Loading