-
Notifications
You must be signed in to change notification settings - Fork 5
/
index.html
511 lines (511 loc) · 18.9 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='utf-8'>
<title>
ContentEditable
</title>
<script src='https://www.w3.org/Tools/respec/respec-w3c' async class=
'remove'></script>
<script class='remove'>
var respecConfig = {
specStatus: "ED",
shortName: "content-editable",
editors: [
{
name: "Johannes Wilm",
mailto: "[email protected]",
company: "Invited Expert",
w3cid: "75083",
},
],
formerEditors: [
{
name: "Ben Peters",
mailto: "[email protected]",
company: "Microsoft",
companyURL: "https://www.microsoft.com",
retiredDate: "2015-02-23",
},
],
group: "webediting",
github: "w3c/contentEditable",
wgPublicList: "public-editing-tf",
xref: "web-platform",
lint: { "no-unused-dfns": false },
localBiblio: {
"css-cascade": {
aliasOf: "css-cascade-4"
}
}
};
</script>
</head>
<body data-cite="css-cascade-4">
<section id='abstract'>
<p>
This specification defines allowed values and expected behaviors for
the {{ElementContentEditable/contentEditable}} attribute. This
specification builds on [[HTML]].
</p>
<p>
This specification defines additional values for the
{{ElementContentEditable/contentEditable}} attribute which is already
defined by [[HTML]].
</p>
</section>
<section id='sotd'>
<p>
This is a work in progress.
</p>
</section>
<section class="informative">
<h2>
Problems solved
</h2>
<p>
Creating a web-based text-editor requires a considerable amount of
JavaScript on top of the browser code, among other things because:
</p>
<ol>
<li>Browsers differ in the manner they handle editing operations.
</li>
<li>Individual sites may have custom preferences for how they want to
handle certain editing operations.
</li>
<li>The development of high-level text editing features in browsers has
not followed the principles laid out in the [[[EXTENSIBLE]]] in that
development of these features has not always been in coordination with
the needs of the web developer community.
</li>
</ol>
<p>
This spec seeks to alleviate the problem by providing a simple way for
web developers prevent all browser default handling of editing
operations at different levels without having to preventDefault each of
them.
</p>
</section>
<section class="informative">
<h2>
Use cases
</h2>
<ol>
<li>Creating a JavaScript text editor in which the [^strong^] element
is used instead of the [^b^] element to mark text that the user marks
as bold, using any browser-builtin way to mark a text as bold, without
having access to all existing browsers.
</li>
<li>Creating a JavaScript text editor which works with a data model in
the background where JavaScript takes care of rendering changes to the
edited text to the DOM.
</li>
<li>Creating a JavaScript editor which only allows a subset of
rich-text editing (for example: bold is allowed, but italic not).
</li>
<li>Creating a collaborative editor in which JavaScript is used to
render changes to the DOM, based on user intentions with users using
different browsers with different ways of expressing specific
intentions.
</li>
<li>Creating a JavaScript editor with different user access options,
where some users only can add or delete text and other users only can
add or remove certain types of formatting.
</li>
<li>Creating a JavaScript editor in which caret movement is handled
differently from the default.
</li>
<li>Creating a JavaScript editor with advanced elements, such as
non-editable regions, inline SVGs, canvas-elements and other elements
for which `contenteditable=true` currently creates caret placement
issues in several browsers.
</li>
</ol>
</section>
<section>
<h2 id="terminology">
Terminology
</h2>
<dl data-sort="">
<dt>
<dfn>Editing host</dfn>
</dt>
<dd>
An editing host is a node that is an HTML element with a
{{ElementContentEditable/contentEditable}} attribute set to something
else than the `false` state.
</dd>
<dt>
<dfn>`contentEditable=false` element</dfn>
</dt>
<dd>
Any element that has the {{ElementContentEditable/contentEditable}}
attribute set to `false`.
</dd>
<dt>
<dfn>Inline elements</dfn>
</dt>
<dd>
All element nodes for whom the <a>used value</a> of the `display`
property resolves to the value `inline`.
</dd>
<dt>
<dfn>Block elements</dfn>
</dt>
<dd>
All element nodes for whom the <a>used value</a> of the `display`
property resolves to the value `block`.
</dd>
<dt>
<dfn>Stub elements</dfn>
</dt>
<dd>
All element nodes that are void elements OR root elements using a
different namespace than their parent elements (such as SVGs).
</dd>
<dt>
<dfn>Invisible elements</dfn>
</dt>
<dd>
All element nodes for whom the <a>used value</a> of the `display`
property resolves to the value `none`.
</dd>
<dt>
<dfn>Legal Caret Positions</dfn>
</dt>
<dd>
<p>
All positions in which the caret can be placed programmatically.
The placement is restricted to the following positions.
Implementations MUST be able to place the caret in all of the
following positions:
</p>
<ol>
<li>Before or after any character in any text node.
</li>
<li>After <a>inline elements</a> that do not have a [=tree/next
sibling=] which is a text node.
</li>
<li>Before <a>inline elements</a> that that do not have a
[=tree/previous sibling=].
</li>
<li>Inside empty <a>inline elements</a> and <a>block elements</a>
that are not <a>stub elements</a>.
</li>
<li>Inside empty text nodes.
</li>
<li>Before or after <a>block elements</a> that are also <a>stub
elements</a>.
</li>
<li>Before or after comment nodes.
</li>
<li>In the <a>editing host</a> itself, if it is empty.
</li>
</ol>
<p>
There are some exceptions to these rules:
</p>
<ol>
<li>Within a table, the caret can only be placed inside [^th^],
[^td^] and [^caption^] elements.
</li>
<li>The caret cannot be placed inside <a>invisible elements</a>.
</li>
<li>The caret cannot be placed inside elements whose
contentEditable attribute returns `false`.
</li>
</ol>
</dd>
</dl>
</section>
<section>
<h2>
`contenteditable`
</h2>
<p>
The contenteditable attribute is an enumerated attribute whose keywords
are the empty string (""), "events", "caret", "typing",
"plaintext-only", "true", and "false". There is one additional state,
the `inherit` state, which is the missing value default (and the
invalid value default).
</p>
<p>
The empty string and the "true" keyword map to the `true` state. The
other keywords map to their respective states.
</p>
<p>
The `false` state indicates that the element is not editable. The
`inherit` state indicates that the element has the state of its parent.
</p>
<p>
The contentEditable IDL attribute, on getting, must return the string
"true" if the content attribute is set to the `true` state,
"plaintext-only" if the content attribute is set to the
`plaintext-only` state, "typing" if the content attribute is set to the
`typing` state, "caret" if the content attribute is set to the `caret`
state, "events" if the content attribute is set to the `events` state,
"false" if the content attribute is set to the `false` state, and
`inherit` otherwise.
</p>
<p>
On setting, if the new value is an ASCII case-insensitive match for the
string "inherit" then the content attribute must be removed, if the new
value is an ASCII case-insensitive match for a string matching the name
of a state, then the content attribute must be set to the name of that
state, and otherwise the attribute setter must throw a SyntaxError
exception.
</p>
<p>
The isContentEditable IDL attribute, on getting, must return true if
the element is either an editing host or editable, and false otherwise.
</p>
</section>
<section>
<h2>
Meaning of states
</h2>
<p>
The states "events", "caret", "typing", "plaintext-only" and "true" are
hierarchically ordered, so that the state "caret" also includes the
features of the "events" state, the "typing" state includes the
features of the "caret" state, the "plaintext-only" state includes the
features of the "typing" state, and the "true" state includes all the
features of the "plaintext-only" state.
</p>
<p>
The "events" state means that beforeinput events are triggered when the
user asks for an editing operation. The "caret" state adds default
browser controlled movement of the caret. The "typing" state adds
handling of text input through IME and keyboard, and deletion within an
IME composition. The "plaintext-only" state adds handling of text
deletion within a text node. The "true" state adds handling of deletion
deletion of non-textual content and editing commands through the
execCommand command.
</p>
<p>
The states "events", "caret", "typing" and "plaintext-only" are defined
in this document.
</p>
<p>
The state "true" is currently not well-defined and its usage is
discouraged. An initial attempt has been made to specify the behavior
of the "true" state in the <a href=
"contentEditableTrue.html">contentEditable=True spec</a>.
</p>
</section>
<section>
<h2 id="editing-states">
contentEditable states
</h2>
<section>
<h3 id="events-state">
contentEditable=events state
</h3>
<p>
In a focused <a>editing host</a> that is in the "events" state, a
caret MUST be drawn if the selection is collapsed, and it MUST be
possible to place the caret in all of the <a>Legal Caret
Positions</a> programmatically.
</p>
<p>
All user editing intentions initiated while an <a>editing host</a>
that is in the events state is focused, MUST trigger a `beforeinput`
event.
</p>
</section>
<section>
<h3 id="caret_state">
contentEditable=caret state
</h3>
<p>
A focused <a>editing host</a> that is in the "caret" state MUST
behave like an <a>editing host</a> in the events state. Additionally,
the default action of the `beforeSelectionChange` event in such an
<a>editing host</a> must be to move the caret in the indicated
direction, if movement in that direction seems possible.
</p>
<p class="note">
Notice the planned <a href=
"https://github.com/w3c/selection-api/issues/56">beforeSelectionChange</a>
event.
</p>
</section>
<section>
<h3 id="typing_state">
contentEditable=typing state
</h3>
<p>
A focused <a>editing host</a> that is in the "typing" state MUST
behave like an <a>editing host</a> in the caret state, and
additionally, it MUST handle text insertion by keyboard at the
position of the caret if the caret is placed within a text node or it
is possible to place a text node at the place of the caret. It must
by default also handle composition by IME, both insertion as well as
deletion of text input.
</p>
</section>
<section>
<h3 id="plaintext_only_state">
contentEditable=plaintext-only state
</h3>
<p>
A focused <a>editing host</a> that is in the "plaintext-only" state
MUST behave like an <a>editing host</a> in the typing state, and
additionally, it MUST handle text deletion.
</p>
</section>
</section>
<section>
<h2 id="cutting_and_pasting">
Cutting and pasting
</h2>
<p>
Within an <a>editing host</a> that is in the "events", "caret" or
"typing" state, cutting and pasting is disabled. Within an <a>editing
host</a> in the "plaintext-only" state, pasting only causes plaintext
pasting by default. Independently of the state of the <a>editing
host</a>, the events `paste` and `cut` should be triggered whenever the
user expresses the intention to paste or cut.
</p>
</section>
<section>
<h2 id="caret_darin_and_movement">
Caret drawing and movement
</h2>
<section>
<h3 id="caret_drawing">
Caret drawing
</h3>
<p>
A caret is drawn in any <a>editing host</a> that is focused, that
does not hold any other selections. Under such conditions, the caret
represents a collapsed selection.
</p>
</section>
<section>
<h3 id="caret_positions">
Caret positions
</h3>
<p>
It MUST be possible to put the caret in any of the <a>Legal Caret
Positions</a> programmatically and for the caret to be visible in
these in any <a>editing host</a> that is in the "events", "caret" or
"typing" state.
</p>
<section>
<h3 id="initial_caret_placement">
Initial caret placement
</h3>
<p>
Carets are initially placed at the first possible position within
the <a>editing host</a>.
</p>
</section>
<section>
<h3 id="caret_movement">
Caret movement
</h3>
<p>
The specific location that the caret is moved to by default in an
<a>editing host</a> in the "caret" and "typing" state, is out of
scope for this specification, but later versions of this
specification or specifications covering other contentEditable
specifications may further specify the movement patterns of the
caret.
</p>
</section>
</section>
<section>
<h2 id="replacing_text">
Replacing text/content
</h2>
<p>
When the user indicates the wish to replace part of the contents of a
<a>editing host</a>, by means of a browser-builtin spell checker or
alike, a `beforeinput` input with `inputType` set to `replaceText` or
`replaceContent` is triggered. No part of the DOM is being changed by
default in an editing host that is in the "events", "caret" or
"typing" state.
</p>
</section>
<section>
<h2 id="removal">
Removal of content
</h2>
<p>
Content is not removed automatically through user input in an
<a>editing host</a> that is in the "events" or "caret" state.
Instead, Del/Backspace key presses, etc. trigger user `beforeinput`
events with `inputType` set to `deleteContentForward` or
`deleteContentBackward`. The same is true for any <a>editing host</a>
that is in the "typing" state, unless it is currently in the
composition mode, in which case it will remove characters from the
DOM if they are part of the composition.
</p>
<p>
In the "plaintext-only" state, an <a>editing host</a> does handle
text deletion within a single text node.
</p>
</section>
<section>
<h2 id="spell_checking">
Advanced grammar checking
</h2>
<p>
An implementation MAY provide spell check, grammar check and other
advanced functionality that are not defined through a specification
for any <a>editing host</a>. These features MUST be disabled by
default.
</p>
</section>
<section>
<h2 id="context_menu">
Context menu
</h2>
<p>
If the implementation provides a `context menu`, this `context menu`
SHOULD contain items for editing operations such as `paste`, `cut`,
`copy`, `delete` and CAN contain items for spellchecking for any
<a>editing host</a>. Triggering any of `context menu` items MUST NOT
by default cause any change to the DOM, `paste`, `cut` and
`beforeinput` events SHOULD be triggered. Menu items in a `context
menu` that do not cause DOM changes by default SHOULD function as in
any other editing context.
</p>
</section>
<section>
<h2>
Privacy and Security Considerations
</h2>
<p>
To be written.
</p>
</section>
<section>
<h2>
Accessibility Considerations
</h2>
<p>
To be written.
</p>
</section>
<section id='conformance'></section>
<section class="appendix">
<h2>
Acknowledgements
</h2>
<p>
Thanks to: Michael Aufreiter, Adrian Bateman, Robin Berjon, Oliver
Buchtala, Enrica Casucci, Olivier Forget, Aryeh Gregor, Marijn
Haverbeke, Xiaocheng Hu, Yoshifumi Inoue, Koji Ishii, Gary Kacmarcik,
Frederico Caldeira Knabben, Takayoshi Kochi, Piotrek Koszuliński,
Travis Leithead, Grisha Lyukshin, Chaals McCathie Nevile, Masayuki
Nakano, Ryosuke Niwa, Julie Parent, Ben Peters, Florian Rivoal,
Hallvord R. M. Steen, Johan Sörlin, Cristian Talau, Ojan Vafai,
Xiaoqian Wu, Chong Zhang, Joanmarie, and everyone in the Editing
Taskforce for their input and feedback.
</p>
</section>
</section>
</body>
</html>