Explorer, but have subsequently been copied by other browsers in a haphazard and imprecise fashion. Although the behaviour specified here does not exactly match any browser at the time of writing, it can serve as a target to converge to in the future ! - W3C HTML Editing APIs, Feb 2014
• Markup isn’t generated consistently in different browsers • Makes it difficult to use HTML as a data format • A markup sanitisation step is a necessity
selection = window.getSelection(); • Find out where the selection starts and ends: ! ! ! ! • It’s a caret if the nodes and offsets are the same selection.anchorNode selection.focusNode selection.anchorOffset selection.focusOffset
document.createRange(); range.setStart(startNode, offset); range.setEnd(endNode, offset); selection.removeAllRanges(); selection.addRange(range); ! • You can now • Apply an execCommand on the selection • Save the range with selection.getRangeAt(0), do some work, re-add the range and it will be reinstated. • Collapse the selection to a caret with selection.collapse() • Get position of the selection or caret with selection.getBoundingClientRect()
IE 1. Create an offscreen contenteditable div 2. On the beforepaste event redirect your caret to the offscreen <div> 3. Don’t e.preventDefault the paste event as your pasted content will now be sent to the offscreen <div> 4. You now have the formatted version of the pasted content
Docs by the presence of: id=“docs-internal-guid-234234” • bold and italic styles are inlined rather than using <b> and <i> elements • Some Google Doc styles are hard to detect
content • Easier to translate than Google Docs as they use HTML classes • MsoTitle MsoSubtitle MsoNormal -> <p> MsoQuote -> <blockquote> <h1> -> <h6>, <b>, <i>, <a>
created their own layout engine to overcome its limitations • Caret is a 2px <div>, text selection highlighting is a <div> • They intercept all keyboard inputs and insert into an area offscreen • Calculate where to put it onscreen
contenteditable behaviour and execCommand • Lots of cross-browser headaches and jumping through hoops to sanitise the output • Hard to do automated testing • We are currently undergoing a rewrite of our editor
contenteditable backed by a model of the document • Have a mapping between the DOM and our model • Define a set strict of editing operations • Map user input and key events to these editing operations • Flush the DOM frequently so the Model and DOM is in sync Intercom Composer v2
what you’re getting yourself into. • Possibly leverage an open source library to save you the pain • If going the pure contenteditable route, DOM sanitisation is a must • There are ways of leveraging the useful bits of contenteditable (selections and events) and minimising the “bad” parts