<!DOCTYPE html>
|
<html>
|
<head>
|
<meta charset="utf-8">
|
<title>Contenteditable issues related to backspace handling</title>
|
<style>
|
|
body {
|
width: 600px;
|
margin: 20px auto;
|
}
|
|
.editable {
|
border: solid 2px blue;
|
padding: 5px;
|
}
|
|
.output {
|
border: solid 2px yellow;
|
padding: 5px;
|
}
|
|
.tc {
|
overflow: auto;
|
}
|
|
.tc1 .editable p {
|
line-height: 1.5em;
|
}
|
|
.tc2 .editable p {
|
line-height: 1.5em;
|
font-size: 14px;
|
}
|
|
.tc4 .marker {
|
background-color: blue;
|
}
|
|
</style>
|
</head>
|
<body>
|
<section class="tc tc1">
|
<h1>TC1</h1>
|
<ol>
|
<li>Place caret next to <code>^</code>.</li>
|
<li>Press enter and backspace.</li>
|
<li>Output: <code><p>foo^<span style="line-height: 1.5em;">bar</span></p></code>.</li>
|
<li>Expected: <code><p>foo^bar</p></code>.</li>
|
</ol>
|
<div contenteditable="true" class="editable">
|
<p>foo^bar</p>
|
</div>
|
<pre class="output"></pre>
|
</section>
|
|
<section class="tc tc2">
|
<h1>TC2</h1>
|
<ol>
|
<li>Place caret before <code>^</code>.</li>
|
<li>Press backspace.</li>
|
<li>Output: <code><h1>foo<span style="font-size: 12px; line-height: 1.5em;">^bar</span></h1></code>.</li>
|
<li>Expected: <code><h1>foo^bar</h1></code>.</li>
|
</ol>
|
<div contenteditable="true" class="editable">
|
<h1>foo</h1>
|
<p>^bar</p>
|
</div>
|
<pre class="output"></pre>
|
</section>
|
|
<section class="tc tc3">
|
<h1>TC3</h1>
|
<ol>
|
<li>Place caret after <code>^</code>.</li>
|
<li>Press backspace 4 times (to delete "foo^").</li>
|
<li>Type sth.</li>
|
<li>Output: <code><p><b>sth</b> bar</p></code>.</li>
|
<li>Expected: <code><p><strong>sth</strong> bar</p></code>.</li>
|
<li>Other unwanted transformations: <code><em></code> to <code><i></code>, <code><sub></code>, <code><sup></code>,
|
<code><span></code> with <code>font-size</code> or <code>color</code> styles to <code><font></code>(?!) and many more.</li>
|
</ol>
|
<div contenteditable="true" class="editable">
|
<p><strong>foo^</strong> bar</p>
|
</div>
|
<pre class="output"></pre>
|
</section>
|
|
<section class="tc tc4">
|
<h1>TC4</h1>
|
<ol>
|
<li>Press CTRL+A and then backspace (once or few times) or use backspace to delete everything.</li>
|
<li>Type sth.</li>
|
<li>In the first and second editables you won't be able to remove formatting. After you start typing the style will be restored.
|
This will happen for most of the "styling" elements (<code>b, strong, em, i, sub, sub</code>) and <code><span></code> with inline styles like
|
<code>font-size, color, etc</code>. Note that in the second editable even if you removed entire paragraph by pressing backspace
|
few times, the style will be restored. However, that does not happen in the third editable which contains style applied by
|
a class. When all letters are removed entire span disappears.</li>
|
<li>I think that this is the expected behaviour:
|
<ol>
|
<li>content: <code><em>foo</em></code> (caret at the end),</li>
|
<li>backspace pressed 3 times: <code><em>[filler?]</em></code>; if user starts typing now the style should be restored (the original one, not transformed);
|
note that the element should not be removed (as Webkit does now), thanks to that WYSIWYG editors will be able to check the
|
state of a style (e.g. if bold is activated),</li>
|
<li>4th backspace removes the style which won't be restored when user starts typing again.</li>
|
</ol>
|
</li>
|
</ol>
|
<div contenteditable="true" class="editable">
|
<span style="font-size:12px">foo</span>
|
</div>
|
<pre class="output"></pre>
|
|
<div contenteditable="true" class="editable">
|
<p><span style="color:green">foo</span></p>
|
</div>
|
<pre class="output"></pre>
|
|
<div contenteditable="true" class="editable">
|
<span class="marker">foo</span>
|
</div>
|
<pre class="output"></pre>
|
</section>
|
|
<script>
|
|
var editables = document.querySelectorAll( '.editable' );
|
|
for ( var i = 0; i < editables.length; ++i )
|
updateOutput( editables[ i ] );
|
|
function updateOutput( editable ) {
|
var pre = editable.nextElementSibling;
|
setInterval( function() {
|
pre.innerHTML = editable.innerHTML.replace( /</g, '<' ).replace( /(^|\n)\s+/g, '$1' );
|
}, 1000 );
|
}
|
|
</script>
|
</body>
|
</html>
|