~ubuntu-branches/ubuntu/utopic/codemirror-js/utopic

« back to all changes in this revision

Viewing changes to doc/internals.html

  • Committer: Package Import Robot
  • Author(s): David Paleino
  • Date: 2012-04-12 12:25:28 UTC
  • Revision ID: package-import@ubuntu.com-20120412122528-8xp5a8frj4h1d3ee
Tags: upstream-2.23
Import upstream version 2.23

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<!doctype html>
 
2
<html>
 
3
  <head>
 
4
    <title>CodeMirror: Internals</title>
 
5
    <link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Droid+Sans|Droid+Sans:bold"/>
 
6
    <link rel="stylesheet" type="text/css" href="docs.css"/>
 
7
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
 
8
    <style>dl dl {margin: 0;} .update {color: #d40 !important}</style>
 
9
  </head>
 
10
  <body>
 
11
 
 
12
<h1><span class="logo-braces">{ }</span> <a href="http://codemirror.net/">CodeMirror</a></h1>
 
13
 
 
14
<pre class="grey">
 
15
<img src="baboon.png" class="logo" alt="logo"/>/* (Re-) Implementing A Syntax-
 
16
   Highlighting Editor in JavaScript */
 
17
</pre>
 
18
 
 
19
<div class="clear"><div class="leftbig blk">
 
20
 
 
21
<p style="font-size: 85%" id="intro">
 
22
  <strong>Topic:</strong> JavaScript, code editor implementation<br>
 
23
  <strong>Author:</strong> Marijn Haverbeke<br>
 
24
  <strong>Date:</strong> March 2nd 2011 (updated November 13th 2011)
 
25
</p>
 
26
 
 
27
<p>This is a followup to
 
28
my <a href="http://codemirror.net/story.html">Brutal Odyssey to the
 
29
Dark Side of the DOM Tree</a> story. That one describes the
 
30
mind-bending process of implementing (what would become) CodeMirror 1.
 
31
This one describes the internals of CodeMirror 2, a complete rewrite
 
32
and rethink of the old code base. I wanted to give this piece another
 
33
Hunter Thompson copycat subtitle, but somehow that would be out of
 
34
place—the process this time around was one of straightforward
 
35
engineering, requiring no serious mind-bending whatsoever.</p>
 
36
 
 
37
<p>So, what is wrong with CodeMirror 1? I'd estimate, by mailing list
 
38
activity and general search-engine presence, that it has been
 
39
integrated into about a thousand systems by now. The most prominent
 
40
one, since a few weeks,
 
41
being <a href="http://googlecode.blogspot.com/2011/01/make-quick-fixes-quicker-on-google.html">Google
 
42
code's project hosting</a>. It works, and it's being used widely.</a>
 
43
 
 
44
<p>Still, I did not start replacing it because I was bored. CodeMirror
 
45
1 was heavily reliant on <code>designMode</code>
 
46
or <code>contentEditable</code> (depending on the browser). Neither of
 
47
these are well specified (HTML5 tries
 
48
to <a href="http://www.w3.org/TR/html5/editing.html#contenteditable">specify</a>
 
49
their basics), and, more importantly, they tend to be one of the more
 
50
obscure and buggy areas of browser functionality—CodeMirror, by using
 
51
this functionality in a non-typical way, was constantly running up
 
52
against browser bugs. WebKit wouldn't show an empty line at the end of
 
53
the document, and in some releases would suddenly get unbearably slow.
 
54
Firefox would show the cursor in the wrong place. Internet Explorer
 
55
would insist on linkifying everything that looked like a URL or email
 
56
address, a behaviour that can't be turned off. Some bugs I managed to
 
57
work around (which was often a frustrating, painful process), others,
 
58
such as the Firefox cursor placement, I gave up on, and had to tell
 
59
user after user that they were known problems, but not something I
 
60
could help.</p>
 
61
 
 
62
<p>Also, there is the fact that <code>designMode</code> (which seemed
 
63
to be less buggy than <code>contentEditable</code> in Webkit and
 
64
Firefox, and was thus used by CodeMirror 1 in those browsers) requires
 
65
a frame. Frames are another tricky area. It takes some effort to
 
66
prevent getting tripped up by domain restrictions, they don't
 
67
initialize synchronously, behave strangely in response to the back
 
68
button, and, on several browsers, can't be moved around the DOM
 
69
without having them re-initialize. They did provide a very nice way to
 
70
namespace the library, though—CodeMirror 1 could freely pollute the
 
71
namespace inside the frame.</p>
 
72
 
 
73
<p>Finally, working with an editable document means working with
 
74
selection in arbitrary DOM structures. Internet Explorer (8 and
 
75
before) has an utterly different (and awkward) selection API than all
 
76
of the other browsers, and even among the different implementations of
 
77
<code>document.selection</code>, details about how exactly a selection
 
78
is represented vary quite a bit. Add to that the fact that Opera's
 
79
selection support tended to be very buggy until recently, and you can
 
80
imagine why CodeMirror 1 contains 700 lines of selection-handling
 
81
code.</p>
 
82
 
 
83
<p>And that brings us to the main issue with the CodeMirror 1
 
84
code base: The proportion of browser-bug-workarounds to real
 
85
application code was getting dangerously high. By building on top of a
 
86
few dodgy features, I put the system in a vulnerable position—any
 
87
incompatibility and bugginess in these features, I had to paper over
 
88
with my own code. Not only did I have to do some serious stunt-work to
 
89
get it to work on older browsers (as detailed in the
 
90
previous <a href="http://codemirror.net/story.html">story</a>), things
 
91
also kept breaking in newly released versions, requiring me to come up
 
92
with <em>new</em> scary hacks in order to keep up. This was starting
 
93
to lose its appeal.</p>
 
94
 
 
95
<h2 id="approach">General Approach</h2>
 
96
 
 
97
<p>What CodeMirror 2 does is try to sidestep most of the hairy hacks
 
98
that came up in version 1. I owe a lot to the
 
99
<a href="http://ace.ajax.org">ACE</a> editor for inspiration on how to
 
100
approach this.</p>
 
101
 
 
102
<p>I absolutely did not want to be completely reliant on key events to
 
103
generate my input. Every JavaScript programmer knows that key event
 
104
information is horrible and incomplete. Some people (most awesomely
 
105
Mihai Bazon with <a href="http://ymacs.org">Ymacs</a>) have been able
 
106
to build more or less functioning editors by directly reading key
 
107
events, but it takes a lot of work (the kind of never-ending, fragile
 
108
work I described earlier), and will never be able to properly support
 
109
things like multi-keystoke international character
 
110
input. <a href="#keymap" class="update">[see below for caveat]</a></p>
 
111
 
 
112
<p>So what I do is focus a hidden textarea, and let the browser
 
113
believe that the user is typing into that. What we show to the user is
 
114
a DOM structure we built to represent his document. If this is updated
 
115
quickly enough, and shows some kind of believable cursor, it feels
 
116
like a real text-input control.</p>
 
117
 
 
118
<p>Another big win is that this DOM representation does not have to
 
119
span the whole document. Some CodeMirror 1 users insisted that they
 
120
needed to put a 30 thousand line XML document into CodeMirror. Putting
 
121
all that into the DOM takes a while, especially since, for some
 
122
reason, an editable DOM tree is slower than a normal one on most
 
123
browsers. If we have full control over what we show, we must only
 
124
ensure that the visible part of the document has been added, and can
 
125
do the rest only when needed. (Fortunately, the <code>onscroll</code>
 
126
event works almost the same on all browsers, and lends itself well to
 
127
displaying things only as they are scrolled into view.)</p>
 
128
 
 
129
<h2 id="input">Input</h2>
 
130
 
 
131
<p>ACE uses its hidden textarea only as a text input shim, and does
 
132
all cursor movement and things like text deletion itself by directly
 
133
handling key events. CodeMirror's way is to let the browser do its
 
134
thing as much as possible, and not, for example, define its own set of
 
135
key bindings. One way to do this would have been to have the whole
 
136
document inside the hidden textarea, and after each key event update
 
137
the display DOM to reflect what's in that textarea.</p>
 
138
 
 
139
<p>That'd be simple, but it is not realistic. For even medium-sized
 
140
document the editor would be constantly munging huge strings, and get
 
141
terribly slow. What CodeMirror 2 does is put the current selection,
 
142
along with an extra line on the top and on the bottom, into the
 
143
textarea.</p>
 
144
 
 
145
<p>This means that the arrow keys (and their ctrl-variations), home,
 
146
end, etcetera, do not have to be handled specially. We just read the
 
147
cursor position in the textarea, and update our cursor to match it.
 
148
Also, copy and paste work pretty much for free, and people get their
 
149
native key bindings, without any special work on my part. For example,
 
150
I have emacs key bindings configured for Chrome and Firefox. There is
 
151
no way for a script to detect this. <a class="update"
 
152
href="#keymap">[no longer the case]</a></p>
 
153
 
 
154
<p>Of course, since only a small part of the document sits in the
 
155
textarea, keys like page up and ctrl-end won't do the right thing.
 
156
CodeMirror is catching those events and handling them itself.</p>
 
157
 
 
158
<h2 id="selection">Selection</h2>
 
159
 
 
160
<p>Getting and setting the selection range of a textarea in modern
 
161
browsers is trivial—you just use the <code>selectionStart</code>
 
162
and <code>selectionEnd</code> properties. On IE you have to do some
 
163
insane stuff with temporary ranges and compensating for the fact that
 
164
moving the selection by a 'character' will treat \r\n as a single
 
165
character, but even there it is possible to build functions that
 
166
reliably set and get the selection range.</p>
 
167
 
 
168
<p>But consider this typical case: When I'm somewhere in my document,
 
169
press shift, and press the up arrow, something gets selected. Then, if
 
170
I, still holding shift, press the up arrow again, the top of my
 
171
selection is adjusted. The selection remembers where its <em>head</em>
 
172
and its <em>anchor</em> are, and moves the head when we shift-move.
 
173
This is a generally accepted property of selections, and done right by
 
174
every editing component built in the past twenty years.</p>
 
175
 
 
176
<p>But not something that the browser selection APIs expose.</p>
 
177
 
 
178
<p>Great. So when someone creates an 'upside-down' selection, the next
 
179
time CodeMirror has to update the textarea, it'll re-create the
 
180
selection as an 'upside-up' selection, with the anchor at the top, and
 
181
the next cursor motion will behave in an unexpected way—our second
 
182
up-arrow press in the example above will not do anything, since it is
 
183
interpreted in exactly the same way as the first.</p>
 
184
 
 
185
<p>No problem. We'll just, ehm, detect that the selection is
 
186
upside-down (you can tell by the way it was created), and then, when
 
187
an upside-down selection is present, and a cursor-moving key is
 
188
pressed in combination with shift, we quickly collapse the selection
 
189
in the textarea to its start, allow the key to take effect, and then
 
190
combine its new head with its old anchor to get the <em>real</em>
 
191
selection.</p>
 
192
 
 
193
<p>In short, scary hacks could not be avoided entirely in CodeMirror
 
194
2.</p>
 
195
 
 
196
<p>And, the observant reader might ask, how do you even know that a
 
197
key combo is a cursor-moving combo, if you claim you support any
 
198
native key bindings? Well, we don't, but we can learn. The editor
 
199
keeps a set known cursor-movement combos (initialized to the
 
200
predictable defaults), and updates this set when it observes that
 
201
pressing a certain key had (only) the effect of moving the cursor.
 
202
This, of course, doesn't work if the first time the key is used was
 
203
for extending an inverted selection, but it works most of the
 
204
time.</p>
 
205
 
 
206
<h2 id="update">Intelligent Updating</h2>
 
207
 
 
208
<p>One thing that always comes up when you have a complicated internal
 
209
state that's reflected in some user-visible external representation
 
210
(in this case, the displayed code and the textarea's content) is
 
211
keeping the two in sync. The naive way is to just update the display
 
212
every time you change your state, but this is not only error prone
 
213
(you'll forget), it also easily leads to duplicate work on big,
 
214
composite operations. Then you start passing around flags indicating
 
215
whether the display should be updated in an attempt to be efficient
 
216
again and, well, at that point you might as well give up completely.</p>
 
217
 
 
218
<p>I did go down that road, but then switched to a much simpler model:
 
219
simply keep track of all the things that have been changed during an
 
220
action, and then, only at the end, use this information to update the
 
221
user-visible display.</p>
 
222
 
 
223
<p>CodeMirror uses a concept of <em>operations</em>, which start by
 
224
calling a specific set-up function that clears the state and end by
 
225
calling another function that reads this state and does the required
 
226
updating. Most event handlers, and all the user-visible methods that
 
227
change state are wrapped like this. There's a method
 
228
called <code>operation</code> that accepts a function, and returns
 
229
another function that wraps the given function as an operation.</p>
 
230
 
 
231
<p>It's trivial to extend this (as CodeMirror does) to detect nesting,
 
232
and, when an operation is started inside an operation, simply
 
233
increment the nesting count, and only do the updating when this count
 
234
reaches zero again.</p>
 
235
 
 
236
<p>If we have a set of changed ranges and know the currently shown
 
237
range, we can (with some awkward code to deal with the fact that
 
238
changes can add and remove lines, so we're dealing with a changing
 
239
coordinate system) construct a map of the ranges that were left
 
240
intact. We can then compare this map with the part of the document
 
241
that's currently visible (based on scroll offset and editor height) to
 
242
determine whether something needs to be updated.</p>
 
243
 
 
244
<p>CodeMirror uses two update algorithms—a full refresh, where it just
 
245
discards the whole part of the DOM that contains the edited text and
 
246
rebuilds it, and a patch algorithm, where it uses the information
 
247
about changed and intact ranges to update only the out-of-date parts
 
248
of the DOM. When more than 30 percent (which is the current heuristic,
 
249
might change) of the lines need to be updated, the full refresh is
 
250
chosen (since it's faster to do than painstakingly finding and
 
251
updating all the changed lines), in the other case it does the
 
252
patching (so that, if you scroll a line or select another character,
 
253
the whole screen doesn't have to be
 
254
re-rendered). <span class="update">[the full-refresh
 
255
algorithm was dropped, it wasn't really faster than the patching
 
256
one]</span></p>
 
257
 
 
258
<p>All updating uses <code>innerHTML</code> rather than direct DOM
 
259
manipulation, since that still seems to be by far the fastest way to
 
260
build documents. There's a per-line function that combines the
 
261
highlighting, <a href="manual.html#markText">marking</a>, and
 
262
selection info for that line into a snippet of HTML. The patch updater
 
263
uses this to reset individual lines, the refresh updater builds an
 
264
HTML chunk for the whole visible document at once, and then uses a
 
265
single <code>innerHTML</code> update to do the refresh.</p>
 
266
 
 
267
<h2 id="parse">Parsers can be Simple</h2>
 
268
 
 
269
<p>When I wrote CodeMirror 1, I
 
270
thought <a href="http://codemirror.net/story.html#parser">interruptable
 
271
parsers</a> were a hugely scary and complicated thing, and I used a
 
272
bunch of heavyweight abstractions to keep this supposed complexity
 
273
under control: parsers
 
274
were <a href="http://bob.pythonmac.org/archives/2005/07/06/iteration-in-javascript/">iterators</a>
 
275
that consumed input from another iterator, and used funny
 
276
closure-resetting tricks to copy and resume themselves.</p>
 
277
 
 
278
<p>This made for a rather nice system, in that parsers formed strictly
 
279
separate modules, and could be composed in predictable ways.
 
280
Unfortunately, it was quite slow (stacking three or four iterators on
 
281
top of each other), and extremely intimidating to people not used to a
 
282
functional programming style.</p>
 
283
 
 
284
<p>With a few small changes, however, we can keep all those
 
285
advantages, but simplify the API and make the whole thing less
 
286
indirect and inefficient. CodeMirror
 
287
2's <a href="manual.html#modeapi">mode API</a> uses explicit state
 
288
objects, and makes the parser/tokenizer a function that simply takes a
 
289
state and a character stream abstraction, advances the stream one
 
290
token, and returns the way the token should be styled. This state may
 
291
be copied, optionally in a mode-defined way, in order to be able to
 
292
continue a parse at a given point. Even someone who's never touched a
 
293
lambda in his life can understand this approach. Additionally, far
 
294
fewer objects are allocated in the course of parsing now.</p>
 
295
 
 
296
<p>The biggest speedup comes from the fact that the parsing no longer
 
297
has to touch the DOM though. In CodeMirror 1, on an older browser, you
 
298
could <em>see</em> the parser work its way through the document,
 
299
managing some twenty lines in each 50-millisecond time slice it got. It
 
300
was reading its input from the DOM, and updating the DOM as it went
 
301
along, which any experienced JavaScript programmer will immediately
 
302
spot as a recipe for slowness. In CodeMirror 2, the parser usually
 
303
finishes the whole document in a single 100-millisecond time slice—it
 
304
manages some 1500 lines during that time on Chrome. All it has to do
 
305
is munge strings, so there is no real reason for it to be slow
 
306
anymore.</p>
 
307
 
 
308
<h2 id="summary">What Gives?</h2>
 
309
 
 
310
<p>Given all this, what can you expect from CodeMirror 2?</p>
 
311
 
 
312
<ul>
 
313
 
 
314
<li><strong>Small.</strong> the base library is
 
315
some <span class="update">45k</span> when minified
 
316
now, <span class="update">17k</span> when gzipped. It's smaller than
 
317
its own logo.</li>
 
318
 
 
319
<li><strong>Lightweight.</strong> CodeMirror 2 initializes very
 
320
quickly, and does almost no work when it is not focused. This means
 
321
you can treat it almost like a textarea, have multiple instances on a
 
322
page without trouble.</li>
 
323
 
 
324
<li><strong>Huge document support.</strong> Since highlighting is
 
325
really fast, and no DOM structure is being built for non-visible
 
326
content, you don't have to worry about locking up your browser when a
 
327
user enters a megabyte-sized document.</li>
 
328
 
 
329
<li><strong>Extended API.</strong> Some things kept coming up in the
 
330
mailing list, such as marking pieces of text or lines, which were
 
331
extremely hard to do with CodeMirror 1. The new version has proper
 
332
support for these built in.</li>
 
333
 
 
334
<li><strong>Tab support.</strong> Tabs inside editable documents were,
 
335
for some reason, a no-go. At least six different people announced they
 
336
were going to add tab support to CodeMirror 1, none survived (I mean,
 
337
none delivered a working version). CodeMirror 2 no longer removes tabs
 
338
from your document.</li>
 
339
 
 
340
<li><strong>Sane styling.</strong> <code>iframe</code> nodes aren't
 
341
really known for respecting document flow. Now that an editor instance
 
342
is a plain <code>div</code> element, it is much easier to size it to
 
343
fit the surrounding elements. You don't even have to make it scroll if
 
344
you do not <a href="../demo/resize.html">want to</a>.</li>
 
345
 
 
346
</ul>
 
347
 
 
348
<p>On the downside, a CodeMirror 2 instance is <em>not</em> a native
 
349
editable component. Though it does its best to emulate such a
 
350
component as much as possible, there is functionality that browsers
 
351
just do not allow us to hook into. Doing select-all from the context
 
352
menu, for example, is not currently detected by CodeMirror.</p>
 
353
 
 
354
<p id="changes" style="margin-top: 2em;"><span style="font-weight:
 
355
bold">[Updates from November 13th 2011]</span> Recently, I've made
 
356
some changes to the codebase that cause some of the text above to no
 
357
longer be current. I've left the text intact, but added markers at the
 
358
passages that are now inaccurate. The new situation is described
 
359
below.</p>
 
360
 
 
361
<h2 id="btree">Content Representation</h2>
 
362
 
 
363
<p>The original implementation of CodeMirror 2 represented the
 
364
document as a flat array of line objects. This worked well—splicing
 
365
arrays will require the part of the array after the splice to be
 
366
moved, but this is basically just a simple <code>memmove</code> of a
 
367
bunch of pointers, so it is cheap even for huge documents.</p>
 
368
 
 
369
<p>However, I recently added line wrapping and code folding (line
 
370
collapsing, basically). Once lines start taking up a non-constant
 
371
amount of vertical space, looking up a line by vertical position
 
372
(which is needed when someone clicks the document, and to determine
 
373
the visible part of the document during scrolling) can only be done
 
374
with a linear scan through the whole array, summing up line heights as
 
375
you go. Seeing how I've been going out of my way to make big documents
 
376
fast, this is not acceptable.</p>
 
377
 
 
378
<p>The new representation is based on a B-tree. The leaves of the tree
 
379
contain arrays of line objects, with a fixed minimum and maximum size,
 
380
and the non-leaf nodes simply hold arrays of child nodes. Each node
 
381
stores both the amount of lines that live below them and the vertical
 
382
space taken up by these lines. This allows the tree to be indexed both
 
383
by line number and by vertical position, and all access has
 
384
logarithmic complexity in relation to the document size.</p>
 
385
 
 
386
<p>I gave line objects and tree nodes parent pointers, to the node
 
387
above them. When a line has to update its height, it can simply walk
 
388
these pointers to the top of the tree, adding or subtracting the
 
389
difference in height from each node it encounters. The parent pointers
 
390
also make it cheaper (in complexity terms, the difference is probably
 
391
tiny in normal-sized documents) to find the current line number when
 
392
given a line object. In the old approach, the whole document array had
 
393
to be searched. Now, we can just walk up the tree and count the sizes
 
394
of the nodes coming before us at each level.</p>
 
395
 
 
396
<p>I chose B-trees, not regular binary trees, mostly because they
 
397
allow for very fast bulk insertions and deletions. When there is a big
 
398
change to a document, it typically involves adding, deleting, or
 
399
replacing a chunk of subsequent lines. In a regular balanced tree, all
 
400
these inserts or deletes would have to be done separately, which could
 
401
be really expensive. In a B-tree, to insert a chunk, you just walk
 
402
down the tree once to find where it should go, insert them all in one
 
403
shot, and then break up the node if needed. This breaking up might
 
404
involve breaking up nodes further up, but only requires a single pass
 
405
back up the tree. For deletion, I'm somewhat lax in keeping things
 
406
balanced—I just collapse nodes into a leaf when their child count goes
 
407
below a given number. This means that there are some weird editing
 
408
patterns that may result in a seriously unbalanced tree, but even such
 
409
an unbalanced tree will perform well, unless you spend a day making
 
410
strangely repeating edits to a really big document.</p>
 
411
 
 
412
<h2 id="keymap">Keymaps</h2>
 
413
 
 
414
<p><a href="#approach">Above</a>, I claimed that directly catching key
 
415
events for things like cursor movement is impractical because it
 
416
requires some browser-specific kludges. I then proceeded to explain
 
417
some awful <a href="#selection">hacks</a> that were needed to make it
 
418
possible for the selection changes to be detected through the
 
419
textarea. In fact, the second hack is about as bad as the first.</p>
 
420
 
 
421
<p>On top of that, in the presence of user-configurable tab sizes and
 
422
collapsed and wrapped lines, lining up cursor movement in the textarea
 
423
with what's visible on the screen becomes a nightmare. Thus, I've
 
424
decided to move to a model where the textarea's selection is no longer
 
425
depended on.</p>
 
426
 
 
427
<p>So I moved to a model where all cursor movement is handled by my
 
428
own code. This adds support for a goal column, proper interaction of
 
429
cursor movement with collapsed lines, and makes it possible for
 
430
vertical movement to move through wrapped lines properly, instead of
 
431
just treating them like non-wrapped lines.</p>
 
432
 
 
433
<p>The key event handlers now translate the key event into a string,
 
434
something like <code>Ctrl-Home</code> or <code>Shift-Cmd-R</code>, and
 
435
use that string to look up an action to perform. To make keybinding
 
436
customizable, this lookup goes through
 
437
a <a href="manual.html#option_keyMap">table</a>, using a scheme that
 
438
allows such tables to be chained together (for example, the default
 
439
Mac bindings fall through to a table named 'emacsy', which defines
 
440
basic Emacs-style bindings like <code>Ctrl-F</code>, and which is also
 
441
used by the custom Emacs bindings).</p>
 
442
 
 
443
<p>A new
 
444
option <a href="manual.html#option_extraKeys"><code>extraKeys</code></a>
 
445
allows ad-hoc keybindings to be defined in a much nicer way than what
 
446
was possible with the
 
447
old <a href="manual.html#option_onKeyEvent"><code>onKeyEvent</code></a>
 
448
callback. You simply provide an object mapping key identifiers to
 
449
functions, instead of painstakingly looking at raw key events.</p>
 
450
 
 
451
<p>Built-in commands map to strings, rather than functions, for
 
452
example <code>"goLineUp"</code> is the default action bound to the up
 
453
arrow key. This allows new keymaps to refer to them without
 
454
duplicating any code. New commands can be defined by assigning to
 
455
the <code>CodeMirror.commands</code> object, which maps such commands
 
456
to functions.</p>
 
457
 
 
458
<p>The hidden textarea now only holds the current selection, with no
 
459
extra characters around it. This has a nice advantage: polling for
 
460
input becomes much, much faster. If there's a big selection, this text
 
461
does not have to be read from the textarea every time—when we poll,
 
462
just noticing that something is still selected is enough to tell us
 
463
that no new text was typed.</p>
 
464
 
 
465
<p>The reason that cheap polling is important is that many browsers do
 
466
not fire useful events on IME (input method engine) input, which is
 
467
the thing where people inputting a language like Japanese or Chinese
 
468
use multiple keystrokes to create a character or sequence of
 
469
characters. Most modern browsers fire <code>input</code> when the
 
470
composing is finished, but many don't fire anything when the character
 
471
is updated <em>during</em> composition. So we poll, whenever the
 
472
editor is focused, to provide immediate updates of the display.</p>
 
473
 
 
474
</div><div class="rightsmall blk">
 
475
 
 
476
    <h2>Contents</h2>
 
477
 
 
478
    <ul>
 
479
      <li><a href="#intro">Introduction</a></li>
 
480
      <li><a href="#approach">General Approach</a></li>
 
481
      <li><a href="#input">Input</a></li>
 
482
      <li><a href="#selection">Selection</a></li>
 
483
      <li><a href="#update">Intelligent Updating</a></li>
 
484
      <li><a href="#parse">Parsing</a></li>
 
485
      <li><a href="#summary">What Gives?</a></li>
 
486
      <li><a href="#btree">Content Representation</a></li>
 
487
      <li><a href="#keymap">Key Maps</a></li>
 
488
    </ul>
 
489
 
 
490
</div></div>
 
491
 
 
492
<div style="height: 2em">&nbsp;</div>
 
493
 
 
494
</body></html>