1
0
mirror of https://github.com/monstra-cms/monstra.git synced 2025-08-05 20:57:49 +02:00

CodeMirror Plugin as a part of Monstra CMS #187

This commit is contained in:
Awilum
2014-01-15 00:18:15 +02:00
parent ed323cfe7b
commit fa00499d93
68 changed files with 0 additions and 15111 deletions

View File

@@ -1,6 +0,0 @@
# Combine existing list of authors with everyone known in git, sort, add header.
tail --lines=+3 AUTHORS > AUTHORS.tmp
git log --format='%aN' >> AUTHORS.tmp
echo -e "List of CodeMirror contributors. Updated before every release.\n" > AUTHORS
sort -u AUTHORS.tmp >> AUTHORS
rm -f AUTHORS.tmp

View File

@@ -1,92 +0,0 @@
#!/usr/bin/env node
// Compression helper for CodeMirror
//
// Example:
//
// bin/compress codemirror runmode javascript xml
//
// Will take lib/codemirror.js, addon/runmode/runmode.js,
// mode/javascript/javascript.js, and mode/xml/xml.js, run them though
// the online minifier at http://marijnhaverbeke.nl/uglifyjs, and spit
// out the result.
//
// bin/compress codemirror --local /path/to/bin/UglifyJS
//
// Will use a local minifier instead of the online default one.
//
// Script files are specified without .js ending. Prefixing them with
// their full (local) path is optional. So you may say lib/codemirror
// or mode/xml/xml to be more precise. In fact, even the .js suffix
// may be speficied, if wanted.
"use strict";
var fs = require("fs");
function help(ok) {
console.log("usage: " + process.argv[1] + " [--local /path/to/uglifyjs] files...");
process.exit(ok ? 0 : 1);
}
var local = null, args = [], extraArgs = null, files = [], blob = "";
for (var i = 2; i < process.argv.length; ++i) {
var arg = process.argv[i];
if (arg == "--local" && i + 1 < process.argv.length) {
var parts = process.argv[++i].split(/\s+/);
local = parts[0];
extraArgs = parts.slice(1);
if (!extraArgs.length) extraArgs = ["-c", "-m"];
} else if (arg == "--help") {
help(true);
} else if (arg[0] != "-") {
files.push({name: arg, re: new RegExp("(?:\\/|^)" + arg + (/\.js$/.test(arg) ? "$" : "\\.js$"))});
} else help(false);
}
function walk(dir) {
fs.readdirSync(dir).forEach(function(fname) {
if (/^[_\.]/.test(fname)) return;
var file = dir + fname;
if (fs.statSync(file).isDirectory()) return walk(file + "/");
if (files.some(function(spec, i) {
var match = spec.re.test(file);
if (match) files.splice(i, 1);
return match;
})) {
if (local) args.push(file);
else blob += fs.readFileSync(file, "utf8");
}
});
}
walk("lib/");
walk("addon/");
walk("mode/");
if (!local && !blob) help(false);
if (files.length) {
console.log("Some speficied files were not found: " +
files.map(function(a){return a.name;}).join(", "));
process.exit(1);
}
if (local) {
require("child_process").spawn(local, args.concat(extraArgs), {stdio: ["ignore", process.stdout, process.stderr]});
} else {
var data = new Buffer("js_code=" + require("querystring").escape(blob), "utf8");
var req = require("http").request({
host: "marijnhaverbeke.nl",
port: 80,
method: "POST",
path: "/uglifyjs",
headers: {"content-type": "application/x-www-form-urlencoded",
"content-length": data.length}
});
req.on("response", function(resp) {
resp.on("data", function (chunk) { process.stdout.write(chunk); });
});
req.end(data);
}

View File

@@ -1,16 +0,0 @@
#!/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);

View File

@@ -1,61 +0,0 @@
#!/usr/bin/env node
// Simple command-line code highlighting tool. Reads code from stdin,
// spits html to stdout. For example:
//
// echo 'function foo(a) { return a; }' | bin/source-highlight -s javascript
// bin/source-highlight -s
var fs = require("fs");
CodeMirror = require("../addon/runmode/runmode.node.js");
require("../mode/meta.js");
var sPos = process.argv.indexOf("-s");
if (sPos == -1 || sPos == process.argv.length - 1) {
console.error("Usage: source-highlight -s language");
process.exit(1);
}
var lang = process.argv[sPos + 1].toLowerCase(), modeName = lang;
CodeMirror.modeInfo.forEach(function(info) {
if (info.mime == lang) {
modeName = info.mode;
} else if (info.name.toLowerCase() == lang) {
modeName = info.mode;
lang = info.mime;
}
});
function ensureMode(name) {
if (CodeMirror.modes[name] || name == "null") return;
try {
require("../mode/" + name + "/" + name + ".js");
} catch(e) {
console.error("Could not load mode " + name + ".");
process.exit(1);
}
var obj = CodeMirror.modes[name];
if (obj.dependencies) obj.dependencies.forEach(ensureMode);
}
ensureMode(modeName);
function esc(str) {
return str.replace(/[<&]/, function(ch) { return ch == "&" ? "&amp;" : "&lt;"; });
}
var code = fs.readFileSync("/dev/stdin", "utf8");
var curStyle = null, accum = "";
function flush() {
if (curStyle) process.stdout.write("<span class=\"" + curStyle.replace(/(^|\s+)/g, "$1cm-") + "\">" + esc(accum) + "</span>");
else process.stdout.write(esc(accum));
}
CodeMirror.runMode(code, lang, function(text, style) {
if (style != curStyle) {
flush();
curStyle = style; accum = text;
} else {
accum += text;
}
});
flush();

View File

@@ -1,78 +0,0 @@
<!doctype html>
<title>CodeMirror: Active Line Demo</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css">
<link rel="stylesheet" href="../lib/codemirror.css">
<script src="../lib/codemirror.js"></script>
<script src="../mode/xml/xml.js"></script>
<script src="../addon/selection/active-line.js"></script>
<style type="text/css">
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
</style>
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="../doc/manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#">Active Line</a>
</ul>
</div>
<article>
<h2>Active Line Demo</h2>
<form><textarea id="code" name="code">
<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"
xmlns:georss="http://www.georss.org/georss"
xmlns:twitter="http://api.twitter.com">
<channel>
<title>Twitter / codemirror</title>
<link>http://twitter.com/codemirror</link>
<atom:link type="application/rss+xml"
href="http://twitter.com/statuses/user_timeline/242283288.rss" rel="self"/>
<description>Twitter updates from CodeMirror / codemirror.</description>
<language>en-us</language>
<ttl>40</ttl>
<item>
<title>codemirror: http://cloud-ide.com &#8212; they're springing up like mushrooms. This one
uses CodeMirror as its editor.</title>
<description>codemirror: http://cloud-ide.com &#8212; they're springing up like mushrooms. This
one uses CodeMirror as its editor.</description>
<pubDate>Thu, 17 Mar 2011 23:34:47 +0000</pubDate>
<guid>http://twitter.com/codemirror/statuses/48527733722058752</guid>
<link>http://twitter.com/codemirror/statuses/48527733722058752</link>
<twitter:source>web</twitter:source>
<twitter:place/>
</item>
<item>
<title>codemirror: Posted a description of the CodeMirror 2 internals at
http://codemirror.net/2/internals.html</title>
<description>codemirror: Posted a description of the CodeMirror 2 internals at
http://codemirror.net/2/internals.html</description>
<pubDate>Wed, 02 Mar 2011 12:15:09 +0000</pubDate>
<guid>http://twitter.com/codemirror/statuses/42920879788789760</guid>
<link>http://twitter.com/codemirror/statuses/42920879788789760</link>
<twitter:source>web</twitter:source>
<twitter:place/>
</item>
</channel>
</rss></textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
mode: "application/xml",
styleActiveLine: true,
lineNumbers: true,
lineWrapping: true
});
</script>
<p>Styling the current cursor line.</p>
</article>

View File

@@ -1,79 +0,0 @@
<!doctype html>
<title>CodeMirror: Any Word Completion Demo</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css">
<link rel="stylesheet" href="../lib/codemirror.css">
<link rel="stylesheet" href="../addon/hint/show-hint.css">
<script src="../lib/codemirror.js"></script>
<script src="../addon/hint/show-hint.js"></script>
<script src="../addon/hint/anyword-hint.js"></script>
<script src="../mode/javascript/javascript.js"></script>
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="../doc/manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#">Any Word Completion</a>
</ul>
</div>
<article>
<h2>Any Word Completion Demo</h2>
<form><textarea id="code" name="code">
(function() {
"use strict";
var WORD = /[\w$]+/g, RANGE = 500;
CodeMirror.registerHelper("hint", "anyword", function(editor, options) {
var word = options && options.word || WORD;
var range = options && options.range || RANGE;
var cur = editor.getCursor(), curLine = editor.getLine(cur.line);
var start = cur.ch, end = start;
while (end < curLine.length && word.test(curLine.charAt(end))) ++end;
while (start && word.test(curLine.charAt(start - 1))) --start;
var curWord = start != end && curLine.slice(start, end);
var list = [], seen = {};
function scan(dir) {
var line = cur.line, end = Math.min(Math.max(line + dir * range, editor.firstLine()), editor.lastLine()) + dir;
for (; line != end; line += dir) {
var text = editor.getLine(line), m;
word.lastIndex = 0;
while (m = word.exec(text)) {
if ((!curWord || m[0].indexOf(curWord) == 0) && !seen.hasOwnProperty(m[0])) {
seen[m[0]] = true;
list.push(m[0]);
}
}
}
}
scan(-1);
scan(1);
return {list: list, from: CodeMirror.Pos(cur.line, start), to: CodeMirror.Pos(cur.line, end)};
});
})();
</textarea></form>
<p>Press <strong>ctrl-space</strong> to activate autocompletion. The
completion uses
the <a href="../doc/manual.html#addon_anyword-hint">anyword-hint.js</a>
module, which simply looks at nearby words in the buffer and completes
to those.</p>
<script>
CodeMirror.commands.autocomplete = function(cm) {
CodeMirror.showHint(cm, CodeMirror.hint.anyword);
}
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
extraKeys: {"Ctrl-Space": "autocomplete"}
});
</script>
</article>

View File

@@ -1,74 +0,0 @@
<!doctype html>
<title>CodeMirror: Bi-directional Text Demo</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css">
<link rel="stylesheet" href="../lib/codemirror.css">
<script src="../lib/codemirror.js"></script>
<script src="../mode/xml/xml.js"></script>
<style type="text/css">
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
</style>
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="../doc/manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#">Bi-directional Text</a>
</ul>
</div>
<article>
<h2>Bi-directional Text Demo</h2>
<form><textarea id="code" name="code"><!-- Piece of the CodeMirror manual, 'translated' into Arabic by
Google Translate -->
<dl>
<dt id=option_value><code>value (string or Doc)</code></dt>
<dd>قيمة البداية المحرر. يمكن أن تكون سلسلة، أو. كائن مستند.</dd>
<dt id=option_mode><code>mode (string or object)</code></dt>
<dd>وضع الاستخدام. عندما لا تعطى، وهذا الافتراضي إلى الطريقة الاولى
التي تم تحميلها. قد يكون من سلسلة، والتي إما أسماء أو ببساطة هو وضع
MIME نوع المرتبطة اسطة. بدلا من ذلك، قد يكون من كائن يحتوي على
خيارات التكوين لواسطة، مع <code>name</code> الخاصية التي وضع أسماء
(على سبيل المثال <code>{name: "javascript", json: true}</code>).
صفحات التجريبي لكل وضع تحتوي على معلومات حول ما معلمات تكوين وضع
يدعمها. يمكنك أن تطلب CodeMirror التي تم تعريفها طرق وأنواع MIME
الكشف على <code>CodeMirror.modes</code>
و <code>CodeMirror.mimeModes</code> الكائنات. وضع خرائط الأسماء
الأولى لمنشئات الخاصة بهم، وخرائط لأنواع MIME 2 المواصفات
واسطة.</dd>
<dt id=option_theme><code>theme (string)</code></dt>
<dd>موضوع لنمط المحرر مع. يجب عليك التأكد من الملف CSS تحديد
المقابلة <code>.cm-s-[name]</code> يتم تحميل أنماط (انظر
<a href=../theme/><code>theme</code></a> الدليل في التوزيع).
الافتراضي هو <code>"default"</code> ، والتي تم تضمينها في
الألوان <code>codemirror.css</code>. فمن الممكن استخدام فئات متعددة
في تطبيق السمات مرة واحدة على سبيل المثال <code>"foo bar"</code>
سيتم تعيين كل من <code>cm-s-foo</code> و <code>cm-s-bar</code>
الطبقات إلى المحرر.</dd>
</dl>
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
mode: "text/html",
lineNumbers: true
});
</script>
<p>Demonstration of bi-directional text support. See
the <a href="http://marijnhaverbeke.nl/blog/cursor-in-bidi-text.html">related
blog post</a> for more background.</p>
<p><strong>Note:</strong> There is
a <a href="https://github.com/marijnh/CodeMirror/issues/1757">known
bug</a> with cursor motion and mouse clicks in bi-directional lines
that are line wrapped.</p>
</article>

View File

@@ -1,86 +0,0 @@
<!doctype html>
<title>CodeMirror: B-Tree visualization</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css">
<link rel="stylesheet" href="../lib/codemirror.css">
<script src="../lib/codemirror.js"></script>
<style type="text/css">
.lineblock { display: inline-block; margin: 1px; height: 5px; }
.CodeMirror {border: 1px solid #aaa; height: 400px}
</style>
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="../doc/manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#">B-Tree visualization</a>
</ul>
</div>
<article>
<h2>B-Tree visualization</h2>
<form><textarea id="code" name="code">type here, see a summary of the document b-tree below</textarea></form>
</div>
<div style="display: inline-block; height: 402px; overflow-y: auto" id="output"></div>
</div>
<script id="me">
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
lineWrapping: true
});
var updateTimeout;
editor.on("change", function(cm) {
clearTimeout(updateTimeout);
updateTimeout = setTimeout(updateVisual, 200);
});
updateVisual();
function updateVisual() {
var out = document.getElementById("output");
out.innerHTML = "";
function drawTree(out, node) {
if (node.lines) {
out.appendChild(document.createElement("div")).innerHTML =
"<b>leaf</b>: " + node.lines.length + " lines, " + Math.round(node.height) + " px";
var lines = out.appendChild(document.createElement("div"));
lines.style.lineHeight = "6px"; lines.style.marginLeft = "10px";
for (var i = 0; i < node.lines.length; ++i) {
var line = node.lines[i], lineElt = lines.appendChild(document.createElement("div"));
lineElt.className = "lineblock";
var gray = Math.min(line.text.length * 3, 230), col = gray.toString(16);
if (col.length == 1) col = "0" + col;
lineElt.style.background = "#" + col + col + col;
console.log(line.height, line);
lineElt.style.width = Math.max(Math.round(line.height / 3), 1) + "px";
}
} else {
out.appendChild(document.createElement("div")).innerHTML =
"<b>node</b>: " + node.size + " lines, " + Math.round(node.height) + " px";
var sub = out.appendChild(document.createElement("div"));
sub.style.paddingLeft = "20px";
for (var i = 0; i < node.children.length; ++i)
drawTree(sub, node.children[i]);
}
}
drawTree(out, editor.getDoc());
}
function fillEditor() {
var sc = document.getElementById("me");
var doc = (sc.textContent || sc.innerText || sc.innerHTML).replace(/^\s*/, "") + "\n";
doc += doc; doc += doc; doc += doc; doc += doc; doc += doc; doc += doc;
editor.setValue(doc);
}
</script>
<p><button onclick="fillEditor()">Add a lot of content</button></p>
</article>

View File

@@ -1,109 +0,0 @@
<!doctype html>
<title>CodeMirror: Multiple Buffer & Split View Demo</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css">
<link rel="stylesheet" href="../lib/codemirror.css">
<script src="../lib/codemirror.js"></script>
<script src="../mode/javascript/javascript.js"></script>
<script src="../mode/css/css.js"></script>
<style type="text/css" id=style>
.CodeMirror {border: 1px solid black; height: 250px;}
</style>
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="../doc/manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#">Multiple Buffer & Split View</a>
</ul>
</div>
<article>
<h2>Multiple Buffer & Split View Demo</h2>
<div id=code_top></div>
<div>
Select buffer: <select id=buffers_top></select>
&nbsp; &nbsp; <button onclick="newBuf('top')">New buffer</button>
</div>
<div id=code_bot></div>
<div>
Select buffer: <select id=buffers_bot></select>
&nbsp; &nbsp; <button onclick="newBuf('bot')">New buffer</button>
</div>
<script id=script>
var sel_top = document.getElementById("buffers_top");
CodeMirror.on(sel_top, "change", function() {
selectBuffer(ed_top, sel_top.options[sel_top.selectedIndex].value);
});
var sel_bot = document.getElementById("buffers_bot");
CodeMirror.on(sel_bot, "change", function() {
selectBuffer(ed_bot, sel_bot.options[sel_bot.selectedIndex].value);
});
var buffers = {};
function openBuffer(name, text, mode) {
buffers[name] = CodeMirror.Doc(text, mode);
var opt = document.createElement("option");
opt.appendChild(document.createTextNode(name));
sel_top.appendChild(opt);
sel_bot.appendChild(opt.cloneNode(true));
}
function newBuf(where) {
var name = prompt("Name for the buffer", "*scratch*");
if (name == null) return;
if (buffers.hasOwnProperty(name)) {
alert("There's already a buffer by that name.");
return;
}
openBuffer(name, "", "javascript");
selectBuffer(where == "top" ? ed_top : ed_bot, name);
var sel = where == "top" ? sel_top : sel_bot;
sel.value = name;
}
function selectBuffer(editor, name) {
var buf = buffers[name];
if (buf.getEditor()) buf = buf.linkedDoc({sharedHist: true});
var old = editor.swapDoc(buf);
var linked = old.iterLinkedDocs(function(doc) {linked = doc;});
if (linked) {
// Make sure the document in buffers is the one the other view is looking at
for (var name in buffers) if (buffers[name] == old) buffers[name] = linked;
old.unlinkDoc(linked);
}
editor.focus();
}
function nodeContent(id) {
var node = document.getElementById(id), val = node.textContent || node.innerText;
val = val.slice(val.match(/^\s*/)[0].length, val.length - val.match(/\s*$/)[0].length) + "\n";
return val;
}
openBuffer("js", nodeContent("script"), "javascript");
openBuffer("css", nodeContent("style"), "css");
var ed_top = CodeMirror(document.getElementById("code_top"), {lineNumbers: true});
selectBuffer(ed_top, "js");
var ed_bot = CodeMirror(document.getElementById("code_bot"), {lineNumbers: true});
selectBuffer(ed_bot, "js");
</script>
<p>Demonstration of
using <a href="../doc/manual.html#linkedDoc">linked documents</a>
to provide a split view on a document, and
using <a href="../doc/manual.html#swapDoc"><code>swapDoc</code></a>
to use a single editor to display multiple documents.</p>
</article>

View File

@@ -1,59 +0,0 @@
<!doctype html>
<title>CodeMirror: Mode-Changing Demo</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css">
<link rel="stylesheet" href="../lib/codemirror.css">
<script src="../lib/codemirror.js"></script>
<script src="../mode/javascript/javascript.js"></script>
<script src="../mode/scheme/scheme.js"></script>
<style type="text/css">
.CodeMirror {border: 1px solid black;}
</style>
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="../doc/manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#">Mode-Changing</a>
</ul>
</div>
<article>
<h2>Mode-Changing Demo</h2>
<form><textarea id="code" name="code">
;; If there is Scheme code in here, the editor will be in Scheme mode.
;; If you put in JS instead, it'll switch to JS mode.
(define (double x)
(* x x))
</textarea></form>
<p>On changes to the content of the above editor, a (crude) script
tries to auto-detect the language used, and switches the editor to
either JavaScript or Scheme mode based on that.</p>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
mode: "scheme",
lineNumbers: true,
tabMode: "indent"
});
editor.on("change", function() {
clearTimeout(pending);
setTimeout(update, 400);
});
var pending;
function looksLikeScheme(code) {
return !/^\s*\(\s*function\b/.test(code) && /^\s*[;\(]/.test(code);
}
function update() {
editor.setOption("mode", looksLikeScheme(editor.getValue()) ? "scheme" : "javascript");
}
</script>
</article>

View File

@@ -1,63 +0,0 @@
<!doctype html>
<title>CodeMirror: Closebrackets Demo</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css">
<link rel="stylesheet" href="../lib/codemirror.css">
<script src="../lib/codemirror.js"></script>
<script src="../addon/edit/closebrackets.js"></script>
<script src="../mode/javascript/javascript.js"></script>
<style type="text/css">
.CodeMirror {border-top: 1px solid #888; border-bottom: 1px solid #888;}
</style>
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="../doc/manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#">Closebrackets</a>
</ul>
</div>
<article>
<h2>Closebrackets Demo</h2>
<form><textarea id="code" name="code">(function() {
var DEFAULT_BRACKETS = "()[]{}''\"\"";
CodeMirror.defineOption("autoCloseBrackets", false, function(cm, val, old) {
var wasOn = old && old != CodeMirror.Init;
if (val && !wasOn)
cm.addKeyMap(buildKeymap(typeof val == "string" ? val : DEFAULT_BRACKETS));
else if (!val && wasOn)
cm.removeKeyMap("autoCloseBrackets");
});
function buildKeymap(pairs) {
var map = {name : "autoCloseBrackets"};
for (var i = 0; i < pairs.length; i += 2) (function(left, right) {
function maybeOverwrite(cm) {
var cur = cm.getCursor(), ahead = cm.getRange(cur, CodeMirror.Pos(cur.line, cur.ch + 1));
if (ahead != right) return CodeMirror.Pass;
else cm.execCommand("goCharRight");
}
map["'" + left + "'"] = function(cm) {
if (left == right && maybeOverwrite(cm) != CodeMirror.Pass) return;
var cur = cm.getCursor(), ahead = CodeMirror.Pos(cur.line, cur.ch + 1);
cm.replaceSelection(left + right, {head: ahead, anchor: ahead});
};
if (left != right) map["'" + right + "'"] = maybeOverwrite;
})(pairs.charAt(i), pairs.charAt(i + 1));
return map;
}
})();
</textarea></form>
<script type="text/javascript">
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {autoCloseBrackets: true});
</script>
</article>

View File

@@ -1,40 +0,0 @@
<!doctype html>
<title>CodeMirror: Close-Tag Demo</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css">
<link rel="stylesheet" href="../lib/codemirror.css">
<script src="../lib/codemirror.js"></script>
<script src="../addon/edit/closetag.js"></script>
<script src="../mode/xml/xml.js"></script>
<script src="../mode/javascript/javascript.js"></script>
<script src="../mode/css/css.js"></script>
<script src="../mode/htmlmixed/htmlmixed.js"></script>
<style type="text/css">
.CodeMirror {border-top: 1px solid #888; border-bottom: 1px solid #888;}
</style>
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="../doc/manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#">Close-Tag</a>
</ul>
</div>
<article>
<h2>Close-Tag Demo</h2>
<form><textarea id="code" name="code"><html</textarea></form>
<script type="text/javascript">
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
mode: 'text/html',
autoCloseTags: true
});
</script>
</article>

View File

@@ -1,80 +0,0 @@
<!doctype html>
<title>CodeMirror: Autocomplete Demo</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css">
<link rel="stylesheet" href="../lib/codemirror.css">
<link rel="stylesheet" href="../addon/hint/show-hint.css">
<script src="../lib/codemirror.js"></script>
<script src="../addon/hint/show-hint.js"></script>
<script src="../addon/hint/javascript-hint.js"></script>
<script src="../mode/javascript/javascript.js"></script>
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="../doc/manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#">Autocomplete</a>
</ul>
</div>
<article>
<h2>Autocomplete Demo</h2>
<form><textarea id="code" name="code">
function getCompletions(token, context) {
var found = [], start = token.string;
function maybeAdd(str) {
if (str.indexOf(start) == 0) found.push(str);
}
function gatherCompletions(obj) {
if (typeof obj == "string") forEach(stringProps, maybeAdd);
else if (obj instanceof Array) forEach(arrayProps, maybeAdd);
else if (obj instanceof Function) forEach(funcProps, maybeAdd);
for (var name in obj) maybeAdd(name);
}
if (context) {
// If this is a property, see if it belongs to some object we can
// find in the current environment.
var obj = context.pop(), base;
if (obj.className == "js-variable")
base = window[obj.string];
else if (obj.className == "js-string")
base = "";
else if (obj.className == "js-atom")
base = 1;
while (base != null && context.length)
base = base[context.pop().string];
if (base != null) gatherCompletions(base);
}
else {
// If not, just look in the window object and any local scope
// (reading into JS mode internals to get at the local variables)
for (var v = token.state.localVars; v; v = v.next) maybeAdd(v.name);
gatherCompletions(window);
forEach(keywords, maybeAdd);
}
return found;
}
</textarea></form>
<p>Press <strong>ctrl-space</strong> to activate autocompletion. Built
on top of the <a href="../doc/manual.html#addon_show-hint"><code>show-hint</code></a>
and <a href="../doc/manual.html#addon_javascript-hint"><code>javascript-hint</code></a>
addons.</p>
<script>
CodeMirror.commands.autocomplete = function(cm) {
CodeMirror.showHint(cm, CodeMirror.hint.javascript);
};
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
extraKeys: {"Ctrl-Space": "autocomplete"}
});
</script>
</article>

View File

@@ -1,75 +0,0 @@
<!doctype html>
<title>CodeMirror: Emacs bindings demo</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css">
<link rel="stylesheet" href="../lib/codemirror.css">
<link rel="stylesheet" href="../addon/dialog/dialog.css">
<script src="../lib/codemirror.js"></script>
<script src="../mode/clike/clike.js"></script>
<script src="../keymap/emacs.js"></script>
<script src="../addon/edit/matchbrackets.js"></script>
<script src="../addon/comment/comment.js"></script>
<script src="../addon/dialog/dialog.js"></script>
<script src="../addon/search/searchcursor.js"></script>
<script src="../addon/search/search.js"></script>
<style type="text/css">
.CodeMirror {border-top: 1px solid #eee; border-bottom: 1px solid #eee;}
</style>
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="../doc/manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#">Emacs bindings</a>
</ul>
</div>
<article>
<h2>Emacs bindings demo</h2>
<form><textarea id="code" name="code">
#include "syscalls.h"
/* getchar: simple buffered version */
int getchar(void)
{
static char buf[BUFSIZ];
static char *bufp = buf;
static int n = 0;
if (n == 0) { /* buffer is empty */
n = read(0, buf, sizeof buf);
bufp = buf;
}
return (--n >= 0) ? (unsigned char) *bufp++ : EOF;
}
</textarea></form>
<p>The emacs keybindings are enabled by
including <a href="../keymap/emacs.js">keymap/emacs.js</a> and setting
the <code>keyMap</code> option to <code>"emacs"</code>. Because
CodeMirror's internal API is quite different from Emacs, they are only
a loose approximation of actual emacs bindings, though.</p>
<p>Also note that a lot of browsers disallow certain keys from being
captured. For example, Chrome blocks both Ctrl-W and Ctrl-N, with the
result that idiomatic use of Emacs keys will constantly close your tab
or open a new window.</p>
<script>
CodeMirror.commands.save = function() {
var elt = editor.getWrapperElement();
elt.style.background = "#def";
setTimeout(function() { elt.style.background = ""; }, 300);
};
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
mode: "text/x-csrc",
keyMap: "emacs"
});
</script>
</article>

View File

@@ -1,75 +0,0 @@
<!doctype html>
<title>CodeMirror: Code Folding Demo</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css">
<link rel="stylesheet" href="../lib/codemirror.css">
<link rel="stylesheet" href="../addon/fold/foldgutter.css" />
<script src="../lib/codemirror.js"></script>
<script src="../addon/fold/foldcode.js"></script>
<script src="../addon/fold/foldgutter.js"></script>
<script src="../addon/fold/brace-fold.js"></script>
<script src="../addon/fold/xml-fold.js"></script>
<script src="../addon/fold/comment-fold.js"></script>
<script src="../mode/javascript/javascript.js"></script>
<script src="../mode/xml/xml.js"></script>
<style type="text/css">
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
</style>
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="../doc/manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#">Code Folding</a>
</ul>
</div>
<article>
<h2>Code Folding Demo</h2>
<form>
<div style="max-width: 50em; margin-bottom: 1em">JavaScript:<br><textarea id="code" name="code"></textarea></div>
<div style="max-width: 50em">HTML:<br><textarea id="code-html" name="code-html"></textarea></div>
</form>
<script id="script">
/*
* Demonstration of code folding
*/
window.onload = function() {
var te = document.getElementById("code");
var sc = document.getElementById("script");
te.value = (sc.textContent || sc.innerText || sc.innerHTML).replace(/^\s*/, "");
sc.innerHTML = "";
var te_html = document.getElementById("code-html");
te_html.value = "<html>\n " + document.documentElement.innerHTML + "\n</html>";
window.editor = CodeMirror.fromTextArea(te, {
mode: "javascript",
lineNumbers: true,
lineWrapping: true,
extraKeys: {"Ctrl-Q": function(cm){ cm.foldCode(cm.getCursor()); }},
foldGutter: {
rangeFinder: new CodeMirror.fold.combine(CodeMirror.fold.brace, CodeMirror.fold.comment)
},
gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"]
});
editor.foldCode(CodeMirror.Pos(8, 0));
window.editor_html = CodeMirror.fromTextArea(te_html, {
mode: "text/html",
lineNumbers: true,
lineWrapping: true,
extraKeys: {"Ctrl-Q": function(cm){ cm.foldCode(cm.getCursor()); }},
foldGutter: true,
gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"]
});
editor_html.foldCode(CodeMirror.Pos(13, 0));
editor_html.foldCode(CodeMirror.Pos(1, 0));
};
</script>
</article>

View File

@@ -1,130 +0,0 @@
<!doctype html>
<title>CodeMirror: Full Screen Editing</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css">
<link rel="stylesheet" href="../lib/codemirror.css">
<link rel="stylesheet" href="../addon/display/fullscreen.css">
<link rel="stylesheet" href="../theme/night.css">
<script src="../lib/codemirror.js"></script>
<script src="../mode/xml/xml.js"></script>
<script src="../addon/display/fullscreen.js"></script>
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="../doc/manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#">Full Screen Editing</a>
</ul>
</div>
<article>
<h2>Full Screen Editing</h2>
<form><textarea id="code" name="code" rows="5">
<dt id="option_indentWithTabs"><code>indentWithTabs (boolean)</code></dt>
<dd>Whether, when indenting, the first N*8 spaces should be
replaced by N tabs. Default is false.</dd>
<dt id="option_tabMode"><code>tabMode (string)</code></dt>
<dd>Determines what happens when the user presses the tab key.
Must be one of the following:
<dl>
<dt><code>"classic" (the default)</code></dt>
<dd>When nothing is selected, insert a tab. Otherwise,
behave like the <code>"shift"</code> mode. (When shift is
held, this behaves like the <code>"indent"</code> mode.)</dd>
<dt><code>"shift"</code></dt>
<dd>Indent all selected lines by
one <a href="#option_indentUnit"><code>indentUnit</code></a>.
If shift was held while pressing tab, un-indent all selected
lines one unit.</dd>
<dt><code>"indent"</code></dt>
<dd>Indent the line the 'correctly', based on its syntactic
context. Only works if the
mode <a href="#indent">supports</a> it.</dd>
<dt><code>"default"</code></dt>
<dd>Do not capture tab presses, let the browser apply its
default behaviour (which usually means it skips to the next
control).</dd>
</dl></dd>
<dt id="option_enterMode"><code>enterMode (string)</code></dt>
<dd>Determines whether and how new lines are indented when the
enter key is pressed. The following modes are supported:
<dl>
<dt><code>"indent" (the default)</code></dt>
<dd>Use the mode's indentation rules to give the new line
the correct indentation.</dd>
<dt><code>"keep"</code></dt>
<dd>Indent the line the same as the previous line.</dd>
<dt><code>"flat"</code></dt>
<dd>Do not indent the new line.</dd>
</dl></dd>
<dt id="option_enterMode"><code>enterMode (string)</code></dt>
<dd>Determines whether and how new lines are indented when the
enter key is pressed. The following modes are supported:
<dl>
<dt><code>"indent" (the default)</code></dt>
<dd>Use the mode's indentation rules to give the new line
the correct indentation.</dd>
<dt><code>"keep"</code></dt>
<dd>Indent the line the same as the previous line.</dd>
<dt><code>"flat"</code></dt>
<dd>Do not indent the new line.</dd>
</dl></dd>
<dt id="option_enterMode"><code>enterMode (string)</code></dt>
<dd>Determines whether and how new lines are indented when the
enter key is pressed. The following modes are supported:
<dl>
<dt><code>"indent" (the default)</code></dt>
<dd>Use the mode's indentation rules to give the new line
the correct indentation.</dd>
<dt><code>"keep"</code></dt>
<dd>Indent the line the same as the previous line.</dd>
<dt><code>"flat"</code></dt>
<dd>Do not indent the new line.</dd>
</dl></dd>
<dt id="option_enterMode"><code>enterMode (string)</code></dt>
<dd>Determines whether and how new lines are indented when the
enter key is pressed. The following modes are supported:
<dl>
<dt><code>"indent" (the default)</code></dt>
<dd>Use the mode's indentation rules to give the new line
the correct indentation.</dd>
<dt><code>"keep"</code></dt>
<dd>Indent the line the same as the previous line.</dd>
<dt><code>"flat"</code></dt>
<dd>Do not indent the new line.</dd>
</dl></dd>
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
theme: "night",
extraKeys: {
"F11": function(cm) {
cm.setOption("fullScreen", !cm.getOption("fullScreen"));
},
"Esc": function(cm) {
if (cm.getOption("fullScreen")) cm.setOption("fullScreen", false);
}
}
});
</script>
<p>Demonstration of
the <a href="../doc/manual.html#addon_fullscreen">fullscreen</a>
addon. Press <strong>F11</strong> when cursor is in the editor to
toggle full screen editing. <strong>Esc</strong> can also be used
to <i>exit</i> full screen editing.</p>
</article>

View File

@@ -1,69 +0,0 @@
<!doctype html>
<title>CodeMirror: Hard-wrapping Demo</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css">
<link rel="stylesheet" href="../lib/codemirror.css">
<script src="../lib/codemirror.js"></script>
<script src="../mode/markdown/markdown.js"></script>
<script src="../addon/wrap/hardwrap.js"></script>
<style type="text/css">
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
</style>
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="../doc/manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#">Hard-wrapping</a>
</ul>
</div>
<article>
<h2>Hard-wrapping Demo</h2>
<form><textarea id="code" name="code">Lorem ipsum dolor sit amet, vim augue dictas constituto ex,
sit falli simul viderer te. Graeco scaevola maluisset sit
ut, in idque viris praesent sea. Ea sea eirmod indoctum
repudiare. Vel noluisse suscipit pericula ut. In ius nulla
alienum molestie. Mei essent discere democritum id.
Equidem ponderum expetendis ius in, mea an erroribus
constituto, congue timeam perfecto ad est. Ius ut primis
timeam, per in ullum mediocrem. An case vero labitur pri,
vel dicit laoreet et. An qui prompta conclusionemque, eam
timeam sapientem in, cum dictas epicurei eu.
Usu cu vide dictas deseruisse, eum choro graece adipiscing
ut. Cibo qualisque ius ad, et dicat scripta mea, eam nihil
mentitum aliquando cu. Debet aperiam splendide at quo, ad
paulo nostro commodo duo. Sea adhuc utinam conclusionemque
id, quas doming malorum nec ad. Tollit eruditi vivendum ad
ius, eos soleat ignota ad.
</textarea></form>
<p>Demonstration of
the <a href="../doc/manual.html#addon_hardwrap">hardwrap</a> addon.
The above editor has its change event hooked up to
the <code>wrapParagraphsInRange</code> method, so that the paragraphs
are reflown as you are typing.</p>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
mode: "markdown",
lineNumbers: true
});
var wait, options = {column: 60};
editor.on("change", function(cm, change) {
clearTimeout(wait);
wait = setTimeout(function() {
cm.wrapParagraphsInRange(change.from, CodeMirror.changeEnd(change), options);
}, 200);
});
</script>
</article>

View File

@@ -1,54 +0,0 @@
<!doctype html>
<title>CodeMirror: HTML completion demo</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css">
<link rel="stylesheet" href="../lib/codemirror.css">
<link rel="stylesheet" href="../addon/hint/show-hint.css">
<script src="../lib/codemirror.js"></script>
<script src="../addon/hint/show-hint.js"></script>
<script src="../addon/hint/xml-hint.js"></script>
<script src="../addon/hint/html-hint.js"></script>
<script src="../mode/xml/xml.js"></script>
<script src="../mode/javascript/javascript.js"></script>
<script src="../mode/css/css.js"></script>
<script src="../mode/htmlmixed/htmlmixed.js"></script>
<style type="text/css">
.CodeMirror {border-top: 1px solid #888; border-bottom: 1px solid #888;}
</style>
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="../doc/manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#">HTML completion</a>
</ul>
</div>
<article>
<h2>HTML completion demo</h2>
<p>Shows the <a href="xmlcomplete.html">XML completer</a>
parameterized with information about the tags in HTML.
Press <strong>ctrl-space</strong> to activate completion.</p>
<div id="code"></div>
<script type="text/javascript">
CodeMirror.commands.autocomplete = function(cm) {
CodeMirror.showHint(cm, CodeMirror.hint.html);
}
window.onload = function() {
editor = CodeMirror(document.getElementById("code"), {
mode: "text/html",
extraKeys: {"Ctrl-Space": "autocomplete"},
value: "<!doctype html>\n<html>\n " + document.documentElement.innerHTML + "\n</html>"
});
};
</script>
</article>

View File

@@ -1,58 +0,0 @@
<!doctype html>
<title>CodeMirror: Indented wrapped line demo</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css">
<link rel="stylesheet" href="../lib/codemirror.css">
<script src="../lib/codemirror.js"></script>
<script src="../mode/xml/xml.js"></script>
<style type="text/css">
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
</style>
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="../doc/manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#">Indented wrapped line</a>
</ul>
</div>
<article>
<h2>Indented wrapped line demo</h2>
<form><textarea id="code" name="code">
<!doctype html>
<body>
<h2 id="overview">Overview</h2>
<p>CodeMirror is a code-editor component that can be embedded in Web pages. The core library provides <em>only</em> the editor component, no accompanying buttons, auto-completion, or other IDE functionality. It does provide a rich API on top of which such functionality can be straightforwardly implemented. See the <a href="#addons">add-ons</a> included in the distribution, and the <a href="https://github.com/jagthedrummer/codemirror-ui">CodeMirror UI</a> project, for reusable implementations of extra features.</p>
<p>CodeMirror works with language-specific modes. Modes are JavaScript programs that help color (and optionally indent) text written in a given language. The distribution comes with a number of modes (see the <a href="../mode/"><code>mode/</code></a> directory), and it isn't hard to <a href="#modeapi">write new ones</a> for other languages.</p>
</body>
</textarea></form>
<p>This page uses a hack on top of the <code>"renderLine"</code>
event to make wrapped text line up with the base indentation of
the line.</p>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
lineWrapping: true,
mode: "text/html"
});
var charWidth = editor.defaultCharWidth(), basePadding = 4;
editor.on("renderLine", function(cm, line, elt) {
var off = CodeMirror.countColumn(line.text, null, cm.getOption("tabSize")) * charWidth;
elt.style.textIndent = "-" + off + "px";
elt.style.paddingLeft = (basePadding + off) + "px";
});
editor.refresh();
</script>
</article>

View File

@@ -1,171 +0,0 @@
<!doctype html>
<title>CodeMirror: Linter Demo</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css">
<link rel="stylesheet" href="../lib/codemirror.css">
<link rel="stylesheet" href="../addon/lint/lint.css">
<script src="../lib/codemirror.js"></script>
<script src="../mode/javascript/javascript.js"></script>
<script src="../mode/css/css.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jshint/r07/jshint.js"></script>
<script src="https://rawgithub.com/zaach/jsonlint/79b553fb65c192add9066da64043458981b3972b/lib/jsonlint.js"></script>
<script src="https://rawgithub.com/stubbornella/csslint/master/release/csslint.js"></script>
<script src="../addon/lint/lint.js"></script>
<script src="../addon/lint/javascript-lint.js"></script>
<script src="../addon/lint/json-lint.js"></script>
<script src="../addon/lint/css-lint.js"></script>
<style type="text/css">
.CodeMirror {border: 1px solid black;}
</style>
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="../doc/manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#">Linter</a>
</ul>
</div>
<article>
<h2>Linter Demo</h2>
<p><textarea id="code-js">var widgets = []
function updateHints() {
editor.operation(function(){
for (var i = 0; i < widgets.length; ++i)
editor.removeLineWidget(widgets[i]);
widgets.length = 0;
JSHINT(editor.getValue());
for (var i = 0; i < JSHINT.errors.length; ++i) {
var err = JSHINT.errors[i];
if (!err) continue;
var msg = document.createElement("div");
var icon = msg.appendChild(document.createElement("span"));
icon.innerHTML = "!!";
icon.className = "lint-error-icon";
msg.appendChild(document.createTextNode(err.reason));
msg.className = "lint-error";
widgets.push(editor.addLineWidget(err.line - 1, msg, {coverGutter: false, noHScroll: true}));
}
});
var info = editor.getScrollInfo();
var after = editor.charCoords({line: editor.getCursor().line + 1, ch: 0}, "local").top;
if (info.top + info.clientHeight < after)
editor.scrollTo(null, after - info.clientHeight + 3);
}
</textarea></p>
<p><textarea id="code-json">[
{
_id: "post 1",
"author": "Bob",
"content": "...",
"page_views": 5
},
{
"_id": "post 2",
"author": "Bob",
"content": "...",
"page_views": 9
},
{
"_id": "post 3",
"author": "Bob",
"content": "...",
"page_views": 8
}
]
</textarea></p>
<p><textarea id="code-css">@charset "UTF-8";
@import url("booya.css") print, screen;
@import "whatup.css" screen;
@import "wicked.css";
/*Error*/
@charset "UTF-8";
@namespace "http://www.w3.org/1999/xhtml";
@namespace svg "http://www.w3.org/2000/svg";
/*Warning: empty ruleset */
.foo {
}
h1 {
font-weight: bold;
}
/*Warning: qualified heading */
.foo h1 {
font-weight: bold;
}
/*Warning: adjoining classes */
.foo.bar {
zoom: 1;
}
li.inline {
width: 100%; /*Warning: 100% can be problematic*/
}
li.last {
display: inline;
padding-left: 3px !important;
padding-right: 3px;
border-right: 0px;
}
@media print {
li.inline {
color: black;
}
}
@page {
margin: 10%;
counter-increment: page;
@top-center {
font-family: sans-serif;
font-weight: bold;
font-size: 2em;
content: counter(page);
}
}
</textarea></p>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code-js"), {
lineNumbers: true,
mode: "javascript",
gutters: ["CodeMirror-lint-markers"],
lint: true
});
var editor_json = CodeMirror.fromTextArea(document.getElementById("code-json"), {
lineNumbers: true,
mode: "application/json",
gutters: ["CodeMirror-lint-markers"],
lint: true
});
var editor_css = CodeMirror.fromTextArea(document.getElementById("code-css"), {
lineNumbers: true,
mode: "css",
gutters: ["CodeMirror-lint-markers"],
lint: true
});
</script>
</article>

View File

@@ -1,49 +0,0 @@
<!doctype html>
<title>CodeMirror: Lazy Mode Loading Demo</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css">
<link rel="stylesheet" href="../lib/codemirror.css">
<script src="../lib/codemirror.js"></script>
<script src="../addon/mode/loadmode.js"></script>
<style type="text/css">
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
</style>
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="../doc/manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#">Lazy Mode Loading</a>
</ul>
</div>
<article>
<h2>Lazy Mode Loading Demo</h2>
<form><textarea id="code" name="code">This is the editor.
// It starts out in plain text mode,
# use the control below to load and apply a mode
"you'll see the highlighting of" this text /*change*/.
</textarea></form>
<p><input type=text value=javascript id=mode> <button type=button onclick="change()">change mode</button></p>
<script>
CodeMirror.modeURL = "../mode/%N/%N.js";
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true
});
var modeInput = document.getElementById("mode");
CodeMirror.on(modeInput, "keypress", function(e) {
if (e.keyCode == 13) change();
});
function change() {
editor.setOption("mode", modeInput.value);
CodeMirror.autoLoadMode(editor, modeInput.value);
}
</script>
</article>

View File

@@ -1,52 +0,0 @@
<!doctype html>
<title>CodeMirror: Breakpoint Demo</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css">
<link rel="stylesheet" href="../lib/codemirror.css">
<script src="../lib/codemirror.js"></script>
<script src="../mode/javascript/javascript.js"></script>
<style type="text/css">
.breakpoints {width: .8em;}
.breakpoint { color: #822; }
.CodeMirror {border: 1px solid #aaa;}
</style>
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="../doc/manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#">Breakpoint</a>
</ul>
</div>
<article>
<h2>Breakpoint Demo</h2>
<form><textarea id="code" name="code">
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
gutters: ["CodeMirror-linenumbers", "breakpoints"]
});
editor.on("gutterClick", function(cm, n) {
var info = cm.lineInfo(n);
cm.setGutterMarker(n, "breakpoints", info.gutterMarkers ? null : makeMarker());
});
function makeMarker() {
var marker = document.createElement("div");
marker.style.color = "#822";
marker.innerHTML = "●";
return marker;
}
</textarea></form>
<p>Click the line-number gutter to add or remove 'breakpoints'.</p>
<script>eval(document.getElementById("code").value);</script>
</article>

View File

@@ -1,45 +0,0 @@
<!doctype html>
<title>CodeMirror: Match Selection Demo</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css">
<link rel="stylesheet" href="../lib/codemirror.css">
<script src="../lib/codemirror.js"></script>
<script src="../addon/search/searchcursor.js"></script>
<script src="../addon/selection/mark-selection.js"></script>
<style type="text/css">
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
.CodeMirror-selected { background-color: blue !important; }
.CodeMirror-selectedtext { color: white; }
</style>
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="../doc/manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#">Match Selection</a>
</ul>
</div>
<article>
<h2>Match Selection Demo</h2>
<form><textarea id="code" name="code">Select something from here.
You'll see that the selection's foreground color changes to white!
Since, by default, CodeMirror only puts an independent "marker" layer
behind the text, you'll need something like this to change its colour.</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
styleSelectedText: true
});
</script>
<p>Simple addon to easily mark (and style) selected text.</p>
</article>

View File

@@ -1,47 +0,0 @@
<!doctype html>
<title>CodeMirror: Match Highlighter Demo</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css">
<link rel="stylesheet" href="../lib/codemirror.css">
<script src="../lib/codemirror.js"></script>
<script src="../addon/search/searchcursor.js"></script>
<script src="../addon/search/match-highlighter.js"></script>
<style type="text/css">
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
.CodeMirror-focused .cm-matchhighlight {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAFklEQVQI12NgYGBgkKzc8x9CMDAwAAAmhwSbidEoSQAAAABJRU5ErkJggg==);
background-position: bottom;
background-repeat: repeat-x;
}
</style>
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="../doc/manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#">Match Highlighter</a>
</ul>
</div>
<article>
<h2>Match Highlighter Demo</h2>
<form><textarea id="code" name="code">Select this text: hardToSpotVar
And everywhere else in your code where hardToSpotVar appears will automatically illuminate.
Give it a try! No more hardToSpotVars.</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
highlightSelectionMatches: {showToken: /\w/}
});
</script>
<p>Search and highlight occurences of the selected text.</p>
</article>

View File

@@ -1,49 +0,0 @@
<!doctype html>
<title>CodeMirror: Tag Matcher Demo</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css">
<link rel="stylesheet" href="../lib/codemirror.css">
<script src="../lib/codemirror.js"></script>
<script src="../addon/fold/xml-fold.js"></script>
<script src="../addon/edit/matchtags.js"></script>
<script src="../mode/xml/xml.js"></script>
<style type="text/css">
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
.CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }
</style>
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="../doc/manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#">Tag Matcher</a>
</ul>
</div>
<article>
<h2>Tag Matcher Demo</h2>
<div id="editor"></div>
<script>
window.onload = function() {
editor = CodeMirror(document.getElementById("editor"), {
value: "<html>\n " + document.documentElement.innerHTML + "\n</html>",
mode: "text/html",
matchTags: {bothTags: true},
extraKeys: {"Ctrl-J": "toMatchingTag"}
});
};
</script>
<p>Put the cursor on or inside a pair of tags to highlight them.
Press Ctrl-J to jump to the tag that matches the one under the
cursor.</p>
</article>

View File

@@ -1,82 +0,0 @@
<!doctype html>
<title>CodeMirror: merge view demo</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css">
<link rel=stylesheet href="../lib/codemirror.css">
<link rel=stylesheet href="../addon/merge/merge.css">
<script src="../lib/codemirror.js"></script>
<script src="../mode/xml/xml.js"></script>
<script src="../addon/merge/dep/diff_match_patch.js"></script>
<script src="../addon/merge/merge.js"></script>
<style>
.CodeMirror { line-height: 1.2; }
body { max-width: 80em; }
span.clicky {
cursor: pointer;
background: #d70;
color: white;
padding: 0 3px;
border-radius: 3px;
}
</style>
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="../doc/manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#">merge view</a>
</ul>
</div>
<article>
<h2>merge view demo</h2>
<div id=view></div>
<p>The <a href="../doc/manual.html#addon_merge"><code>merge</code></a>
addon provides an interface for displaying and merging diffs,
either <span class=clicky onclick="initUI(2)">two-way</span>
or <span class=clicky onclick="initUI(3)">three-way</span>. The left
(or center) pane is editable, and the differences with the other
pane(s) are <span class=clicky onclick="toggleDifferences()">optionally</span> shown live as you edit it.</p>
<p>This addon depends on
the <a href="https://code.google.com/p/google-diff-match-patch/">google-diff-match-patch</a>
library to compute the diffs.</p>
<script>
var value, orig1, orig2, dv, hilight= true;
function initUI(panes) {
if (value == null) return;
var target = document.getElementById("view");
target.innerHTML = "";
dv = CodeMirror.MergeView(target, {
value: value,
origLeft: panes == 3 ? orig1 : null,
orig: orig2,
lineNumbers: true,
mode: "text/html",
highlightDifferences: hilight
});
}
function toggleDifferences() {
dv.setShowDifferences(hilight = !hilight);
}
window.onload = function() {
value = document.documentElement.innerHTML;
orig1 = value.replace(/\.\.\//g, "codemirror/").replace("yellow", "orange");
orig2 = value.replace(/\u003cscript/g, "\u003cscript type=text/javascript ")
.replace("white", "purple;\n font: comic sans;\n text-decoration: underline;\n height: 15em");
initUI(2);
};
</script>
</article>

View File

@@ -1,75 +0,0 @@
<!doctype html>
<title>CodeMirror: Multiplexing Parser Demo</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css">
<link rel="stylesheet" href="../lib/codemirror.css">
<script src="../lib/codemirror.js"></script>
<script src="../addon/mode/multiplex.js"></script>
<script src="../mode/xml/xml.js"></script>
<style type="text/css">
.CodeMirror {border: 1px solid black;}
.cm-delimit {color: #fa4;}
</style>
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="../doc/manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#">Multiplexing Parser</a>
</ul>
</div>
<article>
<h2>Multiplexing Parser Demo</h2>
<form><textarea id="code" name="code">
<html>
<body style="<<magic>>">
<h1><< this is not <html >></h1>
<<
multiline
not html
at all : &amp;amp; <link/>
>>
<p>this is html again</p>
</body>
</html>
</textarea></form>
<script>
CodeMirror.defineMode("demo", function(config) {
return CodeMirror.multiplexingMode(
CodeMirror.getMode(config, "text/html"),
{open: "<<", close: ">>",
mode: CodeMirror.getMode(config, "text/plain"),
delimStyle: "delimit"}
// .. more multiplexed styles can follow here
);
});
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
mode: "demo",
lineNumbers: true,
lineWrapping: true
});
</script>
<p>Demonstration of a multiplexing mode, which, at certain
boundary strings, switches to one or more inner modes. The out
(HTML) mode does not get fed the content of the <code>&lt;&lt;
>></code> blocks. See
the <a href="../doc/manual.html#addon_multiplex">manual</a> and
the <a href="../addon/mode/multiplex.js">source</a> for more
information.</p>
<p>
<strong>Parsing/Highlighting Tests:</strong>
<a href="../test/index.html#multiplexing_*">normal</a>,
<a href="../test/index.html#verbose,multiplexing_*">verbose</a>.
</p>
</article>

View File

@@ -1,68 +0,0 @@
<!doctype html>
<title>CodeMirror: Overlay Parser Demo</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css">
<link rel="stylesheet" href="../lib/codemirror.css">
<script src="../lib/codemirror.js"></script>
<script src="../addon/mode/overlay.js"></script>
<script src="../mode/xml/xml.js"></script>
<style type="text/css">
.CodeMirror {border: 1px solid black;}
.cm-mustache {color: #0ca;}
</style>
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="../doc/manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#">Overlay Parser</a>
</ul>
</div>
<article>
<h2>Overlay Parser Demo</h2>
<form><textarea id="code" name="code">
<html>
<body>
<h1>{{title}}</h1>
<p>These are links to {{things}}:</p>
<ul>{{#links}}
<li><a href="{{url}}">{{text}}</a></li>
{{/links}}</ul>
</body>
</html>
</textarea></form>
<script>
CodeMirror.defineMode("mustache", function(config, parserConfig) {
var mustacheOverlay = {
token: function(stream, state) {
var ch;
if (stream.match("{{")) {
while ((ch = stream.next()) != null)
if (ch == "}" && stream.next() == "}") break;
stream.eat("}");
return "mustache";
}
while (stream.next() != null && !stream.match("{{", false)) {}
return null;
}
};
return CodeMirror.overlayMode(CodeMirror.getMode(config, parserConfig.backdrop || "text/html"), mustacheOverlay);
});
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {mode: "mustache"});
</script>
<p>Demonstration of a mode that parses HTML, highlighting
the <a href="http://mustache.github.com/">Mustache</a> templating
directives inside of it by using the code
in <a href="../addon/mode/overlay.js"><code>overlay.js</code></a>. View
source to see the 15 lines of code needed to accomplish this.</p>
</article>

View File

@@ -1,45 +0,0 @@
<!doctype html>
<title>CodeMirror: Placeholder demo</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css">
<link rel="stylesheet" href="../lib/codemirror.css">
<script src="../lib/codemirror.js"></script>
<script src="../addon/display/placeholder.js"></script>
<style type="text/css">
.CodeMirror { border: 1px solid silver; }
.CodeMirror-empty { outline: 1px solid #c22; }
.CodeMirror-empty.CodeMirror-focused { outline: none; }
.CodeMirror pre.CodeMirror-placeholder { color: #999; }
</style>
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="../doc/manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#">Placeholder</a>
</ul>
</div>
<article>
<h2>Placeholder demo</h2>
<form><textarea id="code" name="code" placeholder="Code goes here..."></textarea></form>
<p>The <a href="../doc/manual.html#addon_placeholder">placeholder</a>
plug-in adds an option <code>placeholder</code> that can be set to
make text appear in the editor when it is empty and not focused.
If the source textarea has a <code>placeholder</code> attribute,
it will automatically be inherited.</p>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true
});
</script>
</article>

View File

@@ -1,88 +0,0 @@
<!doctype html>
<title>CodeMirror: HTML5 preview</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css">
<link rel=stylesheet href=../lib/codemirror.css>
<script src=../lib/codemirror.js></script>
<script src=../mode/xml/xml.js></script>
<script src=../mode/javascript/javascript.js></script>
<script src=../mode/css/css.js></script>
<script src=../mode/htmlmixed/htmlmixed.js></script>
<style type=text/css>
.CodeMirror {
float: left;
width: 50%;
border: 1px solid black;
}
iframe {
width: 49%;
float: left;
height: 300px;
border: 1px solid black;
border-left: 0px;
}
</style>
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="../doc/manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#">HTML5 preview</a>
</ul>
</div>
<article>
<h2>HTML5 preview</h2>
<textarea id=code name=code>
<!doctype html>
<html>
<head>
<meta charset=utf-8>
<title>HTML5 canvas demo</title>
<style>p {font-family: monospace;}</style>
</head>
<body>
<p>Canvas pane goes here:</p>
<canvas id=pane width=300 height=200></canvas>
<script>
var canvas = document.getElementById('pane');
var context = canvas.getContext('2d');
context.fillStyle = 'rgb(250,0,0)';
context.fillRect(10, 10, 55, 50);
context.fillStyle = 'rgba(0, 0, 250, 0.5)';
context.fillRect(30, 30, 55, 50);
</script>
</body>
</html></textarea>
<iframe id=preview></iframe>
<script>
var delay;
// Initialize CodeMirror editor with a nice html5 canvas demo.
var editor = CodeMirror.fromTextArea(document.getElementById('code'), {
mode: 'text/html',
tabMode: 'indent'
});
editor.on("change", function() {
clearTimeout(delay);
delay = setTimeout(updatePreview, 300);
});
function updatePreview() {
var previewFrame = document.getElementById('preview');
var preview = previewFrame.contentDocument || previewFrame.contentWindow.document;
preview.open();
preview.write(editor.getValue());
preview.close();
}
setTimeout(updatePreview, 300);
</script>
</article>

View File

@@ -1,58 +0,0 @@
<!doctype html>
<title>CodeMirror: Autoresize Demo</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css">
<link rel="stylesheet" href="../lib/codemirror.css">
<script src="../lib/codemirror.js"></script>
<script src="../mode/css/css.js"></script>
<style type="text/css">
.CodeMirror {
border: 1px solid #eee;
height: auto;
}
.CodeMirror-scroll {
overflow-y: hidden;
overflow-x: auto;
}
</style>
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="../doc/manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#">Autoresize</a>
</ul>
</div>
<article>
<h2>Autoresize Demo</h2>
<form><textarea id="code" name="code">
.CodeMirror {
border: 1px solid #eee;
height: auto;
}
.CodeMirror-scroll {
overflow-y: hidden;
overflow-x: auto;
}
</textarea></form>
<p>By setting a few CSS properties, and giving
the <a href="../doc/manual.html#option_viewportMargin"><code>viewportMargin</code></a>
a value of <code>Infinity</code>, CodeMirror can be made to
automatically resize to fit its content.</p>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
viewportMargin: Infinity
});
</script>
</article>

View File

@@ -1,62 +0,0 @@
<!doctype html>
<title>CodeMirror: Mode Runner Demo</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css">
<link rel="stylesheet" href="../lib/codemirror.css">
<script src="../lib/codemirror.js"></script>
<script src="../addon/runmode/runmode.js"></script>
<script src="../mode/xml/xml.js"></script>
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="../doc/manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#">Mode Runner</a>
</ul>
</div>
<article>
<h2>Mode Runner Demo</h2>
<textarea id="code" style="width: 90%; height: 7em; border: 1px solid black; padding: .2em .4em;">
<foobar>
<blah>Enter your xml here and press the button below to display
it as highlighted by the CodeMirror XML mode</blah>
<tag2 foo="2" bar="&amp;quot;bar&amp;quot;"/>
</foobar></textarea><br>
<button onclick="doHighlight();">Highlight!</button>
<pre id="output" class="cm-s-default"></pre>
<script>
function doHighlight() {
CodeMirror.runMode(document.getElementById("code").value, "application/xml",
document.getElementById("output"));
}
</script>
<p>Running a CodeMirror mode outside of the editor.
The <code>CodeMirror.runMode</code> function, defined
in <code><a href="../addon/runmode/runmode.js">lib/runmode.js</a></code> takes the following arguments:</p>
<dl>
<dt><code>text (string)</code></dt>
<dd>The document to run through the highlighter.</dd>
<dt><code>mode (<a href="../doc/manual.html#option_mode">mode spec</a>)</code></dt>
<dd>The mode to use (must be loaded as normal).</dd>
<dt><code>output (function or DOM node)</code></dt>
<dd>If this is a function, it will be called for each token with
two arguments, the token's text and the token's style class (may
be <code>null</code> for unstyled tokens). If it is a DOM node,
the tokens will be converted to <code>span</code> elements as in
an editor, and inserted into the node
(through <code>innerHTML</code>).</dd>
</dl>
</article>

View File

@@ -1,94 +0,0 @@
<!doctype html>
<title>CodeMirror: Search/Replace Demo</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css">
<link rel="stylesheet" href="../lib/codemirror.css">
<link rel="stylesheet" href="../addon/dialog/dialog.css">
<script src="../lib/codemirror.js"></script>
<script src="../mode/xml/xml.js"></script>
<script src="../addon/dialog/dialog.js"></script>
<script src="../addon/search/searchcursor.js"></script>
<script src="../addon/search/search.js"></script>
<style type="text/css">
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
dt {font-family: monospace; color: #666;}
</style>
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="../doc/manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#">Search/Replace</a>
</ul>
</div>
<article>
<h2>Search/Replace Demo</h2>
<form><textarea id="code" name="code">
<dt id="option_indentWithTabs"><code>indentWithTabs (boolean)</code></dt>
<dd>Whether, when indenting, the first N*8 spaces should be
replaced by N tabs. Default is false.</dd>
<dt id="option_tabMode"><code>tabMode (string)</code></dt>
<dd>Determines what happens when the user presses the tab key.
Must be one of the following:
<dl>
<dt><code>"classic" (the default)</code></dt>
<dd>When nothing is selected, insert a tab. Otherwise,
behave like the <code>"shift"</code> mode. (When shift is
held, this behaves like the <code>"indent"</code> mode.)</dd>
<dt><code>"shift"</code></dt>
<dd>Indent all selected lines by
one <a href="#option_indentUnit"><code>indentUnit</code></a>.
If shift was held while pressing tab, un-indent all selected
lines one unit.</dd>
<dt><code>"indent"</code></dt>
<dd>Indent the line the 'correctly', based on its syntactic
context. Only works if the
mode <a href="#indent">supports</a> it.</dd>
<dt><code>"default"</code></dt>
<dd>Do not capture tab presses, let the browser apply its
default behaviour (which usually means it skips to the next
control).</dd>
</dl></dd>
<dt id="option_enterMode"><code>enterMode (string)</code></dt>
<dd>Determines whether and how new lines are indented when the
enter key is pressed. The following modes are supported:
<dl>
<dt><code>"indent" (the default)</code></dt>
<dd>Use the mode's indentation rules to give the new line
the correct indentation.</dd>
<dt><code>"keep"</code></dt>
<dd>Indent the line the same as the previous line.</dd>
<dt><code>"flat"</code></dt>
<dd>Do not indent the new line.</dd>
</dl></dd>
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {mode: "text/html", lineNumbers: true});
</script>
<p>Demonstration of primitive search/replace functionality. The
keybindings (which can be overridden by custom keymaps) are:</p>
<dl>
<dt>Ctrl-F / Cmd-F</dt><dd>Start searching</dd>
<dt>Ctrl-G / Cmd-G</dt><dd>Find next</dd>
<dt>Shift-Ctrl-G / Shift-Cmd-G</dt><dd>Find previous</dd>
<dt>Shift-Ctrl-F / Cmd-Option-F</dt><dd>Replace</dd>
<dt>Shift-Ctrl-R / Shift-Cmd-Option-F</dt><dd>Replace all</dd>
</dl>
<p>Searching is enabled by
including <a href="../addon/search/search.js">addon/search/search.js</a>
and <a href="../addon/search/searchcursor.js">addon/search/searchcursor.js</a>.
For good-looking input dialogs, you also want to include
<a href="../addon/dialog/dialog.js">addon/dialog/dialog.js</a>
and <a href="../addon/dialog/dialog.css">addon/dialog/dialog.css</a>.</p>
</article>

View File

@@ -1,85 +0,0 @@
<!doctype html>
<title>CodeMirror: Automatically derive odd wrapping behavior for your browser</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css">
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="../doc/manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#">Automatically derive odd wrapping behavior for your browser</a>
</ul>
</div>
<article>
<h2>Automatically derive odd wrapping behavior for your browser</h2>
<p>This is a hack to automatically derive
a <code>spanAffectsWrapping</code> regexp for a browser. See the
comments above that variable
in <a href="../lib/codemirror.js"><code>lib/codemirror.js</code></a>
for some more details.</p>
<div style="white-space: pre-wrap; width: 50px;" id="area"></div>
<pre id="output"></pre>
<script id="script">
var a = document.getElementById("area"), bad = Object.create(null);
var chars = "a~`!@#$%^&*()-_=+}{[]\\|'\"/?.>,<:;", l = chars.length;
for (var x = 0; x < l; ++x) for (var y = 0; y < l; ++y) {
var s1 = "foooo" + chars.charAt(x), s2 = chars.charAt(y) + "br";
a.appendChild(document.createTextNode(s1 + s2));
var h1 = a.offsetHeight;
a.innerHTML = "";
a.appendChild(document.createElement("span")).appendChild(document.createTextNode(s1));
a.appendChild(document.createElement("span")).appendChild(document.createTextNode(s2));
if (a.offsetHeight != h1)
bad[chars.charAt(x)] = (bad[chars.charAt(x)] || "") + chars.charAt(y);
a.innerHTML = "";
}
var re = "";
function toREElt(str) {
if (str.length > 1) {
var invert = false;
if (str.length > chars.length * .6) {
invert = true;
var newStr = "";
for (var i = 0; i < l; ++i) if (str.indexOf(chars.charAt(i)) == -1) newStr += chars.charAt(i);
str = newStr;
}
str = str.replace(/[\-\.\]\"\'\\\/\^a]/g, function(orig) { return orig == "a" ? "\\w" : "\\" + orig; });
return "[" + (invert ? "^" : "") + str + "]";
} else if (str == "a") {
return "\\w";
} else if (/[?$*()+{}[\]\.|/\'\"]/.test(str)) {
return "\\" + str;
} else {
return str;
}
}
var newRE = "";
for (;;) {
var left = null;
for (var left in bad) break;
if (left == null) break;
var right = bad[left];
delete bad[left];
for (var other in bad) if (bad[other] == right) {
left += other;
delete bad[other];
}
newRE += (newRE ? "|" : "") + toREElt(left) + toREElt(right);
}
document.getElementById("output").appendChild(document.createTextNode("Your regexp is: " + (newRE || "^$")));
</script>
</article>

View File

@@ -1,129 +0,0 @@
<!doctype html>
<title>CodeMirror: Tern Demo</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css">
<link rel="stylesheet" href="../lib/codemirror.css">
<link rel="stylesheet" href="../addon/dialog/dialog.css">
<link rel="stylesheet" href="../addon/hint/show-hint.css">
<link rel="stylesheet" href="../addon/tern/tern.css">
<script src="../lib/codemirror.js"></script>
<script src="../mode/javascript/javascript.js"></script>
<script src="../addon/dialog/dialog.js"></script>
<script src="../addon/hint/show-hint.js"></script>
<script src="../addon/tern/tern.js"></script>
<script src="http://marijnhaverbeke.nl/acorn/acorn.js"></script>
<script src="http://marijnhaverbeke.nl/acorn/acorn_loose.js"></script>
<script src="http://marijnhaverbeke.nl/acorn/util/walk.js"></script>
<script src="http://ternjs.net/doc/demo/polyfill.js"></script>
<script src="http://ternjs.net/lib/signal.js"></script>
<script src="http://ternjs.net/lib/tern.js"></script>
<script src="http://ternjs.net/lib/def.js"></script>
<script src="http://ternjs.net/lib/comment.js"></script>
<script src="http://ternjs.net/lib/infer.js"></script>
<script src="http://ternjs.net/plugin/doc_comment.js"></script>
<style>
.CodeMirror {border: 1px solid #ddd;}
</style>
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="../doc/manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#">Tern</a>
</ul>
</div>
<article>
<h2>Tern Demo</h2>
<form><textarea id="code" name="code">// Use ctrl-space to complete something
// Put the cursor in or after an expression, press ctrl-i to
// find its type
var foo = ["array", "of", "strings"];
var bar = foo.slice(0, 2).join("").split("a")[0];
// Works for locally defined types too.
function CTor() { this.size = 10; }
CTor.prototype.hallo = "hallo";
var baz = new CTor;
baz.
// You can press ctrl-q when the cursor is on a variable name to
// rename it. Try it with CTor...
// When the cursor is in an argument list, the arguments are
// shown below the editor.
[1].reduce( );
// And a little more advanced code...
(function(exports) {
exports.randomElt = function(arr) {
return arr[Math.floor(arr.length * Math.random())];
};
exports.strList = "foo".split("");
exports.intList = exports.strList.map(function(s) { return s.charCodeAt(0); });
})(window.myMod = {});
var randomStr = myMod.randomElt(myMod.strList);
var randomInt = myMod.randomElt(myMod.intList);
</textarea></p>
<p>Demonstrates integration of <a href="http://ternjs.net/">Tern</a>
and CodeMirror. The following keys are bound:</p>
<dl>
<dt>Ctrl-Space</dt><dd>Autocomplete</dd>
<dt>Ctrl-I</dt><dd>Find type at cursor</dd>
<dt>Alt-.</dt><dd>Jump to definition (Alt-, to jump back)</dd>
<dt>Ctrl-Q</dt><dd>Rename variable</dd>
</dl>
<p>Documentation is sparse for now. See the top of
the <a href="../addon/tern/tern.js">script</a> for a rough API
overview.</p>
<script>
function getURL(url, c) {
var xhr = new XMLHttpRequest();
xhr.open("get", url, true);
xhr.send();
xhr.onreadystatechange = function() {
if (xhr.readyState != 4) return;
if (xhr.status < 400) return c(null, xhr.responseText);
var e = new Error(xhr.responseText || "No response");
e.status = xhr.status;
c(e);
};
}
var server;
getURL("http://ternjs.net/defs/ecma5.json", function(err, code) {
if (err) throw new Error("Request for ecma5.json: " + err);
server = new CodeMirror.TernServer({defs: [JSON.parse(code)]});
editor.setOption("extraKeys", {
"Ctrl-Space": function(cm) { server.complete(cm); },
"Ctrl-I": function(cm) { server.showType(cm); },
"Alt-.": function(cm) { server.jumpToDef(cm); },
"Alt-,": function(cm) { server.jumpBack(cm); },
"Ctrl-Q": function(cm) { server.rename(cm); },
})
editor.on("cursorActivity", function(cm) { server.updateArgHints(cm); });
});
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
mode: "javascript"
});
</script>
</article>

View File

@@ -1,121 +0,0 @@
<!doctype html>
<title>CodeMirror: Theme Demo</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css">
<link rel="stylesheet" href="../lib/codemirror.css">
<link rel="stylesheet" href="../theme/3024-day.css">
<link rel="stylesheet" href="../theme/3024-night.css">
<link rel="stylesheet" href="../theme/ambiance.css">
<link rel="stylesheet" href="../theme/base16-dark.css">
<link rel="stylesheet" href="../theme/base16-light.css">
<link rel="stylesheet" href="../theme/blackboard.css">
<link rel="stylesheet" href="../theme/cobalt.css">
<link rel="stylesheet" href="../theme/eclipse.css">
<link rel="stylesheet" href="../theme/elegant.css">
<link rel="stylesheet" href="../theme/erlang-dark.css">
<link rel="stylesheet" href="../theme/lesser-dark.css">
<link rel="stylesheet" href="../theme/mbo.css">
<link rel="stylesheet" href="../theme/midnight.css">
<link rel="stylesheet" href="../theme/monokai.css">
<link rel="stylesheet" href="../theme/neat.css">
<link rel="stylesheet" href="../theme/night.css">
<link rel="stylesheet" href="../theme/paraiso-dark.css">
<link rel="stylesheet" href="../theme/paraiso-light.css">
<link rel="stylesheet" href="../theme/rubyblue.css">
<link rel="stylesheet" href="../theme/solarized.css">
<link rel="stylesheet" href="../theme/the-matrix.css">
<link rel="stylesheet" href="../theme/tomorrow-night-eighties.css">
<link rel="stylesheet" href="../theme/twilight.css">
<link rel="stylesheet" href="../theme/vibrant-ink.css">
<link rel="stylesheet" href="../theme/xq-dark.css">
<link rel="stylesheet" href="../theme/xq-light.css">
<script src="../lib/codemirror.js"></script>
<script src="../mode/javascript/javascript.js"></script>
<script src="../keymap/extra.js"></script>
<script src="../addon/selection/active-line.js"></script>
<script src="../addon/edit/matchbrackets.js"></script>
<style type="text/css">
.CodeMirror {border: 1px solid black; font-size:13px}
</style>
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="../doc/manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#">Theme</a>
</ul>
</div>
<article>
<h2>Theme Demo</h2>
<form><textarea id="code" name="code">
function findSequence(goal) {
function find(start, history) {
if (start == goal)
return history;
else if (start > goal)
return null;
else
return find(start + 5, "(" + history + " + 5)") ||
find(start * 3, "(" + history + " * 3)");
}
return find(1, "1");
}</textarea></form>
<p>Select a theme: <select onchange="selectTheme()" id=select>
<option selected>default</option>
<option>3024-day</option>
<option>3024-night</option>
<option>ambiance</option>
<option>base16-dark</option>
<option>base16-light</option>
<option>blackboard</option>
<option>cobalt</option>
<option>eclipse</option>
<option>elegant</option>
<option>erlang-dark</option>
<option>lesser-dark</option>
<option>mbo</option>
<option>midnight</option>
<option>monokai</option>
<option>neat</option>
<option>night</option>
<option>paraiso-dark</option>
<option>paraiso-light</option>
<option>rubyblue</option>
<option>solarized dark</option>
<option>solarized light</option>
<option>the-matrix</option>
<option>tomorrow-night-eighties</option>
<option>twilight</option>
<option>vibrant-ink</option>
<option>xq-dark</option>
<option>xq-light</option>
</select>
</p>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
styleActiveLine: true,
matchBrackets: true
});
var input = document.getElementById("select");
function selectTheme() {
var theme = input.options[input.selectedIndex].innerHTML;
editor.setOption("theme", theme);
}
var choice = document.location.search &&
decodeURIComponent(document.location.search.slice(1));
if (choice) {
input.value = choice;
editor.setOption("theme", choice);
}
</script>
</article>

View File

@@ -1,48 +0,0 @@
<!doctype html>
<title>CodeMirror: Trailing Whitespace Demo</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css">
<link rel="stylesheet" href="../lib/codemirror.css">
<script src="../lib/codemirror.js"></script>
<script src="../addon/edit/trailingspace.js"></script>
<style type="text/css">
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
.cm-trailingspace {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAACCAYAAAB/qH1jAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QUXCToH00Y1UgAAACFJREFUCNdjPMDBUc/AwNDAAAFMTAwMDA0OP34wQgX/AQBYgwYEx4f9lQAAAABJRU5ErkJggg==);
background-position: bottom left;
background-repeat: repeat-x;
}
</style>
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="../doc/manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#">Trailing Whitespace</a>
</ul>
</div>
<article>
<h2>Trailing Whitespace Demo</h2>
<form><textarea id="code" name="code">This text
has some
trailing whitespace!</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
showTrailingSpace: true
});
</script>
<p>Uses
the <a href="../doc/manual.html#addon_trailingspace">trailingspace</a>
addon to highlight trailing whitespace.</p>
</article>

View File

@@ -1,67 +0,0 @@
<!doctype html>
<title>CodeMirror: Variable Height Demo</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css">
<link rel="stylesheet" href="../lib/codemirror.css">
<script src="../lib/codemirror.js"></script>
<script src="../mode/markdown/markdown.js"></script>
<script src="../mode/xml/xml.js"></script>
<style type="text/css">
.CodeMirror {border: 1px solid silver; border-width: 1px 2px; }
.cm-header { font-family: arial; }
.cm-header1 { font-size: 150%; }
.cm-header2 { font-size: 130%; }
.cm-header3 { font-size: 120%; }
.cm-header4 { font-size: 110%; }
.cm-header5 { font-size: 100%; }
.cm-header6 { font-size: 90%; }
.cm-strong { font-size: 140%; }
</style>
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="../doc/manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#">Variable Height</a>
</ul>
</div>
<article>
<h2>Variable Height Demo</h2>
<form><textarea id="code" name="code"># A First Level Header
**Bold** text in a normal-size paragraph.
And a very long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long, wrapped line with a piece of **big** text inside of it.
## A Second Level Header
Now is the time for all good men to come to
the aid of their country. This is just a
regular paragraph.
The quick brown fox jumped over the lazy
dog's back.
### Header 3
> This is a blockquote.
>
> This is the second paragraph in the blockquote.
>
> ## This is an H2 in a blockquote
</textarea></form>
<script id="script">
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
lineWrapping: true,
mode: "markdown"
});
</script>
</article>

View File

@@ -1,74 +0,0 @@
<!doctype html>
<title>CodeMirror: Vim bindings demo</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css">
<link rel="stylesheet" href="../lib/codemirror.css">
<link rel="stylesheet" href="../addon/dialog/dialog.css">
<script src="../lib/codemirror.js"></script>
<script src="../addon/dialog/dialog.js"></script>
<script src="../addon/search/searchcursor.js"></script>
<script src="../mode/clike/clike.js"></script>
<script src="../keymap/vim.js"></script>
<style type="text/css">
.CodeMirror {border-top: 1px solid #eee; border-bottom: 1px solid #eee;}
</style>
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="../doc/manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#">Vim bindings</a>
</ul>
</div>
<article>
<h2>Vim bindings demo</h2>
<form><textarea id="code" name="code">
#include "syscalls.h"
/* getchar: simple buffered version */
int getchar(void)
{
static char buf[BUFSIZ];
static char *bufp = buf;
static int n = 0;
if (n == 0) { /* buffer is empty */
n = read(0, buf, sizeof buf);
bufp = buf;
}
return (--n >= 0) ? (unsigned char) *bufp++ : EOF;
}
</textarea></form>
<form><textarea id="code2" name="code2">
I am another file! You can yank from my neighbor and paste here.
</textarea></form>
<p>The vim keybindings are enabled by
including <a href="../keymap/vim.js">keymap/vim.js</a> and setting
the <code>keyMap</code> option to <code>"vim"</code>. Because
CodeMirror's internal API is quite different from Vim, they are only
a loose approximation of actual vim bindings, though.</p>
<script>
CodeMirror.commands.save = function(){ alert("Saving"); };
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
mode: "text/x-csrc",
vimMode: true,
showCursorWhenSelecting: true
});
var editor2 = CodeMirror.fromTextArea(document.getElementById("code2"), {
lineNumbers: true,
mode: "text/x-csrc",
vimMode: true,
showCursorWhenSelecting: true
});
</script>
</article>

View File

@@ -1,62 +0,0 @@
<!doctype html>
<title>CodeMirror: Visible tabs demo</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css">
<link rel="stylesheet" href="../lib/codemirror.css">
<script src="../lib/codemirror.js"></script>
<script src="../mode/clike/clike.js"></script>
<style type="text/css">
.CodeMirror {border-top: 1px solid #eee; border-bottom: 1px solid #eee;}
.cm-tab {
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAMCAYAAAAkuj5RAAAAAXNSR0IArs4c6QAAAGFJREFUSMft1LsRQFAQheHPowAKoACx3IgEKtaEHujDjORSgWTH/ZOdnZOcM/sgk/kFFWY0qV8foQwS4MKBCS3qR6ixBJvElOobYAtivseIE120FaowJPN75GMu8j/LfMwNjh4HUpwg4LUAAAAASUVORK5CYII=);
background-position: right;
background-repeat: no-repeat;
}
</style>
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="../doc/manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#">Visible tabs</a>
</ul>
</div>
<article>
<h2>Visible tabs demo</h2>
<form><textarea id="code" name="code">
#include "syscalls.h"
/* getchar: simple buffered version */
int getchar(void)
{
static char buf[BUFSIZ];
static char *bufp = buf;
static int n = 0;
if (n == 0) { /* buffer is empty */
n = read(0, buf, sizeof buf);
bufp = buf;
}
return (--n >= 0) ? (unsigned char) *bufp++ : EOF;
}
</textarea></form>
<p>Tabs inside the editor are spans with the
class <code>cm-tab</code>, and can be styled.</p>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
tabSize: 4,
indentUnit: 4,
indentWithTabs: true,
mode: "text/x-csrc"
});
</script>
</article>

View File

@@ -1,85 +0,0 @@
<!doctype html>
<title>CodeMirror: Inline Widget Demo</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css">
<link rel="stylesheet" href="../lib/codemirror.css">
<script src="../lib/codemirror.js"></script>
<script src="../mode/javascript/javascript.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jshint/r07/jshint.js"></script>
<style type="text/css">
.CodeMirror {border: 1px solid black;}
.lint-error {font-family: arial; font-size: 70%; background: #ffa; color: #a00; padding: 2px 5px 3px; }
.lint-error-icon {color: white; background-color: red; font-weight: bold; border-radius: 50%; padding: 0 3px; margin-right: 7px;}
</style>
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="../doc/manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#">Inline Widget</a>
</ul>
</div>
<article>
<h2>Inline Widget Demo</h2>
<div id=code></div>
<script id="script">var widgets = []
function updateHints() {
editor.operation(function(){
for (var i = 0; i < widgets.length; ++i)
editor.removeLineWidget(widgets[i]);
widgets.length = 0;
JSHINT(editor.getValue());
for (var i = 0; i < JSHINT.errors.length; ++i) {
var err = JSHINT.errors[i];
if (!err) continue;
var msg = document.createElement("div");
var icon = msg.appendChild(document.createElement("span"));
icon.innerHTML = "!!";
icon.className = "lint-error-icon";
msg.appendChild(document.createTextNode(err.reason));
msg.className = "lint-error";
widgets.push(editor.addLineWidget(err.line - 1, msg, {coverGutter: false, noHScroll: true}));
}
});
var info = editor.getScrollInfo();
var after = editor.charCoords({line: editor.getCursor().line + 1, ch: 0}, "local").top;
if (info.top + info.clientHeight < after)
editor.scrollTo(null, after - info.clientHeight + 3);
}
window.onload = function() {
var sc = document.getElementById("script");
var content = sc.textContent || sc.innerText || sc.innerHTML;
window.editor = CodeMirror(document.getElementById("code"), {
lineNumbers: true,
mode: "javascript",
value: content
});
var waiting;
editor.on("change", function() {
clearTimeout(waiting);
waiting = setTimeout(updateHints, 500);
});
setTimeout(updateHints, 100);
};
"long line to create a horizontal scrollbar, in order to test whether the (non-inline) widgets stay in place when scrolling to the right";
</script>
<p>This demo runs <a href="http://jshint.com">JSHint</a> over the code
in the editor (which is the script used on this page), and
inserts <a href="../doc/manual.html#addLineWidget">line widgets</a> to
display the warnings that JSHint comes up with.</p>
</article>

View File

@@ -1,116 +0,0 @@
<!doctype html>
<title>CodeMirror: XML Autocomplete Demo</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css">
<link rel="stylesheet" href="../lib/codemirror.css">
<link rel="stylesheet" href="../addon/hint/show-hint.css">
<script src="../lib/codemirror.js"></script>
<script src="../addon/hint/show-hint.js"></script>
<script src="../addon/hint/xml-hint.js"></script>
<script src="../mode/xml/xml.js"></script>
<style type="text/css">
.CodeMirror { border: 1px solid #eee; }
</style>
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="../doc/manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#">XML Autocomplete</a>
</ul>
</div>
<article>
<h2>XML Autocomplete Demo</h2>
<form><textarea id="code" name="code"><!-- write some xml below -->
</textarea></form>
<p>Press <strong>ctrl-space</strong>, or type a '<' character to
activate autocompletion. This demo defines a simple schema that
guides completion. The schema can be customized—see
the <a href="../doc/manual.html#addon_xml-hint">manual</a>.</p>
<p>Development of the <code>xml-hint</code> addon was kindly
sponsored
by <a href="http://www.xperiment.mobi">www.xperiment.mobi</a>.</p>
<script>
var dummy = {
attrs: {
color: ["red", "green", "blue", "purple", "white", "black", "yellow"],
size: ["large", "medium", "small"],
description: null
},
children: []
};
var tags = {
"!top": ["top"],
top: {
attrs: {
lang: ["en", "de", "fr", "nl"],
freeform: null
},
children: ["animal", "plant"]
},
animal: {
attrs: {
name: null,
isduck: ["yes", "no"]
},
children: ["wings", "feet", "body", "head", "tail"]
},
plant: {
attrs: {name: null},
children: ["leaves", "stem", "flowers"]
},
wings: dummy, feet: dummy, body: dummy, head: dummy, tail: dummy,
leaves: dummy, stem: dummy, flowers: dummy
};
function completeAfter(cm, pred) {
var cur = cm.getCursor();
if (!pred || pred()) setTimeout(function() {
if (!cm.state.completionActive)
CodeMirror.showHint(cm, CodeMirror.hint.xml, {schemaInfo: tags, completeSingle: false});
}, 100);
return CodeMirror.Pass;
}
function completeIfAfterLt(cm) {
return completeAfter(cm, function() {
var cur = cm.getCursor();
return cm.getRange(CodeMirror.Pos(cur.line, cur.ch - 1), cur) == "<";
});
}
function completeIfInTag(cm) {
return completeAfter(cm, function() {
var tok = cm.getTokenAt(cm.getCursor());
if (tok.type == "string" && (!/['"]/.test(tok.string.charAt(tok.string.length - 1)) || tok.string.length == 1)) return false;
var inner = CodeMirror.innerMode(cm.getMode(), tok.state).state;
return inner.tagName;
});
}
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
mode: "xml",
lineNumbers: true,
extraKeys: {
"'<'": completeAfter,
"'/'": completeIfAfterLt,
"' '": completeIfInTag,
"'='": completeIfInTag,
"Ctrl-Space": function(cm) {
CodeMirror.showHint(cm, CodeMirror.hint.xml, {schemaInfo: tags});
}
}
});
</script>
</article>

View File

@@ -1,42 +0,0 @@
(function() {
var pending = false, prevVal = null;
function updateSoon() {
if (!pending) {
pending = true;
setTimeout(update, 250);
}
}
function update() {
pending = false;
var marks = document.getElementById("nav").getElementsByTagName("a"), found;
for (var i = 0; i < marks.length; ++i) {
var mark = marks[i], m;
if (mark.getAttribute("data-default")) {
if (found == null) found = i;
} else if (m = mark.href.match(/#(.*)/)) {
var ref = document.getElementById(m[1]);
if (ref && ref.getBoundingClientRect().top < 50)
found = i;
}
}
if (found != null && found != prevVal) {
prevVal = found;
var lis = document.getElementById("nav").getElementsByTagName("li");
for (var i = 0; i < lis.length; ++i) lis[i].className = "";
for (var i = 0; i < marks.length; ++i) {
if (found == i) {
marks[i].className = "active";
for (var n = marks[i]; n; n = n.parentNode)
if (n.nodeName == "LI") n.className = "active";
} else {
marks[i].className = "";
}
}
}
}
window.addEventListener("scroll", updateSoon);
window.addEventListener("load", updateSoon);
})();

View File

@@ -1,234 +0,0 @@
<!doctype html>
<title>CodeMirror: Compression Helper</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="docs.css">
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#">Compression helper</a>
</ul>
</div>
<article>
<h2>Script compression helper</h2>
<p>To optimize loading CodeMirror, especially when including a
bunch of different modes, it is recommended that you combine and
minify (and preferably also gzip) the scripts. This page makes
those first two steps very easy. Simply select the version and
scripts you need in the form below, and
click <strong>Compress</strong> to download the minified script
file.</p>
<form id="form" action="http://marijnhaverbeke.nl/uglifyjs" method="post">
<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=3.20.0;f=">3.20</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=3.19.0;f=">3.19</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=3.18.0;f=">3.18</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=3.16.0;f=">3.16</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=3.15.0;f=">3.15</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=3.14.0;f=">3.14</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=3.13.0;f=">3.13</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v3.12;f=">3.12</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v3.11;f=">3.11</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v3.1;f=">3.1</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v3.02;f=">3.02</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v3.01;f=">3.01</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v3.0;f=">3.0</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.38;f=">2.38</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.37;f=">2.37</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.36;f=">2.36</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.35;f=">2.35</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.34;f=">2.34</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.33;f=">2.33</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.32;f=">2.32</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.31;f=">2.31</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.3;f=">2.3</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.25;f=">2.25</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.24;f=">2.24</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.23;f=">2.23</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.22;f=">2.22</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.21;f=">2.21</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.2;f=">2.2</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.18;f=">2.18</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.16;f=">2.16</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.15;f=">2.15</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.13;f=">2.13</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.12;f=">2.12</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.11;f=">2.11</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.1;f=">2.1</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.02;f=">2.02</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.01;f=">2.01</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=v2.0;f=">2.0</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=beta2;f=">beta2</option>
<option value="http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=beta1;f=">beta1</option>
</select></p>
<select multiple="multiple" size="20" name="code_url" style="width: 40em;" class="field" id="files">
<optgroup label="CodeMirror Library">
<option value="http://codemirror.net/lib/codemirror.js" selected>codemirror.js</option>
</optgroup>
<optgroup label="Modes">
<option value="http://codemirror.net/mode/apl/apl.js">apl.js</option>
<option value="http://codemirror.net/mode/clike/clike.js">clike.js</option>
<option value="http://codemirror.net/mode/clojure/clojure.js">clojure.js</option>
<option value="http://codemirror.net/mode/cobol/cobol.js">cobol.js</option>
<option value="http://codemirror.net/mode/coffeescript/coffeescript.js">coffeescript.js</option>
<option value="http://codemirror.net/mode/commonlisp/commonlisp.js">commonlisp.js</option>
<option value="http://codemirror.net/mode/css/css.js">css.js</option>
<option value="http://codemirror.net/mode/d/d.js">d.js</option>
<option value="http://codemirror.net/mode/diff/diff.js">diff.js</option>
<option value="http://codemirror.net/mode/dtd/dtd.js">dtd.js</option>
<option value="http://codemirror.net/mode/ecl/ecl.js">ecl.js</option>
<option value="http://codemirror.net/mode/eiffel/eiffel.js">eiffel.js</option>
<option value="http://codemirror.net/mode/erlang/erlang.js">erlang.js</option>
<option value="http://codemirror.net/mode/fortran/fortran.js">fortran.js</option>
<option value="http://codemirror.net/mode/gfm/gfm.js">gfm.js</option>
<option value="http://codemirror.net/mode/gas/gas.js">gas.js</option>
<option value="http://codemirror.net/mode/gherkin/gherkin.js">gherkin.js</option>
<option value="http://codemirror.net/mode/go/go.js">go.js</option>
<option value="http://codemirror.net/mode/groovy/groovy.js">groovy.js</option>
<option value="http://codemirror.net/mode/haml/haml.js">haml.js</option>
<option value="http://codemirror.net/mode/haskell/haskell.js">haskell.js</option>
<option value="http://codemirror.net/mode/haxe/haxe.js">haxe.js</option>
<option value="http://codemirror.net/mode/htmlembedded/htmlembedded.js">htmlembedded.js</option>
<option value="http://codemirror.net/mode/htmlmixed/htmlmixed.js">htmlmixed.js</option>
<option value="http://codemirror.net/mode/http/http.js">http.js</option>
<option value="http://codemirror.net/mode/jade/jade.js">jade.js</option>
<option value="http://codemirror.net/mode/javascript/javascript.js">javascript.js</option>
<option value="http://codemirror.net/mode/jinja2/jinja2.js">jinja2.js</option>
<option value="http://codemirror.net/mode/julia/julia.js">jinja2.js</option>
<option value="http://codemirror.net/mode/less/less.js">less.js</option>
<option value="http://codemirror.net/mode/livescript/livescript.js">livescript.js</option>
<option value="http://codemirror.net/mode/lua/lua.js">lua.js</option>
<option value="http://codemirror.net/mode/markdown/markdown.js">markdown.js</option>
<option value="http://codemirror.net/mode/mirc/mirc.js">mirc.js</option>
<option value="http://codemirror.net/mode/nginx/nginx.js">nginx.js</option>
<option value="http://codemirror.net/mode/ntriples/ntriples.js">ntriples.js</option>
<option value="http://codemirror.net/mode/ocaml/ocaml.js">ocaml.js</option>
<option value="http://codemirror.net/mode/octave/octave.js">octave.js</option>
<option value="http://codemirror.net/mode/pascal/pascal.js">pascal.js</option>
<option value="http://codemirror.net/mode/pegjs/pegjs.js">pegjs.js</option>
<option value="http://codemirror.net/mode/perl/perl.js">perl.js</option>
<option value="http://codemirror.net/mode/php/php.js">php.js</option>
<option value="http://codemirror.net/mode/pig/pig.js">pig.js</option>
<option value="http://codemirror.net/mode/properties/properties.js">properties.js</option>
<option value="http://codemirror.net/mode/python/python.js">python.js</option>
<option value="http://codemirror.net/mode/q/q.js">q.js</option>
<option value="http://codemirror.net/mode/r/r.js">r.js</option>
<option value="http://codemirror.net/mode/rpm/changes/changes.js">rpm/changes.js</option>
<option value="http://codemirror.net/mode/rpm/spec/spec.js">rpm/spec.js</option>
<option value="http://codemirror.net/mode/rst/rst.js">rst.js</option>
<option value="http://codemirror.net/mode/ruby/ruby.js">ruby.js</option>
<option value="http://codemirror.net/mode/rust/rust.js">rust.js</option>
<option value="http://codemirror.net/mode/sass/sass.js">sass.js</option>
<option value="http://codemirror.net/mode/scala/scala.js">scala.js</option>
<option value="http://codemirror.net/mode/scheme/scheme.js">scheme.js</option>
<option value="http://codemirror.net/mode/shell/shell.js">shell.js</option>
<option value="http://codemirror.net/mode/sieve/sieve.js">sieve.js</option>
<option value="http://codemirror.net/mode/smalltalk/smalltalk.js">smalltalk.js</option>
<option value="http://codemirror.net/mode/smarty/smarty.js">smarty.js</option>
<option value="http://codemirror.net/mode/smartymixed/smartymixed.js">smartymixed.js</option>
<option value="http://codemirror.net/mode/sql/sql.js">sql.js</option>
<option value="http://codemirror.net/mode/sparql/sparql.js">sparql.js</option>
<option value="http://codemirror.net/mode/stex/stex.js">stex.js</option>
<option value="http://codemirror.net/mode/tcl/tcl.js">tcl.js</option>
<option value="http://codemirror.net/mode/tiddlywiki/tiddlywiki.js">tiddlywiki.js</option>
<option value="http://codemirror.net/mode/tiki/tiki.js">tiki.js</option>
<option value="http://codemirror.net/mode/toml/toml.js">toml.js</option>
<option value="http://codemirror.net/mode/turtle/turtle.js">turtle.js</option>
<option value="http://codemirror.net/mode/vb/vb.js">vb.js</option>
<option value="http://codemirror.net/mode/vbscript/vbscript.js">vbscript.js</option>
<option value="http://codemirror.net/mode/velocity/velocity.js">velocity.js</option>
<option value="http://codemirror.net/mode/verilog/verilog.js">verilog.js</option>
<option value="http://codemirror.net/mode/xml/xml.js">xml.js</option>
<option value="http://codemirror.net/mode/xquery/xquery.js">xquery.js</option>
<option value="http://codemirror.net/mode/yaml/yaml.js">yaml.js</option>
<option value="http://codemirror.net/mode/z80/z80.js">z80.js</option>
</optgroup>
<optgroup label="Add-ons">
<option value="http://codemirror.net/addon/selection/active-line.js">active-line.js</option>
<option value="http://codemirror.net/addon/fold/brace-fold.js">brace-fold.js</option>
<option value="http://codemirror.net/addon/edit/closebrackets.js">closebrackets.js</option>
<option value="http://codemirror.net/addon/edit/closetag.js">closetag.js</option>
<option value="http://codemirror.net/addon/runmode/colorize.js">colorize.js</option>
<option value="http://codemirror.net/addon/comment/comment.js">comment.js</option>
<option value="http://codemirror.net/addon/fold/comment-fold.js">comment-fold.js</option>
<option value="http://codemirror.net/addon/comment/continuecomment.js">continuecomment.js</option>
<option value="http://codemirror.net/addon/edit/continuelist.js">continuelist.js</option>
<option value="http://codemirror.net/addon/hint/css-hint.js">css-hint.js</option>
<option value="http://codemirror.net/addon/dialog/dialog.js">dialog.js</option>
<option value="http://codemirror.net/addon/fold/foldcode.js">foldcode.js</option>
<option value="http://codemirror.net/addon/fold/foldgutter.js">foldgutter.js</option>
<option value="http://codemirror.net/addon/display/fullscreen.js">fullscreen.js</option>
<option value="http://codemirror.net/addon/wrap/hardwrap.js">hardwrap.js</option>
<option value="http://codemirror.net/addon/hint/html-hint.js">html-hint.js</option>
<option value="http://codemirror.net/addon/fold/indent-fold.js">indent-fold.js</option>
<option value="http://codemirror.net/addon/hint/javascript-hint.js">javascript-hint.js</option>
<option value="http://codemirror.net/addon/lint/javascript-lint.js">javascript-lint.js</option>
<option value="http://codemirror.net/addon/lint/json-lint.js">json-lint.js</option>
<option value="http://codemirror.net/addon/lint/lint.js">lint.js</option>
<option value="http://codemirror.net/addon/mode/loadmode.js">loadmode.js</option>
<option value="http://codemirror.net/addon/selection/mark-selection.js">mark-selection.js</option>
<option value="http://codemirror.net/addon/search/match-highlighter.js">match-highlighter.js</option>
<option value="http://codemirror.net/addon/edit/matchbrackets.js">matchbrackets.js</option>
<option value="http://codemirror.net/addon/edit/matchtags.js">matchtags.js</option>
<option value="http://codemirror.net/addon/merge/merge.js">merge.js</option>
<option value="http://codemirror.net/addon/mode/multiplex.js">multiplex.js</option>
<option value="http://codemirror.net/addon/mode/overlay.js">overlay.js</option>
<option value="http://codemirror.net/addon/hint/pig-hint.js">pig-hint.js</option>
<option value="http://codemirror.net/addon/display/placeholder.js">placeholder.js</option>
<option value="http://codemirror.net/addon/hint/python-hint.js">python-hint.js</option>
<option value="http://codemirror.net/addon/runmode/runmode.js">runmode.js</option>
<option value="http://codemirror.net/addon/runmode/runmode.node.js">runmode.node.js</option>
<option value="http://codemirror.net/addon/runmode/runmode-standalone.js">runmode-standalone.js</option>
<option value="http://codemirror.net/addon/search/search.js">search.js</option>
<option value="http://codemirror.net/addon/search/searchcursor.js">searchcursor.js</option>
<option value="http://codemirror.net/addon/hint/show-hint.js">show-hint.js</option>
<option value="http://codemirror.net/addon/hint/sql-hint.js">sql-hint.js</option>
<option value="http://codemirror.net/addon/edit/trailingspace.js">trailingspace.js</option>
<option value="http://codemirror.net/addon/tern/tern.js">tern.js</option>
<option value="http://codemirror.net/addon/fold/xml-fold.js">xml-fold.js</option>
<option value="http://codemirror.net/addon/hint/xml-hint.js">xml-hint.js</option>
</optgroup>
<optgroup label="Keymaps">
<option value="http://codemirror.net/keymap/emacs.js">emacs.js</option>
<option value="http://codemirror.net/keymap/vim.js">vim.js</option>
</optgroup>
</select>
<p>
<button type="submit">Compress</button> with <a href="http://github.com/mishoo/UglifyJS/">UglifyJS</a>
</p>
<p>Custom code to add to the compressed file:<textarea name="js_code" style="width: 100%; height: 15em;" class="field"></textarea></p>
</form>
<script type="text/javascript">
function setVersion(ver) {
var urlprefix = ver.options[ver.selectedIndex].value;
var select = document.getElementById("files"), m;
for (var optgr = select.firstChild; optgr; optgr = optgr.nextSibling)
for (var opt = optgr.firstChild; opt; opt = opt.nextSibling) {
if (opt.nodeName != "OPTION")
continue;
else if (m = opt.value.match(/^http:\/\/codemirror.net\/(.*)$/))
opt.value = urlprefix + m[1];
else if (m = opt.value.match(/http:\/\/marijnhaverbeke.nl\/git\/codemirror\?a=blob_plain;hb=[^;]+;f=(.*)$/))
opt.value = urlprefix + m[1];
}
}
</script>
</article>

View File

@@ -1,225 +0,0 @@
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 400;
src: local('Source Sans Pro'), local('SourceSansPro-Regular'), url(http://themes.googleusercontent.com/static/fonts/sourcesanspro/v5/ODelI1aHBYDBqgeIAH2zlBM0YzuT7MdOe03otPbuUS0.woff) format('woff');
}
body, html { margin: 0; padding: 0; height: 100%; }
section, article { display: block; padding: 0; }
body {
background: #f8f8f8;
font-family: 'Source Sans Pro', Helvetica, Arial, sans-serif;
line-height: 1.5;
}
p { margin-top: 0; }
h2, h3 {
font-weight: normal;
margin-bottom: .7em;
}
h2 { font-size: 120%; }
h3 { font-size: 110%; }
article > h2:first-child, section:first-child > h2 { margin-top: 0; }
a, a:visited, a:link, .quasilink {
color: #A21313;
text-decoration: none;
}
em {
padding-right: 2px;
}
.quasilink {
cursor: pointer;
}
article {
max-width: 700px;
margin: 0 auto;
border-left: 2px solid #E30808;
border-right: 1px solid #ddd;
padding: 30px 50px 100px 50px;
background: white;
z-index: 2;
position: relative;
min-height: 100%;
box-sizing: border-box;
-moz-box-sizing: border-box;
}
#nav {
position: fixed;
top: 30px;
right: 50%;
padding-right: 350px;
text-align: right;
z-index: 1;
}
@media screen and (max-width: 1000px) {
article {
margin: 0 0 0 160px;
}
#nav {
left: 0; right: none;
width: 160px;
}
}
#nav ul {
display: block;
margin: 0; padding: 0;
margin-bottom: 32px;
}
#nav li {
display: block;
margin-bottom: 4px;
}
#nav li ul {
font-size: 80%;
margin-bottom: 0;
display: none;
}
#nav li.active ul {
display: block;
}
#nav li li a {
padding-right: 20px;
}
#nav ul a {
color: black;
padding: 0 7px 1px 11px;
}
#nav ul a.active, #nav ul a:hover {
border-bottom: 1px solid #E30808;
color: #E30808;
}
#logo {
border: 0;
margin-right: 7px;
margin-bottom: 25px;
}
section {
border-top: 1px solid #E30808;
margin: 1.5em 0;
}
section.first {
border: none;
margin-top: 0;
}
#demo {
position: relative;
}
#demolist {
position: absolute;
right: 5px;
top: 5px;
z-index: 25;
}
#bankinfo {
text-align: left;
display: none;
padding: 0 .5em;
position: absolute;
border: 2px solid #aaa;
border-radius: 5px;
background: #eee;
top: 10px;
left: 30px;
}
#bankinfo_close {
position: absolute;
top: 0; right: 6px;
font-weight: bold;
cursor: pointer;
}
.bigbutton {
cursor: pointer;
text-align: center;
padding: 0 1em;
display: inline-block;
color: white;
position: relative;
line-height: 1.9;
color: white !important;
background: #A21313;
}
.bigbutton.right {
border-bottom-left-radius: 100px;
border-top-left-radius: 100px;
}
.bigbutton.left {
border-bottom-right-radius: 100px;
border-top-right-radius: 100px;
}
.bigbutton:hover {
background: #E30808;
}
th {
text-decoration: underline;
font-weight: normal;
text-align: left;
}
#features ul {
list-style: none;
margin: 0 0 1em;
padding: 0 0 0 1.2em;
}
#features li:before {
content: "-";
width: 1em;
display: inline-block;
padding: 0;
margin: 0;
margin-left: -1em;
}
.rel {
margin-bottom: 0;
}
.rel-note {
margin-top: 0;
color: #555;
}
pre {
padding-left: 15px;
border-left: 2px solid #ddd;
}
code {
padding: 0 2px;
}
strong {
text-decoration: underline;
font-weight: normal;
}
.field {
border: 1px solid #A21313;
}

View File

@@ -1,503 +0,0 @@
<!doctype html>
<title>CodeMirror: Internals</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="docs.css">
<style>dl dl {margin: 0;} .update {color: #d40 !important}</style>
<script src="activebookmark.js"></script>
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a href="#top">Introduction</a></li>
<li><a href="#approach">General Approach</a></li>
<li><a href="#input">Input</a></li>
<li><a href="#selection">Selection</a></li>
<li><a href="#update">Intelligent Updating</a></li>
<li><a href="#parse">Parsing</a></li>
<li><a href="#summary">What Gives?</a></li>
<li><a href="#btree">Content Representation</a></li>
<li><a href="#keymap">Key Maps</a></li>
</ul>
</div>
<article>
<h2 id=top>(Re-) Implementing A Syntax-Highlighting Editor in JavaScript</h2>
<p style="font-size: 85%" id="intro">
<strong>Topic:</strong> JavaScript, code editor implementation<br>
<strong>Author:</strong> Marijn Haverbeke<br>
<strong>Date:</strong> March 2nd 2011 (updated November 13th 2011)
</p>
<p style="padding: 0 3em 0 2em"><strong>Caution</strong>: this text was written briefly after
version 2 was initially written. It no longer (even including the
update at the bottom) fully represents the current implementation. I'm
leaving it here as a historic document. For more up-to-date
information, look at the entries
tagged <a href="http://marijnhaverbeke.nl/blog/#cm-internals">cm-internals</a>
on my blog.</p>
<p>This is a followup to
my <a href="http://codemirror.net/story.html">Brutal Odyssey to the
Dark Side of the DOM Tree</a> story. That one describes the
mind-bending process of implementing (what would become) CodeMirror 1.
This one describes the internals of CodeMirror 2, a complete rewrite
and rethink of the old code base. I wanted to give this piece another
Hunter Thompson copycat subtitle, but somehow that would be out of
place—the process this time around was one of straightforward
engineering, requiring no serious mind-bending whatsoever.</p>
<p>So, what is wrong with CodeMirror 1? I'd estimate, by mailing list
activity and general search-engine presence, that it has been
integrated into about a thousand systems by now. The most prominent
one, since a few weeks,
being <a href="http://googlecode.blogspot.com/2011/01/make-quick-fixes-quicker-on-google.html">Google
code's project hosting</a>. It works, and it's being used widely.</p>
<p>Still, I did not start replacing it because I was bored. CodeMirror
1 was heavily reliant on <code>designMode</code>
or <code>contentEditable</code> (depending on the browser). Neither of
these are well specified (HTML5 tries
to <a href="http://www.w3.org/TR/html5/editing.html#contenteditable">specify</a>
their basics), and, more importantly, they tend to be one of the more
obscure and buggy areas of browser functionality—CodeMirror, by using
this functionality in a non-typical way, was constantly running up
against browser bugs. WebKit wouldn't show an empty line at the end of
the document, and in some releases would suddenly get unbearably slow.
Firefox would show the cursor in the wrong place. Internet Explorer
would insist on linkifying everything that looked like a URL or email
address, a behaviour that can't be turned off. Some bugs I managed to
work around (which was often a frustrating, painful process), others,
such as the Firefox cursor placement, I gave up on, and had to tell
user after user that they were known problems, but not something I
could help.</p>
<p>Also, there is the fact that <code>designMode</code> (which seemed
to be less buggy than <code>contentEditable</code> in Webkit and
Firefox, and was thus used by CodeMirror 1 in those browsers) requires
a frame. Frames are another tricky area. It takes some effort to
prevent getting tripped up by domain restrictions, they don't
initialize synchronously, behave strangely in response to the back
button, and, on several browsers, can't be moved around the DOM
without having them re-initialize. They did provide a very nice way to
namespace the library, though—CodeMirror 1 could freely pollute the
namespace inside the frame.</p>
<p>Finally, working with an editable document means working with
selection in arbitrary DOM structures. Internet Explorer (8 and
before) has an utterly different (and awkward) selection API than all
of the other browsers, and even among the different implementations of
<code>document.selection</code>, details about how exactly a selection
is represented vary quite a bit. Add to that the fact that Opera's
selection support tended to be very buggy until recently, and you can
imagine why CodeMirror 1 contains 700 lines of selection-handling
code.</p>
<p>And that brings us to the main issue with the CodeMirror 1
code base: The proportion of browser-bug-workarounds to real
application code was getting dangerously high. By building on top of a
few dodgy features, I put the system in a vulnerable position—any
incompatibility and bugginess in these features, I had to paper over
with my own code. Not only did I have to do some serious stunt-work to
get it to work on older browsers (as detailed in the
previous <a href="http://codemirror.net/story.html">story</a>), things
also kept breaking in newly released versions, requiring me to come up
with <em>new</em> scary hacks in order to keep up. This was starting
to lose its appeal.</p>
<section id=approach>
<h2>General Approach</h2>
<p>What CodeMirror 2 does is try to sidestep most of the hairy hacks
that came up in version 1. I owe a lot to the
<a href="http://ace.ajax.org">ACE</a> editor for inspiration on how to
approach this.</p>
<p>I absolutely did not want to be completely reliant on key events to
generate my input. Every JavaScript programmer knows that key event
information is horrible and incomplete. Some people (most awesomely
Mihai Bazon with <a href="http://ymacs.org">Ymacs</a>) have been able
to build more or less functioning editors by directly reading key
events, but it takes a lot of work (the kind of never-ending, fragile
work I described earlier), and will never be able to properly support
things like multi-keystoke international character
input. <a href="#keymap" class="update">[see below for caveat]</a></p>
<p>So what I do is focus a hidden textarea, and let the browser
believe that the user is typing into that. What we show to the user is
a DOM structure we built to represent his document. If this is updated
quickly enough, and shows some kind of believable cursor, it feels
like a real text-input control.</p>
<p>Another big win is that this DOM representation does not have to
span the whole document. Some CodeMirror 1 users insisted that they
needed to put a 30 thousand line XML document into CodeMirror. Putting
all that into the DOM takes a while, especially since, for some
reason, an editable DOM tree is slower than a normal one on most
browsers. If we have full control over what we show, we must only
ensure that the visible part of the document has been added, and can
do the rest only when needed. (Fortunately, the <code>onscroll</code>
event works almost the same on all browsers, and lends itself well to
displaying things only as they are scrolled into view.)</p>
</section>
<section id="input">
<h2>Input</h2>
<p>ACE uses its hidden textarea only as a text input shim, and does
all cursor movement and things like text deletion itself by directly
handling key events. CodeMirror's way is to let the browser do its
thing as much as possible, and not, for example, define its own set of
key bindings. One way to do this would have been to have the whole
document inside the hidden textarea, and after each key event update
the display DOM to reflect what's in that textarea.</p>
<p>That'd be simple, but it is not realistic. For even medium-sized
document the editor would be constantly munging huge strings, and get
terribly slow. What CodeMirror 2 does is put the current selection,
along with an extra line on the top and on the bottom, into the
textarea.</p>
<p>This means that the arrow keys (and their ctrl-variations), home,
end, etcetera, do not have to be handled specially. We just read the
cursor position in the textarea, and update our cursor to match it.
Also, copy and paste work pretty much for free, and people get their
native key bindings, without any special work on my part. For example,
I have emacs key bindings configured for Chrome and Firefox. There is
no way for a script to detect this. <a class="update"
href="#keymap">[no longer the case]</a></p>
<p>Of course, since only a small part of the document sits in the
textarea, keys like page up and ctrl-end won't do the right thing.
CodeMirror is catching those events and handling them itself.</p>
</section>
<section id="selection">
<h2>Selection</h2>
<p>Getting and setting the selection range of a textarea in modern
browsers is trivial—you just use the <code>selectionStart</code>
and <code>selectionEnd</code> properties. On IE you have to do some
insane stuff with temporary ranges and compensating for the fact that
moving the selection by a 'character' will treat \r\n as a single
character, but even there it is possible to build functions that
reliably set and get the selection range.</p>
<p>But consider this typical case: When I'm somewhere in my document,
press shift, and press the up arrow, something gets selected. Then, if
I, still holding shift, press the up arrow again, the top of my
selection is adjusted. The selection remembers where its <em>head</em>
and its <em>anchor</em> are, and moves the head when we shift-move.
This is a generally accepted property of selections, and done right by
every editing component built in the past twenty years.</p>
<p>But not something that the browser selection APIs expose.</p>
<p>Great. So when someone creates an 'upside-down' selection, the next
time CodeMirror has to update the textarea, it'll re-create the
selection as an 'upside-up' selection, with the anchor at the top, and
the next cursor motion will behave in an unexpected way—our second
up-arrow press in the example above will not do anything, since it is
interpreted in exactly the same way as the first.</p>
<p>No problem. We'll just, ehm, detect that the selection is
upside-down (you can tell by the way it was created), and then, when
an upside-down selection is present, and a cursor-moving key is
pressed in combination with shift, we quickly collapse the selection
in the textarea to its start, allow the key to take effect, and then
combine its new head with its old anchor to get the <em>real</em>
selection.</p>
<p>In short, scary hacks could not be avoided entirely in CodeMirror
2.</p>
<p>And, the observant reader might ask, how do you even know that a
key combo is a cursor-moving combo, if you claim you support any
native key bindings? Well, we don't, but we can learn. The editor
keeps a set known cursor-movement combos (initialized to the
predictable defaults), and updates this set when it observes that
pressing a certain key had (only) the effect of moving the cursor.
This, of course, doesn't work if the first time the key is used was
for extending an inverted selection, but it works most of the
time.</p>
</section>
<section id="update">
<h2>Intelligent Updating</h2>
<p>One thing that always comes up when you have a complicated internal
state that's reflected in some user-visible external representation
(in this case, the displayed code and the textarea's content) is
keeping the two in sync. The naive way is to just update the display
every time you change your state, but this is not only error prone
(you'll forget), it also easily leads to duplicate work on big,
composite operations. Then you start passing around flags indicating
whether the display should be updated in an attempt to be efficient
again and, well, at that point you might as well give up completely.</p>
<p>I did go down that road, but then switched to a much simpler model:
simply keep track of all the things that have been changed during an
action, and then, only at the end, use this information to update the
user-visible display.</p>
<p>CodeMirror uses a concept of <em>operations</em>, which start by
calling a specific set-up function that clears the state and end by
calling another function that reads this state and does the required
updating. Most event handlers, and all the user-visible methods that
change state are wrapped like this. There's a method
called <code>operation</code> that accepts a function, and returns
another function that wraps the given function as an operation.</p>
<p>It's trivial to extend this (as CodeMirror does) to detect nesting,
and, when an operation is started inside an operation, simply
increment the nesting count, and only do the updating when this count
reaches zero again.</p>
<p>If we have a set of changed ranges and know the currently shown
range, we can (with some awkward code to deal with the fact that
changes can add and remove lines, so we're dealing with a changing
coordinate system) construct a map of the ranges that were left
intact. We can then compare this map with the part of the document
that's currently visible (based on scroll offset and editor height) to
determine whether something needs to be updated.</p>
<p>CodeMirror uses two update algorithms—a full refresh, where it just
discards the whole part of the DOM that contains the edited text and
rebuilds it, and a patch algorithm, where it uses the information
about changed and intact ranges to update only the out-of-date parts
of the DOM. When more than 30 percent (which is the current heuristic,
might change) of the lines need to be updated, the full refresh is
chosen (since it's faster to do than painstakingly finding and
updating all the changed lines), in the other case it does the
patching (so that, if you scroll a line or select another character,
the whole screen doesn't have to be
re-rendered). <span class="update">[the full-refresh
algorithm was dropped, it wasn't really faster than the patching
one]</span></p>
<p>All updating uses <code>innerHTML</code> rather than direct DOM
manipulation, since that still seems to be by far the fastest way to
build documents. There's a per-line function that combines the
highlighting, <a href="manual.html#markText">marking</a>, and
selection info for that line into a snippet of HTML. The patch updater
uses this to reset individual lines, the refresh updater builds an
HTML chunk for the whole visible document at once, and then uses a
single <code>innerHTML</code> update to do the refresh.</p>
</section>
<section id="parse">
<h2>Parsers can be Simple</h2>
<p>When I wrote CodeMirror 1, I
thought <a href="http://codemirror.net/story.html#parser">interruptable
parsers</a> were a hugely scary and complicated thing, and I used a
bunch of heavyweight abstractions to keep this supposed complexity
under control: parsers
were <a href="http://bob.pythonmac.org/archives/2005/07/06/iteration-in-javascript/">iterators</a>
that consumed input from another iterator, and used funny
closure-resetting tricks to copy and resume themselves.</p>
<p>This made for a rather nice system, in that parsers formed strictly
separate modules, and could be composed in predictable ways.
Unfortunately, it was quite slow (stacking three or four iterators on
top of each other), and extremely intimidating to people not used to a
functional programming style.</p>
<p>With a few small changes, however, we can keep all those
advantages, but simplify the API and make the whole thing less
indirect and inefficient. CodeMirror
2's <a href="manual.html#modeapi">mode API</a> uses explicit state
objects, and makes the parser/tokenizer a function that simply takes a
state and a character stream abstraction, advances the stream one
token, and returns the way the token should be styled. This state may
be copied, optionally in a mode-defined way, in order to be able to
continue a parse at a given point. Even someone who's never touched a
lambda in his life can understand this approach. Additionally, far
fewer objects are allocated in the course of parsing now.</p>
<p>The biggest speedup comes from the fact that the parsing no longer
has to touch the DOM though. In CodeMirror 1, on an older browser, you
could <em>see</em> the parser work its way through the document,
managing some twenty lines in each 50-millisecond time slice it got. It
was reading its input from the DOM, and updating the DOM as it went
along, which any experienced JavaScript programmer will immediately
spot as a recipe for slowness. In CodeMirror 2, the parser usually
finishes the whole document in a single 100-millisecond time slice—it
manages some 1500 lines during that time on Chrome. All it has to do
is munge strings, so there is no real reason for it to be slow
anymore.</p>
</section>
<section id="summary">
<h2>What Gives?</h2>
<p>Given all this, what can you expect from CodeMirror 2?</p>
<ul>
<li><strong>Small.</strong> the base library is
some <span class="update">45k</span> when minified
now, <span class="update">17k</span> when gzipped. It's smaller than
its own logo.</li>
<li><strong>Lightweight.</strong> CodeMirror 2 initializes very
quickly, and does almost no work when it is not focused. This means
you can treat it almost like a textarea, have multiple instances on a
page without trouble.</li>
<li><strong>Huge document support.</strong> Since highlighting is
really fast, and no DOM structure is being built for non-visible
content, you don't have to worry about locking up your browser when a
user enters a megabyte-sized document.</li>
<li><strong>Extended API.</strong> Some things kept coming up in the
mailing list, such as marking pieces of text or lines, which were
extremely hard to do with CodeMirror 1. The new version has proper
support for these built in.</li>
<li><strong>Tab support.</strong> Tabs inside editable documents were,
for some reason, a no-go. At least six different people announced they
were going to add tab support to CodeMirror 1, none survived (I mean,
none delivered a working version). CodeMirror 2 no longer removes tabs
from your document.</li>
<li><strong>Sane styling.</strong> <code>iframe</code> nodes aren't
really known for respecting document flow. Now that an editor instance
is a plain <code>div</code> element, it is much easier to size it to
fit the surrounding elements. You don't even have to make it scroll if
you do not <a href="../demo/resize.html">want to</a>.</li>
</ul>
<p>On the downside, a CodeMirror 2 instance is <em>not</em> a native
editable component. Though it does its best to emulate such a
component as much as possible, there is functionality that browsers
just do not allow us to hook into. Doing select-all from the context
menu, for example, is not currently detected by CodeMirror.</p>
<p id="changes" style="margin-top: 2em;"><span style="font-weight:
bold">[Updates from November 13th 2011]</span> Recently, I've made
some changes to the codebase that cause some of the text above to no
longer be current. I've left the text intact, but added markers at the
passages that are now inaccurate. The new situation is described
below.</p>
</section>
<section id="btree">
<h2>Content Representation</h2>
<p>The original implementation of CodeMirror 2 represented the
document as a flat array of line objects. This worked well—splicing
arrays will require the part of the array after the splice to be
moved, but this is basically just a simple <code>memmove</code> of a
bunch of pointers, so it is cheap even for huge documents.</p>
<p>However, I recently added line wrapping and code folding (line
collapsing, basically). Once lines start taking up a non-constant
amount of vertical space, looking up a line by vertical position
(which is needed when someone clicks the document, and to determine
the visible part of the document during scrolling) can only be done
with a linear scan through the whole array, summing up line heights as
you go. Seeing how I've been going out of my way to make big documents
fast, this is not acceptable.</p>
<p>The new representation is based on a B-tree. The leaves of the tree
contain arrays of line objects, with a fixed minimum and maximum size,
and the non-leaf nodes simply hold arrays of child nodes. Each node
stores both the amount of lines that live below them and the vertical
space taken up by these lines. This allows the tree to be indexed both
by line number and by vertical position, and all access has
logarithmic complexity in relation to the document size.</p>
<p>I gave line objects and tree nodes parent pointers, to the node
above them. When a line has to update its height, it can simply walk
these pointers to the top of the tree, adding or subtracting the
difference in height from each node it encounters. The parent pointers
also make it cheaper (in complexity terms, the difference is probably
tiny in normal-sized documents) to find the current line number when
given a line object. In the old approach, the whole document array had
to be searched. Now, we can just walk up the tree and count the sizes
of the nodes coming before us at each level.</p>
<p>I chose B-trees, not regular binary trees, mostly because they
allow for very fast bulk insertions and deletions. When there is a big
change to a document, it typically involves adding, deleting, or
replacing a chunk of subsequent lines. In a regular balanced tree, all
these inserts or deletes would have to be done separately, which could
be really expensive. In a B-tree, to insert a chunk, you just walk
down the tree once to find where it should go, insert them all in one
shot, and then break up the node if needed. This breaking up might
involve breaking up nodes further up, but only requires a single pass
back up the tree. For deletion, I'm somewhat lax in keeping things
balanced—I just collapse nodes into a leaf when their child count goes
below a given number. This means that there are some weird editing
patterns that may result in a seriously unbalanced tree, but even such
an unbalanced tree will perform well, unless you spend a day making
strangely repeating edits to a really big document.</p>
</section>
<section id="keymap">
<h2>Keymaps</h2>
<p><a href="#approach">Above</a>, I claimed that directly catching key
events for things like cursor movement is impractical because it
requires some browser-specific kludges. I then proceeded to explain
some awful <a href="#selection">hacks</a> that were needed to make it
possible for the selection changes to be detected through the
textarea. In fact, the second hack is about as bad as the first.</p>
<p>On top of that, in the presence of user-configurable tab sizes and
collapsed and wrapped lines, lining up cursor movement in the textarea
with what's visible on the screen becomes a nightmare. Thus, I've
decided to move to a model where the textarea's selection is no longer
depended on.</p>
<p>So I moved to a model where all cursor movement is handled by my
own code. This adds support for a goal column, proper interaction of
cursor movement with collapsed lines, and makes it possible for
vertical movement to move through wrapped lines properly, instead of
just treating them like non-wrapped lines.</p>
<p>The key event handlers now translate the key event into a string,
something like <code>Ctrl-Home</code> or <code>Shift-Cmd-R</code>, and
use that string to look up an action to perform. To make keybinding
customizable, this lookup goes through
a <a href="manual.html#option_keyMap">table</a>, using a scheme that
allows such tables to be chained together (for example, the default
Mac bindings fall through to a table named 'emacsy', which defines
basic Emacs-style bindings like <code>Ctrl-F</code>, and which is also
used by the custom Emacs bindings).</p>
<p>A new
option <a href="manual.html#option_extraKeys"><code>extraKeys</code></a>
allows ad-hoc keybindings to be defined in a much nicer way than what
was possible with the
old <a href="manual.html#option_onKeyEvent"><code>onKeyEvent</code></a>
callback. You simply provide an object mapping key identifiers to
functions, instead of painstakingly looking at raw key events.</p>
<p>Built-in commands map to strings, rather than functions, for
example <code>"goLineUp"</code> is the default action bound to the up
arrow key. This allows new keymaps to refer to them without
duplicating any code. New commands can be defined by assigning to
the <code>CodeMirror.commands</code> object, which maps such commands
to functions.</p>
<p>The hidden textarea now only holds the current selection, with no
extra characters around it. This has a nice advantage: polling for
input becomes much, much faster. If there's a big selection, this text
does not have to be read from the textarea every time—when we poll,
just noticing that something is still selected is enough to tell us
that no new text was typed.</p>
<p>The reason that cheap polling is important is that many browsers do
not fire useful events on IME (input method engine) input, which is
the thing where people inputting a language like Japanese or Chinese
use multiple keystrokes to create a character or sequence of
characters. Most modern browsers fire <code>input</code> when the
composing is finished, but many don't fire anything when the character
is updated <em>during</em> composition. So we poll, whenever the
editor is focused, to provide immediate updates of the display.</p>
</article>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

View File

@@ -1,147 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="744.09448819"
height="1052.3622047"
id="svg2"
version="1.1"
inkscape:version="0.48.4 r9939"
inkscape:export-filename="/home/marijn/src/js/codemirror/doc/logo.png"
inkscape:export-xdpi="27.450405"
inkscape:export-ydpi="27.450405"
sodipodi:docname="logo.svg">
<defs
id="defs4">
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath4138">
<path
transform="matrix(1.05,0,0,1,-290.76164,27.927128)"
d="m 705.08647,231.61324 a 70.710678,104.55079 0 1 1 -141.42135,0 70.710678,104.55079 0 1 1 141.42135,0 z"
sodipodi:ry="104.55079"
sodipodi:rx="70.710678"
sodipodi:cy="231.61324"
sodipodi:cx="634.37579"
id="path4140"
style="fill:#ffffff;fill-opacity:1;stroke:none"
sodipodi:type="arc" />
</clipPath>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.4"
inkscape:cx="291.72812"
inkscape:cy="789.2497"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1600"
inkscape:window-height="875"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="0" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<text
xml:space="preserve"
style="font-size:15px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#a21313;fill-opacity:1;stroke:none;font-family:Ubuntu Mono;-inkscape-font-specification:Ubuntu Mono"
x="247.48738"
y="163.42795"
id="text4006"
sodipodi:linespacing="125%"
clip-path="url(#clipPath4138)"
transform="translate(0.50507287,0.50507595)"><tspan
sodipodi:role="line"
id="tspan4008"
x="247.48738"
y="163.42795"> if (unit == &quot;char&quot;) moveOnce();</tspan><tspan
sodipodi:role="line"
x="247.48738"
y="182.17795"
id="tspan4010"> else if (unit == &quot;column&quot;) moveOnce(true);</tspan><tspan
sodipodi:role="line"
x="247.48738"
y="200.92795"
id="tspan4012"> else if (unit == &quot;word&quot; || unit == &quot;group&quot;) {</tspan><tspan
sodipodi:role="line"
x="247.48738"
y="219.67795"
id="tspan4014"> var sawType = null, group = unit == &quot;group&quot;;</tspan><tspan
sodipodi:role="line"
x="247.48738"
y="238.42795"
id="tspan4016"> for (var first = true;; first = false) {</tspan><tspan
sodipodi:role="line"
x="247.48738"
y="257.17795"
id="tspan4018"> if (dir &lt; 0 &amp;&amp; !moveOnce(!first)) break;</tspan><tspan
sodipodi:role="line"
x="247.48738"
y="275.92795"
id="tspan4020"> var cur = lineObj.text.charAt(ch) || &quot;\n&quot;;</tspan><tspan
sodipodi:role="line"
x="247.48738"
y="294.67795"
id="tspan4022"> var type = isWordChar(cur) ? &quot;w&quot;</tspan><tspan
sodipodi:role="line"
x="247.48738"
y="313.42795"
id="tspan4024"> : !group ? null</tspan><tspan
sodipodi:role="line"
x="247.48738"
y="332.17795"
id="tspan4026"> : /\s/.test(cur) ? null</tspan><tspan
sodipodi:role="line"
x="247.48738"
y="350.92795"
id="tspan4028"> : &quot;p&quot;; // punctuation</tspan><tspan
sodipodi:role="line"
x="247.48738"
y="369.67795"
id="tspan4046"> if (sawType &amp;&amp; sawType</tspan></text>
<path
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-opacity:1;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none"
d="M 374.84375 136.8125 C 371.96854 136.71001 368.64305 137.97919 365.15625 142.03125 C 361.97051 140.84608 359.22347 140.35622 356.84375 140.375 C 346.53162 140.4564 343.3125 149.71875 343.3125 149.71875 C 326.2234 146.67934 325.625 162.59375 325.625 162.59375 C 309.43195 163.37101 312.4375 177.375 312.4375 177.375 C 295.67899 180.15651 301.1875 194 301.1875 194 C 284.10838 199.04575 293.4375 212.46875 293.4375 212.46875 C 293.4375 212.46875 277.68174 220.31271 288.1875 232.25 C 288.1875 232.25 273.81776 243.63282 285.90625 253.34375 C 285.90625 253.34375 271.57897 263.97487 286.40625 275.03125 C 286.40625 275.03125 273.84147 285.48036 289.96875 295.3125 C 289.96875 295.3125 278.92374 306.07108 295.59375 314.65625 C 295.59375 314.65625 287.70844 329.01862 305.96875 335.125 C 305.96875 335.125 300.47495 348.88874 319.09375 351.46875 C 319.09375 351.46875 315.90162 357.19564 321.59375 361.15625 C 321.59375 361.15625 310.04416 364.78661 312.5625 374.40625 C 313.83361 379.26171 316.82684 380.49158 323.53125 380.1875 C 323.53125 380.1875 329.096 395.54812 350.46875 398.96875 L 353.125 402.59375 C 353.125 402.59375 342.80592 409.64088 359.125 421.5 C 359.125 421.5 354.16126 425.74314 363.28125 433.34375 C 363.28125 433.34375 357.54117 438.3362 365.75 442.625 C 365.75 442.625 361.35822 445.96166 366.09375 448.125 C 366.09375 448.125 370.88293 490.18262 355.40625 534.4375 C 355.40625 534.4375 341.28721 542.04782 350.1875 556.96875 C 350.1875 556.96875 331.59675 562.24093 345.09375 575.53125 C 345.09375 575.53125 342.0547 585.56155 349.375 585.78125 C 349.375 585.78125 346.16048 592.54552 354.4375 594.5625 C 354.4375 594.5625 353.17883 603.88113 364.09375 602.1875 C 369.44813 608.40994 378.92733 608.70518 385.21875 602.34375 C 396.13361 604.03738 394.875 594.71875 394.875 594.71875 C 403.15197 592.70177 399.9375 585.9375 399.9375 585.9375 C 407.25781 585.7178 404.21875 575.6875 404.21875 575.6875 C 417.71573 562.39718 399.125 557.09375 399.125 557.09375 C 408.0253 542.17282 393.90625 534.5625 393.90625 534.5625 C 378.42953 490.30762 383.21875 448.28125 383.21875 448.28125 C 387.95421 446.11791 383.5625 442.78125 383.5625 442.78125 C 391.77129 438.49245 386.03125 433.5 386.03125 433.5 C 395.15125 425.89939 390.1875 421.65625 390.1875 421.65625 C 406.5066 409.79713 396.1875 402.75 396.1875 402.75 L 398.84375 399.125 C 420.21649 395.70437 425.78125 380.34375 425.78125 380.34375 C 432.48566 380.64783 435.47889 379.41796 436.75 374.5625 C 439.26834 364.94286 427.75 361.3125 427.75 361.3125 C 433.44213 357.35188 430.21875 351.59375 430.21875 351.59375 C 448.83755 349.01373 443.34375 335.28125 443.34375 335.28125 C 461.60406 329.17487 453.71875 314.78125 453.71875 314.78125 C 470.38876 306.19608 459.34375 295.46875 459.34375 295.46875 C 475.47103 285.63661 462.90625 275.1875 462.90625 275.1875 C 477.73353 264.13112 463.40625 253.5 463.40625 253.5 C 475.49474 243.78907 461.15625 232.375 461.15625 232.375 C 471.66201 220.43771 455.875 212.625 455.875 212.625 C 455.875 212.625 465.20411 199.202 448.125 194.15625 C 448.125 194.15625 453.66476 180.31276 436.90625 177.53125 C 436.90625 177.53125 439.88054 163.52726 423.6875 162.75 C 423.6875 162.75 423.0891 146.8356 406 149.875 C 406 149.875 401.14687 135.83532 384.15625 142.15625 C 384.15625 142.15625 380.33279 137.00815 374.84375 136.8125 z M 375.34375 155 C 416.3488 155 449.59375 201.78944 449.59375 259.53125 C 449.59375 317.27306 416.3488 364.09375 375.34375 364.09375 C 334.3387 364.09375 301.09375 317.27306 301.09375 259.53125 C 301.09375 201.78944 334.3387 155 375.34375 155 z "
id="rect3058" />
<text
sodipodi:linespacing="125%"
id="text4207"
y="491.91403"
x="149.69542"
style="font-size:95px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#a21313;fill-opacity:1;stroke:none;font-family:Source Sans;-inkscape-font-specification:Source Sans"
xml:space="preserve"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"><tspan
y="491.91403"
x="149.69542"
id="tspan4209"
sodipodi:role="line">Code Mirror</tspan></text>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 8.8 KiB

File diff suppressed because it is too large Load Diff

View File

@@ -1,136 +0,0 @@
<!doctype html>
<title>CodeMirror: Real-world Uses</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="docs.css">
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#">Real-world uses</a>
</ul>
</div>
<article>
<h2>CodeMirror real-world uses</h2>
<p><a href="mailto:marijnh@gmail.com">Contact me</a> if you'd like
your project to be added to this list.</p>
<ul>
<li><a href="http://brackets.io">Adobe Brackets</a> (code editor)</li>
<li><a href="http://amber-lang.net/">Amber</a> (JavaScript-based Smalltalk system)</li>
<li><a href="http://apeye.org/">APEye</a> (tool for testing &amp; documenting APIs)</li>
<li><a href="http://blog.bitbucket.org/2013/05/14/edit-your-code-in-the-cloud-with-bitbucket/">Bitbucket</a> (code hosting)</li>
<li><a href="http://buzz.blogger.com/2013/04/improvements-to-blogger-template-html.html">Blogger's template editor</a></li>
<li><a href="http://bluegriffon.org/">BlueGriffon</a> (HTML editor)</li>
<li><a href="http://cargocollective.com/">Cargo Collective</a> (creative publishing platform)</li>
<li><a href="http://clickhelp.co/">ClickHelp</a> (technical writing tool)</li>
<li><a href="http://complete-ly.appspot.com/playground/code.playground.html">Complete.ly playground</a></li>
<li><a href="http://drupal.org/project/cpn">Code per Node</a> (Drupal module)</li>
<li><a href="http://www.codebugapp.com/">Codebug</a> (PHP Xdebug front-end)</li>
<li><a href="https://github.com/angelozerr/CodeMirror-Eclipse">CodeMirror Eclipse</a> (embed CM in Eclipse)</li>
<li><a href="http://emmet.io/blog/codemirror-movie/">CodeMirror movie</a> (scripted editing demos)</li>
<li><a href="http://code.google.com/p/codemirror2-gwt/">CodeMirror2-GWT</a> (Google Web Toolkit wrapper)</li>
<li><a href="http://www.crunchzilla.com/code-monster">Code Monster</a> & <a href="http://www.crunchzilla.com/code-maven">Code Maven</a> (learning environment)</li>
<li><a href="http://codepen.io">Codepen</a> (gallery of animations)</li>
<li><a href="http://sasstwo.codeschool.com/levels/1/challenges/1">Code School</a> (online tech learning environment)</li>
<li><a href="http://code-snippets.bungeshea.com/">Code Snippets</a> (WordPress snippet management plugin)</li>
<li><a href="http://antonmi.github.io/code_together/">Code together</a> (collaborative editing)</li>
<li><a href="http://codev.it/">Codev</a> (collaborative IDE)</li>
<li><a href="http://www.codezample.com">CodeZample</a> (code snippet sharing)</li>
<li><a href="http://codio.com">Codio</a> (Web IDE)</li>
<li><a href="http://ot.substance.io/demo/">Collaborative CodeMirror demo</a> (CodeMirror + operational transforms)</li>
<li><a href="http://www.communitycodecamp.com/">Community Code Camp</a> (code snippet sharing)</li>
<li><a href="http://www.compilejava.net/">compilejava.net</a> (online Java sandbox)</li>
<li><a href="http://www.ckwnc.com/">CKWNC</a> (UML editor)</li>
<li><a href="http://www.crudzilla.com/">Crudzilla</a> (self-hosted web IDE)</li>
<li><a href="http://cssdeck.com/">CSSDeck</a> (CSS showcase)</li>
<li><a href="http://ireneros.com/deck/deck.js-codemirror/introduction/#textarea-code">Deck.js integration</a> (slides with editors)</li>
<li><a href="http://www.dbninja.com">DbNinja</a> (MySQL access interface)</li>
<li><a href="https://chat.echoplex.us/">Echoplexus</a> (chat and collaborative coding)</li>
<li><a href="http://elm-lang.org/Examples.elm">Elm language examples</a></li>
<li><a href="http://eloquentjavascript.net/chapter1.html">Eloquent JavaScript</a> (book)</li>
<li><a href="http://emmet.io">Emmet</a> (fast XML editing)</li>
<li><a href="http://www.fastfig.com/">Fastfig</a> (online computation/math tool)</li>
<li><a href="https://metacpan.org/module/Farabi">Farabi</a> (modern Perl IDE)</li>
<li><a href="http://blog.pamelafox.org/2012/02/interactive-html5-slides-with-fathomjs.html">FathomJS integration</a> (slides with editors, again)</li>
<li><a href="http://fiddlesalad.com/">Fiddle Salad</a> (web development environment)</li>
<li><a href="http://www.firepad.io">Firepad</a> (collaborative text editor)</li>
<li><a href="https://code.google.com/p/gerrit/">Gerrit</a>'s diff view</a></li>
<li><a href="http://tour.golang.org">Go language tour</a></li>
<li><a href="https://github.com/github/android">GitHub's Android app</a></li>
<li><a href="https://script.google.com/">Google Apps Script</a></li>
<li><a href="http://web.uvic.ca/~siefkenj/graphit/graphit.html">Graphit</a> (function graphing)</li>
<li><a href="http://www.handcraft.com/">Handcraft</a> (HTML prototyping)</li>
<li><a href="http://try.haxe.org">Haxe</a> (Haxe Playground) </li>
<li><a href="http://haxpad.com/">HaxPad</a> (editor for Win RT)</li>
<li><a href="http://megafonweblab.github.com/histone-javascript/">Histone template engine playground</a></li>
<li><a href="http://icecoder.net">ICEcoder</a> (web IDE)</li>
<li><a href="http://www.janvas.com/">Janvas</a> (vector graphics editor)</li>
<li><a href="http://extensions.joomla.org/extensions/edition/editors/8723">Joomla plugin</a></li>
<li><a href="http://jqfundamentals.com/">jQuery fundamentals</a> (interactive tutorial)</li>
<li><a href="http://jsbin.com">jsbin.com</a> (JS playground)</li>
<li><a href="http://jsfiddle.com">jsfiddle.com</a> (another JS playground)</li>
<li><a href="http://www.jshint.com/">JSHint</a> (JS linter)</li>
<li><a href="http://jumpseller.com/">Jumpseller</a> (online store builder)</li>
<li><a href="http://kl1p.com/cmtest/1">kl1p</a> (paste service)</li>
<li><a href="http://www.chris-granger.com/2012/04/12/light-table---a-new-ide-concept/">Light Table</a> (experimental IDE)</li>
<li><a href="http://liveweave.com/">Liveweave</a> (HTML/CSS/JS scratchpad)</li>
<li><a href="http://marklighteditor.com/">Marklight editor</a> (lightweight markup editor)</li>
<li><a href="http://www.mergely.com/">Mergely</a> (interactive diffing)</li>
<li><a href="http://www.iunbug.com/mihtool">MIHTool</a> (iOS web-app debugging tool)</li>
<li><a href="http://mongo-mapreduce-webbrowser.opensagres.cloudbees.net/">Mongo MapReduce WebBrowser</a></li>
<li><a href="http://mvcplayground.apphb.com/">MVC Playground</a></li>
<li><a href="https://www.my2ndgeneration.com/">My2ndGeneration</a> (social coding)</li>
<li><a href="http://www.navigatecms.com">Navigate CMS</a></li>
<li><a href="https://github.com/soliton4/nodeMirror">nodeMirror</a> (IDE project)</li>
<li><a href="https://notex.ch">NoTex</a> (rST authoring)</li>
<li><a href="http://oakoutliner.com">Oak</a> (online outliner)</li>
<li><a href="http://clrhome.org/asm/">ORG</a> (z80 assembly IDE)</li>
<li><a href="https://github.com/mamacdon/orion-codemirror">Orion-CodeMirror integration</a> (running CodeMirror modes in Orion)</li>
<li><a href="http://paperjs.org/">Paper.js</a> (graphics scripting)</li>
<li><a href="http://prinbit.com/">PrinBit</a> (collaborative coding tool)</li>
<li><a href="http://prose.io/">Prose.io</a> (github content editor)</li>
<li><a href="http://www.puzzlescript.net/">Puzzlescript</a> (puzzle game engine)</li>
<li><a href="http://ql.io/">ql.io</a> (http API query helper)</li>
<li><a href="http://qyapp.com">QiYun web app platform</a></li>
<li><a href="http://ariya.ofilabs.com/2011/09/hybrid-webnative-desktop-codemirror.html">Qt+Webkit integration</a> (building a desktop CodeMirror app)</li>
<li><a href="http://www.quivive-file-manager.com">Quivive File Manager</a></li>
<li><a href="http://rascalmicro.com/docs/basic-tutorial-getting-started.html">Rascal</a> (tiny computer)</li>
<li><a href="https://www.realtime.io/">RealTime.io</a> (Internet-of-Things infrastructure)</li>
<li><a href="https://www.shadertoy.com/">Shadertoy</a> (shader sharing)</li>
<li><a href="http://www.sketchpatch.net/labs/livecodelabIntro.html">sketchPatch Livecodelab</a></li>
<li><a href="http://www.skulpt.org/">Skulpt</a> (in-browser Python environment)</li>
<li><a href="http://snippets.pro/">Snippets.pro</a> (code snippet sharing)</li>
<li><a href="http://www.solidshops.com/">SolidShops</a> (hosted e-commerce platform)</li>
<li><a href="http://sqlfiddle.com">SQLFiddle</a> (SQL playground)</li>
<li><a href="https://thefiletree.com">The File Tree</a> (collab editor)</li>
<li><a href="http://www.mapbox.com/tilemill/">TileMill</a> (map design tool)</li>
<li><a href="http://www.toolsverse.com/products/data-explorer/">Toolsverse Data Explorer</a> (database management)</li>
<li><a href="http://enjalot.com/tributary/2636296/sinwaves.js">Tributary</a> (augmented editing)</li>
<li><a href="http://blog.englard.net/post/39608000629/codeintumblr">Tumblr code highlighting shim</a></li>
<li><a href="http://turbopy.com/">TurboPY</a> (web publishing framework)</li>
<li><a href="http://uicod.com/">uiCod</a> (animation demo gallery and sharing)</li>
<li><a href="http://cruise.eecs.uottawa.ca/umpleonline/">UmpleOnline</a> (model-oriented programming tool)</li>
<li><a href="https://upsource.jetbrains.com/#idea/view/923f30395f2603cd9f42a32bcafd13b6c28de0ff/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/ReplaceAbstractClassInstanceByMapIntention.java">Upsource</a> (code viewer)</li>
<li><a href="https://github.com/brettz9/webappfind">webappfind</a> (windows file bindings for webapps)</li>
<li><a href="http://www.webglacademy.com/">WebGL academy</a> (learning WebGL)</li>
<li><a href="http://webglplayground.net/">WebGL playground</a></li>
<li><a href="https://www.webkit.org/blog/2518/state-of-web-inspector/#source-code">WebKit Web inspector</a></li>
<li><a href="http://www.wescheme.org/">WeScheme</a> (learning tool)</li>
<li><a href="http://wordpress.org/extend/plugins/codemirror-for-codeeditor/">WordPress plugin</a></li>
<li><a href="http://www.xosystem.org/home/applications_websites/xosystem_website/xoside_EN.php">XOSide</a> (online editor)</li>
<li><a href="http://videlibri.sourceforge.net/cgi-bin/xidelcgi">XQuery tester</a></li>
<li><a href="http://q42jaap.github.io/xsd2codemirror/">xsd2codemirror</a> (convert XSD to CM XML completion info)</li>
</ul>
</article>

View File

@@ -1,790 +0,0 @@
<!doctype html>
<title>CodeMirror: Release History</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="docs.css">
<script src="activebookmark.js"></script>
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active data-default="true" href="#v3">Version 3.x</a>
<li><a href="#v2">Version 2.x</a>
<li><a href="#v1">Version 0.x</a>
</ul>
</div>
<article>
<h2>Release notes and version history</h2>
<section id=v3 class=first>
<h2>Version 3.x</h2>
<p class="rel">21-11-2013: <a href="http://codemirror.net/codemirror-3.20.zip">Version 3.20</a>:</p>
<ul class="rel-note">
<li>New modes: <a href="../mode/julia/index.html">Julia</a> and <a href="../mode/pegjs/index.html">PEG.js</a>.</li>
<li>Support ECMAScript 6 in the <a href="../mode/javascript/index.html">JavaScript mode</a>.</li>
<li>Improved indentation for the <a href="../mode/coffeescript/index.html">CoffeeScript mode</a>.</li>
<li>Make non-printable-character representation <a href="manual.html#option_specialChars">configurable</a>.</li>
<li>Add notification functionality to <a href="manual.html#addon_dialog">dialog</a> addon.</li>
<li>Full <a href="https://github.com/marijnh/CodeMirror/compare/3.19.0...3.20.0">list of patches</a>.</li>
</ul>
<p class="rel">21-10-2013: <a href="http://codemirror.net/codemirror-3.19.zip">Version 3.19</a>:</p>
<ul class="rel-note">
<li>New modes: <a href="../mode/eiffel/index.html">Eiffel</a>, <a href="../mode/gherkin/index.html">Gherkin</a>, <a href="../mode/sql/?mime=text/x-mssql">MSSQL dialect</a>.</li>
<li>New addons: <a href="manual.html#addon_hardwrap">hardwrap</a>, <a href="manual.html#addon_sql-hint">sql-hint</a>.</li>
<li>New theme: <a href="../demo/theme.html?mbo">MBO</a>.</li>
<li>Add <a href="manual.html#token_style_line">support</a> for line-level styling from mode tokenizers.</li>
<li>Full <a href="https://github.com/marijnh/CodeMirror/compare/3.18.0...3.19.0">list of patches</a>.</li>
</ul>
<p class="rel">23-09-2013: <a href="http://codemirror.net/codemirror-3.18.zip">Version 3.18</a>:</p>
<p class="rel-note">Emergency release to fix a problem in 3.17
where <code>.setOption("lineNumbers", false)</code> would raise an
error.</p>
<p class="rel">23-09-2013: <a href="http://codemirror.net/codemirror-3.17.zip">Version 3.17</a>:</p>
<ul class="rel-note">
<li>New modes: <a href="../mode/fortran/index.html">Fortran</a>, <a href="../mode/octave/index.html">Octave</a> (Matlab), <a href="../mode/toml/index.html">TOML</a>, and <a href="../mode/dtd/index.html">DTD</a>.</li>
<li>New addons: <a href="../addon/lint/css-lint.js"><code>css-lint</code></a>, <a href="manual.html#addon_css-hint"><code>css-hint</code></a>.</li>
<li>Improve resilience to CSS 'frameworks' that globally mess up <code>box-sizing</code>.</li>
<li>Full <a href="https://github.com/marijnh/CodeMirror/compare/3.16.0...3.17.0">list of patches</a>.</li>
</ul>
<p class="rel">21-08-2013: <a href="http://codemirror.net/codemirror-3.16.zip">Version 3.16</a>:</p>
<ul class="rel-note">
<li>The whole codebase is now under a single <a href="../LICENSE">license</a> file.</li>
<li>The project page was overhauled and redesigned.</li>
<li>New themes: <a href="../demo/theme.html?paraiso-dark">Paraiso</a> (<a href="../demo/theme.html?paraiso-light">light</a>), <a href="../demo/theme.html?the-matrix">The Matrix</a>.</li>
<li>Improved interaction between themes and <a href="manual.html#addon_active-line">active-line</a>/<a href="manual.html#addon_matchbrackets">matchbrackets</a> addons.</li>
<li>New <a href="manual.html#addon_foldcode">folding</a> function <code>CodeMirror.fold.comment</code>.</li>
<li>Added <a href="manual.html#addon_fullscreen">fullscreen</a> addon.</li>
<li>Full <a href="https://github.com/marijnh/CodeMirror/compare/3.15.0...3.16.0">list of patches</a>.</li>
</ul>
<p class="rel">29-07-2013: <a href="http://codemirror.net/codemirror-3.15.zip">Version 3.15</a>:</p>
<ul class="rel-note">
<li>New modes: <a href="../mode/jade/index.html">Jade</a>, <a href="../mode/nginx/index.html">Nginx</a>.</li>
<li>New addons: <a href="../demo/tern.html">Tern</a>, <a href="manual.html#addon_matchtags">matchtags</a>, and <a href="manual.html#addon_foldgutter">foldgutter</a>.</li>
<li>Introduced <a href="manual.html#getHelper"><em>helper</em></a> concept (<a href="https://groups.google.com/forum/#!msg/codemirror/cOc0xvUUEUU/nLrX1-qnidgJ">context</a>).</li>
<li>New method: <a href="manual.html#getModeAt"><code>getModeAt</code></a>.</li>
<li>New themes: base16 <a href="../demo/theme.html?base16-dark">dark</a>/<a href="../demo/theme.html?base16-light">light</a>, 3024 <a href="../demo/theme.html?3024-night">dark</a>/<a href="../demo/theme.html?3024-day">light</a>, <a href="../demo/theme.html?tomorrow-night-eighties">tomorrow-night</a>.</li>
<li>Full <a href="https://github.com/marijnh/CodeMirror/compare/3.14.0...3.15.0">list of patches</a>.</li>
</ul>
<p class="rel">20-06-2013: <a href="http://codemirror.net/codemirror-3.14.zip">Version 3.14</a>:</p>
<ul class="rel-note">
<li>New
addons: <a href="manual.html#addon_trailingspace">trailing
space highlight</a>, <a href="manual.html#addon_xml-hint">XML
completion</a> (rewritten),
and <a href="manual.html#addon_merge">diff merging</a>.</li>
<li><a href="manual.html#markText"><code>markText</code></a>
and <a href="manual.html#addLineWidget"><code>addLineWidget</code></a>
now take a <code>handleMouseEvents</code> option.</li>
<li>New methods: <a href="manual.html#lineAtHeight"><code>lineAtHeight</code></a>,
<a href="manual.html#getTokenTypeAt"><code>getTokenTypeAt</code></a>.</li>
<li>More precise cleanness-tracking
using <a href="manual.html#changeGeneration"><code>changeGeneration</code></a>
and <a href="manual.html#isClean"><code>isClean</code></a>.</li>
<li>Many extensions to <a href="../demo/emacs.html">Emacs</a> mode
(prefixes, more navigation units, and more).</li>
<li>New
events <a href="manual.html#event_keyHandled"><code>"keyHandled"</code></a>
and <a href="manual.html#event_inputRead"><code>"inputRead"</code></a>.</li>
<li>Various improvements to <a href="../mode/ruby/index.html">Ruby</a>,
<a href="../mode/smarty/index.html">Smarty</a>, <a href="../mode/sql/index.html">SQL</a>,
and <a href="../demo/vim.html">Vim</a> modes.</li>
<li>Full <a href="https://github.com/marijnh/CodeMirror/compare/3.13.0...3.14.0">list of patches</a>.</li>
</ul>
<p class="rel">20-05-2013: <a href="http://codemirror.net/codemirror-3.13.zip">Version 3.13</a>:</p>
<ul class="rel-note">
<li>New modes: <a href="../mode/cobol/index.html">COBOL</a> and <a href="../mode/haml/index.html">HAML</a>.</li>
<li>New options: <a href="manual.html#option_cursorScrollMargin"><code>cursorScrollMargin</code></a> and <a href="manual.html#option_coverGutterNextToScrollbar"><code>coverGutterNextToScrollbar</code></a>.</li>
<li>New addon: <a href="manual.html#addon_comment">commenting</a>.</li>
<li>More features added to the <a href="../demo/vim.html">Vim keymap</a>.</li>
<li>Full <a href="https://github.com/marijnh/CodeMirror/compare/v3.12...3.13.0">list of patches</a>.</li>
</ul>
<p class="rel">19-04-2013: <a href="http://codemirror.net/codemirror-3.12.zip">Version 3.12</a>:</p>
<ul class="rel-note">
<li>New mode: <a href="../mode/gas/index.html">GNU assembler</a>.</li>
<li>New
options: <a href="manual.html#option_maxHighlightLength"><code>maxHighlightLength</code></a>
and <a href="manual.html#option_historyEventDelay"><code>historyEventDelay</code></a>.</li>
<li>Added <a href="manual.html#mark_addToHistory"><code>addToHistory</code></a>
option for <code>markText</code>.</li>
<li>Various fixes to JavaScript tokenization and indentation corner cases.</li>
<li>Further improvements to the vim mode.</li>
<li>Full <a href="https://github.com/marijnh/CodeMirror/compare/v3.11...v3.12">list of patches</a>.</li>
</ul>
<p class="rel">20-03-2013: <a href="http://codemirror.net/codemirror-3.11.zip">Version 3.11</a>:</p>
<ul class="rel-note">
<li><strong>Removed code:</strong> <code>collapserange</code>,
<code>formatting</code>, and <code>simple-hint</code>
addons. <code>plsql</code> and <code>mysql</code> modes
(use <a href="../mode/sql/index.html"><code>sql</code></a> mode).</li>
<li><strong>Moved code:</strong> the range-finding functions for folding now have <a href="../addon/fold/">their own files</a>.</li>
<li><strong>Changed interface:</strong>
the <a href="manual.html#addon_continuecomment"><code>continuecomment</code></a>
addon now exposes an option, rather than a command.</li>
<li>New
modes: <a href="../mode/css/scss.html">SCSS</a>, <a href="../mode/tcl/index.html">Tcl</a>, <a href="../mode/livescript/index.html">LiveScript</a>,
and <a href="../mode/mirc/index.html">mIRC</a>.</li>
<li>New addons: <a href="../demo/placeholder.html"><code>placeholder</code></a>, <a href="../demo/html5complete.html">HTML completion</a>.</li>
<li>New
methods: <a href="manual.html#hasFocus"><code>hasFocus</code></a>, <a href="manual.html#defaultCharWidth"><code>defaultCharWidth</code></a>.</li>
<li>New events: <a href="manual.html#event_beforeCursorEnter"><code>beforeCursorEnter</code></a>, <a href="manual.html#event_renderLine"><code>renderLine</code></a>.</li>
<li>Many improvements to the <a href="manual.html#addon_show-hint"><code>show-hint</code></a> completion
dialog addon.</li>
<li>Tweak behavior of by-word cursor motion.</li>
<li>Further improvements to the <a href="../demo/vim.html">vim mode</a>.</li>
<li>Full <a href="https://github.com/marijnh/CodeMirror/compare/v3.1...v3.11">list of patches</a>.</li>
</ul>
<p class="rel">21-02-2013: <a href="http://codemirror.net/codemirror-3.1.zip">Version 3.1</a>:</p>
<ul class="rel-note">
<li><strong>Incompatible:</strong> key handlers may
now <em>return</em>, rather
than <em>throw</em> <code>CodeMirror.Pass</code> to signal they
didn't handle the key.</li>
<li>Make documents a <a href="manual.html#api_doc">first-class
construct</a>, support split views and subviews.</li>
<li>Add a <a href="manual.html#addon_show-hint">new module</a>
for showing completion hints.
Deprecate <code>simple-hint.js</code>.</li>
<li>Extend <a href="../mode/htmlmixed/index.html">htmlmixed mode</a>
to allow custom handling of script types.</li>
<li>Support an <code>insertLeft</code> option
to <a href="manual.html#setBookmark"><code>setBookmark</code></a>.</li>
<li>Add an <a href="manual.html#eachLine"><code>eachLine</code></a>
method to iterate over a document.</li>
<li>New addon modules: <a href="../demo/markselection.html">selection
marking</a>, <a href="../demo/lint.html">linting</a>,
and <a href="../demo/closebrackets.html">automatic bracket
closing</a>.</li>
<li>Add <a href="manual.html#event_beforeChange"><code>"beforeChange"</code></a>
and <a href="manual.html#event_beforeSelectionChange"><code>"beforeSelectionChange"</code></a>
events.</li>
<li>Add <a href="manual.html#event_hide"><code>"hide"</code></a>
and <a href="manual.html#event_unhide"><code>"unhide"</code></a>
events to marked ranges.</li>
<li>Fix <a href="manual.html#coordsChar"><code>coordsChar</code></a>'s
interpretation of its argument to match the documentation.</li>
<li>New modes: <a href="../mode/turtle/index.html">Turtle</a>
and <a href="../mode/q/index.html">Q</a>.</li>
<li>Further improvements to the <a href="../demo/vim.html">vim mode</a>.</li>
<li>Full <a href="https://github.com/marijnh/CodeMirror/compare/v3.01...v3.1">list of patches</a>.</li>
</ul>
<p class="rel">25-01-2013: <a href="http://codemirror.net/codemirror-3.02.zip">Version 3.02</a>:</p>
<p class="rel-note">Single-bugfix release. Fixes a problem that
prevents CodeMirror instances from being garbage-collected after
they become unused.</p>
<p class="rel">21-01-2013: <a href="http://codemirror.net/codemirror-3.01.zip">Version 3.01</a>:</p>
<ul class="rel-note">
<li>Move all add-ons into an organized directory structure
under <a href="../addon/"><code>/addon</code></a>. <strong>You might have to adjust your
paths.</strong></li>
<li>New
modes: <a href="../mode/d/index.html">D</a>, <a href="../mode/sass/index.html">Sass</a>, <a href="../mode/apl/index.html">APL</a>, <a href="../mode/sql/index.html">SQL</a>
(configurable), and <a href="../mode/asterisk/index.html">Asterisk</a>.</li>
<li>Several bugfixes in right-to-left text support.</li>
<li>Add <a href="manual.html#option_rtlMoveVisually"><code>rtlMoveVisually</code></a> option.</li>
<li>Improvements to vim keymap.</li>
<li>Add built-in (lightweight) <a href="manual.html#addOverlay">overlay mode</a> support.</li>
<li>Support <code>showIfHidden</code> option for <a href="manual.html#addLineWidget">line widgets</a>.</li>
<li>Add simple <a href="manual.html#addon_python-hint">Python hinter</a>.</li>
<li>Bring back the <a href="manual.html#option_fixedGutter"><code>fixedGutter</code></a> option.</li>
<li>Full <a href="https://github.com/marijnh/CodeMirror/compare/v3.0...v3.01">list of patches</a>.</li>
</ul>
<p class="rel">10-12-2012: <a href="http://codemirror.net/codemirror-3.0.zip">Version 3.0</a>:</p>
<p class="rel-note"><strong>New major version</strong>. Only
partially backwards-compatible. See
the <a href="upgrade_v3.html">upgrading guide</a> for more
information. Changes since release candidate 2:</p>
<ul class="rel-note">
<li>Rewritten VIM mode.</li>
<li>Fix a few minor scrolling and sizing issues.</li>
<li>Work around Safari segfault when dragging.</li>
<li>Full <a href="https://github.com/marijnh/CodeMirror/compare/v3.0rc2...v3.0">list of patches</a>.</li>
</ul>
<p class="rel">20-11-2012: <a href="http://codemirror.net/codemirror-3.0rc2.zip">Version 3.0, release candidate 2</a>:</p>
<ul class="rel-note">
<li>New mode: <a href="../mode/http/index.html">HTTP</a>.</li>
<li>Improved handling of selection anchor position.</li>
<li>Improve IE performance on longer lines.</li>
<li>Reduce gutter glitches during horiz. scrolling.</li>
<li>Add <a href="manual.html#addKeyMap"><code>addKeyMap</code></a> and <a href="manual.html#removeKeyMap"><code>removeKeyMap</code></a> methods.</li>
<li>Rewrite <code>formatting</code> and <code>closetag</code> add-ons.</li>
<li>Full <a href="https://github.com/marijnh/CodeMirror/compare/v3.0rc1...v3.0rc2">list of patches</a>.</li>
</ul>
<p class="rel">20-11-2012: <a href="http://codemirror.net/codemirror-3.0rc1.zip">Version 3.0, release candidate 1</a>:</p>
<ul class="rel-note">
<li>New theme: <a href="../demo/theme.html?solarized%20light">Solarized</a>.</li>
<li>Introduce <a href="manual.html#addLineClass"><code>addLineClass</code></a>
and <a href="manual.html#removeLineClass"><code>removeLineClass</code></a>,
drop <code>setLineClass</code>.</li>
<li>Add a <em>lot</em> of
new <a href="manual.html#markText">options for marked text</a>
(read-only, atomic, collapsed, widget replacement).</li>
<li>Remove the old code folding interface in favour of these new ranges.</li>
<li>Add <a href="manual.html#isClean"><code>isClean</code></a>/<a href="manual.html#markClean"><code>markClean</code></a> methods.</li>
<li>Remove <code>compoundChange</code> method, use better undo-event-combining heuristic.</li>
<li>Improve scrolling performance smoothness.</li>
<li>Full <a href="https://github.com/marijnh/CodeMirror/compare/v3.0beta2...v3.0rc1">list of patches</a>.</li>
</ul>
<p class="rel">22-10-2012: <a href="http://codemirror.net/codemirror-3.0beta2.zip">Version 3.0, beta 2</a>:</p>
<ul class="rel-note">
<li>Fix page-based coordinate computation.</li>
<li>Fix firing of <a href="manual.html#event_gutterClick"><code>gutterClick</code></a> event.</li>
<li>Add <a href="manual.html#option_cursorHeight"><code>cursorHeight</code></a> option.</li>
<li>Fix bi-directional text regression.</li>
<li>Add <a href="manual.html#option_viewportMargin"><code>viewportMargin</code></a> option.</li>
<li>Directly handle mousewheel events (again, hopefully better).</li>
<li>Make vertical cursor movement more robust (through widgets, big line gaps).</li>
<li>Add <a href="manual.html#option_flattenSpans"><code>flattenSpans</code></a> option.</li>
<li>Many optimizations. Poor responsiveness should be fixed.</li>
<li>Initialization in hidden state works again.</li>
<li>Full <a href="https://github.com/marijnh/CodeMirror/compare/v3.0beta1...v3.0beta2">list of patches</a>.</li>
</ul>
<p class="rel">19-09-2012: <a href="http://codemirror.net/codemirror-3.0beta1.zip">Version 3.0, beta 1</a>:</p>
<ul class="rel-note">
<li>Bi-directional text support.</li>
<li>More powerful gutter model.</li>
<li>Support for arbitrary text/widget height.</li>
<li>In-line widgets.</li>
<li>Generalized event handling.</li>
</ul>
</section>
<section id=v2>
<h2>Version 2.x</h2>
<p class="rel">21-01-2013: <a href="http://codemirror.net/codemirror-2.38.zip">Version 2.38</a>:</p>
<p class="rel-note">Integrate some bugfixes, enhancements to the vim keymap, and new
modes
(<a href="../mode/d/index.html">D</a>, <a href="../mode/sass/index.html">Sass</a>, <a href="../mode/apl/index.html">APL</a>)
from the v3 branch.</p>
<p class="rel">20-12-2012: <a href="http://codemirror.net/codemirror-2.37.zip">Version 2.37</a>:</p>
<ul class="rel-note">
<li>New mode: <a href="../mode/sql/index.html">SQL</a> (will replace <a href="../mode/plsql/index.html">plsql</a> and <a href="../mode/mysql/index.html">mysql</a> modes).</li>
<li>Further work on the new VIM mode.</li>
<li>Fix Cmd/Ctrl keys on recent Operas on OS X.</li>
<li>Full <a href="https://github.com/marijnh/CodeMirror/compare/v2.36...v2.37">list of patches</a>.</li>
</ul>
<p class="rel">20-11-2012: <a href="http://codemirror.net/codemirror-2.36.zip">Version 2.36</a>:</p>
<ul class="rel-note">
<li>New mode: <a href="../mode/z80/index.html">Z80 assembly</a>.</li>
<li>New theme: <a href="../demo/theme.html?twilight">Twilight</a>.</li>
<li>Add command-line compression helper.</li>
<li>Make <a href="manual.html#scrollIntoView"><code>scrollIntoView</code></a> public.</li>
<li>Add <a href="manual.html#defaultTextHeight"><code>defaultTextHeight</code></a> method.</li>
<li>Various extensions to the vim keymap.</li>
<li>Make <a href="../mode/php/index.html">PHP mode</a> build on <a href="../mode/htmlmixed/index.html">mixed HTML mode</a>.</li>
<li>Add <a href="manual.html#addon_continuecomment">comment-continuing</a> add-on.</li>
<li>Full <a href="../https://github.com/marijnh/CodeMirror/compare/v2.35...v2.36">list of patches</a>.</li>
</ul>
<p class="rel">22-10-2012: <a href="http://codemirror.net/codemirror-2.35.zip">Version 2.35</a>:</p>
<ul class="rel-note">
<li>New (sub) mode: <a href="../mode/javascript/typescript.html">TypeScript</a>.</li>
<li>Don't overwrite (insert key) when pasting.</li>
<li>Fix several bugs in <a href="manual.html#markText"><code>markText</code></a>/undo interaction.</li>
<li>Better indentation of JavaScript code without semicolons.</li>
<li>Add <a href="manual.html#defineInitHook"><code>defineInitHook</code></a> function.</li>
<li>Full <a href="https://github.com/marijnh/CodeMirror/compare/v2.34...v2.35">list of patches</a>.</li>
</ul>
<p class="rel">19-09-2012: <a href="http://codemirror.net/codemirror-2.34.zip">Version 2.34</a>:</p>
<ul class="rel-note">
<li>New mode: <a href="../mode/commonlisp/index.html">Common Lisp</a>.</li>
<li>Fix right-click select-all on most browsers.</li>
<li>Change the way highlighting happens:<br>&nbsp; Saves memory and CPU cycles.<br>&nbsp; <code>compareStates</code> is no longer needed.<br>&nbsp; <code>onHighlightComplete</code> no longer works.</li>
<li>Integrate mode (Markdown, XQuery, CSS, sTex) tests in central testsuite.</li>
<li>Add a <a href="manual.html#version"><code>CodeMirror.version</code></a> property.</li>
<li>More robust handling of nested modes in <a href="../demo/formatting.html">formatting</a> and <a href="../demo/closetag.html">closetag</a> plug-ins.</li>
<li>Un/redo now preserves <a href="manual.html#markText">marked text</a> and bookmarks.</li>
<li><a href="https://github.com/marijnh/CodeMirror/compare/v2.33...v2.34">Full list</a> of patches.</li>
</ul>
<p class="rel">23-08-2012: <a href="http://codemirror.net/codemirror-2.33.zip">Version 2.33</a>:</p>
<ul class="rel-note">
<li>New mode: <a href="../mode/sieve/index.html">Sieve</a>.</li>
<li>New <a href="manual.html#getViewport"><code>getViewPort</code></a> and <a href="manual.html#option_onViewportChange"><code>onViewportChange</code></a> API.</li>
<li><a href="manual.html#option_cursorBlinkRate">Configurable</a> cursor blink rate.</li>
<li>Make binding a key to <code>false</code> disabling handling (again).</li>
<li>Show non-printing characters as red dots.</li>
<li>More tweaks to the scrolling model.</li>
<li>Expanded testsuite. Basic linter added.</li>
<li>Remove most uses of <code>innerHTML</code>. Remove <code>CodeMirror.htmlEscape</code>.</li>
<li><a href="https://github.com/marijnh/CodeMirror/compare/v2.32...v2.33">Full list</a> of patches.</li>
</ul>
<p class="rel">23-07-2012: <a href="http://codemirror.net/codemirror-2.32.zip">Version 2.32</a>:</p>
<p class="rel-note">Emergency fix for a bug where an editor with
line wrapping on IE will break when there is <em>no</em>
scrollbar.</p>
<p class="rel">20-07-2012: <a href="http://codemirror.net/codemirror-2.31.zip">Version 2.31</a>:</p>
<ul class="rel-note">
<li>New modes: <a href="../mode/ocaml/index.html">OCaml</a>, <a href="../mode/haxe/index.html">Haxe</a>, and <a href="../mode/vb/index.html">VB.NET</a>.</li>
<li>Several fixes to the new scrolling model.</li>
<li>Add a <a href="manual.html#setSize"><code>setSize</code></a> method for programmatic resizing.</li>
<li>Add <a href="manual.html#getHistory"><code>getHistory</code></a> and <a href="manual.html#setHistory"><code>setHistory</code></a> methods.</li>
<li>Allow custom line separator string in <a href="manual.html#getValue"><code>getValue</code></a> and <a href="manual.html#getRange"><code>getRange</code></a>.</li>
<li>Support double- and triple-click drag, double-clicking whitespace.</li>
<li>And more... <a href="https://github.com/marijnh/CodeMirror/compare/v2.3...v2.31">(all patches)</a></li>
</ul>
<p class="rel">22-06-2012: <a href="http://codemirror.net/codemirror-2.3.zip">Version 2.3</a>:</p>
<ul class="rel-note">
<li><strong>New scrollbar implementation</strong>. Should flicker less. Changes DOM structure of the editor.</li>
<li>New theme: <a href="../demo/theme.html?vibrant-ink">vibrant-ink</a>.</li>
<li>Many extensions to the VIM keymap (including text objects).</li>
<li>Add <a href="../demo/multiplex.html">mode-multiplexing</a> utility script.</li>
<li>Fix bug where right-click paste works in read-only mode.</li>
<li>Add a <a href="manual.html#getScrollInfo"><code>getScrollInfo</code></a> method.</li>
<li>Lots of other <a href="https://github.com/marijnh/CodeMirror/compare/v2.25...v2.3">fixes</a>.</li>
</ul>
<p class="rel">23-05-2012: <a href="http://codemirror.net/codemirror-2.25.zip">Version 2.25</a>:</p>
<ul class="rel-note">
<li>New mode: <a href="../mode/erlang/index.html">Erlang</a>.</li>
<li><strong>Remove xmlpure mode</strong> (use <a href="../mode/xml/index.html">xml.js</a>).</li>
<li>Fix line-wrapping in Opera.</li>
<li>Fix X Windows middle-click paste in Chrome.</li>
<li>Fix bug that broke pasting of huge documents.</li>
<li>Fix backspace and tab key repeat in Opera.</li>
</ul>
<p class="rel">23-04-2012: <a href="http://codemirror.net/codemirror-2.24.zip">Version 2.24</a>:</p>
<ul class="rel-note">
<li><strong>Drop support for Internet Explorer 6</strong>.</li>
<li>New
modes: <a href="../mode/shell/index.html">Shell</a>, <a href="../mode/tiki/index.html">Tiki
wiki</a>, <a href="../mode/pig/index.html">Pig Latin</a>.</li>
<li>New themes: <a href="../demo/theme.html?ambiance">Ambiance</a>, <a href="../demo/theme.html?blackboard">Blackboard</a>.</li>
<li>More control over drag/drop
with <a href="manual.html#option_dragDrop"><code>dragDrop</code></a>
and <a href="manual.html#option_onDragEvent"><code>onDragEvent</code></a>
options.</li>
<li>Make HTML mode a bit less pedantic.</li>
<li>Add <a href="manual.html#compoundChange"><code>compoundChange</code></a> API method.</li>
<li>Several fixes in undo history and line hiding.</li>
<li>Remove (broken) support for <code>catchall</code> in key maps,
add <code>nofallthrough</code> boolean field instead.</li>
</ul>
<p class="rel">26-03-2012: <a href="http://codemirror.net/codemirror-2.23.zip">Version 2.23</a>:</p>
<ul class="rel-note">
<li>Change <strong>default binding for tab</strong> <a href="javascript:void(document.getElementById('tabbinding').style.display='')">[more]</a>
<div style="display: none" id=tabbinding>
Starting in 2.23, these bindings are default:
<ul><li>Tab: Insert tab character</li>
<li>Shift-tab: Reset line indentation to default</li>
<li>Ctrl/Cmd-[: Reduce line indentation (old tab behaviour)</li>
<li>Ctrl/Cmd-]: Increase line indentation (old shift-tab behaviour)</li>
</ul>
</div>
</li>
<li>New modes: <a href="../mode/xquery/index.html">XQuery</a> and <a href="../mode/vbscript/index.html">VBScript</a>.</li>
<li>Two new themes: <a href="../mode/less/index.html">lesser-dark</a> and <a href="../mode/xquery/index.html">xq-dark</a>.</li>
<li>Differentiate between background and text styles in <a href="manual.html#setLineClass"><code>setLineClass</code></a>.</li>
<li>Fix drag-and-drop in IE9+.</li>
<li>Extend <a href="manual.html#charCoords"><code>charCoords</code></a>
and <a href="manual.html#cursorCoords"><code>cursorCoords</code></a> with a <code>mode</code> argument.</li>
<li>Add <a href="manual.html#option_autofocus"><code>autofocus</code></a> option.</li>
<li>Add <a href="manual.html#findMarksAt"><code>findMarksAt</code></a> method.</li>
</ul>
<p class="rel">27-02-2012: <a href="http://codemirror.net/codemirror-2.22.zip">Version 2.22</a>:</p>
<ul class="rel-note">
<li>Allow <a href="manual.html#keymaps">key handlers</a> to pass up events, allow binding characters.</li>
<li>Add <a href="manual.html#option_autoClearEmptyLines"><code>autoClearEmptyLines</code></a> option.</li>
<li>Properly use tab stops when rendering tabs.</li>
<li>Make PHP mode more robust.</li>
<li>Support indentation blocks in <a href="manual.html#addon_foldcode">code folder</a>.</li>
<li>Add a script for <a href="manual.html#addon_match-highlighter">highlighting instances of the selection</a>.</li>
<li>New <a href="../mode/properties/index.html">.properties</a> mode.</li>
<li>Fix many bugs.</li>
</ul>
<p class="rel">27-01-2012: <a href="http://codemirror.net/codemirror-2.21.zip">Version 2.21</a>:</p>
<ul class="rel-note">
<li>Added <a href="../mode/less/index.html">LESS</a>, <a href="../mode/mysql/index.html">MySQL</a>,
<a href="../mode/go/index.html">Go</a>, and <a href="../mode/verilog/index.html">Verilog</a> modes.</li>
<li>Add <a href="manual.html#option_smartIndent"><code>smartIndent</code></a>
option.</li>
<li>Support a cursor in <a href="manual.html#option_readOnly"><code>readOnly</code></a>-mode.</li>
<li>Support assigning multiple styles to a token.</li>
<li>Use a new approach to drawing the selection.</li>
<li>Add <a href="manual.html#scrollTo"><code>scrollTo</code></a> method.</li>
<li>Allow undo/redo events to span non-adjacent lines.</li>
<li>Lots and lots of bugfixes.</li>
</ul>
<p class="rel">20-12-2011: <a href="http://codemirror.net/codemirror-2.2.zip">Version 2.2</a>:</p>
<ul class="rel-note">
<li>Slightly incompatible API changes. Read <a href="upgrade_v2.2.html">this</a>.</li>
<li>New approach
to <a href="manual.html#option_extraKeys">binding</a> keys,
support for <a href="manual.html#option_keyMap">custom
bindings</a>.</li>
<li>Support for overwrite (insert).</li>
<li><a href="manual.html#option_tabSize">Custom-width</a>
and <a href="../demo/visibletabs.html">stylable</a> tabs.</li>
<li>Moved more code into <a href="manual.html#addons">add-on scripts</a>.</li>
<li>Support for sane vertical cursor movement in wrapped lines.</li>
<li>More reliable handling of
editing <a href="manual.html#markText">marked text</a>.</li>
<li>Add minimal <a href="../demo/emacs.html">emacs</a>
and <a href="../demo/vim.html">vim</a> bindings.</li>
<li>Rename <code>coordsFromIndex</code>
to <a href="manual.html#posFromIndex"><code>posFromIndex</code></a>,
add <a href="manual.html#indexFromPos"><code>indexFromPos</code></a>
method.</li>
</ul>
<p class="rel">21-11-2011: <a href="http://codemirror.net/codemirror-2.18.zip">Version 2.18</a>:</p>
<p class="rel-note">Fixes <code>TextMarker.clear</code>, which is broken in 2.17.</p>
<p class="rel">21-11-2011: <a href="http://codemirror.net/codemirror-2.17.zip">Version 2.17</a>:</p>
<ul class="rel-note">
<li>Add support for <a href="manual.html#option_lineWrapping">line
wrapping</a> and <a href="manual.html#hideLine">code
folding</a>.</li>
<li>Add <a href="../mode/gfm/index.html">Github-style Markdown</a> mode.</li>
<li>Add <a href="../theme/monokai.css">Monokai</a>
and <a href="../theme/rubyblue.css">Rubyblue</a> themes.</li>
<li>Add <a href="manual.html#setBookmark"><code>setBookmark</code></a> method.</li>
<li>Move some of the demo code into reusable components
under <a href="../addon/"><code>lib/util</code></a>.</li>
<li>Make screen-coord-finding code faster and more reliable.</li>
<li>Fix drag-and-drop in Firefox.</li>
<li>Improve support for IME.</li>
<li>Speed up content rendering.</li>
<li>Fix browser's built-in search in Webkit.</li>
<li>Make double- and triple-click work in IE.</li>
<li>Various fixes to modes.</li>
</ul>
<p class="rel">27-10-2011: <a href="http://codemirror.net/codemirror-2.16.zip">Version 2.16</a>:</p>
<ul class="rel-note">
<li>Add <a href="../mode/perl/index.html">Perl</a>, <a href="../mode/rust/index.html">Rust</a>, <a href="../mode/tiddlywiki/index.html">TiddlyWiki</a>, and <a href="../mode/groovy/index.html">Groovy</a> modes.</li>
<li>Dragging text inside the editor now moves, rather than copies.</li>
<li>Add a <a href="manual.html#coordsFromIndex"><code>coordsFromIndex</code></a> method.</li>
<li><strong>API change</strong>: <code>setValue</code> now no longer clears history. Use <a href="manual.html#clearHistory"><code>clearHistory</code></a> for that.</li>
<li><strong>API change</strong>: <a href="manual.html#markText"><code>markText</code></a> now
returns an object with <code>clear</code> and <code>find</code>
methods. Marked text is now more robust when edited.</li>
<li>Fix editing code with tabs in Internet Explorer.</li>
</ul>
<p class="rel">26-09-2011: <a href="http://codemirror.net/codemirror-2.15.zip">Version 2.15</a>:</p>
<p class="rel-note">Fix bug that snuck into 2.14: Clicking the
character that currently has the cursor didn't re-focus the
editor.</p>
<p class="rel">26-09-2011: <a href="http://codemirror.net/codemirror-2.14.zip">Version 2.14</a>:</p>
<ul class="rel-note">
<li>Add <a href="../mode/clojure/index.html">Clojure</a>, <a href="../mode/pascal/index.html">Pascal</a>, <a href="../mode/ntriples/index.html">NTriples</a>, <a href="../mode/jinja2/index.html">Jinja2</a>, and <a href="../mode/markdown/index.html">Markdown</a> modes.</li>
<li>Add <a href="../theme/cobalt.css">Cobalt</a> and <a href="../theme/eclipse.css">Eclipse</a> themes.</li>
<li>Add a <a href="manual.html#option_fixedGutter"><code>fixedGutter</code></a> option.</li>
<li>Fix bug with <code>setValue</code> breaking cursor movement.</li>
<li>Make gutter updates much more efficient.</li>
<li>Allow dragging of text out of the editor (on modern browsers).</li>
</ul>
<p class="rel">23-08-2011: <a href="http://codemirror.net/codemirror-2.13.zip">Version 2.13</a>:</p>
<ul class="rel-note">
<li>Add <a href="../mode/ruby/index.html">Ruby</a>, <a href="../mode/r/index.html">R</a>, <a href="../mode/coffeescript/index.html">CoffeeScript</a>, and <a href="../mode/velocity/index.html">Velocity</a> modes.</li>
<li>Add <a href="manual.html#getGutterElement"><code>getGutterElement</code></a> to API.</li>
<li>Several fixes to scrolling and positioning.</li>
<li>Add <a href="manual.html#option_smartHome"><code>smartHome</code></a> option.</li>
<li>Add an experimental <a href="../mode/xmlpure/index.html">pure XML</a> mode.</li>
</ul>
<p class="rel">25-07-2011: <a href="http://codemirror.net/codemirror-2.12.zip">Version 2.12</a>:</p>
<ul class="rel-note">
<li>Add a <a href="../mode/sparql/index.html">SPARQL</a> mode.</li>
<li>Fix bug with cursor jumping around in an unfocused editor in IE.</li>
<li>Allow key and mouse events to bubble out of the editor. Ignore widget clicks.</li>
<li>Solve cursor flakiness after undo/redo.</li>
<li>Fix block-reindent ignoring the last few lines.</li>
<li>Fix parsing of multi-line attrs in XML mode.</li>
<li>Use <code>innerHTML</code> for HTML-escaping.</li>
<li>Some fixes to indentation in C-like mode.</li>
<li>Shrink horiz scrollbars when long lines removed.</li>
<li>Fix width feedback loop bug that caused the width of an inner DIV to shrink.</li>
</ul>
<p class="rel">04-07-2011: <a href="http://codemirror.net/codemirror-2.11.zip">Version 2.11</a>:</p>
<ul class="rel-note">
<li>Add a <a href="../mode/scheme/index.html">Scheme mode</a>.</li>
<li>Add a <code>replace</code> method to search cursors, for cursor-preserving replacements.</li>
<li>Make the <a href="../mode/clike/index.html">C-like mode</a> mode more customizable.</li>
<li>Update XML mode to spot mismatched tags.</li>
<li>Add <code>getStateAfter</code> API and <code>compareState</code> mode API methods for finer-grained mode magic.</li>
<li>Add a <code>getScrollerElement</code> API method to manipulate the scrolling DIV.</li>
<li>Fix drag-and-drop for Firefox.</li>
<li>Add a C# configuration for the <a href="../mode/clike/index.html">C-like mode</a>.</li>
<li>Add <a href="../demo/fullscreen.html">full-screen editing</a> and <a href="../demo/changemode.html">mode-changing</a> demos.</li>
</ul>
<p class="rel">07-06-2011: <a href="http://codemirror.net/codemirror-2.1.zip">Version 2.1</a>:</p>
<p class="rel-note">Add
a <a href="manual.html#option_theme">theme</a> system
(<a href="../demo/theme.html">demo</a>). Note that this is not
backwards-compatible—you'll have to update your styles and
modes!</p>
<p class="rel">07-06-2011: <a href="http://codemirror.net/codemirror-2.02.zip">Version 2.02</a>:</p>
<ul class="rel-note">
<li>Add a <a href="../mode/lua/index.html">Lua mode</a>.</li>
<li>Fix reverse-searching for a regexp.</li>
<li>Empty lines can no longer break highlighting.</li>
<li>Rework scrolling model (the outer wrapper no longer does the scrolling).</li>
<li>Solve horizontal jittering on long lines.</li>
<li>Add <a href="../demo/runmode.html">runmode.js</a>.</li>
<li>Immediately re-highlight text when typing.</li>
<li>Fix problem with 'sticking' horizontal scrollbar.</li>
</ul>
<p class="rel">26-05-2011: <a href="http://codemirror.net/codemirror-2.01.zip">Version 2.01</a>:</p>
<ul class="rel-note">
<li>Add a <a href="../mode/smalltalk/index.html">Smalltalk mode</a>.</li>
<li>Add a <a href="../mode/rst/index.html">reStructuredText mode</a>.</li>
<li>Add a <a href="../mode/python/index.html">Python mode</a>.</li>
<li>Add a <a href="../mode/plsql/index.html">PL/SQL mode</a>.</li>
<li><code>coordsChar</code> now works</li>
<li>Fix a problem where <code>onCursorActivity</code> interfered with <code>onChange</code>.</li>
<li>Fix a number of scrolling and mouse-click-position glitches.</li>
<li>Pass information about the changed lines to <code>onChange</code>.</li>
<li>Support cmd-up/down on OS X.</li>
<li>Add triple-click line selection.</li>
<li>Don't handle shift when changing the selection through the API.</li>
<li>Support <code>"nocursor"</code> mode for <code>readOnly</code> option.</li>
<li>Add an <code>onHighlightComplete</code> option.</li>
<li>Fix the context menu for Firefox.</li>
</ul>
<p class="rel">28-03-2011: <a href="http://codemirror.net/codemirror-2.0.zip">Version 2.0</a>:</p>
<p class="rel-note">CodeMirror 2 is a complete rewrite that's
faster, smaller, simpler to use, and less dependent on browser
quirks. See <a href="internals.html">this</a>
and <a href="http://groups.google.com/group/codemirror/browse_thread/thread/5a8e894024a9f580">this</a>
for more information.</p>
<p class="rel">22-02-2011: <a href="https://github.com/marijnh/codemirror/tree/beta2">Version 2.0 beta 2</a>:</p>
<p class="rel-note">Somewhat more mature API, lots of bugs shaken out.</p>
<p class="rel">17-02-2011: <a href="http://codemirror.net/codemirror-0.94.zip">Version 0.94</a>:</p>
<ul class="rel-note">
<li><code>tabMode: "spaces"</code> was modified slightly (now indents when something is selected).</li>
<li>Fixes a bug that would cause the selection code to break on some IE versions.</li>
<li>Disabling spell-check on WebKit browsers now works.</li>
</ul>
<p class="rel">08-02-2011: <a href="http://codemirror.net/">Version 2.0 beta 1</a>:</p>
<p class="rel-note">CodeMirror 2 is a complete rewrite of
CodeMirror, no longer depending on an editable frame.</p>
<p class="rel">19-01-2011: <a href="http://codemirror.net/codemirror-0.93.zip">Version 0.93</a>:</p>
<ul class="rel-note">
<li>Added a <a href="contrib/regex/index.html">Regular Expression</a> parser.</li>
<li>Fixes to the PHP parser.</li>
<li>Support for regular expression in search/replace.</li>
<li>Add <code>save</code> method to instances created with <code>fromTextArea</code>.</li>
<li>Add support for MS T-SQL in the SQL parser.</li>
<li>Support use of CSS classes for highlighting brackets.</li>
<li>Fix yet another hang with line-numbering in hidden editors.</li>
</ul>
</section>
<section id=v1>
<h2>Version 0.x</h2>
<p class="rel">28-03-2011: <a href="http://codemirror.net/codemirror-1.0.zip">Version 1.0</a>:</p>
<ul class="rel-note">
<li>Fix error when debug history overflows.</li>
<li>Refine handling of C# verbatim strings.</li>
<li>Fix some issues with JavaScript indentation.</li>
</ul>
<p class="rel">17-12-2010: <a href="http://codemirror.net/codemirror-0.92.zip">Version 0.92</a>:</p>
<ul class="rel-note">
<li>Make CodeMirror work in XHTML documents.</li>
<li>Fix bug in handling of backslashes in Python strings.</li>
<li>The <code>styleNumbers</code> option is now officially
supported and documented.</li>
<li><code>onLineNumberClick</code> option added.</li>
<li>More consistent names <code>onLoad</code> and
<code>onCursorActivity</code> callbacks. Old names still work, but
are deprecated.</li>
<li>Add a <a href="contrib/freemarker/index.html">Freemarker</a> mode.</li>
</ul>
<p class="rel">11-11-2010: <a
href="http://codemirror.net/codemirror-0.91.zip">Version 0.91</a>:</p>
<ul class="rel-note">
<li>Adds support for <a href="contrib/java">Java</a>.</li>
<li>Small additions to the <a href="contrib/php">PHP</a> and <a href="contrib/sql">SQL</a> parsers.</li>
<li>Work around various <a href="https://bugs.webkit.org/show_bug.cgi?id=47806">Webkit</a> <a href="https://bugs.webkit.org/show_bug.cgi?id=23474">issues</a>.</li>
<li>Fix <code>toTextArea</code> to update the code in the textarea.</li>
<li>Add a <code>noScriptCaching</code> option (hack to ease development).</li>
<li>Make sub-modes of <a href="mixedtest.html">HTML mixed</a> mode configurable.</li>
</ul>
<p class="rel">02-10-2010: <a
href="http://codemirror.net/codemirror-0.9.zip">Version 0.9</a>:</p>
<ul class="rel-note">
<li>Add support for searching backwards.</li>
<li>There are now parsers for <a href="contrib/scheme/index.html">Scheme</a>, <a href="contrib/xquery/index.html">XQuery</a>, and <a href="contrib/ometa/index.html">OmetaJS</a>.</li>
<li>Makes <code>height: "dynamic"</code> more robust.</li>
<li>Fixes bug where paste did not work on OS X.</li>
<li>Add a <code>enterMode</code> and <code>electricChars</code> options to make indentation even more customizable.</li>
<li>Add <code>firstLineNumber</code> option.</li>
<li>Fix bad handling of <code>@media</code> rules by the CSS parser.</li>
<li>Take a new, more robust approach to working around the invisible-last-line bug in WebKit.</li>
</ul>
<p class="rel">22-07-2010: <a
href="http://codemirror.net/codemirror-0.8.zip">Version 0.8</a>:</p>
<ul class="rel-note">
<li>Add a <code>cursorCoords</code> method to find the screen
coordinates of the cursor.</li>
<li>A number of fixes and support for more syntax in the PHP parser.</li>
<li>Fix indentation problem with JSON-mode JS parser in Webkit.</li>
<li>Add a <a href="compress.html">minification</a> UI.</li>
<li>Support a <code>height: dynamic</code> mode, where the editor's
height will adjust to the size of its content.</li>
<li>Better support for IME input mode.</li>
<li>Fix JavaScript parser getting confused when seeing a no-argument
function call.</li>
<li>Have CSS parser see the difference between selectors and other
identifiers.</li>
<li>Fix scrolling bug when pasting in a horizontally-scrolled
editor.</li>
<li>Support <code>toTextArea</code> method in instances created with
<code>fromTextArea</code>.</li>
<li>Work around new Opera cursor bug that causes the cursor to jump
when pressing backspace at the end of a line.</li>
</ul>
<p class="rel">27-04-2010: <a
href="http://codemirror.net/codemirror-0.67.zip">Version
0.67</a>:</p>
<p class="rel-note">More consistent page-up/page-down behaviour
across browsers. Fix some issues with hidden editors looping forever
when line-numbers were enabled. Make PHP parser parse
<code>"\\"</code> correctly. Have <code>jumpToLine</code> work on
line handles, and add <code>cursorLine</code> function to fetch the
line handle where the cursor currently is. Add new
<code>setStylesheet</code> function to switch style-sheets in a
running editor.</p>
<p class="rel">01-03-2010: <a
href="http://codemirror.net/codemirror-0.66.zip">Version
0.66</a>:</p>
<p class="rel-note">Adds <code>removeLine</code> method to API.
Introduces the <a href="contrib/plsql/index.html">PLSQL parser</a>.
Marks XML errors by adding (rather than replacing) a CSS class, so
that they can be disabled by modifying their style. Fixes several
selection bugs, and a number of small glitches.</p>
<p class="rel">12-11-2009: <a
href="http://codemirror.net/codemirror-0.65.zip">Version
0.65</a>:</p>
<p class="rel-note">Add support for having both line-wrapping and
line-numbers turned on, make paren-highlighting style customisable
(<code>markParen</code> and <code>unmarkParen</code> config
options), work around a selection bug that Opera
<em>re</em>introduced in version 10.</p>
<p class="rel">23-10-2009: <a
href="http://codemirror.net/codemirror-0.64.zip">Version
0.64</a>:</p>
<p class="rel-note">Solves some issues introduced by the
paste-handling changes from the previous release. Adds
<code>setSpellcheck</code>, <code>setTextWrapping</code>,
<code>setIndentUnit</code>, <code>setUndoDepth</code>,
<code>setTabMode</code>, and <code>setLineNumbers</code> to
customise a running editor. Introduces an <a
href="contrib/sql/index.html">SQL</a> parser. Fixes a few small
problems in the <a href="contrib/python/index.html">Python</a>
parser. And, as usual, add workarounds for various newly discovered
browser incompatibilities.</p>
<p class="rel"><em>31-08-2009</em>: <a href="http://codemirror.net/codemirror-0.63.zip">Version 0.63</a>:</p>
<p class="rel-note"> Overhaul of paste-handling (less fragile), fixes for several
serious IE8 issues (cursor jumping, end-of-document bugs) and a number
of small problems.</p>
<p class="rel"><em>30-05-2009</em>: <a href="http://codemirror.net/codemirror-0.62.zip">Version 0.62</a>:</p>
<p class="rel-note">Introduces <a href="contrib/python/index.html">Python</a>
and <a href="contrib/lua/index.html">Lua</a> parsers. Add
<code>setParser</code> (on-the-fly mode changing) and
<code>clearHistory</code> methods. Make parsing passes time-based
instead of lines-based (see the <code>passTime</code> option).</p>
</section>
</article>

View File

@@ -1,61 +0,0 @@
<!doctype html>
<title>CodeMirror: Reporting Bugs</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="docs.css">
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#">Reporting bugs</a>
</ul>
</div>
<article>
<h2>Reporting bugs effectively</h2>
<div class="left">
<p>So you found a problem in CodeMirror. By all means, report it! Bug
reports from users are the main drive behind improvements to
CodeMirror. But first, please read over these points:</p>
<ol>
<li>CodeMirror is maintained by volunteers. They don't owe you
anything, so be polite. Reports with an indignant or belligerent
tone tend to be moved to the bottom of the pile.</li>
<li>Include information about <strong>the browser in which the
problem occurred</strong>. Even if you tested several browsers, and
the problem occurred in all of them, mention this fact in the bug
report. Also include browser version numbers and the operating
system that you're on.</li>
<li>Mention which release of CodeMirror you're using. Preferably,
try also with the current development snapshot, to ensure the
problem has not already been fixed.</li>
<li>Mention very precisely what went wrong. "X is broken" is not a
good bug report. What did you expect to happen? What happened
instead? Describe the exact steps a maintainer has to take to make
the problem occur. We can not fix something that we can not
observe.</li>
<li>If the problem can not be reproduced in any of the demos
included in the CodeMirror distribution, please provide an HTML
document that demonstrates the problem. The best way to do this is
to go to <a href="http://jsbin.com/ihunin/edit">jsbin.com</a>, enter
it there, press save, and include the resulting link in your bug
report.</li>
</ol>
</div>
</article>

View File

@@ -1,96 +0,0 @@
<!doctype html>
<title>CodeMirror: Version 2.2 upgrade guide</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="docs.css">
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#">2.2 upgrade guide</a>
</ul>
</div>
<article>
<h2>Upgrading to v2.2</h2>
<p>There are a few things in the 2.2 release that require some care
when upgrading.</p>
<h3>No more default.css</h3>
<p>The default theme is now included
in <a href="../lib/codemirror.css"><code>codemirror.css</code></a>, so
you do not have to included it separately anymore. (It was tiny, so
even if you're not using it, the extra data overhead is negligible.)
<h3>Different key customization</h3>
<p>CodeMirror has moved to a system
where <a href="manual.html#option_keyMap">keymaps</a> are used to
bind behavior to keys. This means <a href="../demo/emacs.html">custom
bindings</a> are now possible.</p>
<p>Three options that influenced key
behavior, <code>tabMode</code>, <code>enterMode</code>,
and <code>smartHome</code>, are no longer supported. Instead, you can
provide custom bindings to influence the way these keys act. This is
done through the
new <a href="manual.html#option_extraKeys"><code>extraKeys</code></a>
option, which can hold an object mapping key names to functionality. A
simple example would be:</p>
<pre> extraKeys: {
"Ctrl-S": function(instance) { saveText(instance.getValue()); },
"Ctrl-/": "undo"
}</pre>
<p>Keys can be mapped either to functions, which will be given the
editor instance as argument, or to strings, which are mapped through
functions through the <code>CodeMirror.commands</code> table, which
contains all the built-in editing commands, and can be inspected and
extended by external code.</p>
<p>By default, the <code>Home</code> key is bound to
the <code>"goLineStartSmart"</code> command, which moves the cursor to
the first non-whitespace character on the line. You can set do this to
make it always go to the very start instead:</p>
<pre> extraKeys: {"Home": "goLineStart"}</pre>
<p>Similarly, <code>Enter</code> is bound
to <code>"newlineAndIndent"</code> by default. You can bind it to
something else to get different behavior. To disable special handling
completely and only get a newline character inserted, you can bind it
to <code>false</code>:</p>
<pre> extraKeys: {"Enter": false}</pre>
<p>The same works for <code>Tab</code>. If you don't want CodeMirror
to handle it, bind it to <code>false</code>. The default behaviour is
to indent the current line more (<code>"indentMore"</code> command),
and indent it less when shift is held (<code>"indentLess"</code>).
There are also <code>"indentAuto"</code> (smart indent)
and <code>"insertTab"</code> commands provided for alternate
behaviors. Or you can write your own handler function to do something
different altogether.</p>
<h3>Tabs</h3>
<p>Handling of tabs changed completely. The display width of tabs can
now be set with the <code>tabSize</code> option, and tabs can
be <a href="../demo/visibletabs.html">styled</a> by setting CSS rules
for the <code>cm-tab</code> class.</p>
<p>The default width for tabs is now 4, as opposed to the 8 that is
hard-wired into browsers. If you are relying on 8-space tabs, make
sure you explicitly set <code>tabSize: 8</code> in your options.</p>
</article>

View File

@@ -1,230 +0,0 @@
<!doctype html>
<title>CodeMirror: Version 3 upgrade guide</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="docs.css">
<script src="../lib/codemirror.js"></script>
<link rel="stylesheet" href="../lib/codemirror.css">
<script src="../addon/runmode/runmode.js"></script>
<script src="../addon/runmode/colorize.js"></script>
<script src="../mode/javascript/javascript.js"></script>
<script src="../mode/xml/xml.js"></script>
<script src="../mode/css/css.js"></script>
<script src="../mode/htmlmixed/htmlmixed.js"></script>
<script src="activebookmark.js"></script>
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#upgrade">Upgrade guide</a>
<li><a href="#dom">DOM structure</a></li>
<li><a href="#gutters">Gutter model</a></li>
<li><a href="#events">Event handling</a></li>
<li><a href="#marktext">markText method arguments</a></li>
<li><a href="#folding">Line folding</a></li>
<li><a href="#lineclass">Line CSS classes</a></li>
<li><a href="#positions">Position properties</a></li>
<li><a href="#matchbrackets">Bracket matching</a></li>
<li><a href="#modes">Mode management</a></li>
<li><a href="#new">New features</a></li>
</ul>
</div>
<article>
<h2 id=upgrade>Upgrading to version 3</h2>
<p>Version 3 does not depart too much from 2.x API, and sites that use
CodeMirror in a very simple way might be able to upgrade without
trouble. But it does introduce a number of incompatibilities. Please
at least skim this text before upgrading.</p>
<p>Note that <strong>version 3 drops full support for Internet
Explorer 7</strong>. The editor will mostly work on that browser, but
it'll be significantly glitchy.</p>
<section id=dom>
<h2>DOM structure</h2>
<p>This one is the most likely to cause problems. The internal
structure of the editor has changed quite a lot, mostly to implement a
new scrolling model.</p>
<p>Editor height is now set on the outer wrapper element (CSS
class <code>CodeMirror</code>), not on the scroller element
(<code>CodeMirror-scroll</code>).</p>
<p>Other nodes were moved, dropped, and added. If you have any code
that makes assumptions about the internal DOM structure of the editor,
you'll have to re-test it and probably update it to work with v3.</p>
<p>See the <a href="manual.html#styling">styling section</a> of the
manual for more information.</p>
</section>
<section id=gutters>
<h2>Gutter model</h2>
<p>In CodeMirror 2.x, there was a single gutter, and line markers
created with <code>setMarker</code> would have to somehow coexist with
the line numbers (if present). Version 3 allows you to specify an
array of gutters, <a href="manual.html#option_gutters">by class
name</a>,
use <a href="manual.html#setGutterMarker"><code>setGutterMarker</code></a>
to add or remove markers in individual gutters, and clear whole
gutters
with <a href="manual.html#clearGutter"><code>clearGutter</code></a>.
Gutter markers are now specified as DOM nodes, rather than HTML
snippets.</p>
<p>The gutters no longer horizontally scrolls along with the content.
The <code>fixedGutter</code> option was removed (since it is now the
only behavior).</p>
<pre data-lang="text/html">
&lt;style>
/* Define a gutter style */
.note-gutter { width: 3em; background: cyan; }
&lt;/style>
&lt;script>
// Create an instance with two gutters -- line numbers and notes
var cm = new CodeMirror(document.body, {
gutters: ["note-gutter", "CodeMirror-linenumbers"],
lineNumbers: true
});
// Add a note to line 0
cm.setGutterMarker(0, "note-gutter", document.createTextNode("hi"));
&lt;/script>
</pre>
</section>
<section id=events>
<h2>Event handling</h2>
<p>Most of the <code>onXYZ</code> options have been removed. The same
effect is now obtained by calling
the <a href="manual.html#on"><code>on</code></a> method with a string
identifying the event type. Multiple handlers can now be registered
(and individually unregistered) for an event, and objects such as line
handlers now also expose events. See <a href="manual.html#events">the
full list here</a>.</p>
<p>(The <code>onKeyEvent</code> and <code>onDragEvent</code> options,
which act more as hooks than as event handlers, are still there in
their old form.)</p>
<pre data-lang="javascript">
cm.on("change", function(cm, change) {
console.log("something changed! (" + change.origin + ")");
});
</pre>
</section>
<section id=marktext>
<h2>markText method arguments</h2>
<p>The <a href="manual.html#markText"><code>markText</code></a> method
(which has gained some interesting new features, such as creating
atomic and read-only spans, or replacing spans with widgets) no longer
takes the CSS class name as a separate argument, but makes it an
optional field in the options object instead.</p>
<pre data-lang="javascript">
// Style first ten lines, and forbid the cursor from entering them
cm.markText({line: 0, ch: 0}, {line: 10, ch: 0}, {
className: "magic-text",
inclusiveLeft: true,
atomic: true
});
</pre>
</section>
<section id=folding>
<h2>Line folding</h2>
<p>The interface for hiding lines has been
removed. <a href="manual.html#markText"><code>markText</code></a> can
now be used to do the same in a more flexible and powerful way.</p>
<p>The <a href="../demo/folding.html">folding script</a> has been
updated to use the new interface, and should now be more robust.</p>
<pre data-lang="javascript">
// Fold a range, replacing it with the text "??"
var range = cm.markText({line: 4, ch: 2}, {line: 8, ch: 1}, {
replacedWith: document.createTextNode("??"),
// Auto-unfold when cursor moves into the range
clearOnEnter: true
});
// Get notified when auto-unfolding
CodeMirror.on(range, "clear", function() {
console.log("boom");
});
</pre>
</section>
<section id=lineclass>
<h2>Line CSS classes</h2>
<p>The <code>setLineClass</code> method has been replaced
by <a href="manual.html#addLineClass"><code>addLineClass</code></a>
and <a href="manual.html#removeLineClass"><code>removeLineClass</code></a>,
which allow more modular control over the classes attached to a line.</p>
<pre data-lang="javascript">
var marked = cm.addLineClass(10, "background", "highlighted-line");
setTimeout(function() {
cm.removeLineClass(marked, "background", "highlighted-line");
});
</pre>
</section>
<section id=positions>
<h2>Position properties</h2>
<p>All methods that take or return objects that represent screen
positions now use <code>{left, top, bottom, right}</code> properties
(not always all of them) instead of the <code>{x, y, yBot}</code> used
by some methods in v2.x.</p>
<p>Affected methods
are <a href="manual.html#cursorCoords"><code>cursorCoords</code></a>, <a href="manual.html#charCoords"><code>charCoords</code></a>, <a href="manual.html#coordsChar"><code>coordsChar</code></a>,
and <a href="manual.html#getScrollInfo"><code>getScrollInfo</code></a>.</p>
</section>
<section id=matchbrackets>
<h2>Bracket matching no longer in core</h2>
<p>The <a href="manual.html#addon_matchbrackets"><code>matchBrackets</code></a>
option is no longer defined in the core editor.
Load <code>addon/edit/matchbrackets.js</code> to enable it.</p>
</section>
<section id=modes>
<h2>Mode management</h2>
<p>The <code>CodeMirror.listModes</code>
and <code>CodeMirror.listMIMEs</code> functions, used for listing
defined modes, are gone. You are now encouraged to simply
inspect <code>CodeMirror.modes</code> (mapping mode names to mode
constructors) and <code>CodeMirror.mimeModes</code> (mapping MIME
strings to mode specs).</p>
</section>
<section id=new>
<h2>New features</h2>
<p>Some more reasons to upgrade to version 3.</p>
<ul>
<li>Bi-directional text support. CodeMirror will now mostly do the
right thing when editing Arabic or Hebrew text.</li>
<li>Arbitrary line heights. Using fonts with different heights
inside the editor (whether off by one pixel or fifty) is now
supported and handled gracefully.</li>
<li>In-line widgets. See <a href="../demo/widget.html">the demo</a>
and <a href="manual.html#addLineWidget">the docs</a>.</li>
<li>Defining custom options
with <a href="manual.html#defineOption"><code>CodeMirror.defineOption</code></a>.</li>
</ul>
</section>
</article>
<script>setTimeout(function(){CodeMirror.colorize();}, 20);</script>

View File

@@ -1,51 +0,0 @@
namespace = "comment_";
(function() {
function test(name, mode, run, before, after) {
return testCM(name, function(cm) {
run(cm);
eq(cm.getValue(), after);
}, {value: before, mode: mode});
}
var simpleProg = "function foo() {\n return bar;\n}";
test("block", "javascript", function(cm) {
cm.blockComment(Pos(0, 3), Pos(3, 0), {blockCommentLead: " *"});
}, simpleProg + "\n", "/* function foo() {\n * return bar;\n * }\n */");
test("blockToggle", "javascript", function(cm) {
cm.blockComment(Pos(0, 3), Pos(2, 0), {blockCommentLead: " *"});
cm.uncomment(Pos(0, 3), Pos(2, 0), {blockCommentLead: " *"});
}, simpleProg, simpleProg);
test("line", "javascript", function(cm) {
cm.lineComment(Pos(1, 1), Pos(1, 1));
}, simpleProg, "function foo() {\n// return bar;\n}");
test("lineToggle", "javascript", function(cm) {
cm.lineComment(Pos(0, 0), Pos(2, 1));
cm.uncomment(Pos(0, 0), Pos(2, 1));
}, simpleProg, simpleProg);
test("fallbackToBlock", "css", function(cm) {
cm.lineComment(Pos(0, 0), Pos(2, 1));
}, "html {\n border: none;\n}", "/* html {\n border: none;\n} */");
test("fallbackToLine", "ruby", function(cm) {
cm.blockComment(Pos(0, 0), Pos(1));
}, "def blah()\n return hah\n", "# def blah()\n# return hah\n");
test("commentRange", "javascript", function(cm) {
cm.blockComment(Pos(1, 2), Pos(1, 13), {fullLines: false});
}, simpleProg, "function foo() {\n /*return bar;*/\n}");
test("indented", "javascript", function(cm) {
cm.lineComment(Pos(1, 0), Pos(2), {indent: true});
}, simpleProg, "function foo() {\n // return bar;\n // }");
test("singleEmptyLine", "javascript", function(cm) {
cm.setCursor(1);
cm.execCommand("toggleComment");
}, "a;\n\nb;", "a;\n// \nb;");
})();

View File

@@ -1,329 +0,0 @@
(function() {
// A minilanguage for instantiating linked CodeMirror instances and Docs
function instantiateSpec(spec, place, opts) {
var names = {}, pos = 0, l = spec.length, editors = [];
while (spec) {
var m = spec.match(/^(\w+)(\*?)(?:='([^\']*)'|<(~?)(\w+)(?:\/(\d+)-(\d+))?)\s*/);
var name = m[1], isDoc = m[2], cur;
if (m[3]) {
cur = isDoc ? CodeMirror.Doc(m[3]) : CodeMirror(place, clone(opts, {value: m[3]}));
} else {
var other = m[5];
if (!names.hasOwnProperty(other)) {
names[other] = editors.length;
editors.push(CodeMirror(place, opts));
}
var doc = editors[names[other]].linkedDoc({
sharedHist: !m[4],
from: m[6] ? Number(m[6]) : null,
to: m[7] ? Number(m[7]) : null
});
cur = isDoc ? doc : CodeMirror(place, clone(opts, {value: doc}));
}
names[name] = editors.length;
editors.push(cur);
spec = spec.slice(m[0].length);
}
return editors;
}
function clone(obj, props) {
if (!obj) return;
clone.prototype = obj;
var inst = new clone();
if (props) for (var n in props) if (props.hasOwnProperty(n))
inst[n] = props[n];
return inst;
}
function eqAll(val) {
var end = arguments.length, msg = null;
if (typeof arguments[end-1] == "string")
msg = arguments[--end];
if (i == end) throw new Error("No editors provided to eqAll");
for (var i = 1; i < end; ++i)
eq(arguments[i].getValue(), val, msg)
}
function testDoc(name, spec, run, opts, expectFail) {
if (!opts) opts = {};
return test("doc_" + name, function() {
var place = document.getElementById("testground");
var editors = instantiateSpec(spec, place, opts);
var successful = false;
try {
run.apply(null, editors);
successful = true;
} finally {
if ((debug && !successful) || verbose) {
place.style.visibility = "visible";
} else {
for (var i = 0; i < editors.length; ++i)
if (editors[i] instanceof CodeMirror)
place.removeChild(editors[i].getWrapperElement());
}
}
}, expectFail);
}
var ie_lt8 = /MSIE [1-7]\b/.test(navigator.userAgent);
function testBasic(a, b) {
eqAll("x", a, b);
a.setValue("hey");
eqAll("hey", a, b);
b.setValue("wow");
eqAll("wow", a, b);
a.replaceRange("u\nv\nw", Pos(0, 3));
b.replaceRange("i", Pos(0, 4));
b.replaceRange("j", Pos(2, 1));
eqAll("wowui\nv\nwj", a, b);
}
testDoc("basic", "A='x' B<A", testBasic);
testDoc("basicSeparate", "A='x' B<~A", testBasic);
testDoc("sharedHist", "A='ab\ncd\nef' B<A", function(a, b) {
a.replaceRange("x", Pos(0));
b.replaceRange("y", Pos(1));
a.replaceRange("z", Pos(2));
eqAll("abx\ncdy\nefz", a, b);
a.undo();
a.undo();
eqAll("abx\ncd\nef", a, b);
a.redo();
eqAll("abx\ncdy\nef", a, b);
b.redo();
eqAll("abx\ncdy\nefz", a, b);
a.undo(); b.undo(); a.undo(); a.undo();
eqAll("ab\ncd\nef", a, b);
}, null, ie_lt8);
testDoc("undoIntact", "A='ab\ncd\nef' B<~A", function(a, b) {
a.replaceRange("x", Pos(0));
b.replaceRange("y", Pos(1));
a.replaceRange("z", Pos(2));
a.replaceRange("q", Pos(0));
eqAll("abxq\ncdy\nefz", a, b);
a.undo();
a.undo();
eqAll("abx\ncdy\nef", a, b);
b.undo();
eqAll("abx\ncd\nef", a, b);
a.redo();
eqAll("abx\ncd\nefz", a, b);
a.redo();
eqAll("abxq\ncd\nefz", a, b);
a.undo(); a.undo(); a.undo(); a.undo();
eqAll("ab\ncd\nef", a, b);
b.redo();
eqAll("ab\ncdy\nef", a, b);
});
testDoc("undoConflict", "A='ab\ncd\nef' B<~A", function(a, b) {
a.replaceRange("x", Pos(0));
a.replaceRange("z", Pos(2));
// This should clear the first undo event in a, but not the second
b.replaceRange("y", Pos(0));
a.undo(); a.undo();
eqAll("abxy\ncd\nef", a, b);
a.replaceRange("u", Pos(2));
a.replaceRange("v", Pos(0));
// This should clear both events in a
b.replaceRange("w", Pos(0));
a.undo(); a.undo();
eqAll("abxyvw\ncd\nefu", a, b);
});
testDoc("doubleRebase", "A='ab\ncd\nef\ng' B<~A C<B", function(a, b, c) {
c.replaceRange("u", Pos(3));
a.replaceRange("", Pos(0, 0), Pos(1, 0));
c.undo();
eqAll("cd\nef\ng", a, b, c);
});
testDoc("undoUpdate", "A='ab\ncd\nef' B<~A", function(a, b) {
a.replaceRange("x", Pos(2));
b.replaceRange("u\nv\nw\n", Pos(0, 0));
a.undo();
eqAll("u\nv\nw\nab\ncd\nef", a, b);
a.redo();
eqAll("u\nv\nw\nab\ncd\nefx", a, b);
a.undo();
eqAll("u\nv\nw\nab\ncd\nef", a, b);
b.undo();
a.redo();
eqAll("ab\ncd\nefx", a, b);
a.undo();
eqAll("ab\ncd\nef", a, b);
});
testDoc("undoKeepRanges", "A='abcdefg' B<A", function(a, b) {
var m = a.markText(Pos(0, 1), Pos(0, 3), {className: "foo"});
b.replaceRange("x", Pos(0, 0));
eqPos(m.find().from, Pos(0, 2));
b.replaceRange("yzzy", Pos(0, 1), Pos(0));
eq(m.find(), null);
b.undo();
eqPos(m.find().from, Pos(0, 2));
b.undo();
eqPos(m.find().from, Pos(0, 1));
});
testDoc("longChain", "A='uv' B<A C<B D<C", function(a, b, c, d) {
a.replaceSelection("X");
eqAll("Xuv", a, b, c, d);
d.replaceRange("Y", Pos(0));
eqAll("XuvY", a, b, c, d);
});
testDoc("broadCast", "B<A C<A D<A E<A", function(a, b, c, d, e) {
b.setValue("uu");
eqAll("uu", a, b, c, d, e);
a.replaceRange("v", Pos(0, 1));
eqAll("uvu", a, b, c, d, e);
});
// A and B share a history, C and D share a separate one
testDoc("islands", "A='x\ny\nz' B<A C<~A D<C", function(a, b, c, d) {
a.replaceRange("u", Pos(0));
d.replaceRange("v", Pos(2));
b.undo();
eqAll("x\ny\nzv", a, b, c, d);
c.undo();
eqAll("x\ny\nz", a, b, c, d);
a.redo();
eqAll("xu\ny\nz", a, b, c, d);
d.redo();
eqAll("xu\ny\nzv", a, b, c, d);
});
testDoc("unlink", "B<A C<A D<B", function(a, b, c, d) {
a.setValue("hi");
b.unlinkDoc(a);
d.setValue("aye");
eqAll("hi", a, c);
eqAll("aye", b, d);
a.setValue("oo");
eqAll("oo", a, c);
eqAll("aye", b, d);
});
testDoc("bareDoc", "A*='foo' B*<A C<B", function(a, b, c) {
is(a instanceof CodeMirror.Doc);
is(b instanceof CodeMirror.Doc);
is(c instanceof CodeMirror);
eqAll("foo", a, b, c);
a.replaceRange("hey", Pos(0, 0), Pos(0));
c.replaceRange("!", Pos(0));
eqAll("hey!", a, b, c);
b.unlinkDoc(a);
b.setValue("x");
eqAll("x", b, c);
eqAll("hey!", a);
});
testDoc("swapDoc", "A='a' B*='b' C<A", function(a, b, c) {
var d = a.swapDoc(b);
d.setValue("x");
eqAll("x", c, d);
eqAll("b", a, b);
});
testDoc("docKeepsScroll", "A='x' B*='y'", function(a, b) {
addDoc(a, 200, 200);
a.scrollIntoView(Pos(199, 200));
var c = a.swapDoc(b);
a.swapDoc(c);
var pos = a.getScrollInfo();
is(pos.left > 0, "not at left");
is(pos.top > 0, "not at top");
});
testDoc("copyDoc", "A='u'", function(a) {
var copy = a.getDoc().copy(true);
a.setValue("foo");
copy.setValue("bar");
var old = a.swapDoc(copy);
eq(a.getValue(), "bar");
a.undo();
eq(a.getValue(), "u");
a.swapDoc(old);
eq(a.getValue(), "foo");
eq(old.historySize().undo, 1);
eq(old.copy(false).historySize().undo, 0);
});
testDoc("docKeepsMode", "A='1+1'", function(a) {
var other = CodeMirror.Doc("hi", "text/x-markdown");
a.setOption("mode", "text/javascript");
var old = a.swapDoc(other);
eq(a.getOption("mode"), "text/x-markdown");
eq(a.getMode().name, "markdown");
a.swapDoc(old);
eq(a.getOption("mode"), "text/javascript");
eq(a.getMode().name, "javascript");
});
testDoc("subview", "A='1\n2\n3\n4\n5' B<~A/1-3", function(a, b) {
eq(b.getValue(), "2\n3");
eq(b.firstLine(), 1);
b.setCursor(Pos(4));
eqPos(b.getCursor(), Pos(2, 1));
a.replaceRange("-1\n0\n", Pos(0, 0));
eq(b.firstLine(), 3);
eqPos(b.getCursor(), Pos(4, 1));
a.undo();
eqPos(b.getCursor(), Pos(2, 1));
b.replaceRange("oyoy\n", Pos(2, 0));
eq(a.getValue(), "1\n2\noyoy\n3\n4\n5");
b.undo();
eq(a.getValue(), "1\n2\n3\n4\n5");
});
testDoc("subviewEditOnBoundary", "A='11\n22\n33\n44\n55' B<~A/1-4", function(a, b) {
a.replaceRange("x\nyy\nz", Pos(0, 1), Pos(2, 1));
eq(b.firstLine(), 2);
eq(b.lineCount(), 2);
eq(b.getValue(), "z3\n44");
a.replaceRange("q\nrr\ns", Pos(3, 1), Pos(4, 1));
eq(b.firstLine(), 2);
eq(b.getValue(), "z3\n4q");
eq(a.getValue(), "1x\nyy\nz3\n4q\nrr\ns5");
a.execCommand("selectAll");
a.replaceSelection("!");
eqAll("!", a, b);
});
testDoc("sharedMarker", "A='ab\ncd\nef\ngh' B<A C<~A/1-2", function(a, b, c) {
var mark = b.markText(Pos(0, 1), Pos(3, 1),
{className: "cm-searching", shared: true});
var found = a.findMarksAt(Pos(0, 2));
eq(found.length, 1);
eq(found[0], mark);
eq(c.findMarksAt(Pos(1, 1)).length, 1);
eqPos(mark.find().from, Pos(0, 1));
eqPos(mark.find().to, Pos(3, 1));
b.replaceRange("x\ny\n", Pos(0, 0));
eqPos(mark.find().from, Pos(2, 1));
eqPos(mark.find().to, Pos(5, 1));
var cleared = 0;
CodeMirror.on(mark, "clear", function() {++cleared;});
b.operation(function(){mark.clear();});
eq(a.findMarksAt(Pos(3, 1)).length, 0);
eq(b.findMarksAt(Pos(3, 1)).length, 0);
eq(c.findMarksAt(Pos(3, 1)).length, 0);
eq(mark.find(), null);
eq(cleared, 1);
});
testDoc("undoInSubview", "A='line 0\nline 1\nline 2\nline 3\nline 4' B<A/1-4", function(a, b) {
b.replaceRange("x", Pos(2, 0));
a.undo();
eq(a.getValue(), "line 0\nline 1\nline 2\nline 3\nline 4");
eq(b.getValue(), "line 1\nline 2\nline 3");
});
})();

View File

@@ -1,139 +0,0 @@
var tests = [], debug = null, debugUsed = new Array(), allNames = [];
function Failure(why) {this.message = why;}
Failure.prototype.toString = function() { return this.message; };
function indexOf(collection, elt) {
if (collection.indexOf) return collection.indexOf(elt);
for (var i = 0, e = collection.length; i < e; ++i)
if (collection[i] == elt) return i;
return -1;
}
function test(name, run, expectedFail) {
// Force unique names
var originalName = name;
var i = 2; // Second function would be NAME_2
while (indexOf(allNames, name) !== -1){
name = originalName + "_" + i;
i++;
}
allNames.push(name);
// Add test
tests.push({name: name, func: run, expectedFail: expectedFail});
return name;
}
var namespace = "";
function testCM(name, run, opts, expectedFail) {
return test(namespace + name, function() {
var place = document.getElementById("testground"), cm = window.cm = CodeMirror(place, opts);
var successful = false;
try {
run(cm);
successful = true;
} finally {
if ((debug && !successful) || verbose) {
place.style.visibility = "visible";
} else {
place.removeChild(cm.getWrapperElement());
}
}
}, expectedFail);
}
function runTests(callback) {
if (debug) {
if (indexOf(debug, "verbose") === 0) {
verbose = true;
debug.splice(0, 1);
}
if (debug.length < 1) {
debug = null;
}
}
var totalTime = 0;
function step(i) {
if (i === tests.length){
running = false;
return callback("done");
}
var test = tests[i], expFail = test.expectedFail, startTime = +new Date;
if (debug !== null) {
var debugIndex = indexOf(debug, test.name);
if (debugIndex !== -1) {
// Remove from array for reporting incorrect tests later
debug.splice(debugIndex, 1);
} else {
var wildcardName = test.name.split("_")[0] + "_*";
debugIndex = indexOf(debug, wildcardName);
if (debugIndex !== -1) {
// Remove from array for reporting incorrect tests later
debug.splice(debugIndex, 1);
debugUsed.push(wildcardName);
} else {
debugIndex = indexOf(debugUsed, wildcardName);
if (debugIndex == -1) return step(i + 1);
}
}
}
var threw = false;
try {
var message = test.func();
} catch(e) {
threw = true;
if (expFail) callback("expected", test.name);
else if (e instanceof Failure) callback("fail", test.name, e.message);
else {
var pos = /(?:\bat |@).*?([^\/:]+):(\d+)/.exec(e.stack);
callback("error", test.name, e.toString() + (pos ? " (" + pos[1] + ":" + pos[2] + ")" : ""));
}
}
if (!threw) {
if (expFail) callback("fail", test.name, message || "expected failure, but succeeded");
else callback("ok", test.name, message);
}
if (!quit) { // Run next test
var delay = 0;
totalTime += (+new Date) - startTime;
if (totalTime > 500){
totalTime = 0;
delay = 50;
}
setTimeout(function(){step(i + 1);}, delay);
} else { // Quit tests
running = false;
return null;
}
}
step(0);
}
function label(str, msg) {
if (msg) return str + " (" + msg + ")";
return str;
}
function eq(a, b, msg) {
if (a != b) throw new Failure(label(a + " != " + b, msg));
}
function eqPos(a, b, msg) {
function str(p) { return "{line:" + p.line + ",ch:" + p.ch + "}"; }
if (a == b) return;
if (a == null) throw new Failure(label("comparing null to " + str(b), msg));
if (b == null) throw new Failure(label("comparing " + str(a) + " to null", msg));
if (a.line != b.line || a.ch != b.ch) throw new Failure(label(str(a) + " != " + str(b), msg));
}
function is(a, msg) {
if (!a) throw new Failure(label("assertion failed", msg));
}
function countTests() {
if (!debug) return tests.length;
var sum = 0;
for (var i = 0; i < tests.length; ++i) {
var name = tests[i].name;
if (indexOf(debug, name) != -1 ||
indexOf(debug, name.split("_")[0] + "_*") != -1)
++sum;
}
return sum;
}

View File

@@ -1,135 +0,0 @@
(function() {
"use strict";
var Pos = CodeMirror.Pos;
namespace = "emacs_";
var eventCache = {};
function fakeEvent(keyName) {
var event = eventCache[key];
if (event) return event;
var ctrl, shift, alt;
var key = keyName.replace(/\w+-/g, function(type) {
if (type == "Ctrl-") ctrl = true;
else if (type == "Alt-") alt = true;
else if (type == "Shift-") shift = true;
return "";
});
var code;
for (var c in CodeMirror.keyNames)
if (CodeMirror.keyNames[c] == key) { code = c; break; }
if (c == null) throw new Error("Unknown key: " + key);
return eventCache[keyName] = {
type: "keydown", keyCode: code, ctrlKey: ctrl, shiftKey: shift, altKey: alt,
preventDefault: function(){}, stopPropagation: function(){}
};
}
function sim(name, start /*, actions... */) {
var keys = Array.prototype.slice.call(arguments, 2);
testCM(name, function(cm) {
for (var i = 0; i < keys.length; ++i) {
var cur = keys[i];
if (cur instanceof Pos) cm.setCursor(cur);
else if (cur.call) cur(cm);
else cm.triggerOnKeyDown(fakeEvent(cur));
}
}, {keyMap: "emacs", value: start, mode: "javascript"});
}
function at(line, ch) { return function(cm) { eqPos(cm.getCursor(), Pos(line, ch)); }; }
function txt(str) { return function(cm) { eq(cm.getValue(), str); }; }
sim("motionHSimple", "abc", "Ctrl-F", "Ctrl-F", "Ctrl-B", at(0, 1));
sim("motionHMulti", "abcde",
"Ctrl-4", "Ctrl-F", at(0, 4), "Ctrl--", "Ctrl-2", "Ctrl-F", at(0, 2),
"Ctrl-5", "Ctrl-B", at(0, 0));
sim("motionHWord", "abc. def ghi",
"Alt-F", at(0, 3), "Alt-F", at(0, 8),
"Ctrl-B", "Alt-B", at(0, 5), "Alt-B", at(0, 0));
sim("motionHWordMulti", "abc. def ghi ",
"Ctrl-3", "Alt-F", at(0, 12), "Ctrl-2", "Alt-B", at(0, 5),
"Ctrl--", "Alt-B", at(0, 8));
sim("motionVSimple", "a\nb\nc\n", "Ctrl-N", "Ctrl-N", "Ctrl-P", at(1, 0));
sim("motionVMulti", "a\nb\nc\nd\ne\n",
"Ctrl-2", "Ctrl-N", at(2, 0), "Ctrl-F", "Ctrl--", "Ctrl-N", at(1, 1),
"Ctrl--", "Ctrl-3", "Ctrl-P", at(4, 1));
sim("killYank", "abc\ndef\nghi",
"Ctrl-F", "Ctrl-Space", "Ctrl-N", "Ctrl-N", "Ctrl-W", "Ctrl-E", "Ctrl-Y",
txt("ahibc\ndef\ng"));
sim("killRing", "abcdef",
"Ctrl-Space", "Ctrl-F", "Ctrl-W", "Ctrl-Space", "Ctrl-F", "Ctrl-W",
"Ctrl-Y", "Alt-Y",
txt("acdef"));
sim("copyYank", "abcd",
"Ctrl-Space", "Ctrl-E", "Alt-W", "Ctrl-Y",
txt("abcdabcd"));
sim("killLineSimple", "foo\nbar", "Ctrl-F", "Ctrl-K", txt("f\nbar"));
sim("killLineEmptyLine", "foo\n \nbar", "Ctrl-N", "Ctrl-K", txt("foo\nbar"));
sim("killLineMulti", "foo\nbar\nbaz",
"Ctrl-F", "Ctrl-F", "Ctrl-K", "Ctrl-K", "Ctrl-K", "Ctrl-A", "Ctrl-Y",
txt("o\nbarfo\nbaz"));
sim("moveByParagraph", "abc\ndef\n\n\nhij\nklm\n\n",
"Ctrl-F", "Ctrl-Down", at(2, 0), "Ctrl-Down", at(6, 0),
"Ctrl-N", "Ctrl-Up", at(3, 0), "Ctrl-Up", at(0, 0),
Pos(1, 2), "Ctrl-Down", at(2, 0), Pos(4, 2), "Ctrl-Up", at(3, 0));
sim("moveByParagraphMulti", "abc\n\ndef\n\nhij\n\nklm",
"Ctrl-U", "2", "Ctrl-Down", at(3, 0),
"Shift-Alt-.", "Ctrl-3", "Ctrl-Up", at(1, 0));
sim("moveBySentence", "sentence one! sentence\ntwo\n\nparagraph two",
"Alt-E", at(0, 13), "Alt-E", at(1, 3), "Ctrl-F", "Alt-A", at(0, 13));
sim("moveByExpr", "function foo(a, b) {}",
"Ctrl-Alt-F", at(0, 8), "Ctrl-Alt-F", at(0, 12), "Ctrl-Alt-F", at(0, 18),
"Ctrl-Alt-B", at(0, 12), "Ctrl-Alt-B", at(0, 9));
sim("moveByExprMulti", "foo bar baz bug",
"Ctrl-2", "Ctrl-Alt-F", at(0, 7),
"Ctrl--", "Ctrl-Alt-F", at(0, 4),
"Ctrl--", "Ctrl-2", "Ctrl-Alt-B", at(0, 11));
sim("delExpr", "var x = [\n a,\n b\n c\n];",
Pos(0, 8), "Ctrl-Alt-K", txt("var x = ;"), "Ctrl-/",
Pos(4, 1), "Ctrl-Alt-Backspace", txt("var x = ;"));
sim("delExprMulti", "foo bar baz",
"Ctrl-2", "Ctrl-Alt-K", txt(" baz"),
"Ctrl-/", "Ctrl-E", "Ctrl-2", "Ctrl-Alt-Backspace", txt("foo "));
sim("justOneSpace", "hi bye ",
Pos(0, 4), "Alt-Space", txt("hi bye "),
Pos(0, 4), "Alt-Space", txt("hi b ye "),
"Ctrl-A", "Alt-Space", "Ctrl-E", "Alt-Space", txt(" hi b ye "));
sim("openLine", "foo bar", "Alt-F", "Ctrl-O", txt("foo\n bar"))
sim("transposeChar", "abcd\n\ne",
"Ctrl-F", "Ctrl-T", "Ctrl-T", txt("bcad\n\ne"), at(0, 3),
"Ctrl-F", "Ctrl-T", "Ctrl-T", "Ctrl-T", txt("bcda\n\ne"), at(0, 4),
"Ctrl-F", "Ctrl-T", txt("bcd\na\ne"), at(1, 1));
sim("manipWordCase", "foo BAR bAZ",
"Alt-C", "Alt-L", "Alt-U", txt("Foo bar BAZ"),
"Ctrl-A", "Alt-U", "Alt-L", "Alt-C", txt("FOO bar Baz"));
sim("manipWordCaseMulti", "foo Bar bAz",
"Ctrl-2", "Alt-U", txt("FOO BAR bAz"),
"Ctrl-A", "Ctrl-3", "Alt-C", txt("Foo Bar Baz"));
sim("upExpr", "foo {\n bar[];\n baz(blah);\n}",
Pos(2, 7), "Ctrl-Alt-U", at(2, 5), "Ctrl-Alt-U", at(0, 4));
sim("transposeExpr", "do foo[bar] dah",
Pos(0, 6), "Ctrl-Alt-T", txt("do [bar]foo dah"));
testCM("save", function(cm) {
var saved = false;
CodeMirror.commands.save = function(cm) { saved = cm.getValue(); };
cm.triggerOnKeyDown(fakeEvent("Ctrl-X"));
cm.triggerOnKeyDown(fakeEvent("Ctrl-S"));
is(saved, "hi");
}, {value: "hi", keyMap: "emacs"});
})();

View File

@@ -1,209 +0,0 @@
<!doctype html>
<title>CodeMirror: Test Suite</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css">
<link rel="stylesheet" href="../lib/codemirror.css">
<link rel="stylesheet" href="mode_test.css">
<script src="../lib/codemirror.js"></script>
<script src="../addon/mode/overlay.js"></script>
<script src="../addon/mode/multiplex.js"></script>
<script src="../addon/search/searchcursor.js"></script>
<script src="../addon/dialog/dialog.js"></script>
<script src="../addon/edit/matchbrackets.js"></script>
<script src="../addon/comment/comment.js"></script>
<script src="../mode/javascript/javascript.js"></script>
<script src="../mode/xml/xml.js"></script>
<script src="../keymap/vim.js"></script>
<script src="../keymap/emacs.js"></script>
<style type="text/css">
.ok {color: #090;}
.fail {color: #e00;}
.error {color: #c90;}
.done {font-weight: bold;}
#progress {
background: #45d;
color: white;
text-shadow: 0 0 1px #45d, 0 0 2px #45d, 0 0 3px #45d;
font-weight: bold;
white-space: pre;
}
#testground {
visibility: hidden;
}
#testground.offscreen {
visibility: visible;
position: absolute;
left: -10000px;
top: -10000px;
}
.CodeMirror { border: 1px solid black; }
</style>
<div id=nav>
<a href="http://codemirror.net"><img id=logo src="../doc/logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="../doc/manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#">Test suite</a>
</ul>
</div>
<article>
<h2>Test Suite</h2>
<p>A limited set of programmatic sanity tests for CodeMirror.</p>
<div style="border: 1px solid black; padding: 1px; max-width: 700px;">
<div style="width: 0px;" id=progress><div style="padding: 3px;">Ran <span id="progress_ran">0</span><span id="progress_total"> of 0</span> tests</div></div>
</div>
<p id=status>Please enable JavaScript...</p>
<div id=output></div>
<div id=testground></div>
<script src="driver.js"></script>
<script src="test.js"></script>
<script src="doc_test.js"></script>
<script src="comment_test.js"></script>
<script src="mode_test.js"></script>
<script src="../mode/javascript/test.js"></script>
<script src="../mode/css/css.js"></script>
<script src="../mode/css/test.js"></script>
<script src="../mode/css/scss_test.js"></script>
<script src="../mode/xml/xml.js"></script>
<script src="../mode/htmlmixed/htmlmixed.js"></script>
<script src="../mode/ruby/ruby.js"></script>
<script src="../mode/haml/haml.js"></script>
<script src="../mode/haml/test.js"></script>
<script src="../mode/markdown/markdown.js"></script>
<script src="../mode/markdown/test.js"></script>
<script src="../mode/gfm/gfm.js"></script>
<script src="../mode/gfm/test.js"></script>
<script src="../mode/stex/stex.js"></script>
<script src="../mode/stex/test.js"></script>
<script src="../mode/xquery/xquery.js"></script>
<script src="../mode/xquery/test.js"></script>
<script src="../addon/mode/multiplex_test.js"></script>
<script src="vim_test.js"></script>
<script src="emacs_test.js"></script>
<script>
window.onload = runHarness;
CodeMirror.on(window, 'hashchange', runHarness);
function esc(str) {
return str.replace(/[<&]/, function(ch) { return ch == "<" ? "&lt;" : "&amp;"; });
}
var output = document.getElementById("output"),
progress = document.getElementById("progress"),
progressRan = document.getElementById("progress_ran").childNodes[0],
progressTotal = document.getElementById("progress_total").childNodes[0];
var count = 0,
failed = 0,
bad = "",
running = false, // Flag that states tests are running
quit = false, // Flag to quit tests ASAP
verbose = false; // Adds message for *every* test to output
function runHarness(){
if (running) {
quit = true;
setStatus("Restarting tests...", '', true);
setTimeout(function(){runHarness();}, 500);
return;
}
if (window.location.hash.substr(1)){
debug = window.location.hash.substr(1).split(",");
} else {
debug = null;
}
quit = false;
running = true;
setStatus("Loading tests...");
count = 0;
failed = 0;
bad = "";
verbose = false;
debugUsed = Array();
totalTests = countTests();
progressTotal.nodeValue = " of " + totalTests;
progressRan.nodeValue = count;
output.innerHTML = '';
document.getElementById("testground").innerHTML = "<form>" +
"<textarea id=\"code\" name=\"code\"></textarea>" +
"<input type=submit value=ok name=submit>" +
"</form>";
runTests(displayTest);
}
function setStatus(message, className, force){
if (quit && !force) return;
if (!message) throw("must provide message");
var status = document.getElementById("status").childNodes[0];
status.nodeValue = message;
status.parentNode.className = className;
}
function addOutput(name, className, code){
var newOutput = document.createElement("dl");
var newTitle = document.createElement("dt");
newTitle.className = className;
newTitle.appendChild(document.createTextNode(name));
newOutput.appendChild(newTitle);
var newMessage = document.createElement("dd");
newMessage.innerHTML = code;
newOutput.appendChild(newTitle);
newOutput.appendChild(newMessage);
output.appendChild(newOutput);
}
function displayTest(type, name, customMessage) {
var message = "???";
if (type != "done") ++count;
progress.style.width = (count * (progress.parentNode.clientWidth - 2) / totalTests) + "px";
progressRan.nodeValue = count;
if (type == "ok") {
message = "Test '" + name + "' succeeded";
if (!verbose) customMessage = false;
} else if (type == "expected") {
message = "Test '" + name + "' failed as expected";
if (!verbose) customMessage = false;
} else if (type == "error" || type == "fail") {
++failed;
message = "Test '" + name + "' failed";
} else if (type == "done") {
if (failed) {
type += " fail";
message = failed + " failure" + (failed > 1 ? "s" : "");
} else if (count < totalTests) {
failed = totalTests - count;
type += " fail";
message = failed + " failure" + (failed > 1 ? "s" : "");
} else {
type += " ok";
message = "All passed";
}
if (debug && debug.length) {
var bogusTests = totalTests - count;
message += " — " + bogusTests + " nonexistent test" +
(bogusTests > 1 ? "s" : "") + " requested by location.hash: " +
"`" + debug.join("`, `") + "`";
} else {
progressTotal.nodeValue = '';
}
customMessage = true; // Hack to avoid adding to output
}
if (verbose && !customMessage) customMessage = message;
setStatus(message, type);
if (customMessage && customMessage.length > 0) {
addOutput(name, type, customMessage);
}
}
</script>
</article>

File diff suppressed because it is too large Load Diff

View File

@@ -1,139 +0,0 @@
/*
Simple linter, based on the Acorn [1] parser module
All of the existing linters either cramp my style or have huge
dependencies (Closure). So here's a very simple, non-invasive one
that only spots
- missing semicolons and trailing commas
- variables or properties that are reserved words
- assigning to a variable you didn't declare
- access to non-whitelisted globals
(use a '// declare global: foo, bar' comment to declare extra
globals in a file)
[1]: https://github.com/marijnh/acorn/
*/
var topAllowedGlobals = Object.create(null);
("Error RegExp Number String Array Function Object Math Date undefined " +
"parseInt parseFloat Infinity NaN isNaN " +
"window document navigator prompt alert confirm console " +
"FileReader Worker postMessage importScripts " +
"setInterval clearInterval setTimeout clearTimeout " +
"CodeMirror test")
.split(" ").forEach(function(n) { topAllowedGlobals[n] = true; });
var fs = require("fs"), acorn = require("./acorn.js"), walk = require("./walk.js");
var scopePasser = walk.make({
ScopeBody: function(node, prev, c) { c(node, node.scope); }
});
function checkFile(fileName) {
var file = fs.readFileSync(fileName, "utf8"), notAllowed;
if (notAllowed = file.match(/[\x00-\x08\x0b\x0c\x0e-\x19\uFEFF\t]|[ \t]\n/)) {
var msg;
if (notAllowed[0] == "\t") msg = "Found tab character";
else if (notAllowed[0].indexOf("\n") > -1) msg = "Trailing whitespace";
else msg = "Undesirable character " + notAllowed[0].charCodeAt(0);
var info = acorn.getLineInfo(file, notAllowed.index);
fail(msg + " at line " + info.line + ", column " + info.column, {source: fileName});
}
var globalsSeen = Object.create(null);
try {
var parsed = acorn.parse(file, {
locations: true,
ecmaVersion: 3,
strictSemicolons: true,
allowTrailingCommas: false,
forbidReserved: true,
sourceFile: fileName
});
} catch (e) {
fail(e.message, {source: fileName});
return;
}
var scopes = [];
walk.simple(parsed, {
ScopeBody: function(node, scope) {
node.scope = scope;
scopes.push(scope);
}
}, walk.scopeVisitor, {vars: Object.create(null)});
var ignoredGlobals = Object.create(null);
function inScope(name, scope) {
for (var cur = scope; cur; cur = cur.prev)
if (name in cur.vars) return true;
}
function checkLHS(node, scope) {
if (node.type == "Identifier" && !(node.name in ignoredGlobals) &&
!inScope(node.name, scope)) {
ignoredGlobals[node.name] = true;
fail("Assignment to global variable", node.loc);
}
}
walk.simple(parsed, {
UpdateExpression: function(node, scope) {checkLHS(node.argument, scope);},
AssignmentExpression: function(node, scope) {checkLHS(node.left, scope);},
Identifier: function(node, scope) {
if (node.name == "arguments") return;
// Mark used identifiers
for (var cur = scope; cur; cur = cur.prev)
if (node.name in cur.vars) {
cur.vars[node.name].used = true;
return;
}
globalsSeen[node.name] = node.loc;
},
FunctionExpression: function(node) {
if (node.id) fail("Named function expression", node.loc);
}
}, scopePasser);
if (!globalsSeen.exports) {
var allowedGlobals = Object.create(topAllowedGlobals), m;
if (m = file.match(/\/\/ declare global:\s+(.*)/))
m[1].split(/,\s*/g).forEach(function(n) { allowedGlobals[n] = true; });
for (var glob in globalsSeen)
if (!(glob in allowedGlobals))
fail("Access to global variable " + glob + ". Add a '// declare global: " + glob +
"' comment or add this variable in test/lint/lint.js.", globalsSeen[glob]);
}
for (var i = 0; i < scopes.length; ++i) {
var scope = scopes[i];
for (var name in scope.vars) {
var info = scope.vars[name];
if (!info.used && info.type != "catch clause" && info.type != "function name" && name.charAt(0) != "_")
fail("Unused " + info.type + " " + name, info.node.loc);
}
}
}
var failed = false;
function fail(msg, pos) {
if (pos.start) msg += " (" + pos.start.line + ":" + pos.start.column + ")";
console.log(pos.source + ": " + msg);
failed = true;
}
function checkDir(dir) {
fs.readdirSync(dir).forEach(function(file) {
var fname = dir + "/" + file;
if (/\.js$/.test(file)) checkFile(fname);
else if (file != "dep" && fs.lstatSync(fname).isDirectory()) checkDir(fname);
});
}
exports.checkDir = checkDir;
exports.checkFile = checkFile;
exports.success = function() { return !failed; };

View File

@@ -1,216 +0,0 @@
// AST walker module for Mozilla Parser API compatible trees
(function(exports) {
"use strict";
// A simple walk is one where you simply specify callbacks to be
// called on specific nodes. The last two arguments are optional. A
// simple use would be
//
// walk.simple(myTree, {
// Expression: function(node) { ... }
// });
//
// to do something with all expressions. All Parser API node types
// can be used to identify node types, as well as Expression,
// Statement, and ScopeBody, which denote categories of nodes.
//
// The base argument can be used to pass a custom (recursive)
// walker, and state can be used to give this walked an initial
// state.
exports.simple = function(node, visitors, base, state) {
if (!base) base = exports;
function c(node, st, override) {
var type = override || node.type, found = visitors[type];
if (found) found(node, st);
base[type](node, st, c);
}
c(node, state);
};
// A recursive walk is one where your functions override the default
// walkers. They can modify and replace the state parameter that's
// threaded through the walk, and can opt how and whether to walk
// their child nodes (by calling their third argument on these
// nodes).
exports.recursive = function(node, state, funcs, base) {
var visitor = exports.make(funcs, base);
function c(node, st, override) {
visitor[override || node.type](node, st, c);
}
c(node, state);
};
// Used to create a custom walker. Will fill in all missing node
// type properties with the defaults.
exports.make = function(funcs, base) {
if (!base) base = exports;
var visitor = {};
for (var type in base)
visitor[type] = funcs.hasOwnProperty(type) ? funcs[type] : base[type];
return visitor;
};
function skipThrough(node, st, c) { c(node, st); }
function ignore(node, st, c) {}
// Node walkers.
exports.Program = exports.BlockStatement = function(node, st, c) {
for (var i = 0; i < node.body.length; ++i)
c(node.body[i], st, "Statement");
};
exports.Statement = skipThrough;
exports.EmptyStatement = ignore;
exports.ExpressionStatement = function(node, st, c) {
c(node.expression, st, "Expression");
};
exports.IfStatement = function(node, st, c) {
c(node.test, st, "Expression");
c(node.consequent, st, "Statement");
if (node.alternate) c(node.alternate, st, "Statement");
};
exports.LabeledStatement = function(node, st, c) {
c(node.body, st, "Statement");
};
exports.BreakStatement = exports.ContinueStatement = ignore;
exports.WithStatement = function(node, st, c) {
c(node.object, st, "Expression");
c(node.body, st, "Statement");
};
exports.SwitchStatement = function(node, st, c) {
c(node.discriminant, st, "Expression");
for (var i = 0; i < node.cases.length; ++i) {
var cs = node.cases[i];
if (cs.test) c(cs.test, st, "Expression");
for (var j = 0; j < cs.consequent.length; ++j)
c(cs.consequent[j], st, "Statement");
}
};
exports.ReturnStatement = function(node, st, c) {
if (node.argument) c(node.argument, st, "Expression");
};
exports.ThrowStatement = function(node, st, c) {
c(node.argument, st, "Expression");
};
exports.TryStatement = function(node, st, c) {
c(node.block, st, "Statement");
for (var i = 0; i < node.handlers.length; ++i)
c(node.handlers[i].body, st, "ScopeBody");
if (node.finalizer) c(node.finalizer, st, "Statement");
};
exports.WhileStatement = function(node, st, c) {
c(node.test, st, "Expression");
c(node.body, st, "Statement");
};
exports.DoWhileStatement = exports.WhileStatement;
exports.ForStatement = function(node, st, c) {
if (node.init) c(node.init, st, "ForInit");
if (node.test) c(node.test, st, "Expression");
if (node.update) c(node.update, st, "Expression");
c(node.body, st, "Statement");
};
exports.ForInStatement = function(node, st, c) {
c(node.left, st, "ForInit");
c(node.right, st, "Expression");
c(node.body, st, "Statement");
};
exports.ForInit = function(node, st, c) {
if (node.type == "VariableDeclaration") c(node, st);
else c(node, st, "Expression");
};
exports.DebuggerStatement = ignore;
exports.FunctionDeclaration = function(node, st, c) {
c(node, st, "Function");
};
exports.VariableDeclaration = function(node, st, c) {
for (var i = 0; i < node.declarations.length; ++i) {
var decl = node.declarations[i];
if (decl.init) c(decl.init, st, "Expression");
}
};
exports.Function = function(node, st, c) {
c(node.body, st, "ScopeBody");
};
exports.ScopeBody = function(node, st, c) {
c(node, st, "Statement");
};
exports.Expression = skipThrough;
exports.ThisExpression = ignore;
exports.ArrayExpression = function(node, st, c) {
for (var i = 0; i < node.elements.length; ++i) {
var elt = node.elements[i];
if (elt) c(elt, st, "Expression");
}
};
exports.ObjectExpression = function(node, st, c) {
for (var i = 0; i < node.properties.length; ++i)
c(node.properties[i].value, st, "Expression");
};
exports.FunctionExpression = exports.FunctionDeclaration;
exports.SequenceExpression = function(node, st, c) {
for (var i = 0; i < node.expressions.length; ++i)
c(node.expressions[i], st, "Expression");
};
exports.UnaryExpression = exports.UpdateExpression = function(node, st, c) {
c(node.argument, st, "Expression");
};
exports.BinaryExpression = exports.AssignmentExpression = exports.LogicalExpression = function(node, st, c) {
c(node.left, st, "Expression");
c(node.right, st, "Expression");
};
exports.ConditionalExpression = function(node, st, c) {
c(node.test, st, "Expression");
c(node.consequent, st, "Expression");
c(node.alternate, st, "Expression");
};
exports.NewExpression = exports.CallExpression = function(node, st, c) {
c(node.callee, st, "Expression");
if (node.arguments) for (var i = 0; i < node.arguments.length; ++i)
c(node.arguments[i], st, "Expression");
};
exports.MemberExpression = function(node, st, c) {
c(node.object, st, "Expression");
if (node.computed) c(node.property, st, "Expression");
};
exports.Identifier = exports.Literal = ignore;
// A custom walker that keeps track of the scope chain and the
// variables defined in it.
function makeScope(prev) {
return {vars: Object.create(null), prev: prev};
}
exports.scopeVisitor = exports.make({
Function: function(node, scope, c) {
var inner = makeScope(scope);
for (var i = 0; i < node.params.length; ++i)
inner.vars[node.params[i].name] = {type: "argument", node: node.params[i]};
if (node.id) {
var decl = node.type == "FunctionDeclaration";
(decl ? scope : inner).vars[node.id.name] =
{type: decl ? "function" : "function name", node: node.id};
}
c(node.body, inner, "ScopeBody");
},
TryStatement: function(node, scope, c) {
c(node.block, scope, "Statement");
for (var i = 0; i < node.handlers.length; ++i) {
var handler = node.handlers[i], inner = makeScope(scope);
inner.vars[handler.param.name] = {type: "catch clause", node: handler.param};
c(handler.body, inner, "ScopeBody");
}
if (node.finalizer) c(node.finalizer, scope, "Statement");
},
VariableDeclaration: function(node, scope, c) {
for (var i = 0; i < node.declarations.length; ++i) {
var decl = node.declarations[i];
scope.vars[decl.id.name] = {type: "var", node: decl.id};
if (decl.init) c(decl.init, scope, "Expression");
}
}
});
})(typeof exports == "undefined" ? acorn.walk = {} : exports);

View File

@@ -1,10 +0,0 @@
.mt-output .mt-token {
border: 1px solid #ddd;
white-space: pre;
font-family: "Consolas", monospace;
text-align: center;
}
.mt-output .mt-style {
font-size: x-small;
}

View File

@@ -1,200 +0,0 @@
/**
* Helper to test CodeMirror highlighting modes. It pretty prints output of the
* highlighter and can check against expected styles.
*
* Mode tests are registered by calling test.mode(testName, mode,
* tokens), where mode is a mode object as returned by
* CodeMirror.getMode, and tokens is an array of lines that make up
* the test.
*
* These lines are strings, in which styled stretches of code are
* enclosed in brackets `[]`, and prefixed by their style. For
* example, `[keyword if]`. Brackets in the code itself must be
* duplicated to prevent them from being interpreted as token
* boundaries. For example `a[[i]]` for `a[i]`. If a token has
* multiple styles, the styles must be separated by ampersands, for
* example `[tag&error </hmtl>]`.
*
* See the test.js files in the css, markdown, gfm, and stex mode
* directories for examples.
*/
(function() {
function findSingle(str, pos, ch) {
for (;;) {
var found = str.indexOf(ch, pos);
if (found == -1) return null;
if (str.charAt(found + 1) != ch) return found;
pos = found + 2;
}
}
var styleName = /[\w&-_]+/g;
function parseTokens(strs) {
var tokens = [], plain = "";
for (var i = 0; i < strs.length; ++i) {
if (i) plain += "\n";
var str = strs[i], pos = 0;
while (pos < str.length) {
var style = null, text;
if (str.charAt(pos) == "[" && str.charAt(pos+1) != "[") {
styleName.lastIndex = pos + 1;
var m = styleName.exec(str);
style = m[0].replace(/&/g, " ");
var textStart = pos + style.length + 2;
var end = findSingle(str, textStart, "]");
if (end == null) throw new Error("Unterminated token at " + pos + " in '" + str + "'" + style);
text = str.slice(textStart, end);
pos = end + 1;
} else {
var end = findSingle(str, pos, "[");
if (end == null) end = str.length;
text = str.slice(pos, end);
pos = end;
}
text = text.replace(/\[\[|\]\]/g, function(s) {return s.charAt(0);});
tokens.push(style, text);
plain += text;
}
}
return {tokens: tokens, plain: plain};
}
test.indentation = function(name, mode, tokens, modeName) {
var data = parseTokens(tokens);
return test((modeName || mode.name) + "_indent_" + name, function() {
return compare(data.plain, data.tokens, mode, true);
});
};
test.mode = function(name, mode, tokens, modeName) {
var data = parseTokens(tokens);
return test((modeName || mode.name) + "_" + name, function() {
return compare(data.plain, data.tokens, mode);
});
};
function compare(text, expected, mode, compareIndentation) {
var expectedOutput = [];
for (var i = 0; i < expected.length; i += 2) {
var sty = expected[i];
if (sty && sty.indexOf(" ")) sty = sty.split(' ').sort().join(' ');
expectedOutput.push(sty, expected[i + 1]);
}
var observedOutput = highlight(text, mode, compareIndentation);
var pass, passStyle = "";
pass = highlightOutputsEqual(expectedOutput, observedOutput);
passStyle = pass ? 'mt-pass' : 'mt-fail';
var s = '';
if (pass) {
s += '<div class="mt-test ' + passStyle + '">';
s += '<pre>' + text.replace('&', '&amp;').replace('<', '&lt;') + '</pre>';
s += '<div class="cm-s-default">';
s += prettyPrintOutputTable(observedOutput);
s += '</div>';
s += '</div>';
return s;
} else {
s += '<div class="mt-test ' + passStyle + '">';
s += '<pre>' + text.replace('&', '&amp;').replace('<', '&lt;') + '</pre>';
s += '<div class="cm-s-default">';
s += 'expected:';
s += prettyPrintOutputTable(expectedOutput);
s += 'observed:';
s += prettyPrintOutputTable(observedOutput);
s += '</div>';
s += '</div>';
throw s;
}
}
/**
* Emulation of CodeMirror's internal highlight routine for testing. Multi-line
* input is supported.
*
* @param string to highlight
*
* @param mode the mode that will do the actual highlighting
*
* @return array of [style, token] pairs
*/
function highlight(string, mode, compareIndentation) {
var state = mode.startState()
var lines = string.replace(/\r\n/g,'\n').split('\n');
var st = [], pos = 0;
for (var i = 0; i < lines.length; ++i) {
var line = lines[i], newLine = true;
var stream = new CodeMirror.StringStream(line);
if (line == "" && mode.blankLine) mode.blankLine(state);
/* Start copied code from CodeMirror.highlight */
while (!stream.eol()) {
var compare = mode.token(stream, state), substr = stream.current();
if(compareIndentation) compare = mode.indent(state) || null;
else if (compare && compare.indexOf(" ") > -1) compare = compare.split(' ').sort().join(' ');
stream.start = stream.pos;
if (pos && st[pos-2] == compare && !newLine) {
st[pos-1] += substr;
} else if (substr) {
st[pos++] = compare; st[pos++] = substr;
}
// Give up when line is ridiculously long
if (stream.pos > 5000) {
st[pos++] = null; st[pos++] = this.text.slice(stream.pos);
break;
}
newLine = false;
}
}
return st;
}
/**
* Compare two arrays of output from highlight.
*
* @param o1 array of [style, token] pairs
*
* @param o2 array of [style, token] pairs
*
* @return boolean; true iff outputs equal
*/
function highlightOutputsEqual(o1, o2) {
if (o1.length != o2.length) return false;
for (var i = 0; i < o1.length; ++i)
if (o1[i] != o2[i]) return false;
return true;
}
/**
* Print tokens and corresponding styles in a table. Spaces in the token are
* replaced with 'interpunct' dots (&middot;).
*
* @param output array of [style, token] pairs
*
* @return html string
*/
function prettyPrintOutputTable(output) {
var s = '<table class="mt-output">';
s += '<tr>';
for (var i = 0; i < output.length; i += 2) {
var style = output[i], val = output[i+1];
s +=
'<td class="mt-token">' +
'<span class="cm-' + String(style).replace(/ +/g, " cm-") + '">' +
val.replace(/ /g,'\xb7').replace('&', '&amp;').replace('<', '&lt;') +
'</span>' +
'</td>';
}
s += '</tr><tr>';
for (var i = 0; i < output.length; i += 2) {
s += '<td class="mt-style"><span>' + (output[i] || null) + '</span></td>';
}
s += '</table>';
return s;
}
})();

View File

@@ -1,31 +0,0 @@
var page = require('webpage').create();
page.open("http://localhost:3000/test/index.html", function (status) {
if (status != "success") {
console.log("page couldn't be loaded successfully");
phantom.exit(1);
}
waitFor(function () {
return page.evaluate(function () {
var output = document.getElementById('status');
if (!output) { return false; }
return (/^(\d+ failures?|all passed)/i).test(output.innerText);
});
}, function () {
var failed = page.evaluate(function () { return window.failed; });
var output = page.evaluate(function () {
return document.getElementById('output').innerText + "\n" +
document.getElementById('status').innerText;
});
console.log(output);
phantom.exit(failed > 0 ? 1 : 0);
});
});
function waitFor (test, cb) {
if (test()) {
cb();
} else {
setTimeout(function () { waitFor(test, cb); }, 250);
}
}

View File

@@ -1,34 +0,0 @@
#!/usr/bin/env node
var lint = require("./lint/lint");
lint.checkDir("mode");
lint.checkDir("lib");
lint.checkDir("addon");
lint.checkDir("keymap");
var ok = lint.success();
var files = new (require('node-static').Server)('.');
var server = require('http').createServer(function (req, res) {
req.addListener('end', function () {
files.serve(req, res);
});
}).addListener('error', function (err) {
throw err;
}).listen(3000, function () {
var child_process = require('child_process');
child_process.exec("which phantomjs", function (err) {
if (err) {
console.error("PhantomJS is not installed. Download from http://phantomjs.org");
process.exit(1);
}
var cmd = 'phantomjs test/phantom_driver.js';
child_process.exec(cmd, function (err, stdout) {
server.close();
console.log(stdout);
process.exit(err || !ok ? 1 : 0);
});
});
});

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff