diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /testing/web-platform/tests/editing | |
parent | Initial commit. (diff) | |
download | firefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz firefox-26a029d407be480d791972afb5975cf62c9360a6.zip |
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/editing')
272 files changed, 71264 insertions, 0 deletions
diff --git a/testing/web-platform/tests/editing/META.yml b/testing/web-platform/tests/editing/META.yml new file mode 100644 index 0000000000..f7f2f109d6 --- /dev/null +++ b/testing/web-platform/tests/editing/META.yml @@ -0,0 +1,3 @@ +spec: https://w3c.github.io/editing/execCommand.html +suggested_reviewers: + - johanneswilm diff --git a/testing/web-platform/tests/editing/README b/testing/web-platform/tests/editing/README new file mode 100644 index 0000000000..945ce83a00 --- /dev/null +++ b/testing/web-platform/tests/editing/README @@ -0,0 +1,14 @@ +Most of this directory tests conformance to the editing spec written long ago +by Aryeh Gregor. Nobody actually implements the spec, but the tests are still +useful for regression testing. The files in data/ were generated from a +JavaScript implementation of the specification using a complex procedure that +can't actually be replicated right now as-is. Editing them manually is +possible, but they're not really meant to be human-readable. If anyone is +interested, it would be possible for Aryeh to get the test generation procedure +working again. Or you could look into the repository history and figure out +how to do it yourself, if you're brave. + +There is also a directory other/ that contains additional editor-related tests. +They aren't necessarily based on any specification, but try to specify sensible +behavior, and are meant to be helpful with regression testing for existing +implementations and finding bugs in new implementations. diff --git a/testing/web-platform/tests/editing/crashtests/backcolor-in-nested-editing-host-td-from-DOMAttrModified.html b/testing/web-platform/tests/editing/crashtests/backcolor-in-nested-editing-host-td-from-DOMAttrModified.html new file mode 100644 index 0000000000..f8f004b910 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/backcolor-in-nested-editing-host-td-from-DOMAttrModified.html @@ -0,0 +1,29 @@ +<html class="test-wait"> +<head> +<script type="text/javascript"> +function boom() +{ + function x() + { + document.removeEventListener("DOMAttrModified", x); + document.execCommand("backcolor", false, "green"); + } + + document.getElementById("td").focus(); + + document.addEventListener("DOMAttrModified", x); + try { + document.execCommand("subscript", false, null); + } catch(e) { + } + document.removeEventListener("DOMAttrModified", x); + document.documentElement.removeAttribute("class"); +} +</script> +</head> + +<body contenteditable="true" onload="setTimeout(boom, 30);"> +<table><tbody contenteditable="false"><tr><td contenteditable="true" id="td"></td></tr></tbody></table> +</body> + +</html> diff --git a/testing/web-platform/tests/editing/crashtests/bold-in-output.html b/testing/web-platform/tests/editing/crashtests/bold-in-output.html new file mode 100644 index 0000000000..43d78ec4e9 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/bold-in-output.html @@ -0,0 +1,20 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<style> +* { font-weight: bolder } +</style> +<script> +document.addEventListener("DOMContentLoaded", () => { + document.querySelector("output").focus(); + document.execCommand("selectAll"); + document.execCommand("bold"); +}) +</script> +</head> +<body> +<output contenteditable="true"> +A +</output></body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/change-input-type-of-focused-text-control-and-make-it-editing-host.html b/testing/web-platform/tests/editing/crashtests/change-input-type-of-focused-text-control-and-make-it-editing-host.html new file mode 100644 index 0000000000..fec4ff13e8 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/change-input-type-of-focused-text-control-and-make-it-editing-host.html @@ -0,0 +1,16 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<script> +document.addEventListener("DOMContentLoaded", () => { + const input = document.createElement("input"); + document.documentElement.appendChild(input); + input.focus(); + input.type = "file"; + input.getBoundingClientRect(); + input.setAttribute("contenteditable", "true"); +}); +</script> +<body></body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/contenteditable-will-be-blurred-by-focus-event-listener.html b/testing/web-platform/tests/editing/crashtests/contenteditable-will-be-blurred-by-focus-event-listener.html new file mode 100644 index 0000000000..a887b1de90 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/contenteditable-will-be-blurred-by-focus-event-listener.html @@ -0,0 +1,16 @@ +<!DOCTYPE html> +<html class="test-wait"> +<meta charset="utf-8"> +<script> +addEventListener("load", () => { + const editingHost = document.querySelector("div[contenteditable]"); + editingHost.addEventListener("focus", () => { + document.execCommand("insertText", false, "def"); + editingHost.parentElement.setAttribute("hidden", "hidden"); + setTimeout(() => document.documentElement.removeAttribute("class"), 0); + }); + editingHost.focus(); +}); +</script> +<div><div contenteditable>abc</div></div> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/crash-test.html b/testing/web-platform/tests/editing/crashtests/crash-test.html new file mode 100644 index 0000000000..a7baba30ec --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/crash-test.html @@ -0,0 +1,24 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Testcase for bug 1273593 of Chromium</title> +<script type="text/javascript"> + function eventhandle_n0BpsTiUS(){ + document.getElementById('id_xEmarzXTw').getBoundingClientRect(); + create_object_mJ9MFgX5.appendChild(document.getElementById('id_nJMWIU7Mp')); + } + function operate(){ + document.getElementById('id_VQmNKZL69').addEventListener('pause', eventhandle_n0BpsTiUS); + create_object_mJ9MFgX5 = document.createElement("canvas"); + event = new Event('pause') + document.getElementById('id_VQmNKZL69').dispatchEvent(event) + }// end exec_event +</script> +<body onload="operate();" contentEditable="true"> + <menu id='id_xEmarzXTw'> + <i id='id_VQmNKZL69' onfocusout='eventhandle_n0BpsTiUS();'> + <nobr id='id_nJMWIU7Mp' > + <iframe onpointerover='eventhandle_n0BpsTiUS();'></iframe> + </nobr> + </i> + </menu> +</body> diff --git a/testing/web-platform/tests/editing/crashtests/delete-after-empty-script-element.html b/testing/web-platform/tests/editing/crashtests/delete-after-empty-script-element.html new file mode 100644 index 0000000000..c06a4af802 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/delete-after-empty-script-element.html @@ -0,0 +1,19 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +</head> +<body> +A +<script> +addEventListener("load", () => { + document.documentElement.contentEditable = true; + getSelection().collapse(document.body.lastChild, document.body.lastChild.length); + document.execCommand("delete"); +}); +</script> +<li> +<form readonly contenteditable> +</form> +<script> +</script></li></body></html> diff --git a/testing/web-platform/tests/editing/crashtests/delete-after-justifyleft-in-closed-editable-dialog.html b/testing/web-platform/tests/editing/crashtests/delete-after-justifyleft-in-closed-editable-dialog.html new file mode 100644 index 0000000000..185cb01ee5 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/delete-after-justifyleft-in-closed-editable-dialog.html @@ -0,0 +1,17 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<script> +addEventListener("load", () => { + const dialog = document.querySelector("dialog"); + dialog.showModal(); + dialog.close(); + document.execCommand("justifyLeft"); + document.execCommand("delete"); +}); +</script> +</head> +<body><dialog contenteditable> +</dialog></body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/delete-and-justifycenter-recursively-with-mutation-event-listeners.html b/testing/web-platform/tests/editing/crashtests/delete-and-justifycenter-recursively-with-mutation-event-listeners.html new file mode 100644 index 0000000000..ce0c7e886f --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/delete-and-justifycenter-recursively-with-mutation-event-listeners.html @@ -0,0 +1,34 @@ +<!doctype html> +<html class="test-wait"> +<head> +<meta charset="utf-8"> +<script> +try { + function onDOMNodeInsertedOfContentEditable() { + getSelection().collapse(document.querySelector("input")); + document.execCommand("justifyCenter"); + document.querySelector("dl").addEventListener("DOMSubtreeModified", onDOMSubtreeModifiedOfDLElement); + document.querySelector("dl").appendChild(document.querySelector("style")); + } + function onDOMSubtreeModifiedOfDLElement() { + document.execCommand("delete"); + document.querySelector("label").appendChild(document.querySelector("input")); + document.querySelector("dd[contenteditable]").addEventListener("DOMNodeInserted", onDOMNodeInsertedOfContentEditable); + } + addEventListener("load", () => { + onDOMNodeInsertedOfContentEditable(); + document.documentElement.removeAttribute("class"); + }); +} catch (ex) { + // maybe too many recursive exception would be thrown. + document.documentElement.removeAttribute("class"); +} +</script> +</head> +<body><label></label> +<dl> +<dd contenteditable> +<style>@</style> +<input> +</body> +</html>
\ No newline at end of file diff --git a/testing/web-platform/tests/editing/crashtests/delete-at-next-to-svg-display-table-cell.html b/testing/web-platform/tests/editing/crashtests/delete-at-next-to-svg-display-table-cell.html new file mode 100644 index 0000000000..edb38bb9df --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/delete-at-next-to-svg-display-table-cell.html @@ -0,0 +1,18 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<script> +addEventListener("load", async () => { + document.documentElement.setAttribute("contenteditable", "true"); + getSelection().collapse(document.body.lastChild, document.body.lastChild.length); + document.execCommand("delete"); +}); +</script> +</head> +<body><svg> + <svg display="table-cell"> + </svg> +</svg> +</body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/delete-at-start-of-first-li-in-ol-in-video.html b/testing/web-platform/tests/editing/crashtests/delete-at-start-of-first-li-in-ol-in-video.html new file mode 100644 index 0000000000..43baf25a86 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/delete-at-start-of-first-li-in-ol-in-video.html @@ -0,0 +1,24 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<script> +addEventListener("DOMContentLoaded", () => { + getSelection().collapse(document.querySelector("ol"), 0); + document.execCommand("delete"); +}); +</script> +</head> +<body> +<details open contenteditable> +<map> +<video> +<source></source> +<ol> +<li>a</li> +</ol> +</video> +</map> +</details> +</body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/delete-at-text-following-svg.html b/testing/web-platform/tests/editing/crashtests/delete-at-text-following-svg.html new file mode 100644 index 0000000000..cc2040a2a3 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/delete-at-text-following-svg.html @@ -0,0 +1,41 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<style> +mask, li { + float: inline-start; + animation-name: kf0; +} +@keyframes kf0 {} +</style> +<script> +document.addEventListener("DOMContentLoaded", () => { + window.focus(); + document.designMode = "on"; + document.onpointerlockerror = onPointerLockErrorOrAnimationStart; + const mask = document.querySelector("mask"); + mask.requestPointerLock(); + mask.prepend(document.querySelector("table")); +}); +function onPointerLockErrorOrAnimationStart() { + document.execCommand("underline"); + document.execCommand("delete"); + onanimationstart = onPointerLockErrorOrAnimationStart; + try { + getSelection().setBaseAndExtent( + document.querySelector("li"), 0, + document.querySelector("thead"), 0 + ); + } catch (e) {} +} +</script> +<body><svg> +<mask> +<clipPath> +</clipPath></mask></svg><sup> +AA +<li> +<br></li></sup><table> +<thead> +</thead></table> diff --git a/testing/web-platform/tests/editing/crashtests/delete-content-in-no-data-object.html b/testing/web-platform/tests/editing/crashtests/delete-content-in-no-data-object.html new file mode 100644 index 0000000000..749dba303b --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/delete-content-in-no-data-object.html @@ -0,0 +1,31 @@ +<!doctype html> +<html class="test-wait"> +<head> +<meta charset="utf-8"> +<script> +document.addEventListener("DOMContentLoaded", () => { + requestAnimationFrame(() => { + setTimeout(() => { + document.execCommand("delete"); + document.documentElement.removeAttribute("class"); + }, 0); + document.execCommand("insertImage", false, "x"); + }); + document.execCommand("justifyCenter"); +}) +function onError() { + document.querySelector("s").before("BEFORE"); + document.designMode = "on"; + const img = document.querySelector("img"); + img.innerHTML = "IMG"; + getSelection().setBaseAndExtent(document.querySelector("kbd"), 0, img, 1); +} +</script> +</head> +<body><object onerror="onError()"> +<s> +<img> +SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS +<kbd> +</kbd></s></object></body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/delete-from-after-empty-table-header-grouped-element.html b/testing/web-platform/tests/editing/crashtests/delete-from-after-empty-table-header-grouped-element.html new file mode 100644 index 0000000000..e6ad4fa9e3 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/delete-from-after-empty-table-header-grouped-element.html @@ -0,0 +1,16 @@ +<!doctype html> +<html> +<head> +<meta char="utf-8"> +<script> +addEventListener("load", () => { + document.documentElement.contentEditable = true; + getSelection().collapse(document.querySelector("svg"), document.querySelector("svg").childNodes.length); + document.execCommand("delete"); +}); +</script> +<body> +<svg> + <a display="table-header-group"> + </a> + </svg></body></html>
\ No newline at end of file diff --git a/testing/web-platform/tests/editing/crashtests/delete-from-ruby-at-start-of-button.html b/testing/web-platform/tests/editing/crashtests/delete-from-ruby-at-start-of-button.html new file mode 100644 index 0000000000..0159e52815 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/delete-from-ruby-at-start-of-button.html @@ -0,0 +1,29 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<style> +*:last-child { + white-space: pre-wrap; +} +</style> +<script> +addEventListener("DOMContentLoaded", () => { + getSelection().collapse(document.querySelector("ruby")); + document.designMode = "on"; + document.execCommand("delete"); +}); +</script> +</head> +<body> +<label contenteditable="true"></label> +<bdi style="white-space: nowrap"> +<button> +<kbd> +<ruby> +</ruby> +</kbd> +</button> +</bdi> +</body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/delete-immediately-after-changing-input-type-from-time.html b/testing/web-platform/tests/editing/crashtests/delete-immediately-after-changing-input-type-from-time.html new file mode 100644 index 0000000000..e608b8c866 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/delete-immediately-after-changing-input-type-from-time.html @@ -0,0 +1,23 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<script> +document.addEventListener("DOMContentLoaded", () => { + const input = document.querySelector("input"); + requestAnimationFrame(() => { + document.body.appendChild(document.querySelector("time")); + input.value = "A"; + }); + input.focus(); + input.setAttribute("type", "text"); + document.execCommand("delete"); +}); +</script> +</head> +<body> +<input type="time"> +<time> +<dir> +<li></li></dir></time></body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/delete-in-block-in-progress.html b/testing/web-platform/tests/editing/crashtests/delete-in-block-in-progress.html new file mode 100644 index 0000000000..233b834ab0 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/delete-in-block-in-progress.html @@ -0,0 +1,25 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<script> +document.addEventListener("DOMContentLoaded", () => { + document.querySelector("mo").appendChild(document.querySelector("dialog")); + getSelection().collapse(document.querySelector("template"), 0); + document.execCommand("delete"); +}, {once:true}); +</script> +<body> +<dialog> +<template> +</template> +</dialog> +<dl contenteditable> +<li> +<b><progress> +<mo>a</mo> +</progress></b> +</li> +</dl> +</body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/delete-in-dd-editing-host-after-selectall-with-focus.html b/testing/web-platform/tests/editing/crashtests/delete-in-dd-editing-host-after-selectall-with-focus.html new file mode 100644 index 0000000000..585cd17bb8 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/delete-in-dd-editing-host-after-selectall-with-focus.html @@ -0,0 +1,12 @@ +<script> +addEventListener("DOMContentLoaded", () => { + document.querySelector("dd[contenteditable]").focus(); + document.querySelector("dd[contenteditable]").addEventListener("DOMNodeRemoved", () => { + document.querySelector("h6").textContent = ""; + }); + document.execCommand("selectAll"); + document.execCommand("delete"); +}) +</script> +<h6> +<dd contenteditable> diff --git a/testing/web-platform/tests/editing/crashtests/delete-in-dd-editing-host-after-selectall-without-focus.html b/testing/web-platform/tests/editing/crashtests/delete-in-dd-editing-host-after-selectall-without-focus.html new file mode 100644 index 0000000000..a45f2dad82 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/delete-in-dd-editing-host-after-selectall-without-focus.html @@ -0,0 +1,12 @@ +<script> +addEventListener("DOMContentLoaded", () => { + document.querySelector("dd[contenteditable]").blur(); + document.querySelector("dd[contenteditable]").addEventListener("DOMNodeRemoved", () => { + document.querySelector("h6").textContent = ""; + }); + document.execCommand("selectAll"); + document.execCommand("delete"); +}) +</script> +<h6> +<dd contenteditable> diff --git a/testing/web-platform/tests/editing/crashtests/delete-in-designMode-without-explicitly-setting-focus.html b/testing/web-platform/tests/editing/crashtests/delete-in-designMode-without-explicitly-setting-focus.html new file mode 100644 index 0000000000..16e1808dc8 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/delete-in-designMode-without-explicitly-setting-focus.html @@ -0,0 +1,17 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<script> +document.addEventListener("DOMContentLoaded", () => { + const dl = document.querySelector("dl"); + dl.textContent = "�"; + document.designMode = "on"; + document.execCommand("delete"); +}) +</script> +</head> +<del> + <dl></dl> +</del> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/delete-in-empty-editable-list-followed-by-non-editable-listitem.html b/testing/web-platform/tests/editing/crashtests/delete-in-empty-editable-list-followed-by-non-editable-listitem.html new file mode 100644 index 0000000000..9e872f5ac4 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/delete-in-empty-editable-list-followed-by-non-editable-listitem.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<html id="a"> +<meta charset="utf-8"> +<script id="b"> +window.onload = () => { + c.appendChild(document.head) + a.appendChild(d) + document.execCommand("selectAll") + document.execCommand("delete") +} +</script> +<dl id="c" contenteditable="true"> +<dt id="d"> diff --git a/testing/web-platform/tests/editing/crashtests/designMode-document-will-be-blurred-by-focus-event-listener.html b/testing/web-platform/tests/editing/crashtests/designMode-document-will-be-blurred-by-focus-event-listener.html new file mode 100644 index 0000000000..3cd6509c4b --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/designMode-document-will-be-blurred-by-focus-event-listener.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html class="test-wait"> +<meta charset="utf-8"> +<script> +addEventListener("load", () => { + const parentDocument = document; + const iframe = parentDocument.querySelector("iframe"); + iframe.contentDocument.designMode = "on"; + iframe.contentWindow.addEventListener("focus", () => { + iframe.contentDocument.execCommand("insertText", false, "def"); + iframe.parentElement.setAttribute("hidden", "hidden"); + setTimeout(() => parentDocument.documentElement.removeAttribute("class"), 0); + }); + iframe.contentWindow.focus(); +}); +</script> +<div><iframe srcdoc="<div>abc</div>"></iframe></div> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/designMode-off-during-inserthorizontalrule.html b/testing/web-platform/tests/editing/crashtests/designMode-off-during-inserthorizontalrule.html new file mode 100644 index 0000000000..21a6199898 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/designMode-off-during-inserthorizontalrule.html @@ -0,0 +1,22 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<script> +document.addEventListener("DOMContentLoaded", () => { + document.designMode = "on"; + document.addEventListener("DOMNodeRemoved", () => { + document.documentElement.normalize(); + document.designMode = "off"; + }); + getSelection().collapse(document.querySelector("address").firstChild, 1); + document.execCommand("insertHorizontalRule"); +}); +</script> +</head> +<body> +<address> +A +</address> +</body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/designMode-on-of-lazy-loading-iframe.html b/testing/web-platform/tests/editing/crashtests/designMode-on-of-lazy-loading-iframe.html new file mode 100644 index 0000000000..90a6c85c45 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/designMode-on-of-lazy-loading-iframe.html @@ -0,0 +1,20 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<style> +*::first-letter {} +</style> +<script> +addEventListener("load", () => { + const iframe = document.querySelector("iframe"); + iframe.contentWindow.focus(); + document.styleSheets[0].deleteRule(0); + iframe.contentWindow.document.designMode = "on"; +}); +</script> +</head> +<body> +<iframe loading="lazy"> +</body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/execCommand-at-load-with-changing-editing-host.html b/testing/web-platform/tests/editing/crashtests/execCommand-at-load-with-changing-editing-host.html new file mode 100644 index 0000000000..ec1dd30dc0 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/execCommand-at-load-with-changing-editing-host.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<html contenteditable="true"> +<head> +<meta charset="utf-8"> +<title>Test for bug 615450 of Mozilla</title> +<script> +function boom() +{ + document.documentElement.appendChild(document.body); + document.documentElement.contentEditable = "false"; + try { document.execCommand("outdent", false, null); } catch(e) { } + document.body.contentEditable = "true"; + try { document.execCommand("inserthtml", false, "x"); } catch(e) { } +} +</script> +</head> +<body onload="boom();"><div style="margin-left: 40px;"><span contenteditable="true">p q r s</span> T</div></body></html> diff --git a/testing/web-platform/tests/editing/crashtests/execCommand-backcolor-and-hilitecolor-in-empty-iframe-in-designMode.html b/testing/web-platform/tests/editing/crashtests/execCommand-backcolor-and-hilitecolor-in-empty-iframe-in-designMode.html new file mode 100644 index 0000000000..0750dddca7 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/execCommand-backcolor-and-hilitecolor-in-empty-iframe-in-designMode.html @@ -0,0 +1,116 @@ +<!DOCTYPE HTML> +<html><head> + <meta charset="iso-8859-1"> + <title>Testcase #3 for bug 448329 of Bugzilla</title> +</head> +<body> + +<iframe id="frame448329"></iframe> + +<script> + +function test448329(id,cmd,val) { + + var elm = document.getElementById(id); + var doc = elm.contentDocument; + doc.designMode = "On"; + + doc.body.offsetWidth; + var selection = doc.defaultView.getSelection(); + + // Test document node + if (selection.rangeCount > 0) { + selection.removeAllRanges(); + } + var range = doc.createRange(); + range.setStart(doc, 0); + range.setEnd(doc, 0); + selection.addRange(range); + doc.execCommand(cmd,false,val); + + // Test HTML node + if (selection.rangeCount > 0) { + selection.removeAllRanges(); + } + range = doc.createRange(); + range.setStart(doc.documentElement, 0); + range.setEnd(doc.documentElement, 0); + selection.addRange(range); + doc.execCommand(cmd,false,val); + + // Test BODY node + if (selection.rangeCount > 0) { + selection.removeAllRanges(); + } + range = doc.createRange(); + var body = doc.documentElement.childNodes[1]; + range.setStart(body, 0); + range.setEnd(body, 0); + selection.addRange(range); + doc.execCommand(cmd,false,val); + + var text = doc.createTextNode("Hello Kitty"); + body.insertBefore(text, null) + + // Test TEXT node + if (selection.rangeCount > 0) { + selection.removeAllRanges(); + } + range = doc.createRange(); + range.setStart(text, 0); + range.setEnd(text, 1); + selection.addRange(range); + doc.execCommand(cmd,false,val); + + // Test BODY[0,0] + TEXT node + if (selection.rangeCount > 0) { + selection.removeAllRanges(); + } + range = doc.createRange(); + range.setStart(body, 0); + range.setEnd(body, 0); + selection.addRange(range); + range = doc.createRange(); + range.setStart(text, 0); + range.setEnd(text, 1); + selection.addRange(range); + doc.execCommand(cmd,false,val); + + // Test BODY[0,1] + TEXT node + if (selection.rangeCount > 0) { + selection.removeAllRanges(); + } + range = doc.createRange(); + range.setStart(body, 0); + range.setEnd(body, 1); + selection.addRange(range); + range = doc.createRange(); + range.setStart(text, 0); + range.setEnd(text, 1); + selection.addRange(range); + doc.execCommand(cmd,false,val); + + // Test BODY[0,1] + TEXT node without a parent + if (selection.rangeCount > 0) { + selection.removeAllRanges(); + } + range = doc.createRange(); + range.setStart(body, 0); + range.setEnd(body, 1); + selection.addRange(range); + range = doc.createRange(); + text = doc.createTextNode("Hello there"); // not in doc + range.setStart(text, 0); + range.setEnd(text, 1); + selection.addRange(range); + doc.execCommand(cmd,false,val); +} + +test448329("frame448329", "backcolor", "green") +test448329("frame448329", "hilitecolor", "green") + +</script> + + +</body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/execCommand-without-selection-ranges.html b/testing/web-platform/tests/editing/crashtests/execCommand-without-selection-ranges.html new file mode 100644 index 0000000000..04913664e6 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/execCommand-without-selection-ranges.html @@ -0,0 +1,65 @@ +<!doctype html> +<head> +<meta charset="utf-8"> +</head> +<body> +<script> +for (const command of [ + ["bold", ""], + ["italic", ""], + ["underline", ""], + ["strikethrough", ""], + ["subscript", ""], + ["superscript", ""], + ["cut", ""], + ["copy", ""], + ["paste", ""], + ["delete", ""], + ["forwarddelete", ""], + ["selectall", ""], + ["undo", ""], + ["redo", ""], + ["indent", ""], + ["outdent", ""], + ["backcolor", "#888888"], + ["forecolor", "#888888"], + ["hilitecolor", "#888888"], + ["fontname", "Courier"], + ["fontsize", "6"], + ["increasefontsize", ""], + ["decreasefontsize", ""], + ["inserthorizontalrule", ""], + ["createlink", "foo"], + ["insertimage", "foo"], + ["inserthtml", "foo"], + ["inserttext", "foo"], + ["insertparagraph", ""], + ["gethtml", ""], + ["justifyleft", ""], + ["justifyright", ""], + ["justifycenter", ""], + ["justifyfull", ""], + ["removeformat", ""], + ["unlink", ""], + ["insertorderedlist", ""], + ["insertunorderedlist", ""], + ["formatblock", "h1"], + ["heading", "h1"], + ["stylewithcss", "true"], + ["usecss", "true"], + ["contentreadonly", "true"], + ["readonly", "true"], + ["insertbronreturn", "true"], + ["enableobjectresizing", "true"], + ["enableinlinetableediting", "true"], +]) { + document.body.innerHTML = "<div contenteditable>abc</div>"; + document.querySelector("div[contenteditable]").focus(); + getSelection().removeAllRanges(); + try { + document.execCommand(command[0], false, command[1]); + } catch(e) {} +} +</script> +</body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/format-block-selection-containing-non-editable-list.html b/testing/web-platform/tests/editing/crashtests/format-block-selection-containing-non-editable-list.html new file mode 100644 index 0000000000..2f8f8ea5ab --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/format-block-selection-containing-non-editable-list.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> +<head> + <script> + window.addEventListener('load', () => { + document.execCommand('selectAll', false, null) + document.execCommand('formatBlock', false, 'h1') + }) + </script> +</head> +<body> +<main contenteditable='true'> + <li></li> + <ol contenteditable='false'> + </ol> +</main> +</body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/forwarddelete-after-editable-slot-element-outside-body.html b/testing/web-platform/tests/editing/crashtests/forwarddelete-after-editable-slot-element-outside-body.html new file mode 100644 index 0000000000..480f02ded9 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/forwarddelete-after-editable-slot-element-outside-body.html @@ -0,0 +1,28 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<script> +document.addEventListener("DOMContentLoaded", () => { + const slot = document.createElement("slot"); + document.documentElement.appendChild(slot); + const anchor = document.querySelector("a[contenteditable]"); + const selection = document.getSelection() + getSelection().collapse(anchor, 0); + getSelection().setBaseAndExtent( + document, 0, + document.documentElement, document.documentElement.childNodes.length + ); + const range = selection.getRangeAt(0); + document.documentElement.contentEditable = true; + document.documentElement.contentEditable = false; + range.collapse(false); + getSelection().removeAllRanges(); + getSelection().addRange(range); + document.documentElement.contentEditable = true; + document.execCommand("forwardDelete"); +}); +</script> +</head><body> +<a contenteditable></a> +</body></html> diff --git a/testing/web-platform/tests/editing/crashtests/forwarddelete-at-empty-text-node-in-body.html b/testing/web-platform/tests/editing/crashtests/forwarddelete-at-empty-text-node-in-body.html new file mode 100644 index 0000000000..4fba13d5d8 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/forwarddelete-at-empty-text-node-in-body.html @@ -0,0 +1,8 @@ +<body contenteditable=true>x y +<script> +document.body.firstChild.splitText(2) // "x " and " y" + .splitText(1) // "x", " " and " y" + .splitText(1); // "x", "", " " and " y" +getSelection().collapse(document.body, 1); +document.execCommand("forwardDelete"); +</script> diff --git a/testing/web-platform/tests/editing/crashtests/forwarddelete-delete-after-justifyleft-indent.html b/testing/web-platform/tests/editing/crashtests/forwarddelete-delete-after-justifyleft-indent.html new file mode 100644 index 0000000000..0b0e188732 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/forwarddelete-delete-after-justifyleft-indent.html @@ -0,0 +1,20 @@ +<script> +document.addEventListener("DOMContentLoaded", () => { + const fieldset = document.querySelector("fieldset"); + document.documentElement.contentEditable = true; + fieldset.contentEditable = false; + document.execCommand("justifyLeft"); + document.designMode = "on"; + document.execCommand("indent"); + document.execCommand("forwardDelete"); + document.execCommand("delete"); +}); +</script> +<acronym readonly autofocus> +<sup> +<fieldset> + +here is fieldset +</fieldset> +</acronym> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/forwarddelete-in-list-editing-host-after-selectall-with-focus.html b/testing/web-platform/tests/editing/crashtests/forwarddelete-in-list-editing-host-after-selectall-with-focus.html new file mode 100644 index 0000000000..266cc4fb60 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/forwarddelete-in-list-editing-host-after-selectall-with-focus.html @@ -0,0 +1,15 @@ +<script> +addEventListener("load", () => { + document.querySelector("ol[contenteditable]").focus(); + document.execCommand("selectAll"); + const targetListItem = document.querySelector("li + li"); + targetListItem.addEventListener("DOMSubtreeModified", () => { + document.execCommand("forwardDelete"); + document.querySelector("script").appendChild(targetListItem); + }); + targetListItem.setAttribute("scrolling", "auto"); +}); +</script> +<ol contenteditable> +<li> +<li>a</li> diff --git a/testing/web-platform/tests/editing/crashtests/forwarddelete-in-list-editing-host-after-selectall-without-focus.html b/testing/web-platform/tests/editing/crashtests/forwarddelete-in-list-editing-host-after-selectall-without-focus.html new file mode 100644 index 0000000000..de10e8b8a9 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/forwarddelete-in-list-editing-host-after-selectall-without-focus.html @@ -0,0 +1,15 @@ +<script> +addEventListener("load", () => { + document.querySelector("ol[contenteditable]").blur(); + document.execCommand("selectAll"); + const targetListItem = document.querySelector("li + li"); + targetListItem.addEventListener("DOMSubtreeModified", () => { + document.execCommand("forwardDelete"); + document.querySelector("script").appendChild(targetListItem); + }); + targetListItem.setAttribute("scrolling", "auto"); +}); +</script> +<ol contenteditable> +<li> +<li>a</li> diff --git a/testing/web-platform/tests/editing/crashtests/forwarddelete-in-text-in-span-in-editable-documentElement.html b/testing/web-platform/tests/editing/crashtests/forwarddelete-in-text-in-span-in-editable-documentElement.html new file mode 100644 index 0000000000..26f2f64b81 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/forwarddelete-in-text-in-span-in-editable-documentElement.html @@ -0,0 +1,15 @@ +<!doctype html> +<script> +addEventListener("load", () => { + const r = document.documentElement; + while (r.firstChild) { + r.firstChild.remove(); + } + + document.documentElement.contentEditable = "true"; + document.documentElement.appendChild(document.createElement("span")); + document.documentElement.firstChild.appendChild(document.createTextNode("_")); + document.execCommand("forwarddelete"); +}); +</script> +<body> diff --git a/testing/web-platform/tests/editing/crashtests/indent-in-inline-editing-host-outside-body.html b/testing/web-platform/tests/editing/crashtests/indent-in-inline-editing-host-outside-body.html new file mode 100644 index 0000000000..d56a0fd248 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/indent-in-inline-editing-host-outside-body.html @@ -0,0 +1,18 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<script> +addEventListener("load", () => { + const samp = document.createElement("samp"); + samp.innerText = "ABC"; + samp.contentEditable = true; + document.documentElement.appendChild(samp); + getSelection().selectAllChildren(samp); + document.execCommand("indent"); +}); +</script> +</head> +<body> +</body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/indent-in-textarea-in-designMode-during-outdent.html b/testing/web-platform/tests/editing/crashtests/indent-in-textarea-in-designMode-during-outdent.html new file mode 100644 index 0000000000..313c51bb5a --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/indent-in-textarea-in-designMode-during-outdent.html @@ -0,0 +1,34 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +</head> +<body> +A +<script> +addEventListener("load", () => { + const textarea = document.querySelector("textarea"); + textarea.addEventListener("focusin", onFocusIn); + textarea.select(); + document.execCommand("outdent"); +}); + +function onFocusIn() { + document.querySelector("marquee").onstart = () => { + document.designMode = "off"; + window.find("AA"); + }; + document.designMode = "on"; + document.execCommand("selectAll"); + document.execCommand("indent"); + document.designMode = "on"; +} +</script> +<fieldset> +<textarea></textarea> +AA +</fieldset> +<marquee id="b"></marquee> +<blockquote contenteditable="true"></blockquote> +</body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/indent-outdent-after-closing-editable-dialog-element.html b/testing/web-platform/tests/editing/crashtests/indent-outdent-after-closing-editable-dialog-element.html new file mode 100644 index 0000000000..7f73de048d --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/indent-outdent-after-closing-editable-dialog-element.html @@ -0,0 +1,31 @@ +<html class="reftest-wait"> +<script> +var eventCount = 0; +document.addEventListener("DOMContentLoaded", () => { + const dialog = document.querySelector("dialog"); + const object = document.createElement("object"); + object.addEventListener("DOMSubtreeModified", () => { + dialog.show(); + dialog.focus(); + document.execCommand("selectAll"); + dialog.close(); + setTimeout(() => { + document.execCommand("selectAll"); + document.execCommand("strikeThrough"); + document.execCommand("indent"); + document.execCommand("outdent"); + eventCount--; + if (!eventCount) { + document.documentElement.removeAttribute("class"); + } + }); + eventCount++; + }); + object.setAttribute("role", "x"); // Run DOMSubtreeModified + object.setAttribute("role", "y"); // Run DOMSubtreeModified + document.execCommand("forwardDelete"); + document.execCommand("justifyRight"); +}) +</script> +<dialog id="a" contenteditable="true">a</dialog> +</html>
\ No newline at end of file diff --git a/testing/web-platform/tests/editing/crashtests/insert-image-with-joining-header-element-and-body.html b/testing/web-platform/tests/editing/crashtests/insert-image-with-joining-header-element-and-body.html new file mode 100644 index 0000000000..cf5b2df225 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/insert-image-with-joining-header-element-and-body.html @@ -0,0 +1,24 @@ +<!DOCTYPE html> +<html> +<head> + <script> + window.addEventListener("load", () => { + const heading = document.getElementById("heading") + const input = document.createElementNS("http://www.w3.org/1999/xhtml", "input") + heading.appendChild(input) + const selection = window.getSelection() + const range = new Range() + range.setStartBefore(input) + heading.contentEditable = true + document.execCommand("selectAll", false, null) + document.designMode = "on" + selection.addRange(range) + range.setEndBefore(heading) + range.setEndAfter(heading) + document.execCommand("insertImage", false, "wss://:pass@[::1]$/") + }) + </script> +</head> +<h4 id="heading"></h4> +<!-- COMMENT --> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/insertAdjacentElement-with-DOMSubtreeModified.html b/testing/web-platform/tests/editing/crashtests/insertAdjacentElement-with-DOMSubtreeModified.html new file mode 100644 index 0000000000..4b9533282d --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/insertAdjacentElement-with-DOMSubtreeModified.html @@ -0,0 +1,26 @@ +<!DOCTYPE html> +<head> +<script src="../resources/js-test.js"></script> +<script> +function onLoad() { + const x1 = document.getElementById('x1'); + x1.addEventListener('DOMSubtreeModified', () => { + const x2 = document.getElementById('x2'); + x2.contentDocument; + }); + x1.setAttribute('inputmode', 'url'); +} +function insertAdjacent() { + const x2 = document.getElementById('x2'); + const x3 = document.getElementById('x3'); + document.onreadystatechange = insertAdjacent; + x3.insertAdjacentElement('beforebegin', x2); +} +</script> +</head> +<body onload="onLoad()"> +<div id="x1"></div> +<object id="x2" data="invalid-url" onerror="insertAdjacent()"></object> +<div id="x3"></div> +</body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/insertText-at-end-of-text-in-body.html b/testing/web-platform/tests/editing/crashtests/insertText-at-end-of-text-in-body.html new file mode 100644 index 0000000000..763697314b --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/insertText-at-end-of-text-in-body.html @@ -0,0 +1,16 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<script> +addEventListener("load", event => { + document.body.focus(); + const text = document.createTextNode("x".repeat(15)); + document.body.appendChild(text); + getSelection().collapse(text, text.length); + document.execCommand("insertText", false, "a"); +}); +</script> +</head> +<body contenteditable></body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/insertText-nested-by-DOMSubtreeModified.html b/testing/web-platform/tests/editing/crashtests/insertText-nested-by-DOMSubtreeModified.html new file mode 100644 index 0000000000..45b0e67ed4 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/insertText-nested-by-DOMSubtreeModified.html @@ -0,0 +1,29 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<script> +document.addEventListener("DOMContentLoaded", () => { + const output = document.querySelector("output"); + const table = document.querySelector("table"); + table.addEventListener("DOMSubtreeModified", () => { + document.execCommand("bold"); + document.execCommand("hiliteColor", false, "white"); + output.appendChild(table); + document.execCommand("forwardDelete"); + table.setAttribute("onwebkitsourceclose", "foo()"); + document.execCommand("insertText", false, "a"); + }); + document.execCommand("selectAll"); + table.insertRow(); +}); +</script> +</head> +<body> +<canvas contenteditable> +<output> +<table tabindex="0" autofocus></table> +</output> +</canvas> +</body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/inserthorizontalrule-in-fieldset-and-everything-styled-white-space-pre.html b/testing/web-platform/tests/editing/crashtests/inserthorizontalrule-in-fieldset-and-everything-styled-white-space-pre.html new file mode 100644 index 0000000000..d06157e784 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/inserthorizontalrule-in-fieldset-and-everything-styled-white-space-pre.html @@ -0,0 +1,25 @@ +<!DOCTYPE html> +<html> +<head> + <style> + * { + white-space: pre + } + </style> + <script> + document.addEventListener('DOMContentLoaded', () => { + const quote_0 = document.getElementById('id_0') + const quote_1 = document.createElement('blockquote') + const fieldset_1 = document.createElement('fieldset') + quote_1.appendChild(fieldset_1) + document.documentElement.appendChild(quote_1) + const selection = self.getSelection() + selection.collapse(fieldset_1, 0) + quote_0.contentEditable = false + document.documentElement.contentEditable = true + document.execCommand('insertHorizontalRule', false, null) + }) + </script> +</head> +<blockquote id='id_0'></blockquote> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/inserthorizontalrule-in-textarea-in-editor-and-undo-on-error-events.html b/testing/web-platform/tests/editing/crashtests/inserthorizontalrule-in-textarea-in-editor-and-undo-on-error-events.html new file mode 100644 index 0000000000..204f75a89f --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/inserthorizontalrule-in-textarea-in-editor-and-undo-on-error-events.html @@ -0,0 +1,31 @@ +<!doctype html> +<html class="test-wait"> +<head> +<meta charset="utf-8"> +<script> +var count = 0; +function onError() { + if (++count > 2) { + document.documentElement.removeAttribute("class"); + return; + } + const object = document.getElementById("a"); + const mi = document.getElementById("b"); + object.data = ""; + object.appendChild(document.getElementById("c")); + mi.appendChild(document.getElementById("c")); + getSelection().collapse(document.getElementById("c"), 0); + document.execCommand("undo"); + document.execCommand("insertHorizontalRule"); +} +</script> +</head> +<body> +<textarea id="c">a</textarea> +<dt contenteditable="true"> +<mi id="b">#</mi> +<object id="a" onerror="onError()"> +</object> +</dt> +</body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/inserthorizontalrule-with-2-selection-ranges-and-one-is-outside-body.html b/testing/web-platform/tests/editing/crashtests/inserthorizontalrule-with-2-selection-ranges-and-one-is-outside-body.html new file mode 100644 index 0000000000..d248c333d9 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/inserthorizontalrule-with-2-selection-ranges-and-one-is-outside-body.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<script> +document.addEventListener('DOMContentLoaded', () => { + const form = document.createElement("form"); + const range = new Range(); + document.documentElement.contentEditable = true; + document.execCommand("formatBlock", false, "h3"); + document.documentElement.appendChild(form); + range.setStartBefore(form); + getSelection().addRange(range); + range.selectNode(form); + document.execCommand("insertHorizontalRule"); +}); +</script> +</head> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/inserthorizontalrule-with-range-ending-in-collapsible-spaces-before-comment.html b/testing/web-platform/tests/editing/crashtests/inserthorizontalrule-with-range-ending-in-collapsible-spaces-before-comment.html new file mode 100644 index 0000000000..d7224c3095 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/inserthorizontalrule-with-range-ending-in-collapsible-spaces-before-comment.html @@ -0,0 +1,25 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<script> +document.addEventListener("DOMContentLoaded", () => { + getSelection().setBaseAndExtent( + document.querySelector("b"), 0, + document.querySelector("i").firstChild, 2 + ); + document.documentElement.contentEditable = true; + document.execCommand("insertHorizontalRule"); +}); +</script> +</head> +<body> +<div> +<b> +</b> +<i>X +</i> +<!-- COMMENT --> +</div> +</body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/inserthorizontalrule-with-selecting-text-in-document-element.html b/testing/web-platform/tests/editing/crashtests/inserthorizontalrule-with-selecting-text-in-document-element.html new file mode 100644 index 0000000000..c46b0359e8 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/inserthorizontalrule-with-selecting-text-in-document-element.html @@ -0,0 +1,18 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<script> +document.addEventListener("DOMContentLoaded", () => { + const text = document.createTextNode("abc"); + document.documentElement.appendChild(text); + const range = new Range(); + range.selectNodeContents(text); + document.documentElement.contentEditable = "true"; + document.execCommand("insertUnorderedList"); + getSelection().addRange(range); + document.execCommand("insertHorizontalRule"); +}); +</script> +</head> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/inserthtml-after-temporarily-removing-document-element.html b/testing/web-platform/tests/editing/crashtests/inserthtml-after-temporarily-removing-document-element.html new file mode 100644 index 0000000000..7245fe3ddc --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/inserthtml-after-temporarily-removing-document-element.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<html class="test-wait"> +<head> +<meta charset="utf-8"> +<title>Testcase for bug 716456 of Mozilla</title> +<script> +function boom() { + const div = document.querySelector("div"); + div.contentEditable = "true"; + div.focus(); + + const root = document.documentElement; + document.removeChild(root); + document.appendChild(root); + + setTimeout(() => { + getSelection().collapse(div, 0); + document.execCommand("inserthtml", false, "a"); + setTimeout(() => { + document.documentElement.removeAttribute("class"); + }, 0); + }, 0); +} +</script> +</head> +<body onload="boom();"><div></div></body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/inserthtml-in-inline-editing-host-at-load-event.html b/testing/web-platform/tests/editing/crashtests/inserthtml-in-inline-editing-host-at-load-event.html new file mode 100644 index 0000000000..22f172856a --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/inserthtml-in-inline-editing-host-at-load-event.html @@ -0,0 +1,7 @@ +<html> +<head> +</head> + +<body onload="try { document.execCommand('inserthtml', false, '0'); } catch(e) { }"><span id="textarea" contenteditable="true">is</span></body> + +</html> diff --git a/testing/web-platform/tests/editing/crashtests/inserthtml-in-li-in-option.html b/testing/web-platform/tests/editing/crashtests/inserthtml-in-li-in-option.html new file mode 100644 index 0000000000..c8aa9f780f --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/inserthtml-in-li-in-option.html @@ -0,0 +1,25 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<script> +"use strict"; +document.addEventListener("DOMContentLoaded", () => { + const select = document.querySelector("select"); + select.appendChild(document.querySelector("option")); + select.appendChild(document.createElement("optgroup")); + document.querySelector("p").appendChild(document.querySelector("li[contenteditable]")); + getSelection().collapse(document.querySelector("output"), 0); + document.execCommand("insertHTML", false, select.innerHTML); +}); +</script> +</head> +<body> +<dl> +<select>a</select> +<p></p> +<option> +<li contenteditable> +<output> +</output><li></option></dl></body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/inserthtml-in-text-adopted-to-other-document.html b/testing/web-platform/tests/editing/crashtests/inserthtml-in-text-adopted-to-other-document.html new file mode 100644 index 0000000000..d8234f917a --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/inserthtml-in-text-adopted-to-other-document.html @@ -0,0 +1,52 @@ +<!DOCTYPE html> +<html class="test-wait"> +<head> +<script> +function init1() +{ + targetIframe = document.createElementNS('http://www.w3.org/1999/xhtml', 'iframe'); + targetIframe.srcdoc = "<html></html>"; + targetIframe.setAttribute("style", "width: 300px; height: 200px; border: 1px dotted green;"); + targetIframe.addEventListener("load", init2); + document.body.appendChild(targetIframe); +} + +function init2() +{ + targetWindow = targetIframe.contentWindow; + targetDocument = targetWindow.document; + + var div = document.getElementById("div"); + textNode = div.firstChild; + + targetDocument.body.appendChild(targetDocument.adoptNode(div, true)); + + targetDocument.designMode = 'on'; + setTimeout(init3, 0); +} + +function init3() +{ + var rng = targetDocument.createRange(); + rng.setStart(textNode, 1); + rng.setEnd(textNode, 1); + targetWindow.getSelection().addRange(rng); + + try { + targetDocument.execCommand("inserthtml", false, "<p>"); + } catch(e) {} + + document.documentElement.removeAttribute("class"); +} +</script> + +</head> + +<body onload="init1();"> + +<div id="div"> </div> + +<script> +</script> +</body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/inserthtml-indent-delete-when-input-element-in-editing-host-has-focus.html b/testing/web-platform/tests/editing/crashtests/inserthtml-indent-delete-when-input-element-in-editing-host-has-focus.html new file mode 100644 index 0000000000..ff1eebe041 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/inserthtml-indent-delete-when-input-element-in-editing-host-has-focus.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Test for bug 636074 of Mozilla</title> +<script> +function boom() +{ + document.getElementById("i").focus(); + document.documentElement.contentEditable = "true"; + document.execCommand("inserthtml", false, "<table>"); + document.execCommand("indent", false, null); + document.execCommand("delete", false, null); +} +</script> +</head> +<body onload="boom();"><input id="i"></body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/inserthtml-to-replace-root-list-element-in-designMode.html b/testing/web-platform/tests/editing/crashtests/inserthtml-to-replace-root-list-element-in-designMode.html new file mode 100644 index 0000000000..c751a5bebc --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/inserthtml-to-replace-root-list-element-in-designMode.html @@ -0,0 +1,33 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<script> +document.addEventListener("DOMContentLoaded", () => { + document.execCommand("selectAll"); + const editingHost = document.querySelector("thead[contenteditable]"); + editingHost.addEventListener("focus", () => { + editingHost.addEventListener("focusout", () => { + document.execCommand("italic"); + document.execCommand("insertText", false, "A"); + document.execCommand("insertUnorderedList"); + }); + document.designMode = "on"; + document.execCommand("selectAll"); + document.execCommand("insertHTML", false, "A"); + }); + editingHost.focus(); +}); +</script> +</head> +<body> +<big> +</big> +<table> +<thead contenteditable> +</thead></table> +<p> +<object></object> +</p> +</body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/insertimage-with-replacing-selection-in-picture-element.html b/testing/web-platform/tests/editing/crashtests/insertimage-with-replacing-selection-in-picture-element.html new file mode 100644 index 0000000000..aaae4c7c9f --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/insertimage-with-replacing-selection-in-picture-element.html @@ -0,0 +1,47 @@ +<!doctype html> +<html class="test-wait"> +<head> +<meta charset="utf-8"> +<style> +@keyframes keyframes0 {} +picture { + animation: keyframes0 300ms alternate,alternate paused; +} +ruby { + animation: keyframes0 step-start -1.5s normal backwards paused; +} +</style> +<script> +document.addEventListener("DOMContentLoaded", () => { + find("AAA") + const header = document.querySelector("header"); + addEventListener("animationend", () => { + const imgsrc = + "data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAOxAAADsQBlSsOGwAAABh0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjIyt5EXfQAAAU5JREFUeF7t07ENACAMxMDA/jsDBTtcY6TUlmx+zcx510MGNuKG/QYKgL9CAQqADWB8CygANoDxLaAA2ADGt4ACYAMY3wIKgA1gfAsoADaA8S2gANgAxreAAmADGN8CCoANYHwLKAA2gPEtoADYAMa3gAJgAxjfAgqADWB8CygANoDxLaAA2ADGt4ACYAMY3wIKgA1gfAsoADaA8S2gANgAxreAAmADGN8CCoANYHwLKAA2gPEtoADYAMa3gAJgAxjfAgqADWB8CygANoDxLaAA2ADGt4ACYAMY3wIKgA1gfAsoADaA8S2gANgAxreAAmADGN8CCoANYHwLKAA2gPEtoADYAMa3gAJgAxjfAgqADWB8CygANoDxLaAA2ADGt4ACYAMY3wIKgA1gfAsoADaA8S2gANgAxreAAmADGN8CCoANYHwLKAA2gPEtAAe4i54BvwLfXFAAAAAASUVORK5CYII="; + function doIt() { + getSelection().extend(header, 0); + document.querySelector("figure").insertAdjacentElement("beforeend", header); + document.execCommand("insertImage", false, imgsrc); + } + doIt(); + doIt(); + doIt(); + document.documentElement.removeAttribute("class"); + }, {once: true}); + document.designMode = "on"; +}, {once:true}); +</script> +</head> +<body> +<picture autocapitalize="sentences"> +<figure> +<figcaption> +</figure> +<ruby contenteditable="true"> +AAA +<header> +</header> +</ruby> +</picture> +</body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/insertlinebreak-around-comment-node.html b/testing/web-platform/tests/editing/crashtests/insertlinebreak-around-comment-node.html new file mode 100644 index 0000000000..dc2d5e2bd4 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/insertlinebreak-around-comment-node.html @@ -0,0 +1,20 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<script> +document.addEventListener("DOMContentLoaded", () => { + const element_0 = document.createElement("s"); + const element_1 = document.createElement("a"); + const element_2 = document.createElement("l"); + element_2.setAttribute("contenteditable", "true"); + element_1.appendChild(element_2); + element_0.appendChild(element_1); + document.documentElement.appendChild(element_0); + document.designMode = "on"; + document.execCommand("insertLineBreak"); +}); +</script> +</head> +<body><!-- COMMENT --></body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/insertlinebreak-in-map-element-editing-host.html b/testing/web-platform/tests/editing/crashtests/insertlinebreak-in-map-element-editing-host.html new file mode 100644 index 0000000000..c141f89c4e --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/insertlinebreak-in-map-element-editing-host.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<script> + document.addEventListener("DOMContentLoaded", () => { + document.getElementById("id_0").contentEditable = false; + document.querySelector("[contenteditable]").focus(); + document.execCommand("insertLineBreak"); + }) +</script> +<pre> +<ins id="id_0"> +<map contenteditable>
\ No newline at end of file diff --git a/testing/web-platform/tests/editing/crashtests/insertorderedlist-in-focused-inline-editing-host.html b/testing/web-platform/tests/editing/crashtests/insertorderedlist-in-focused-inline-editing-host.html new file mode 100644 index 0000000000..73869af3b5 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/insertorderedlist-in-focused-inline-editing-host.html @@ -0,0 +1,23 @@ +<!DOCTYPE html> +<html class="test-wait"> +<head> +<script type="text/javascript"> + +function boom() +{ + const inlineEditingHost = document.getElementById("s"); + inlineEditingHost.addEventListener("focus", () => { + try { + document.execCommand("insertorderedlist"); + } catch(e) { } + document.documentElement.removeAttribute("class"); + }, {once: true}); + inlineEditingHost.focus(); +} + +</script> +</head> + +<body onload="boom();"><span id="s" contenteditable="true">One<div></div></span><marquee></marquee></body> + +</html> diff --git a/testing/web-platform/tests/editing/crashtests/insertorderedlist-in-text-adopted-to-other-document.html b/testing/web-platform/tests/editing/crashtests/insertorderedlist-in-text-adopted-to-other-document.html new file mode 100644 index 0000000000..e505e5bf2f --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/insertorderedlist-in-text-adopted-to-other-document.html @@ -0,0 +1,49 @@ +<!DOCTYPE html> +<html class="test-wait"> +<head> +<script> +function init1() +{ + // Create an html:iframe in HTML mode (so designMode can be used 320092) + targetIframe = document.createElementNS('http://www.w3.org/1999/xhtml', 'iframe'); + targetIframe.srcdoc = "<html></html>"; + targetIframe.setAttribute("style", "width: 700px; height: 500px; border: 1px dotted green;"); + targetIframe.addEventListener("load", init2); + document.body.appendChild(targetIframe); +} + +function init2() +{ + targetWindow = targetIframe.contentWindow; + targetDocument = targetWindow.document; + + p = document.getElementById("p"); + pText = p.firstChild; + + targetDocument.body.appendChild(targetDocument.adoptNode(p, true)); + + targetDocument.designMode = 'on'; + + setTimeout(boom, 0); +} + +function boom() +{ + var rng = targetDocument.createRange(); + rng.setStart(pText, 3); + rng.setEnd(pText, 3); + + targetWindow.getSelection().addRange(rng); + + targetDocument.execCommand("insertorderedlist", false, null); + + document.documentElement.removeAttribute("class") +} +</script> +</head> + +<body onload="init1();"> +<p id="p">word word</p> +</body> + +</html> diff --git a/testing/web-platform/tests/editing/crashtests/insertparagraph-from-DOMNodeInserted-caused-by-insertorderedlist.html b/testing/web-platform/tests/editing/crashtests/insertparagraph-from-DOMNodeInserted-caused-by-insertorderedlist.html new file mode 100644 index 0000000000..fa322420cb --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/insertparagraph-from-DOMNodeInserted-caused-by-insertorderedlist.html @@ -0,0 +1,23 @@ +<html> +<head> +<script type="text/javascript"> + +function boom() +{ + document.addEventListener("DOMNodeInserted", x); + + function x() + { + document.removeEventListener("DOMNodeInserted", x); + document.execCommand("insertParagraph", false, ""); + } + + document.execCommand("insertorderedlist", false, ""); +} + +</script> +</head> + +<body contenteditable="true" onload="boom()"></body> + +</html> diff --git a/testing/web-platform/tests/editing/crashtests/insertparagraph-in-listitem-in-svg-followed-by-collapsible-spaces.html b/testing/web-platform/tests/editing/crashtests/insertparagraph-in-listitem-in-svg-followed-by-collapsible-spaces.html new file mode 100644 index 0000000000..f5f981965b --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/insertparagraph-in-listitem-in-svg-followed-by-collapsible-spaces.html @@ -0,0 +1,28 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<script> +addEventListener("load", () => { + document.querySelector("svg").insertAdjacentText("afterend", `\n${" ".repeat(336860180)}`); + + document.designMode = "on"; + getSelection().selectAllChildren(document.querySelector("input")); + + document.querySelector("li").appendChild(document.querySelector("p")); + document.execCommand("outdent"); + document.execCommand("insertOrderedList"); + document.execCommand("insertParagraph"); +}); +</script> +</head> +<body> +<svg> + <foreignObject> + <li></li> +/> + </foreignObject></svg><p> + <input> +</p> +<title>This test takes long time due to the long white-spaces are required</title> +</body></html> diff --git a/testing/web-platform/tests/editing/crashtests/insertparagraph-in-map-element-editing-host.html b/testing/web-platform/tests/editing/crashtests/insertparagraph-in-map-element-editing-host.html new file mode 100644 index 0000000000..e05b36907e --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/insertparagraph-in-map-element-editing-host.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<script> + document.addEventListener("DOMContentLoaded", () => { + document.getElementById("id_0").contentEditable = false; + document.querySelector("[contenteditable]").focus(); + document.execCommand("insertParagraph"); + }) +</script> +<pre> +<ins id="id_0"> +<map contenteditable>
\ No newline at end of file diff --git a/testing/web-platform/tests/editing/crashtests/inserttext-at-start-with-different-style.html b/testing/web-platform/tests/editing/crashtests/inserttext-at-start-with-different-style.html new file mode 100644 index 0000000000..ddd19aafd4 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/inserttext-at-start-with-different-style.html @@ -0,0 +1,20 @@ +<html> +<head> +<meta charset="utf-8"> +<head> +<script> +function go() { + a.show(); + document.execCommand("bold", false); + b.style.setProperty("font", "0px/43%"); + document.execCommand("insertText", false, "a"); +} +</script> +</head> +<body onload=go()> +<ul contenteditable="true"> +<li id="b" style="font-weight: bolder">a</li> +<dialog id="a" tabindex="0">a</dialog> +</ul> +</body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/inserttext-with-clearing-subscript.html b/testing/web-platform/tests/editing/crashtests/inserttext-with-clearing-subscript.html new file mode 100644 index 0000000000..9c27a7ed53 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/inserttext-with-clearing-subscript.html @@ -0,0 +1,31 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<script> +document.addEventListener("DOMContentLoaded", () => { + getSelection().collapse(document.querySelector("code[contenteditable]").firstChild, 0); + window.top.find("A"); + document.querySelector("table").insertRow(1); + document.querySelector("table").insertRow(1); + document.execCommand("subscript"); + document.execCommand("foreColor", false, "currentColor"); + document.execCommand("insertHTML", false, document.querySelector("h5").outerHTML); + document.execCommand("subscript"); + document.execCommand("foreColor", false, "currentColor"); + document.execCommand("insertHTML", false, document.querySelector("h5").outerHTML); + document.execCommand("insertText", false, "A"); +}); +</script> +</head> +<body> +<table> +<tr> +<td> +<code contenteditable> +A +<h5> +</h5> +</code> +</body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/insertunorderedlist-in-empty-inline-editing-host.html b/testing/web-platform/tests/editing/crashtests/insertunorderedlist-in-empty-inline-editing-host.html new file mode 100644 index 0000000000..74b0993322 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/insertunorderedlist-in-empty-inline-editing-host.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Test for bug 615015 of Mozilla</title> +<script> +function boom() +{ + document.getElementById("j").focus(); + try { + document.execCommand("insertunorderedlist", false, null); + } catch(e) { } +} +</script> +</head> +<body onload="boom();"><span><span contenteditable id="j"></span>T</span></body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/insertunorderedlist-in-empty-table-editing-host.html b/testing/web-platform/tests/editing/crashtests/insertunorderedlist-in-empty-table-editing-host.html new file mode 100644 index 0000000000..19cc205b91 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/insertunorderedlist-in-empty-table-editing-host.html @@ -0,0 +1,22 @@ +<!DOCTYPE html> +<html> +<head> +<script type="text/javascript"> + +function boom() +{ + var table = document.createElement("table"); + document.body.appendChild(table); + table.contentEditable = "true"; + table.focus(); + try { + // This will throw, since it's attempting to inject a list inside a table + document.execCommand("insertunorderedlist", false, null); + } catch (e) {} +} + +</script> +</head> + +<body onload="boom();"></body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/justifycenter-around-textarea.html b/testing/web-platform/tests/editing/crashtests/justifycenter-around-textarea.html new file mode 100644 index 0000000000..71d24f37b4 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/justifycenter-around-textarea.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<script> +function go() { + a.replaceWith(undefined) + window.getSelection().modify("move", "right", "word") + document.execCommand("justifyCenter", false) +} +</script> +<div contenteditable="true">a</div> +<textarea>23</textarea> +<li dir="RTL"> +<strong id="a"> +<svg onload="go()"> diff --git a/testing/web-platform/tests/editing/crashtests/justifycenter-then-delete-selection-on-DOMSubtreeModified.html b/testing/web-platform/tests/editing/crashtests/justifycenter-then-delete-selection-on-DOMSubtreeModified.html new file mode 100644 index 0000000000..1ee9ac35cb --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/justifycenter-then-delete-selection-on-DOMSubtreeModified.html @@ -0,0 +1,24 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<script> +document.addEventListener("DOMContentLoaded", () => { + document.execCommand("selectAll"); + document.querySelector("li").addEventListener("DOMSubtreeModified", () => { + document.designMode = "on"; + document.execCommand("justifyCenter"); + getSelection().deleteFromDocument(); + }); + document.querySelector("li").type = "1"; +}); +</script> +</head> +<body> +<li> + <h3 align="right"> + <option contenteditable="true"></option> + </h3> +</li> +</body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/justifyfull-selection-containing-non-editable-div-and-everything-styled-white-space-break-space.html b/testing/web-platform/tests/editing/crashtests/justifyfull-selection-containing-non-editable-div-and-everything-styled-white-space-break-space.html new file mode 100644 index 0000000000..cf199fa087 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/justifyfull-selection-containing-non-editable-div-and-everything-styled-white-space-break-space.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> +<head> + <style> + * { + white-space: break-spaces ! important; + } + </style> + <script> + window.addEventListener('load', () => { + document.documentElement.contentEditable = true + document.execCommand('selectAll', false, null) + document.execCommand('justifyFull', false, null) + }) + </script> +</head> +<div contenteditable='false'></div> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/loading-different-page-in-iframe-while-iframe-sets-spellcheck-attr-from-load.html b/testing/web-platform/tests/editing/crashtests/loading-different-page-in-iframe-while-iframe-sets-spellcheck-attr-from-load.html new file mode 100644 index 0000000000..afddac34e1 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/loading-different-page-in-iframe-while-iframe-sets-spellcheck-attr-from-load.html @@ -0,0 +1,13 @@ +<html> +<head> +<script> +function crash() { + document.querySelector("iframe").onload = null; + document.querySelector("iframe").srcdoc = "2nd page"; +} +</script> +</head> +<body onload="crash()"> + <iframe srcdoc="<html><body onload=$quot;document.body.setAttribute('spellcheck', true);$quot;></body></html>"></iframe> +</body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/make-editable-div-inline-and-set-contenteditable-of-input-to-false.html b/testing/web-platform/tests/editing/crashtests/make-editable-div-inline-and-set-contenteditable-of-input-to-false.html new file mode 100644 index 0000000000..1743a2641d --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/make-editable-div-inline-and-set-contenteditable-of-input-to-false.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<html class="test-wait"> +<head> +<meta charset="utf-8"> +<title>Testcase for bug 650572 of Mozilla</title> +<script> +function boom() +{ + document.documentElement.offsetHeight; + document.body.focus(); + document.querySelector("div").style.display = "inline"; + document.querySelector("input").contentEditable = "false"; + document.documentElement.removeAttribute("class"); +} +</script> +</head> +<body contenteditable="true" onload="setTimeout(boom, 200);"><div><input></div></body> +</html> + diff --git a/testing/web-platform/tests/editing/crashtests/make-parent-element-editable-after-making-focused-editing-host-non-editable.html b/testing/web-platform/tests/editing/crashtests/make-parent-element-editable-after-making-focused-editing-host-non-editable.html new file mode 100644 index 0000000000..d624d7d3b9 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/make-parent-element-editable-after-making-focused-editing-host-non-editable.html @@ -0,0 +1,21 @@ +<html> +<head> +<script> +function boom() +{ + document.getElementById("div").contentEditable = "true"; + document.getElementById("div").focus(); + document.getElementById("div").contentEditable = "false"; + + document.getElementById("table").contentEditable = "true"; +} +</script> +</head> + +<body onload="boom();"> + +<table id="table"><td></td></table><div id="div"></div> + +</body> + +</html> diff --git a/testing/web-platform/tests/editing/crashtests/move-editing-host-to-subdocument-when-textarea-has-focus.html b/testing/web-platform/tests/editing/crashtests/move-editing-host-to-subdocument-when-textarea-has-focus.html new file mode 100644 index 0000000000..b7d2e2f902 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/move-editing-host-to-subdocument-when-textarea-has-focus.html @@ -0,0 +1,15 @@ +<script> +addEventListener("DOMContentLoaded", () => { + document.querySelector("iframe").contentDocument.body.appendChild( + document.querySelector("span") + ); + document.documentElement.style.display = "none"; +}) +</script> +<hgroup> +<audio controls> +</audio> +<iframe></iframe> +<span contenteditable></span> +</hgroup> +<textarea autofocus> diff --git a/testing/web-platform/tests/editing/crashtests/move-first-element-from-editinghost-to-outside-on-input-of-embolden.html b/testing/web-platform/tests/editing/crashtests/move-first-element-from-editinghost-to-outside-on-input-of-embolden.html new file mode 100644 index 0000000000..6bb87c2810 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/move-first-element-from-editinghost-to-outside-on-input-of-embolden.html @@ -0,0 +1,22 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<script> +addEventListener("load", () => { + document.querySelector("ol").addEventListener("input", () => { + const inlineEditingHost = document.querySelector("span[contenteditable]"); + const iter = document.createNodeIterator(inlineEditingHost, NodeFilter.SHOW_ELEMENT); + iter.nextNode().before(inlineEditingHost); + }); + document.execCommand("selectAll"); + document.execCommand("bold"); +}); +</script> +</head> +<body> +<ol> +<span contenteditable> +<h6></h6> +</span></ol></body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/move-legend-followed-by-textarea-into-orphan-div.html b/testing/web-platform/tests/editing/crashtests/move-legend-followed-by-textarea-into-orphan-div.html new file mode 100644 index 0000000000..462ff37fd6 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/move-legend-followed-by-textarea-into-orphan-div.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Testcase for bug 667321 of Mozilla</title> +<script> +function boom() +{ + document.body.style.float = "left"; + document.createElement("div").appendChild(document.querySelector("legend")); +} +</script> +</head> +<body onload="boom();"><fieldset><legend></legend><textarea></textarea></fieldset></body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/mozilla-bug-1851730.html b/testing/web-platform/tests/editing/crashtests/mozilla-bug-1851730.html new file mode 100644 index 0000000000..ee11f76792 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/mozilla-bug-1851730.html @@ -0,0 +1,11 @@ +<script> +document.addEventListener("DOMContentLoaded", () => { + document.execCommand("selectAll", false) + a.wrap = "hard" + a.value = "A" + b.style.cssFloat = "left" +}) +</script> +<textarea id="a" autofocus="autofocus">"</textarea> +<font id="b"> +<pre> diff --git a/testing/web-platform/tests/editing/crashtests/multiple-execCommand-calls-after-interting-long-text.html b/testing/web-platform/tests/editing/crashtests/multiple-execCommand-calls-after-interting-long-text.html new file mode 100644 index 0000000000..32d0e38248 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/multiple-execCommand-calls-after-interting-long-text.html @@ -0,0 +1,20 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Testcase for bug 682650 of Mozilla</title> +<script> +function boom() { + document.documentElement.contentEditable = "true"; + document.execCommand("inserthtml", false, "<button><\/button>"); + document.execCommand("inserthtml", false, "i".repeat(34646)); + document.execCommand("contentReadOnly", false, null); + document.execCommand("removeformat", false, null); + document.execCommand("hilitecolor", false, "red"); + document.execCommand("inserthtml", false, "a"); + document.execCommand("delete", false, null); +} +</script> +</head> +<body onload="boom();"></body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/non-root-editable-html-element.html b/testing/web-platform/tests/editing/crashtests/non-root-editable-html-element.html new file mode 100644 index 0000000000..2e4c02b0e1 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/non-root-editable-html-element.html @@ -0,0 +1,7 @@ +<span> +<script contenteditable="true"></script> +<blockquote> +<input> +<code style="display: table-row;"> +<html contenteditable="true"> +</blockquote> diff --git a/testing/web-platform/tests/editing/crashtests/normalize_document_at_DOMSubtreeModified_during_insertparagraph.html b/testing/web-platform/tests/editing/crashtests/normalize_document_at_DOMSubtreeModified_during_insertparagraph.html new file mode 100644 index 0000000000..a8cbaf7217 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/normalize_document_at_DOMSubtreeModified_during_insertparagraph.html @@ -0,0 +1,16 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<script> +addEventListener("load", () => { + document.documentElement.innerHTML = "<main>\n>"; + document.addEventListener("DOMSubtreeModified", () => { + document.normalize(); + }, {capture: true}); + document.designMode = "on" + document.execCommand("insertParagraph"); +}); +</script> +</head> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/outdent-across-svg-boundary.html b/testing/web-platform/tests/editing/crashtests/outdent-across-svg-boundary.html new file mode 100644 index 0000000000..f652a2e237 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/outdent-across-svg-boundary.html @@ -0,0 +1,38 @@ +<html xmlns="http://www.w3.org/1999/xhtml" class="test-wait"> +<head> +<script> +function init() +{ + var targetWindow = window.frames[0]; + var targetDocument = targetWindow.document; + var rootish = document.getElementById('rootish'); + + targetDocument.body.appendChild(targetDocument.adoptNode(rootish)); + targetDocument.designMode = 'on'; + + targetWindow.getSelection().removeAllRanges(); + + var r = targetDocument.createRange(); + r.setStart(targetDocument.getElementById("start"), 0); + r.setEnd(targetDocument.getElementById("endparent").firstChild, 0); + targetWindow.getSelection().addRange(r); + + targetDocument.execCommand('outdent', false, null); + document.documentElement.removeAttribute("class"); +} +</script> + +</head> + +<body onload="setTimeout(init, 300);"> + +<iframe srcdoc="" style="width: 95%; height: 500px;"></iframe> + +<div id="rootish"> + <div id="start"></div> + <p>Huh</p> + <svg xmlns="http://www.w3.org/2000/svg" id="endparent"> </svg> +</div> + +</body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/outdent-editing-host-containing-combining-diacritical-mark.html b/testing/web-platform/tests/editing/crashtests/outdent-editing-host-containing-combining-diacritical-mark.html new file mode 100644 index 0000000000..0ed71f789b --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/outdent-editing-host-containing-combining-diacritical-mark.html @@ -0,0 +1,16 @@ +<html class="test-wait"> +<head> +<meta charset="utf-8"> +<title>Test for bug 499844 of Mozilla</title> +<script> +function boom() +{ + document.body.contentEditable = "true"; + getSelection().collapse(document.body.firstChild, 0); + document.execCommand("outdent"); + document.documentElement.removeAttribute("class"); +} +</script> +</head> +<body style="word-spacing: 3px;" onload="boom();"> ́</body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/outdent-in-empty-body-editing-host.html b/testing/web-platform/tests/editing/crashtests/outdent-in-empty-body-editing-host.html new file mode 100644 index 0000000000..f68e46bc53 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/outdent-in-empty-body-editing-host.html @@ -0,0 +1,7 @@ +<html> +<head> +</head> +<body style="margin: initial;" + contenteditable="true" + onload="document.execCommand('outdent', false, null);"></body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/outdent-in-meter-indented-by-legend-in-css-mode.html b/testing/web-platform/tests/editing/crashtests/outdent-in-meter-indented-by-legend-in-css-mode.html new file mode 100644 index 0000000000..af20ea8128 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/outdent-in-meter-indented-by-legend-in-css-mode.html @@ -0,0 +1,25 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<script> +addEventListener("load", () => { + document.execCommand("styleWithCSS", false, "true"); + document.getSelection().collapse(document.querySelector("label"), 0); + document.execCommand("outdent"); +}); +</script> +</head> +<body> +<li contenteditable> +<legend style="margin-right: 43%"> +<meter> +<mi dir="rtl">8</mi> +<label> +<dir></dir> +</label> +</meter> +</legend> +</li> +</body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/outdent-indent-inserthorizontalrule-on-selectionchange.html b/testing/web-platform/tests/editing/crashtests/outdent-indent-inserthorizontalrule-on-selectionchange.html new file mode 100644 index 0000000000..800d9d1969 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/outdent-indent-inserthorizontalrule-on-selectionchange.html @@ -0,0 +1,23 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<script> +var count = 0; +document.addEventListener("DOMContentLoaded", () => { + document.onselectionchange = () => { + document.execCommand("outdent"); + document.execCommand("indent"); + document.execCommand("insertHorizontalRule"); + if (count++ == 10) { + document.onselectionchange = null; + } + }; + find("A"); +}); +</script> +</head> +<body><isindex contenteditable> +A +</body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/queryCommandIndeterm-backcolor-and-hilitecolor-in-empty-iframe-in-designMode.html b/testing/web-platform/tests/editing/crashtests/queryCommandIndeterm-backcolor-and-hilitecolor-in-empty-iframe-in-designMode.html new file mode 100644 index 0000000000..6cf2524a54 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/queryCommandIndeterm-backcolor-and-hilitecolor-in-empty-iframe-in-designMode.html @@ -0,0 +1,73 @@ +<!DOCTYPE HTML> +<html><head> + <meta charset="iso-8859-1"> + <title>Testcase for bug 448329 of Mozilla</title> +</head> +<body> + +<iframe id="frame448329"></iframe> + +<script> + +function test448329(id,cmd) { + var elm = document.getElementById(id); + var doc = elm.contentDocument; + doc.designMode = "On"; + + doc.body.offsetWidth; + var selection = doc.defaultView.getSelection(); + + // Test document node + if (selection.rangeCount > 0) { + selection.removeAllRanges(); + } + var range = doc.createRange(); + range.setStart(doc, 0); + range.setEnd(doc, 0); + selection.addRange(range); + doc.queryCommandIndeterm(cmd); + + // Test HTML node + if (selection.rangeCount > 0) { + selection.removeAllRanges(); + } + range = doc.createRange(); + range.setStart(doc.documentElement, 0); + range.setEnd(doc.documentElement, 0); + selection.addRange(range); + doc.queryCommandIndeterm(cmd); + + // Test BODY node + if (selection.rangeCount > 0) { + selection.removeAllRanges(); + } + range = doc.createRange(); + var body = doc.documentElement.childNodes[1]; + range.setStart(body, 0); + range.setEnd(body, 0); + selection.addRange(range); + doc.queryCommandIndeterm(cmd); + + var text = doc.createTextNode("Hello there"); + body.insertBefore(text, null) + + // Test TEXT node + if (selection.rangeCount > 0) { + selection.removeAllRanges(); + } + range = doc.createRange(); + range.setStart(text, 0); + range.setEnd(text, 1); + selection.addRange(range); + doc.queryCommandIndeterm(cmd); + +} + +test448329("frame448329", "backcolor") +test448329("frame448329", "hilitecolor") + +</script> + + +</body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/queryCommandIndeterm-backcolor-in-empty-iframe-in-designMode-from-load.html b/testing/web-platform/tests/editing/crashtests/queryCommandIndeterm-backcolor-in-empty-iframe-in-designMode-from-load.html new file mode 100644 index 0000000000..74d80e19b3 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/queryCommandIndeterm-backcolor-in-empty-iframe-in-designMode-from-load.html @@ -0,0 +1,21 @@ +<html> +<head> + <title>Testcase for bug 448329 of Mozilla</title> +<script> +function go() { + test("myFrame", "backcolor"); +} +function test(id,cmd) { + var doc = document.getElementById(id).contentDocument; + doc.designMode = "On"; + + var selection = doc.defaultView.getSelection(); + selection.removeAllRanges(); + selection.addRange(doc.createRange()); + + doc.queryCommandIndeterm(cmd); +} +</script> +</head> +<body onload="go()"><iframe id="myFrame"></iframe></body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/queryCommandState-backcolor-after-removing-html-element-in-designMode-from-load.html b/testing/web-platform/tests/editing/crashtests/queryCommandState-backcolor-after-removing-html-element-in-designMode-from-load.html new file mode 100644 index 0000000000..1c8fe5db9b --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/queryCommandState-backcolor-after-removing-html-element-in-designMode-from-load.html @@ -0,0 +1,8 @@ +<html> +<BODY onload=" +document.designMode='on'; +document.removeChild(document.firstChild); +document.queryCommandState('BackColor'); +"> +</body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/queryCommandValue-backcolor-after-replacing-html-element-with-new-one-in-designMode-from-load.html b/testing/web-platform/tests/editing/crashtests/queryCommandValue-backcolor-after-replacing-html-element-with-new-one-in-designMode-from-load.html new file mode 100644 index 0000000000..d14422c931 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/queryCommandValue-backcolor-after-replacing-html-element-with-new-one-in-designMode-from-load.html @@ -0,0 +1,8 @@ +<html> +<BODY onload=" +document.designMode='on'; +document.replaceChild(document.createElement('HTML'), document.firstChild); +document.queryCommandValue('backcolor'); +"> +</body> +</html>
\ No newline at end of file diff --git a/testing/web-platform/tests/editing/crashtests/remove-document-element-of-iframe-having-style-content.html b/testing/web-platform/tests/editing/crashtests/remove-document-element-of-iframe-having-style-content.html new file mode 100644 index 0000000000..b032311fa7 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/remove-document-element-of-iframe-having-style-content.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Testcase for bug 643706 of Mozilla</title> +<script> +function boom() { + const iframe = document.querySelector("iframe"); + const win = iframe.contentWindow; + win.document.designMode = 'on'; + iframe.style.content = "'m'"; + win.document.removeChild(win.document.documentElement) +} +</script> +</head> +<body onload="boom();"><iframe srcdoc=""></iframe></body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/remove-editing-host-during-forwarddelete.html b/testing/web-platform/tests/editing/crashtests/remove-editing-host-during-forwarddelete.html new file mode 100644 index 0000000000..6013361ccb --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/remove-editing-host-during-forwarddelete.html @@ -0,0 +1,65 @@ +<!doctype html> +<html class="test-wait"> +<head> +<meta charset="utf-8"> +<style> +dir { + animation: kf, 0s infinite paused; +} +svg { + animation-name: kf; +} +@keyframes kf {} +</style> +<script> +let dir; +// animationend for <svg> and <dir> may be fired before "DOMContentLoaded". +// Therefore, let's start to listen them immediately. +const waitForAnimationEnd = new Promise(resolve => { + let count = 0; + function onAnimationEnd() { + window.find("AAAAAAAAAA"); + document.execCommand("forwardDelete"); + count++; + function getRemainingEventCount(event) { + if (count >= 2) { + return 0; + } + if (event.target.tagName == "DIR") { + return 0; + } + // If `animationend` is delayed and `<dir>` has already been removed, + // `animationend` for it is never fired anymore. + return dir && !dir.isConnected ? 0 : 1; + } + if (!getRemainingEventCount()) { + window.removeEventListener("animationend", onAnimationEnd); + resolve(); + } + } + window.addEventListener("animationend", onAnimationEnd); +}); + +document.addEventListener("DOMContentLoaded", async () => { + dir = document.querySelector("dir"); + window.find("A"); + document.execCommand("insertHTML", false, "AAAAAAAAAAAAAAAA"); + dir.addEventListener("DOMNodeRemoved", event => { + dir.remove(); + }); + window.find("A"); + document.execCommand("delete"); + await waitForAnimationEnd; + document.documentElement.removeAttribute("class"); +}); +</script> +</head> +<body> +<svg> +<s></s> +<dir contenteditable> +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +</dir> +</svg> +</body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/remove-editing-host-on-DOMNodeInserted-at-indent.html b/testing/web-platform/tests/editing/crashtests/remove-editing-host-on-DOMNodeInserted-at-indent.html new file mode 100644 index 0000000000..22e8fd0713 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/remove-editing-host-on-DOMNodeInserted-at-indent.html @@ -0,0 +1,24 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<script> +document.addEventListener("DOMContentLoaded", () => { + const editingHost = document.querySelector("h6[contenteditable]"); + document.querySelector("wbr").addEventListener( + "DOMNodeInserted", + () => editingHost.remove() + ); + window.find("A"); + document.execCommand("indent"); +}) +</script> +</head> +<body> +<h6 contenteditable> +<time> +<wbr> +<main></main> +A +</time></h6></body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/remove-editing-host-which-is-selected.html b/testing/web-platform/tests/editing/crashtests/remove-editing-host-which-is-selected.html new file mode 100644 index 0000000000..06ee6dc505 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/remove-editing-host-which-is-selected.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<script> +window.onload = () => { + let s = window.getSelection() + let r = document.createRange() + r.selectNode(document.getElementById('b')) + s.addRange(r) + r = document.createRange() + r.selectNode(document.getElementById('a')) + s.addRange(r) + document.documentElement.innerHTML = '' +} +</script> +<body id='a' contenteditable='true'> +<canvas tabindex='0'> +<audio id='b'> diff --git a/testing/web-platform/tests/editing/crashtests/remove-iframe-for-designMode.html b/testing/web-platform/tests/editing/crashtests/remove-iframe-for-designMode.html new file mode 100644 index 0000000000..609a9ca542 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/remove-iframe-for-designMode.html @@ -0,0 +1,21 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Test for bug 612565 of Mozilla</title> +</head> + <body> + <iframe></iframe> + </body> + <script> + onload = function() { + var i = document.querySelector("iframe"); + var doc = i.contentDocument; + doc.body.appendChild(doc.createTextNode("foo")); + doc.designMode = "on"; + while (doc.body.firstChild) { + doc.body.firstChild.remove(); + } + }; + </script> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/remove-parent-element-during-inserthtml.html b/testing/web-platform/tests/editing/crashtests/remove-parent-element-during-inserthtml.html new file mode 100644 index 0000000000..3a0cf1c957 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/remove-parent-element-during-inserthtml.html @@ -0,0 +1,24 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<script> +document.addEventListener("DOMContentLoaded", () => { + document.onselectionchange = () => { + document.execCommand("insertHTML", false, "a") + document.designMode = "on" + }; + window.find("a"); + document.querySelector("dl[contenteditable] > dd").addEventListener("DOMNodeRemoved", () => { + document.querySelector("dl[contenteditable]").remove(); + }); +}); +</script> +</head> +<body> +<dl contenteditable> +<dd></dd> +a +</dl> +</body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/remove-right-block-during-joining-with-parent-left-block.html b/testing/web-platform/tests/editing/crashtests/remove-right-block-during-joining-with-parent-left-block.html new file mode 100644 index 0000000000..29ee228fea --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/remove-right-block-during-joining-with-parent-left-block.html @@ -0,0 +1,33 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<title>Test removing right block while joining it and parent left block</title> +<script> +addEventListener("load", () => { + const editingHosts = document.querySelectorAll("div[contenteditable]"); + for (const editingHost of editingHosts) { + editingHost.focus(); + const rightChildBlock = editingHost.querySelector("div > div > div"); + getSelection().collapse(rightChildBlock.firstChild.firstChild, 0); + editingHost.addEventListener("DOMSubtreeModified", () => { + document.body.appendChild(rightChildBlock); + }); + document.execCommand("delete"); + } +}); +</script> +</head> +<body> + <div contenteditable> + <div>parent<div><b>child</b></div>parent</div> + </div> + <div contenteditable> + <div>parent<div><b>child<br>2nd line</b></div>parent</div> + </div> + <div contenteditable style="white-space:pre"> + <div>parent<div>child +2nd line</div>parent</div> + </div> +</body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/removeformat-from-DOMNodeRemoved.html b/testing/web-platform/tests/editing/crashtests/removeformat-from-DOMNodeRemoved.html new file mode 100644 index 0000000000..3f78f99436 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/removeformat-from-DOMNodeRemoved.html @@ -0,0 +1,29 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<script> +document.addEventListener("DOMContentLoaded", () => { + window.find("a"); + document.addEventListener("DOMNodeRemoved", () => { + try { + document.getElementById("target").normalize(); + document.execCommand("removeFormat"); + } catch (e) { + } + }); + document.adoptNode(document.querySelector("datalist")); +}); +</script> +</head> +<body> +<kbd> +<datalist> +</kbd> +<figcaption contenteditable> +<font id="target"> +a +</font> +</figcaption> +</body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/removeformat-in-number-input-immediately-after-type-change-and-stepUp.html b/testing/web-platform/tests/editing/crashtests/removeformat-in-number-input-immediately-after-type-change-and-stepUp.html new file mode 100644 index 0000000000..d83c2e0079 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/removeformat-in-number-input-immediately-after-type-change-and-stepUp.html @@ -0,0 +1,20 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<script> +document.addEventListener("DOMContentLoaded", () => { + const input = document.querySelector("input"); + input.select(); + input.type = "number"; + document.querySelector("switch").scrollIntoView(true); + input.stepUp(1); + document.execCommand("removeFormat"); +}); +</script> +</head> +<body> +<input> +<switch> +</body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/remve-documentElement-after-inserthtml-svg-and-td.html b/testing/web-platform/tests/editing/crashtests/remve-documentElement-after-inserthtml-svg-and-td.html new file mode 100644 index 0000000000..eebeac317d --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/remve-documentElement-after-inserthtml-svg-and-td.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<script> +addEventListener("load", () => { + document.querySelector("div[contenteditable]").focus(); + document.execCommand("inserthtml", false, "<svg><td>"); + document.documentElement.remove(); +}); +</script> +</head> + +<body><div contenteditable></div></body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/replace-document-root-with-object-and-mo.html b/testing/web-platform/tests/editing/crashtests/replace-document-root-with-object-and-mo.html new file mode 100644 index 0000000000..bdad541422 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/replace-document-root-with-object-and-mo.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<html> +<head> +<script> +addEventListener("load", () => { + const object = document.querySelector("object[contenteditable]"); + const mo = object.querySelector("mo"); + const range = new Range(); + document.replaceChildren(); + range.insertNode(object); + object.replaceChild(mo, object.firstChild); +}); +</script> +</head> +<object contenteditable> + <mo> + </mo> +</object> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/replace-parent-of-editing-host-on-DOMSubtreeModified.html b/testing/web-platform/tests/editing/crashtests/replace-parent-of-editing-host-on-DOMSubtreeModified.html new file mode 100644 index 0000000000..9d431aa860 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/replace-parent-of-editing-host-on-DOMSubtreeModified.html @@ -0,0 +1,28 @@ +<!doctype html> +<html> +<head> +<script> +document.addEventListener("DOMContentLoaded", () => { + getSelection().collapse(document.querySelector("content"), 1); + document.querySelector("div[contenteditable]").addEventListener("DOMSubtreeModified", () => { + document.querySelector("tr").replaceChild( + document.querySelector("meter"), + document.querySelector("th") + ); + }); + document.execCommand("justifyFull"); +}); +</script> +</head> +<body> +<table> +<tr> +<th> +<div contenteditable> +<meter> +<content> +<ul></ul> +</div> +</th></tr></table> +</body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/selectall-and-inerthtml-in-textarea-editing-host.html b/testing/web-platform/tests/editing/crashtests/selectall-and-inerthtml-in-textarea-editing-host.html new file mode 100644 index 0000000000..8b0e36cd65 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/selectall-and-inerthtml-in-textarea-editing-host.html @@ -0,0 +1,15 @@ +<html> +<head> +<script type="text/javascript"> + +function boom() +{ + document.execCommand("selectAll", false, null); + document.execCommand("inserthtml", false, "<p>"); +} + +</script> +</head> + +<body onload="boom();"><textarea contenteditable="true"></textarea></body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/selectall-in-head-editing-host-after-body-removed.html b/testing/web-platform/tests/editing/crashtests/selectall-in-head-editing-host-after-body-removed.html new file mode 100644 index 0000000000..786ea25d9a --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/selectall-in-head-editing-host-after-body-removed.html @@ -0,0 +1,19 @@ +<html><head><script type="text/javascript"> + +function boom() +{ + var dE = document.documentElement; + var head = document.getElementsByTagName("head")[0]; + dE.removeChild(document.body); + dE.contentEditable = "true"; + dE.focus(); + dE.contentEditable = "false"; + head.focus(); + head.contentEditable = "true"; + try { + document.execCommand("selectAll", false, ""); + } catch(e) { + } +} + +</script></head><body onload="boom();"></body></html>
\ No newline at end of file diff --git a/testing/web-platform/tests/editing/crashtests/selectall-selection-modify-move-forward-lineboundary-selectall-around-editable-canvas.html b/testing/web-platform/tests/editing/crashtests/selectall-selection-modify-move-forward-lineboundary-selectall-around-editable-canvas.html new file mode 100644 index 0000000000..8e57700af5 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/selectall-selection-modify-move-forward-lineboundary-selectall-around-editable-canvas.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<script> +onload = () => { + document.querySelector("canvas[contenteditable]").blur(); + document.execCommand("selectAll", false); + getSelection().modify("move", "forward", "lineboundary"); + document.execCommand("selectAll", false); +}; +</script> +<canvas contenteditable="true"> +<audio controls> diff --git a/testing/web-platform/tests/editing/crashtests/selection-modify-around-input-in-contenteditable.html b/testing/web-platform/tests/editing/crashtests/selection-modify-around-input-in-contenteditable.html new file mode 100644 index 0000000000..90b615da5c --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/selection-modify-around-input-in-contenteditable.html @@ -0,0 +1,22 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<script> +addEventListener("load", () => { + const selection = window.getSelection(); + const range = selection.getRangeAt(0); + selection.modify("move", "backward", "character"); + selection.addRange(range); +}); +</script> +</head> +<body> +<fieldset contenteditable spellcheck="true"> + <input value="x"> + <table> + <caption></caption> + </table> +</fieldset> +</body> +</html>
\ No newline at end of file diff --git a/testing/web-platform/tests/editing/crashtests/selection-modify-extend-backward-character-to-outside-body-in-designMode.html b/testing/web-platform/tests/editing/crashtests/selection-modify-extend-backward-character-to-outside-body-in-designMode.html new file mode 100644 index 0000000000..9f465cc462 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/selection-modify-extend-backward-character-to-outside-body-in-designMode.html @@ -0,0 +1,10 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<script> +onload = () => { + document.designMode = 'on'; + getSelection().selectAllChildren(document.body); + getSelection().modify('extend', 'backward', 'character'); +}; +</script> +<audio controls> diff --git a/testing/web-platform/tests/editing/crashtests/set-input-value-of-editing-host-after-changing-type.html b/testing/web-platform/tests/editing/crashtests/set-input-value-of-editing-host-after-changing-type.html new file mode 100644 index 0000000000..34a1558896 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/set-input-value-of-editing-host-after-changing-type.html @@ -0,0 +1,15 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<script> +document.addEventListener("DOMContentLoaded", () => { + const input = document.querySelector("input"); + input.focus(); + input.type = "text"; + input.value = "new value"; +}, {once: true}); +</script> +</head> +<body><input type="button" contenteditable></body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/set-output-value-to-empty-while-deleting-its-content.html b/testing/web-platform/tests/editing/crashtests/set-output-value-to-empty-while-deleting-its-content.html new file mode 100644 index 0000000000..6ddf89205f --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/set-output-value-to-empty-while-deleting-its-content.html @@ -0,0 +1,33 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<script> +document.addEventListener("DOMContentLoaded", () => { + document.designMode = "on"; + window.find("AA"); + document.addEventListener( + "selectionchange", + onSelectionChangeOrDOMNodeInserted, + {once: true} + ); + document.querySelector("output").addEventListener( + "DOMNodeInserted", + onSelectionChangeOrDOMNodeInserted + ); + document.execCommand("forwarddelete"); +}); + +function onSelectionChangeOrDOMNodeInserted() { + document.execCommand("delete"); + document.querySelector("output").value = ""; +} +</script> +</head> +<body> +<output> +<ruby></ruby> +<div> +AAA +</div></output></body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/set-selection-range-after-updating-textarea-default-value.html b/testing/web-platform/tests/editing/crashtests/set-selection-range-after-updating-textarea-default-value.html new file mode 100644 index 0000000000..421306fc96 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/set-selection-range-after-updating-textarea-default-value.html @@ -0,0 +1,16 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<script> +addEventListener("load", () => { + const textarea = document.createElement("textarea"); + document.documentElement.appendChild(textarea); + textarea.focus(); + textarea.dir = "rtl"; + textarea.prepend("0123456789A", document.createElement("marquee")); + textarea.setSelectionRange(8, 13, ""); +}); +</script> +</head> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/support/unloading-editor-in-subdocument-containing-misspelled-word-iframe.html b/testing/web-platform/tests/editing/crashtests/support/unloading-editor-in-subdocument-containing-misspelled-word-iframe.html new file mode 100644 index 0000000000..cfedfa8d2e --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/support/unloading-editor-in-subdocument-containing-misspelled-word-iframe.html @@ -0,0 +1 @@ +<html><meta charset="utf-8"><body><textarea>notaword</textarea></body></html> diff --git a/testing/web-platform/tests/editing/crashtests/textarea-will-be-blurred-by-focus-event-listener.html b/testing/web-platform/tests/editing/crashtests/textarea-will-be-blurred-by-focus-event-listener.html new file mode 100644 index 0000000000..bcb145c309 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/textarea-will-be-blurred-by-focus-event-listener.html @@ -0,0 +1,16 @@ +<!DOCTYPE html> +<html class="test-wait"> +<meta charset="utf-8"> +<script> +addEventListener("load", () => { + const textarea = document.querySelector("textarea"); + textarea.addEventListener("focus", () => { + textarea.select(); + textarea.parentElement.setAttribute("hidden", "hidden"); + setTimeout(() => document.documentElement.removeAttribute("class"), 0); + }); + textarea.focus(); +}); +</script> +<div><textarea>abc</textarea></div> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/unloading-editor-in-subdocument-containing-misspelled-word.html b/testing/web-platform/tests/editing/crashtests/unloading-editor-in-subdocument-containing-misspelled-word.html new file mode 100644 index 0000000000..1b90e1d56a --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/unloading-editor-in-subdocument-containing-misspelled-word.html @@ -0,0 +1,11 @@ +<html class="test-wait"> +<head> +<meta charset="utf-8"> +<title>Test case for bug 459613 of Mozilla</title> +</head> +<body> +<iframe + srcdoc="support/unloading-editor-in-subdocument-containing-misspelled-word-iframe.html" + onload="document.documentElement.removeAttribute('class')"></iframe> +</body> +</html> diff --git a/testing/web-platform/tests/editing/crashtests/update-dom-during-undoing-in-textarea.html b/testing/web-platform/tests/editing/crashtests/update-dom-during-undoing-in-textarea.html new file mode 100644 index 0000000000..56f7f82a21 --- /dev/null +++ b/testing/web-platform/tests/editing/crashtests/update-dom-during-undoing-in-textarea.html @@ -0,0 +1,32 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<title>Test for updating the DOM tree while execCommand("undo") is running in the textarea</title> +<script> +"use strict"; + +let count = 0; +addEventListener("load", () => { + document.execCommand("insertText", false, "F"); + document.execCommand("undo"); +}); + +function onInputOfTextarea() { + if (count) { + document.querySelector("base").appendChild( + document.querySelector("content") + ); + } + count++; +} +</script> +</head> +<body> +<iframe></iframe> +<textarea autofocus oninput="onInputOfTextarea()">a</textarea> +<base></base> +<content> +<menu> +</body> +</html> diff --git a/testing/web-platform/tests/editing/data/README.md b/testing/web-platform/tests/editing/data/README.md new file mode 100644 index 0000000000..2ac414b280 --- /dev/null +++ b/testing/web-platform/tests/editing/data/README.md @@ -0,0 +1,173 @@ +# editing/data/*.js Format # + +In the interests of keeping file size down, the format of these +(machine-generated) data files is relatively concise. Unfortunately, this +means they can appear slightly cryptic to the untrained eye: + + ["foo[bar]baz", + [["stylewithcss","false"],["bold",""]], + "foo<b>[bar]</b>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], + +But never fear! It's not actually so complicated (assuming you understand the +relevant APIs to begin with). Each line has the following format, which we +will explain in due course: + + ["initial HTML", + [["command1", "arg1"], ["command2", "arg2"]], + "expected HTML", + [expected retval from command1, expected retval from command2], + {"command1":[expected original/final indeterm/state/value 1], + "command2":[expected original/final indeterm/state/value 2]}], + +## Line 1: Initial HTML ## + + -> ["foo[bar]baz", + [["stylewithcss","false"],["bold",""]], + "foo<b>[bar]</b>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], + +When testing, first a contenteditable div's innerHTML is set to the value given +here. Then the characters []{} are located and removed, and the selection is +set to where they used to be, as follows: + + * [ and ] indicate the left or right endpoint of the selection, if it's in + a text node. + * { and } indicate the left or right endpoint of the selection, if it's not + in a text node. + +Thus `<b>[foo]</b>` means the selection start and end are (foo, 0) and (foo, +3), while `<b>{foo}</b>` means they're (`<b>`, 0) and (`<b>`, 1). +`<b>[foo}</b>` and `<b>{foo]</b>` are also possible. There is no way to +describe backwards selections (i.e., distinguish anchor/focus). + +In cases where you want the selection in a place where it's not possible to +place text, like `<table><tbody>{<tr></tr>}</tbody></table>`, another format +exists using data-start and data-end attributes. It's only used in a few +tests, so it is not documented here. + +## Line 2: commands ## + + ["foo[bar]baz", + -> [["stylewithcss","false"],["bold",""]], + "foo<b>[bar]</b>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], + +After the innerHTML of the editing host is filled in, the commands given here +are run in order, like this: + + document.execCommand("stylewithcss", false, "false"); + document.execCommand("bold", false, ""); + +Most tests have only one command run. The exceptions are: + + 1. styleWithCSS. Tests that involve formatting elements or styles are run + twice, once with styleWithCSS on and once with it off. + 2. defaultParagraphSeparator. Tests that involve `<p>`s or `<div>`s are run + twice, once with defaultParagraphSeparator set to "div" and once "p". + 3. multitest.js tests interactions between different commands, so it contains + arbitrary combinations of commands. + +## Line 3: expected HTML ## + + ["foo[bar]baz", + [["stylewithcss","false"],["bold",""]], + -> "foo<b>[bar]</b>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], + +After the commands are run, we check that the innerHTML of the editing host +matches the expected HTML provided here. As on line 1, the characters []{} +(and data-start/data-end attributes) have special meaning and are not really +expected to be in the HTML. However, on this line they don't affect the test's +processing -- there are no tests of what the final selection is. + +This can be array of string if there are some acceptable cases. However, +array shouldn't be used as far as possible because WPT checks compatibility +between browsers. So, this should be used when: + +- There are some different behaviors in edge cases. +- There are some differences which are not related to the test. + +## Line 4: expected return values ## + + ["foo[bar]baz", + [["stylewithcss","false"],["bold",""]], + "foo<b>[bar]</b>baz", + -> [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], + +execCommand() returns a boolean: true if all went well, false if not (e.g., +invalid value). This line says what value each execCommand() call from line 2 +was supposed to return. Usually they'll all be true, but for tests of +error-handling they'll sometimes be false. + +## Line 5: expected indeterm/state/value ## + + ["foo[bar]baz", + [["stylewithcss","false"],["bold",""]], + "foo<b>[bar]</b>baz", + [true,true], + -> {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], + +For each command that we're running, we check queryCommandIndeterm(), +queryCommandState(), and queryCommandValue() before we begin running any of our +commands, and again after we've finished the last one. (We don't run these +checks in between commands.) For each command, this line gives an array of six +expected values, in order: + + 1. Indeterm before + 2. State before + 3. Value before + 4. Indeterm after + 5. State after + 6. Value after + +You can remember this by keeping in mind that the three "before" values come +before the three "after" values, and each set of three values is in +alphabetical order (indeterm/state/value). + +## Analysis of a real-world example ## + +Let's look back at the example we started with and see what it means: + + ["foo[bar]baz", + [["stylewithcss","false"],["bold",""]], + "foo<b>[bar]</b>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], + +Line 1: Set the innerHTML of our editing host to `foobarbaz`, and set the +selection's start and end inside the resulting text node, selecting the letters +"bar". (We actually first set the innerHTML to `foo[bar]baz` and remove the +brackets afterwards.) + +Line 2: Execute the commands: + + document.execCommand("stylewithcss", false, "false"); + document.execCommand("bold", false, ""); + +Before doing this, we record the indeterm/state/value for both "stylewithcss" +and "bold", and afterwards, we record them again. We also record the return +value of both execCommand() calls. + +Line 3: Our new innerHTML should be `foo<b>bar</b>baz`. The [ and ] say where +we would theoretically want the selection to be, but no actual test is run. + +Line 4: Both execCommands we ran should return true. + +Line 5: We expect the indeterm for styleWithCSS to be false both before and +after, and the value to be "" before and after -- since they always are for +this command. The state for styleWithCSS should be true beforehand, because +that's the way the previous test left it -- the testing framework doesn't clear +these settings in between tests. (Thus the first test of styleWithCSS on the +page also tests the default value of the state.) But we set it to false, so +after the tests it should be false. + +We expect the indeterm for bold to be false both before and after, because +before nothing is bold, and after everything is bold. Value should be "" +before and after, because it always is for bold. The state before should be +false, but after should have changed to true. diff --git a/testing/web-platform/tests/editing/data/backcolor.js b/testing/web-platform/tests/editing/data/backcolor.js new file mode 100644 index 0000000000..4d6e77e21d --- /dev/null +++ b/testing/web-platform/tests/editing/data/backcolor.js @@ -0,0 +1,353 @@ +// For documentation of the format, see README in this directory. +var browserTests = [ +["foo[]bar", + [["backcolor","#00FFFF"]], + "foo[]bar", + [true], + {"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<p>[foo</p> <p>bar]</p>", + [["stylewithcss","true"],["backcolor","#00FFFF"]], + "<p><span style=\"background-color:rgb(0, 255, 255)\">[foo</span></p> <p><span style=\"background-color:rgb(0, 255, 255)\">bar]</span></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<p>[foo</p> <p>bar]</p>", + [["stylewithcss","false"],["backcolor","#00FFFF"]], + "<p><span style=\"background-color:rgb(0, 255, 255)\">[foo</span></p> <p><span style=\"background-color:rgb(0, 255, 255)\">bar]</span></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<span>[foo</span> <span>bar]</span>", + [["stylewithcss","true"],["backcolor","#00FFFF"]], + "<span style=\"background-color:rgb(0, 255, 255)\"><span>[foo</span> <span>bar]</span></span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<span>[foo</span> <span>bar]</span>", + [["stylewithcss","false"],["backcolor","#00FFFF"]], + "<span style=\"background-color:rgb(0, 255, 255)\"><span>[foo</span> <span>bar]</span></span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<p>[foo</p><p> <span>bar</span> </p><p>baz]</p>", + [["stylewithcss","true"],["backcolor","#00FFFF"]], + "<p><span style=\"background-color:rgb(0, 255, 255)\">[foo</span></p><p> <span style=\"background-color:rgb(0, 255, 255)\"><span>bar</span></span> </p><p><span style=\"background-color:rgb(0, 255, 255)\">baz]</span></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<p>[foo</p><p> <span>bar</span> </p><p>baz]</p>", + [["stylewithcss","false"],["backcolor","#00FFFF"]], + "<p><span style=\"background-color:rgb(0, 255, 255)\">[foo</span></p><p> <span style=\"background-color:rgb(0, 255, 255)\"><span>bar</span></span> </p><p><span style=\"background-color:rgb(0, 255, 255)\">baz]</span></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<p>[foo<p><br><p>bar]", + [["stylewithcss","true"],["backcolor","#00FFFF"]], + "<p><span style=\"background-color:rgb(0, 255, 255)\">[foo</span></p><p><span style=\"background-color:rgb(0, 255, 255)\"><br></span></p><p><span style=\"background-color:rgb(0, 255, 255)\">bar]</span></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<p>[foo<p><br><p>bar]", + [["stylewithcss","false"],["backcolor","#00FFFF"]], + "<p><span style=\"background-color:rgb(0, 255, 255)\">[foo</span></p><p><span style=\"background-color:rgb(0, 255, 255)\"><br></span></p><p><span style=\"background-color:rgb(0, 255, 255)\">bar]</span></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<b>foo[]bar</b>", + [["backcolor","#00FFFF"]], + "<b>foo[]bar</b>", + [true], + {"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<i>foo[]bar</i>", + [["backcolor","#00FFFF"]], + "<i>foo[]bar</i>", + [true], + {"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<span>foo</span>{}<span>bar</span>", + [["backcolor","#00FFFF"]], + "<span>foo</span>{}<span>bar</span>", + [true], + {"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<span>foo[</span><span>]bar</span>", + [["backcolor","#00FFFF"]], + "<span>foo[</span><span>]bar</span>", + [true], + {"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["foo[bar]baz", + [["stylewithcss","true"],["backcolor","#00FFFF"]], + "foo<span style=\"background-color:rgb(0, 255, 255)\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["foo[bar]baz", + [["stylewithcss","false"],["backcolor","#00FFFF"]], + "foo<span style=\"background-color:rgb(0, 255, 255)\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["foo[bar<b>baz]qoz</b>quz", + [["stylewithcss","true"],["backcolor","#00FFFF"]], + "foo<span style=\"background-color:rgb(0, 255, 255)\">[bar</span><b><span style=\"background-color:rgb(0, 255, 255)\">baz]</span>qoz</b>quz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["foo[bar<b>baz]qoz</b>quz", + [["stylewithcss","false"],["backcolor","#00FFFF"]], + "foo<span style=\"background-color:rgb(0, 255, 255)\">[bar</span><b><span style=\"background-color:rgb(0, 255, 255)\">baz]</span>qoz</b>quz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["foo[bar<i>baz]qoz</i>quz", + [["stylewithcss","true"],["backcolor","#00FFFF"]], + "foo<span style=\"background-color:rgb(0, 255, 255)\">[bar</span><i><span style=\"background-color:rgb(0, 255, 255)\">baz]</span>qoz</i>quz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["foo[bar<i>baz]qoz</i>quz", + [["stylewithcss","false"],["backcolor","#00FFFF"]], + "foo<span style=\"background-color:rgb(0, 255, 255)\">[bar</span><i><span style=\"background-color:rgb(0, 255, 255)\">baz]</span>qoz</i>quz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["{<p><p> <p>foo</p>}", + [["stylewithcss","true"],["backcolor","#00FFFF"]], + "{<p></p><p> </p><p><span style=\"background-color:rgb(0, 255, 255)\">foo</span></p>}", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["{<p><p> <p>foo</p>}", + [["stylewithcss","false"],["backcolor","#00FFFF"]], + "{<p></p><p> </p><p><span style=\"background-color:rgb(0, 255, 255)\">foo</span></p>}", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>", + [["stylewithcss","true"],["backcolor","#00FFFF"]], + "<table><tbody><tr><td>foo</td><td>b<span style=\"background-color:rgb(0, 255, 255)\">[a]</span>r</td><td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>", + [["stylewithcss","false"],["backcolor","#00FFFF"]], + "<table><tbody><tr><td>foo</td><td>b<span style=\"background-color:rgb(0, 255, 255)\">[a]</span>r</td><td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table>", + [["stylewithcss","true"],["backcolor","#00FFFF"]], + "<table><tbody><tr><td>foo</td>{<td><span style=\"background-color:rgb(0, 255, 255)\">bar</span></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table>", + [["stylewithcss","false"],["backcolor","#00FFFF"]], + "<table><tbody><tr><td>foo</td>{<td><span style=\"background-color:rgb(0, 255, 255)\">bar</span></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table>", + [["stylewithcss","true"],["backcolor","#00FFFF"]], + "<table><tbody><tr>{<td><span style=\"background-color:rgb(0, 255, 255)\">foo</span></td><td><span style=\"background-color:rgb(0, 255, 255)\">bar</span></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table>", + [["stylewithcss","false"],["backcolor","#00FFFF"]], + "<table><tbody><tr>{<td><span style=\"background-color:rgb(0, 255, 255)\">foo</span></td><td><span style=\"background-color:rgb(0, 255, 255)\">bar</span></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>", + [["stylewithcss","true"],["backcolor","#00FFFF"]], + "<table><tbody>{<tr><td><span style=\"background-color:rgb(0, 255, 255)\">foo</span></td><td><span style=\"background-color:rgb(0, 255, 255)\">bar</span></td><td><span style=\"background-color:rgb(0, 255, 255)\">baz</span></td></tr>}</tbody></table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>", + [["stylewithcss","false"],["backcolor","#00FFFF"]], + "<table><tbody>{<tr><td><span style=\"background-color:rgb(0, 255, 255)\">foo</span></td><td><span style=\"background-color:rgb(0, 255, 255)\">bar</span></td><td><span style=\"background-color:rgb(0, 255, 255)\">baz</span></td></tr>}</tbody></table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>", + [["stylewithcss","true"],["backcolor","#00FFFF"]], + "<table>{<tbody><tr><td><span style=\"background-color:rgb(0, 255, 255)\">foo</span></td><td><span style=\"background-color:rgb(0, 255, 255)\">bar</span></td><td><span style=\"background-color:rgb(0, 255, 255)\">baz</span></td></tr></tbody>}</table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>", + [["stylewithcss","false"],["backcolor","#00FFFF"]], + "<table>{<tbody><tr><td><span style=\"background-color:rgb(0, 255, 255)\">foo</span></td><td><span style=\"background-color:rgb(0, 255, 255)\">bar</span></td><td><span style=\"background-color:rgb(0, 255, 255)\">baz</span></td></tr></tbody>}</table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["{<table><tr><td>foo<td>bar<td>baz</table>}", + [["stylewithcss","true"],["backcolor","#00FFFF"]], + "{<table><tbody><tr><td><span style=\"background-color:rgb(0, 255, 255)\">foo</span></td><td><span style=\"background-color:rgb(0, 255, 255)\">bar</span></td><td><span style=\"background-color:rgb(0, 255, 255)\">baz</span></td></tr></tbody></table>}", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["{<table><tr><td>foo<td>bar<td>baz</table>}", + [["stylewithcss","false"],["backcolor","#00FFFF"]], + "{<table><tbody><tr><td><span style=\"background-color:rgb(0, 255, 255)\">foo</span></td><td><span style=\"background-color:rgb(0, 255, 255)\">bar</span></td><td><span style=\"background-color:rgb(0, 255, 255)\">baz</span></td></tr></tbody></table>}", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<p style=\"background-color: rgb(0, 255, 255)\">foo[bar]baz</p>", + [["backcolor","#00FFFF"]], + "<p style=\"background-color:rgb(0, 255, 255)\">foo[bar]baz</p>", + [true], + {"backcolor":[false,false,"rgb(0, 255, 255)",false,false,"rgb(0, 255, 255)"]}], +["<p style=\"background-color: #00ffff\">foo[bar]baz</p>", + [["backcolor","#00FFFF"]], + "<p style=\"background-color:rgb(0, 255, 255)\">foo[bar]baz</p>", + [true], + {"backcolor":[false,false,"rgb(0, 255, 255)",false,false,"rgb(0, 255, 255)"]}], +["<p style=\"background-color: aqua\">foo[bar]baz</p>", + [["backcolor","#00FFFF"]], + "<p style=\"background-color:rgb(0, 255, 255)\">foo[bar]baz</p>", + [true], + {"backcolor":[false,false,"rgb(0, 255, 255)",false,false,"rgb(0, 255, 255)"]}], +["{<p style=\"background-color: aqua\">foo</p><p>bar</p>}", + [["stylewithcss","true"],["backcolor","#00FFFF"]], + "{<p style=\"background-color:rgb(0, 255, 255)\">foo</p><p><span style=\"background-color:rgb(0, 255, 255)\">bar</span></p>}", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"backcolor":[true,false,"rgb(0, 255, 255)",false,false,"rgb(0, 255, 255)"]}], +["{<p style=\"background-color: aqua\">foo</p><p>bar</p>}", + [["stylewithcss","false"],["backcolor","#00FFFF"]], + "{<p style=\"background-color:rgb(0, 255, 255)\">foo</p><p><span style=\"background-color:rgb(0, 255, 255)\">bar</span></p>}", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"backcolor":[true,false,"rgb(0, 255, 255)",false,false,"rgb(0, 255, 255)"]}], +["<span style=\"background-color: aqua\">foo<span style=\"background-color: tan\">[bar]</span>baz</span>", + [["stylewithcss","true"],["backcolor","#00FFFF"]], + "<span style=\"background-color:rgb(0, 255, 255)\">foo[bar]baz</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"backcolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["<span style=\"background-color: aqua\">foo<span style=\"background-color: tan\">[bar]</span>baz</span>", + [["stylewithcss","false"],["backcolor","#00FFFF"]], + "<span style=\"background-color:rgb(0, 255, 255)\">foo[bar]baz</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"backcolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["<span style=\"background-color: #00ffff\">foo<span style=\"background-color: tan\">[bar]</span>baz</span>", + [["stylewithcss","true"],["backcolor","#00FFFF"]], + "<span style=\"background-color:rgb(0, 255, 255)\">foo[bar]baz</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"backcolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["<span style=\"background-color: #00ffff\">foo<span style=\"background-color: tan\">[bar]</span>baz</span>", + [["stylewithcss","false"],["backcolor","#00FFFF"]], + "<span style=\"background-color:rgb(0, 255, 255)\">foo[bar]baz</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"backcolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["<span style=\"background-color: #0ff\">foo<span style=\"background-color: tan\">[bar]</span>baz</span>", + [["stylewithcss","true"],["backcolor","#00FFFF"]], + "<span style=\"background-color:rgb(0, 255, 255)\">foo[bar]baz</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"backcolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["<span style=\"background-color: #0ff\">foo<span style=\"background-color: tan\">[bar]</span>baz</span>", + [["stylewithcss","false"],["backcolor","#00FFFF"]], + "<span style=\"background-color:rgb(0, 255, 255)\">foo[bar]baz</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"backcolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["<span style=\"background-color: rgb(0, 255, 255)\">foo<span style=\"background-color: tan\">[bar]</span>baz</span>", + [["stylewithcss","true"],["backcolor","#00FFFF"]], + "<span style=\"background-color:rgb(0, 255, 255)\">foo[bar]baz</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"backcolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["<span style=\"background-color: rgb(0, 255, 255)\">foo<span style=\"background-color: tan\">[bar]</span>baz</span>", + [["stylewithcss","false"],["backcolor","#00FFFF"]], + "<span style=\"background-color:rgb(0, 255, 255)\">foo[bar]baz</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"backcolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["<span style=\"background-color: aqua\">foo<span style=\"background-color: tan\">b[ar]</span>baz</span>", + [["backcolor","#00FFFF"]], + "<span style=\"background-color:rgb(0, 255, 255)\">foo<span style=\"background-color:rgb(210, 180, 140)\">b</span>[ar]baz</span>", + [true], + {"backcolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["<p style=\"background-color: aqua\">foo<span style=\"background-color: tan\">b[ar]</span>baz</p>", + [["backcolor","#00FFFF"]], + "<p style=\"background-color:rgb(0, 255, 255)\">foo<span style=\"background-color:rgb(210, 180, 140)\">b</span>[ar]baz</p>", + [true], + {"backcolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["<div style=\"background-color: aqua\"><p style=\"background-color: tan\">b[ar]</p></div>", + [["stylewithcss","true"],["backcolor","#00FFFF"]], + "<div style=\"background-color:rgb(0, 255, 255)\"><p style=\"background-color:rgb(210, 180, 140)\">b<span style=\"background-color:rgb(0, 255, 255)\">[ar]</span></p></div>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"backcolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["<div style=\"background-color: aqua\"><p style=\"background-color: tan\">b[ar]</p></div>", + [["stylewithcss","false"],["backcolor","#00FFFF"]], + "<div style=\"background-color:rgb(0, 255, 255)\"><p style=\"background-color:rgb(210, 180, 140)\">b<span style=\"background-color:rgb(0, 255, 255)\">[ar]</span></p></div>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"backcolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["<span style=\"display: block; background-color: aqua\"><span style=\"display: block; background-color: tan\">b[ar]</span></span>", + [["stylewithcss","true"],["backcolor","#00FFFF"]], + "<span style=\"display:block; background-color:rgb(0, 255, 255)\"><span style=\"display:block; background-color:rgb(210, 180, 140)\">b<span style=\"background-color:rgb(0, 255, 255)\">[ar]</span></span></span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"backcolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["<span style=\"display: block; background-color: aqua\"><span style=\"display: block; background-color: tan\">b[ar]</span></span>", + [["stylewithcss","false"],["backcolor","#00FFFF"]], + "<span style=\"display:block; background-color:rgb(0, 255, 255)\"><span style=\"display:block; background-color:rgb(210, 180, 140)\">b<span style=\"background-color:rgb(0, 255, 255)\">[ar]</span></span></span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"backcolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["fo[o<span style=background-color:tan>b]ar</span>baz", + [["stylewithcss","true"],["backcolor","#00FFFF"]], + "fo<span style=\"background-color:rgb(0, 255, 255)\">[o</span><span style=\"background-color:rgb(210, 180, 140)\"><span style=\"background-color:rgb(0, 255, 255)\">b]</span>ar</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"backcolor":[true,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["fo[o<span style=background-color:tan>b]ar</span>baz", + [["stylewithcss","false"],["backcolor","#00FFFF"]], + "fo<span style=\"background-color:rgb(0, 255, 255)\">[o</span><span style=\"background-color:rgb(210, 180, 140)\"><span style=\"background-color:rgb(0, 255, 255)\">b]</span>ar</span>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"backcolor":[true,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["foo<span style=background-color:tan>ba[r</span>b]az", + [["stylewithcss","true"],["backcolor","#00FFFF"]], + "foo<span style=\"background-color:rgb(210, 180, 140)\">ba<span style=\"background-color:rgb(0, 255, 255)\">[r</span></span><span style=\"background-color:rgb(0, 255, 255)\">b]</span>az", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"backcolor":[true,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["foo<span style=background-color:tan>ba[r</span>b]az", + [["stylewithcss","false"],["backcolor","#00FFFF"]], + "foo<span style=\"background-color:rgb(210, 180, 140)\">ba<span style=\"background-color:rgb(0, 255, 255)\">[r</span></span><span style=\"background-color:rgb(0, 255, 255)\">b]</span>az", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"backcolor":[true,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["fo[o<span style=background-color:tan>bar</span>b]az", + [["backcolor","#00FFFF"]], + "fo<span style=\"background-color:rgb(0, 255, 255)\">[obarb]</span>az", + [true], + {"backcolor":[true,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["foo[<span style=background-color:tan>b]ar</span>baz", + [["stylewithcss","true"],["backcolor","#00FFFF"]], + "foo[<span style=\"background-color:rgb(210, 180, 140)\"><span style=\"background-color:rgb(0, 255, 255)\">b]</span>ar</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"backcolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["foo[<span style=background-color:tan>b]ar</span>baz", + [["stylewithcss","false"],["backcolor","#00FFFF"]], + "foo[<span style=\"background-color:rgb(210, 180, 140)\"><span style=\"background-color:rgb(0, 255, 255)\">b]</span>ar</span>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"backcolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["foo<span style=background-color:tan>ba[r</span>]baz", + [["stylewithcss","true"],["backcolor","#00FFFF"]], + "foo<span style=\"background-color:rgb(210, 180, 140)\">ba<span style=\"background-color:rgb(0, 255, 255)\">[r</span></span>]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"backcolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["foo<span style=background-color:tan>ba[r</span>]baz", + [["stylewithcss","false"],["backcolor","#00FFFF"]], + "foo<span style=\"background-color:rgb(210, 180, 140)\">ba<span style=\"background-color:rgb(0, 255, 255)\">[r</span></span>]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"backcolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["foo[<span style=background-color:tan>bar</span>]baz", + [["backcolor","#00FFFF"]], + "foo[<span style=\"background-color:rgb(0, 255, 255)\">bar</span>]baz", + [true], + {"backcolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["foo<span style=background-color:tan>[bar]</span>baz", + [["backcolor","#00FFFF"]], + "foo<span style=\"background-color:rgb(0, 255, 255)\">[bar]</span>baz", + [true], + {"backcolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["foo{<span style=background-color:tan>bar</span>}baz", + [["backcolor","#00FFFF"]], + "foo{<span style=\"background-color:rgb(0, 255, 255)\">bar}</span>baz", + [true], + {"backcolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["<span style=background-color:tan>fo[o</span><span style=background-color:yellow>b]ar</span>", + [["stylewithcss","true"],["backcolor","#00FFFF"]], + "<span style=\"background-color:rgb(210, 180, 140)\">fo<span style=\"background-color:rgb(0, 255, 255)\">[o</span></span><span style=\"background-color:rgb(255, 255, 0)\"><span style=\"background-color:rgb(0, 255, 255)\">b]</span>ar</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"backcolor":[true,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["<span style=background-color:tan>fo[o</span><span style=background-color:yellow>b]ar</span>", + [["stylewithcss","false"],["backcolor","#00FFFF"]], + "<span style=\"background-color:rgb(210, 180, 140)\">fo<span style=\"background-color:rgb(0, 255, 255)\">[o</span></span><span style=\"background-color:rgb(255, 255, 0)\"><span style=\"background-color:rgb(0, 255, 255)\">b]</span>ar</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"backcolor":[true,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["<span style=background-color:tan>fo[o</span><span style=background-color:tan>b]ar</span>", + [["stylewithcss","true"],["backcolor","#00FFFF"]], + "<span style=\"background-color:rgb(210, 180, 140)\">fo<span style=\"background-color:rgb(0, 255, 255)\">[o</span></span><span style=\"background-color:rgb(210, 180, 140)\"><span style=\"background-color:rgb(0, 255, 255)\">b]</span>ar</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"backcolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["<span style=background-color:tan>fo[o</span><span style=background-color:tan>b]ar</span>", + [["stylewithcss","false"],["backcolor","#00FFFF"]], + "<span style=\"background-color:rgb(210, 180, 140)\">fo<span style=\"background-color:rgb(0, 255, 255)\">[o</span></span><span style=\"background-color:rgb(210, 180, 140)\"><span style=\"background-color:rgb(0, 255, 255)\">b]</span>ar</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"backcolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["<span style=background-color:tan>fo[o<span style=background-color:transparent>b]ar</span></span>", + [["stylewithcss","true"],["backcolor","#00FFFF"]], + "<span style=\"background-color:rgb(210, 180, 140)\">fo<span style=\"background-color:rgb(0, 255, 255)\">[o</span><span style=\"background-color:rgba(0, 0, 0, 0)\"><span style=\"background-color:rgb(0, 255, 255)\">b]</span>ar</span></span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"backcolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["<span style=background-color:tan>fo[o<span style=background-color:transparent>b]ar</span></span>", + [["stylewithcss","false"],["backcolor","#00FFFF"]], + "<span style=\"background-color:rgb(210, 180, 140)\">fo<span style=\"background-color:rgb(0, 255, 255)\">[o</span><span style=\"background-color:rgba(0, 0, 0, 0)\"><span style=\"background-color:rgb(0, 255, 255)\">b]</span>ar</span></span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"backcolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}] +] diff --git a/testing/web-platform/tests/editing/data/bold.js b/testing/web-platform/tests/editing/data/bold.js new file mode 100644 index 0000000000..4e2882c8cc --- /dev/null +++ b/testing/web-platform/tests/editing/data/bold.js @@ -0,0 +1,1075 @@ +// For documentation of the format, see README in this directory. +var browserTests = [ +["foo[]bar", + [["bold",""]], + "foo[]bar", + [true], + {"bold":[false,false,"",false,true,""]}], +["<p>[foo</p> <p>bar]</p>", + [["stylewithcss","true"],["bold",""]], + "<p><span style=\"font-weight:bold\">[foo</span></p> <p><span style=\"font-weight:bold\">bar]</span></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,false,"",false,true,""]}], +["<p>[foo</p> <p>bar]</p>", + [["stylewithcss","false"],["bold",""]], + "<p><b>[foo</b></p> <p><b>bar]</b></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], +["<span>[foo</span> <span>bar]</span>", + [["stylewithcss","true"],["bold",""]], + "<span style=\"font-weight:bold\"><span>[foo</span> <span>bar]</span></span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,false,"",false,true,""]}], +["<span>[foo</span> <span>bar]</span>", + [["stylewithcss","false"],["bold",""]], + "<b><span>[foo</span> <span>bar]</span></b>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], +["<p>[foo</p><p> <span>bar</span> </p><p>baz]</p>", + [["stylewithcss","true"],["bold",""]], + "<p><span style=\"font-weight:bold\">[foo</span></p><p> <span style=\"font-weight:bold\"><span>bar</span></span> </p><p><span style=\"font-weight:bold\">baz]</span></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,false,"",false,true,""]}], +["<p>[foo</p><p> <span>bar</span> </p><p>baz]</p>", + [["stylewithcss","false"],["bold",""]], + "<p><b>[foo</b></p><p> <b><span>bar</span></b> </p><p><b>baz]</b></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], +["<p>[foo<p><br><p>bar]", + [["stylewithcss","true"],["bold",""]], + "<p><span style=\"font-weight:bold\">[foo</span></p><p><span style=\"font-weight:bold\"><br></span></p><p><span style=\"font-weight:bold\">bar]</span></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,false,"",false,true,""]}], +["<p>[foo<p><br><p>bar]", + [["stylewithcss","false"],["bold",""]], + "<p><b>[foo</b></p><p><b><br></b></p><p><b>bar]</b></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], +["<b>foo[]bar</b>", + [["bold",""]], + "<b>foo[]bar</b>", + [true], + {"bold":[false,true,"",false,false,""]}], +["<i>foo[]bar</i>", + [["bold",""]], + "<i>foo[]bar</i>", + [true], + {"bold":[false,false,"",false,true,""]}], +["<span>foo</span>{}<span>bar</span>", + [["bold",""]], + "<span>foo</span>{}<span>bar</span>", + [true], + {"bold":[false,false,"",false,true,""]}], +["<span>foo[</span><span>]bar</span>", + [["bold",""]], + "<span>foo[</span><span>]bar</span>", + [true], + {"bold":[false,false,"",false,true,""]}], +["foo[bar]baz", + [["stylewithcss","true"],["bold",""]], + "foo<span style=\"font-weight:bold\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,false,"",false,true,""]}], +["foo[bar]baz", + [["stylewithcss","false"],["bold",""]], + "foo<b>[bar]</b>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], +["foo[bar<b>baz]qoz</b>quz", + [["bold",""]], + "foo<b>[barbaz]qoz</b>quz", + [true], + {"bold":[true,false,"",false,true,""]}], +["foo[bar<i>baz]qoz</i>quz", + [["stylewithcss","true"],["bold",""]], + "foo<span style=\"font-weight:bold\">[bar</span><i><span style=\"font-weight:bold\">baz]</span>qoz</i>quz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,false,"",false,true,""]}], +["foo[bar<i>baz]qoz</i>quz", + [["stylewithcss","false"],["bold",""]], + "foo<b>[bar</b><i><b>baz]</b>qoz</i>quz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], +["{<p><p> <p>foo</p>}", + [["stylewithcss","true"],["bold",""]], + "{<p></p><p> </p><p><span style=\"font-weight:bold\">foo</span></p>}", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,false,"",false,true,""]}], +["{<p><p> <p>foo</p>}", + [["stylewithcss","false"],["bold",""]], + "{<p></p><p> </p><p><b>foo</b></p>}", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], +["foo<span contenteditable=false>[bar]</span>baz", + [["bold",""]], + "foo<span contenteditable=\"false\">[bar]</span>baz", + [false], + {"bold":[false,false,"",false,false,""]}], +["fo[o<span contenteditable=false>bar</span>b]az", + [["stylewithcss","true"],["bold",""]], + "fo<span style=\"font-weight:bold\">[o</span><span contenteditable=\"false\">bar</span><span style=\"font-weight:bold\">b]</span>az", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,false,"",false,true,""]}], +["fo[o<span contenteditable=false>bar</span>b]az", + [["stylewithcss","false"],["bold",""]], + "fo<b>[o</b><span contenteditable=\"false\">bar</span><b>b]</b>az", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], +["foo<span contenteditable=false>ba[r</span>b]az", + [["bold",""]], + "foo<span contenteditable=\"false\">ba[r</span>b]az", + [false], + {"bold":[false,false,"",false,false,""]}], +["fo[o<span contenteditable=false>b]ar</span>baz", + [["bold",""]], + "fo[o<span contenteditable=\"false\">b]ar</span>baz", + [false], + {"bold":[false,false,"",false,false,""]}], +["fo[<b>o</b><span contenteditable=false>bar</span><b>b</b>]az", + [["stylewithcss","true"],["bold",""]], + "fo[o<span contenteditable=\"false\">bar</span>b]az", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,true,"",false,false,""]}], +["fo[<b>o</b><span contenteditable=false>bar</span><b>b</b>]az", + [["stylewithcss","false"],["bold",""]], + "fo[o<span contenteditable=\"false\">bar</span>b]az", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,true,"",false,false,""]}], +["<span contenteditable=false>foo<span contenteditable=true>[bar]</span>baz</span>", + [["stylewithcss","true"],["bold",""]], + "<span contenteditable=\"false\">foo<span contenteditable=\"true\"><span style=\"font-weight:bold\">[bar]</span></span>baz</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,false,"",false,true,""]}], +["<span contenteditable=false>foo<span contenteditable=true>[bar]</span>baz</span>", + [["stylewithcss","false"],["bold",""]], + "<span contenteditable=\"false\">foo<span contenteditable=\"true\"><b>[bar]</b></span>baz</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], +["<span contenteditable=false>fo[o<span contenteditable=true>bar</span>b]az</span>", + [["bold",""]], + "<span contenteditable=\"false\">fo[o<span contenteditable=\"true\">bar</span>b]az</span>", + [false], + {"bold":[false,false,"",false,false,""]}], +["<span contenteditable=false>foo<span contenteditable=true>ba[r</span>b]az</span>", + [["bold",""]], + "<span contenteditable=\"false\">foo<span contenteditable=\"true\">ba[r</span>b]az</span>", + [false], + {"bold":[false,false,"",false,false,""]}], +["<span contenteditable=false>fo[o<span contenteditable=true>b]ar</span>baz</span>", + [["bold",""]], + "<span contenteditable=\"false\">fo[o<span contenteditable=\"true\">b]ar</span>baz</span>", + [false], + {"bold":[false,false,"",false,false,""]}], +["<span contenteditable=false>fo[<b>o<span contenteditable=true>bar</span>b</b>]az</span>", + [["bold",""]], + "<span contenteditable=\"false\">fo[<b>o<span contenteditable=\"true\">bar</span>b</b>]az</span>", + [false], + {"bold":[false,true,"",false,true,""]}], +["<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>", + [["stylewithcss","true"],["bold",""]], + "<table><tbody><tr><td>foo</td><td>b<span style=\"font-weight:bold\">[a]</span>r</td><td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,false,"",false,true,""]}], +["<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>", + [["stylewithcss","false"],["bold",""]], + "<table><tbody><tr><td>foo</td><td>b<b>[a]</b>r</td><td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], +["<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table>", + [["stylewithcss","true"],["bold",""]], + "<table><tbody><tr><td>foo</td>{<td><span style=\"font-weight:bold\">bar</span></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,false,"",false,true,""]}], +["<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table>", + [["stylewithcss","false"],["bold",""]], + "<table><tbody><tr><td>foo</td>{<td><b>bar</b></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], +["<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table>", + [["stylewithcss","true"],["bold",""]], + "<table><tbody><tr>{<td><span style=\"font-weight:bold\">foo</span></td><td><span style=\"font-weight:bold\">bar</span></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,false,"",false,true,""]}], +["<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table>", + [["stylewithcss","false"],["bold",""]], + "<table><tbody><tr>{<td><b>foo</b></td><td><b>bar</b></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], +["<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>", + [["stylewithcss","true"],["bold",""]], + "<table><tbody>{<tr><td><span style=\"font-weight:bold\">foo</span></td><td><span style=\"font-weight:bold\">bar</span></td><td><span style=\"font-weight:bold\">baz</span></td></tr>}</tbody></table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,false,"",false,true,""]}], +["<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>", + [["stylewithcss","false"],["bold",""]], + "<table><tbody>{<tr><td><b>foo</b></td><td><b>bar</b></td><td><b>baz</b></td></tr>}</tbody></table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], +["<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>", + [["stylewithcss","true"],["bold",""]], + "<table>{<tbody><tr><td><span style=\"font-weight:bold\">foo</span></td><td><span style=\"font-weight:bold\">bar</span></td><td><span style=\"font-weight:bold\">baz</span></td></tr></tbody>}</table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,false,"",false,true,""]}], +["<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>", + [["stylewithcss","false"],["bold",""]], + "<table>{<tbody><tr><td><b>foo</b></td><td><b>bar</b></td><td><b>baz</b></td></tr></tbody>}</table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], +["{<table><tr><td>foo<td>bar<td>baz</table>}", + [["stylewithcss","true"],["bold",""]], + "{<table><tbody><tr><td><span style=\"font-weight:bold\">foo</span></td><td><span style=\"font-weight:bold\">bar</span></td><td><span style=\"font-weight:bold\">baz</span></td></tr></tbody></table>}", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,false,"",false,true,""]}], +["{<table><tr><td>foo<td>bar<td>baz</table>}", + [["stylewithcss","false"],["bold",""]], + "{<table><tbody><tr><td><b>foo</b></td><td><b>bar</b></td><td><b>baz</b></td></tr></tbody></table>}", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], +["foo<span style=\"font-weight: bold\">[bar]</span>baz", + [["stylewithcss","true"],["bold",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,true,"",false,false,""]}], +["foo<span style=\"font-weight: bold\">[bar]</span>baz", + [["stylewithcss","false"],["bold",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,true,"",false,false,""]}], +["foo<b>[bar]</b>baz", + [["stylewithcss","true"],["bold",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,true,"",false,false,""]}], +["foo<b>[bar]</b>baz", + [["stylewithcss","false"],["bold",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,true,"",false,false,""]}], +["foo<b>bar</b>[baz]", + [["bold",""]], + "foo<b>bar[baz]</b>", + [true], + {"bold":[false,false,"",false,true,""]}], +["[foo]<b>bar</b>baz", + [["bold",""]], + "<b>[foo]bar</b>baz", + [true], + {"bold":[false,false,"",false,true,""]}], +["<b>foo</b>[bar]<b>baz</b>", + [["stylewithcss","true"],["bold",""]], + "<b>foo</b><span style=\"font-weight:bold\">[bar]</span><b>baz</b>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,false,"",false,true,""]}], +["<b>foo</b>[bar]<b>baz</b>", + [["stylewithcss","false"],["bold",""]], + "<b>foo[bar]baz</b>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], +// Should not use the near <strong> as alternative container of <b> and +// <span style="font-weight: bold">. +["foo<strong>bar</strong>[baz]", + [["bold",""]], + "foo<strong>bar</strong><b>baz</b>", + [true], + {"bold":[false,false,"",false,true,""]}], +["[foo]<strong>bar</strong>baz", + [["bold",""]], + "<b>foo</b><strong>bar</strong>baz", + [true], + {"bold":[false,false,"",false,true,""]}], +["<strong>foo</strong>[bar]<strong>baz</strong>", + [["bold",""]], + "<strong>foo</strong><b>bar</b><strong>baz</strong>", + [true], + {"bold":[false,false,"",false,true,""]}], +["<b>foo</b>[bar]<strong>baz</strong>", + [["bold",""]], + "<b>foo[bar]</b><strong>baz</strong>", + [true], + {"bold":[false,false,"",false,true,""]}], +// Should not use the near <b> as alternative container of +// <span style="font-weight: bold"> +["<strong>foo</strong>[bar]<b>baz</b>", + [["stylewithcss","true"],["bold",""]], + "<strong>foo</strong><span style=\"font-weight:bold\">bar</span><b>baz</b>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,false,"",false,true,""]}], +// Should use the near <b> as new container +["<strong>foo</strong>[bar]<b>baz</b>", + [["stylewithcss","false"],["bold",""]], + "<strong>foo</strong><b>barbaz</b>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], +["foo[<b>bar</b>]baz", + [["stylewithcss","true"],["bold",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,true,"",false,false,""]}], +["foo[<b>bar</b>]baz", + [["stylewithcss","false"],["bold",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,true,"",false,false,""]}], +["foo[<b>bar]</b>baz", + [["stylewithcss","true"],["bold",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,true,"",false,false,""]}], +["foo[<b>bar]</b>baz", + [["stylewithcss","false"],["bold",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,true,"",false,false,""]}], +["foo<b>[bar</b>]baz", + [["stylewithcss","true"],["bold",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,true,"",false,false,""]}], +["foo<b>[bar</b>]baz", + [["stylewithcss","false"],["bold",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,true,"",false,false,""]}], +["foo{<b></b>}baz", + [["bold",""]], + "foo{<b></b>}baz", + [true], + {"bold":[false,false,"",false,true,""]}], +["foo{<i></i>}baz", + [["bold",""]], + "foo{<i></i>}baz", + [true], + {"bold":[false,false,"",false,true,""]}], +["foo{<b><i></i></b>}baz", + [["bold",""]], + "foo{<b><i></i></b>}baz", + [true], + {"bold":[false,false,"",false,true,""]}], +["foo{<i><b></b></i>}baz", + [["bold",""]], + "foo{<i><b></b></i>}baz", + [true], + {"bold":[false,false,"",false,true,""]}], +["foo<strong>[bar]</strong>baz", + [["bold",""]], + "foo[bar]baz", + [true], + {"bold":[false,true,"",false,false,""]}], +["foo[<strong>bar</strong>]baz", + [["bold",""]], + "foo[bar]baz", + [true], + {"bold":[false,true,"",false,false,""]}], +["foo[<strong>bar]</strong>baz", + [["bold",""]], + "foo[bar]baz", + [true], + {"bold":[false,true,"",false,false,""]}], +["foo<strong>[bar</strong>]baz", + [["bold",""]], + "foo[bar]baz", + [true], + {"bold":[false,true,"",false,false,""]}], +["foo[<span style=\"font-weight: bold\">bar</span>]baz", + [["stylewithcss","true"],["bold",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,true,"",false,false,""]}], +["foo[<span style=\"font-weight: bold\">bar</span>]baz", + [["stylewithcss","false"],["bold",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,true,"",false,false,""]}], +["foo[<span style=\"font-weight: bold\">bar]</span>baz", + [["stylewithcss","true"],["bold",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,true,"",false,false,""]}], +["foo[<span style=\"font-weight: bold\">bar]</span>baz", + [["stylewithcss","false"],["bold",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,true,"",false,false,""]}], +["foo<span style=\"font-weight: bold\">[bar</span>]baz", + [["stylewithcss","true"],["bold",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,true,"",false,false,""]}], +["foo<span style=\"font-weight: bold\">[bar</span>]baz", + [["stylewithcss","false"],["bold",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,true,"",false,false,""]}], +["<b>{<p>foo</p><p>bar</p>}<p>baz</p></b>", + [["stylewithcss","true"],["bold",""]], + "{<p>foo</p><p>bar</p>}<p><span style=\"font-weight:bold\">baz</span></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,true,"",false,false,""]}], +["<b>{<p>foo</p><p>bar</p>}<p>baz</p></b>", + [["stylewithcss","false"],["bold",""]], + "{<p>foo</p><p>bar</p>}<p><b>baz</b></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,true,"",false,false,""]}], +["<b><p>foo[<i>bar</i>}</p><p>baz</p></b>", + [["stylewithcss","true"],["bold",""]], + "<p><span style=\"font-weight:bold\">foo[</span><i>bar</i>}</p><p><span style=\"font-weight:bold\">baz</span></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,true,"",false,false,""]}], +["<b><p>foo[<i>bar</i>}</p><p>baz</p></b>", + [["stylewithcss","false"],["bold",""]], + "<p><b>foo[</b><i>bar</i>}</p><p><b>baz</b></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,true,"",false,false,""]}], +["foo [bar <b>baz] qoz</b> quz sic", + [["bold",""]], + "foo <b>[bar baz] qoz</b> quz sic", + [true], + {"bold":[true,false,"",false,true,""]}], +["foo bar <b>baz [qoz</b> quz] sic", + [["bold",""]], + "foo bar <b>baz [qoz quz]</b> sic", + [true], + {"bold":[true,false,"",false,true,""]}], +["<b id=purple>bar [baz] qoz</b>", + [["stylewithcss","true"],["bold",""]], + "<span id=\"purple\"><span style=\"font-weight:bold\">bar </span>[baz]<span style=\"font-weight:bold\"> qoz</span></span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,true,"",false,false,""]}], +["<b id=purple>bar [baz] qoz</b>", + [["stylewithcss","false"],["bold",""]], + "<span id=\"purple\"><b>bar </b>[baz]<b> qoz</b></span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,true,"",false,false,""]}], +["foo<span style=\"font-weight: 100\">[bar]</span>baz", + [["stylewithcss","true"],["bold",""]], + "foo<span style=\"font-weight:bold\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,false,"",false,true,""]}], +["foo<span style=\"font-weight: 100\">[bar]</span>baz", + [["stylewithcss","false"],["bold",""]], + "foo<b>[bar]</b>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], +["foo<span style=\"font-weight: 200\">[bar]</span>baz", + [["stylewithcss","true"],["bold",""]], + "foo<span style=\"font-weight:bold\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,false,"",false,true,""]}], +["foo<span style=\"font-weight: 200\">[bar]</span>baz", + [["stylewithcss","false"],["bold",""]], + "foo<b>[bar]</b>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], +["foo<span style=\"font-weight: 300\">[bar]</span>baz", + [["stylewithcss","true"],["bold",""]], + "foo<span style=\"font-weight:bold\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,false,"",false,true,""]}], +["foo<span style=\"font-weight: 300\">[bar]</span>baz", + [["stylewithcss","false"],["bold",""]], + "foo<b>[bar]</b>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], +["foo<span style=\"font-weight: 400\">[bar]</span>baz", + [["stylewithcss","true"],["bold",""]], + "foo<span style=\"font-weight:bold\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,false,"",false,true,""]}], +["foo<span style=\"font-weight: 400\">[bar]</span>baz", + [["stylewithcss","false"],["bold",""]], + "foo<b>[bar]</b>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], +["foo<span style=\"font-weight: 500\">[bar]</span>baz", + [["stylewithcss","true"],["bold",""]], + "foo<span style=\"font-weight:bold\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,false,"",false,true,""]}], +["foo<span style=\"font-weight: 500\">[bar]</span>baz", + [["stylewithcss","false"],["bold",""]], + "foo<b>[bar]</b>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], +["foo<span style=\"font-weight: 600\">[bar]</span>baz", + [["stylewithcss","true"],["bold",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,true,"",false,false,""]}], +["foo<span style=\"font-weight: 600\">[bar]</span>baz", + [["stylewithcss","false"],["bold",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,true,"",false,false,""]}], +["foo<span style=\"font-weight: 700\">[bar]</span>baz", + [["stylewithcss","true"],["bold",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,true,"",false,false,""]}], +["foo<span style=\"font-weight: 700\">[bar]</span>baz", + [["stylewithcss","false"],["bold",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,true,"",false,false,""]}], +["foo<span style=\"font-weight: 800\">[bar]</span>baz", + [["stylewithcss","true"],["bold",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,true,"",false,false,""]}], +["foo<span style=\"font-weight: 800\">[bar]</span>baz", + [["stylewithcss","false"],["bold",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,true,"",false,false,""]}], +["foo<span style=\"font-weight: 900\">[bar]</span>baz", + [["stylewithcss","true"],["bold",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,true,"",false,false,""]}], +["foo<span style=\"font-weight: 900\">[bar]</span>baz", + [["stylewithcss","false"],["bold",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,true,"",false,false,""]}], +["foo<span style=\"font-weight: 400\">[bar</span>]baz", + [["stylewithcss","true"],["bold",""]], + "foo<span style=\"font-weight:bold\">[bar</span>]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,false,"",false,true,""]}], +["foo<span style=\"font-weight: 400\">[bar</span>]baz", + [["stylewithcss","false"],["bold",""]], + "foo<b>[bar</b>]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], +["foo<span style=\"font-weight: 700\">[bar</span>]baz", + [["stylewithcss","true"],["bold",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,true,"",false,false,""]}], +["foo<span style=\"font-weight: 700\">[bar</span>]baz", + [["stylewithcss","false"],["bold",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,true,"",false,false,""]}], +["foo[<span style=\"font-weight: 400\">bar]</span>baz", + [["stylewithcss","true"],["bold",""]], + "foo[<span style=\"font-weight:bold\">bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,false,"",false,true,""]}], +["foo[<span style=\"font-weight: 400\">bar]</span>baz", + [["stylewithcss","false"],["bold",""]], + "foo[<b>bar]</b>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], +["foo[<span style=\"font-weight: 700\">bar]</span>baz", + [["stylewithcss","true"],["bold",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,true,"",false,false,""]}], +["foo[<span style=\"font-weight: 700\">bar]</span>baz", + [["stylewithcss","false"],["bold",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,true,"",false,false,""]}], +["foo[<span style=\"font-weight: 400\">bar</span>]baz", + [["stylewithcss","true"],["bold",""]], + "foo[<span style=\"font-weight:bold\">bar</span>]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,false,"",false,true,""]}], +["foo[<span style=\"font-weight: 400\">bar</span>]baz", + [["stylewithcss","false"],["bold",""]], + "foo[<b>bar</b>]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], +["foo[<span style=\"font-weight: 700\">bar</span>]baz", + [["stylewithcss","true"],["bold",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,true,"",false,false,""]}], +["foo[<span style=\"font-weight: 700\">bar</span>]baz", + [["stylewithcss","false"],["bold",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,true,"",false,false,""]}], +["<span style=\"font-weight: 100\">foo[bar]baz</span>", + [["stylewithcss","true"],["bold",""]], + "<span style=\"font-weight:100\">foo<span style=\"font-weight:bold\">[bar]</span>baz</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,false,"",false,true,""]}], +["<span style=\"font-weight: 100\">foo[bar]baz</span>", + [["stylewithcss","false"],["bold",""]], + "<span style=\"font-weight:100\">foo<b>[bar]</b>baz</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], +["<span style=\"font-weight: 400\">foo[bar]baz</span>", + [["stylewithcss","true"],["bold",""]], + "<span style=\"font-weight:400\">foo<span style=\"font-weight:bold\">[bar]</span>baz</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,false,"",false,true,""]}], +["<span style=\"font-weight: 400\">foo[bar]baz</span>", + [["stylewithcss","false"],["bold",""]], + "<span style=\"font-weight:400\">foo<b>[bar]</b>baz</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], +["<span style=\"font-weight: 700\">foo[bar]baz</span>", + [["stylewithcss","true"],["bold",""]], + "<span style=\"font-weight:700\">foo</span>[bar]<span style=\"font-weight:700\">baz</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,true,"",false,false,""]}], +["<span style=\"font-weight: 700\">foo[bar]baz</span>", + [["stylewithcss","false"],["bold",""]], + "<b>foo</b>[bar]<b>baz</b>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,true,"",false,false,""]}], +["<span style=\"font-weight: 900\">foo[bar]baz</span>", + [["stylewithcss","true"],["bold",""]], + "<span style=\"font-weight:900\">foo</span>[bar]<span style=\"font-weight:900\">baz</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,true,"",false,false,""]}], +["<span style=\"font-weight: 900\">foo[bar]baz</span>", + [["stylewithcss","false"],["bold",""]], + "<span style=\"font-weight:900\">foo</span>[bar]<span style=\"font-weight:900\">baz</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,true,"",false,false,""]}], +["{<span style=\"font-weight: 100\">foobar]baz</span>", + [["stylewithcss","true"],["bold",""]], + "{<span style=\"font-weight:100\"><span style=\"font-weight:bold\">foobar]</span>baz</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,false,"",false,true,""]}], +["{<span style=\"font-weight: 100\">foobar]baz</span>", + [["stylewithcss","false"],["bold",""]], + "{<span style=\"font-weight:100\"><b>foobar]</b>baz</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], +["{<span style=\"font-weight: 400\">foobar]baz</span>", + [["stylewithcss","true"],["bold",""]], + "{<span style=\"font-weight:400\"><span style=\"font-weight:bold\">foobar]</span>baz</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,false,"",false,true,""]}], +["{<span style=\"font-weight: 400\">foobar]baz</span>", + [["stylewithcss","false"],["bold",""]], + "{<span style=\"font-weight:400\"><b>foobar]</b>baz</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], +["{<span style=\"font-weight: 700\">foobar]baz</span>", + [["stylewithcss","true"],["bold",""]], + "{foobar]<span style=\"font-weight:700\">baz</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,true,"",false,false,""]}], +["{<span style=\"font-weight: 700\">foobar]baz</span>", + [["stylewithcss","false"],["bold",""]], + "{foobar]<b>baz</b>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,true,"",false,false,""]}], +["{<span style=\"font-weight: 900\">foobar]baz</span>", + [["bold",""]], + "{foobar]<span style=\"font-weight:900\">baz</span>", + [true], + {"bold":[false,true,"",false,false,""]}], +["<span style=\"font-weight: 100\">foo[barbaz</span>}", + [["stylewithcss","true"],["bold",""]], + "<span style=\"font-weight:100\">foo<span style=\"font-weight:bold\">[barbaz</span></span>}", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,false,"",false,true,""]}], +["<span style=\"font-weight: 100\">foo[barbaz</span>}", + [["stylewithcss","false"],["bold",""]], + "<span style=\"font-weight:100\">foo<b>[barbaz</b></span>}", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], +["<span style=\"font-weight: 400\">foo[barbaz</span>}", + [["stylewithcss","true"],["bold",""]], + "<span style=\"font-weight:400\">foo<span style=\"font-weight:bold\">[barbaz</span></span>}", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,false,"",false,true,""]}], +["<span style=\"font-weight: 400\">foo[barbaz</span>}", + [["stylewithcss","false"],["bold",""]], + "<span style=\"font-weight:400\">foo<b>[barbaz</b></span>}", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], +["<span style=\"font-weight: 700\">foo[barbaz</span>}", + [["stylewithcss","true"],["bold",""]], + "<span style=\"font-weight:700\">foo</span>[barbaz}", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,true,"",false,false,""]}], +["<span style=\"font-weight: 700\">foo[barbaz</span>}", + [["stylewithcss","false"],["bold",""]], + "<b>foo</b>[barbaz}", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,true,"",false,false,""]}], +["<span style=\"font-weight: 900\">foo[barbaz</span>}", + [["bold",""]], + "<span style=\"font-weight:900\">foo</span>[barbaz}", + [true], + {"bold":[false,true,"",false,false,""]}], +["<h3>foo[bar]baz</h3>", + [["stylewithcss","true"],["bold",""]], + "<h3>foo<span style=\"font-weight:normal\">[bar]</span>baz</h3>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,true,"",false,false,""]}], +["<h3>foo[bar]baz</h3>", + [["stylewithcss","false"],["bold",""]], + "<h3>foo<span style=\"font-weight:normal\">[bar]</span>baz</h3>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,true,"",false,false,""]}], +["{<h3>foobar]baz</h3>", + [["stylewithcss","true"],["bold",""]], + "{<h3><span style=\"font-weight:normal\">foobar]</span>baz</h3>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,true,"",false,false,""]}], +["{<h3>foobar]baz</h3>", + [["stylewithcss","false"],["bold",""]], + "{<h3><span style=\"font-weight:normal\">foobar]</span>baz</h3>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,true,"",false,false,""]}], +["<h3>foo[barbaz</h3>}", + [["stylewithcss","true"],["bold",""]], + "<h3>foo<span style=\"font-weight:normal\">[barbaz</span></h3>}", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,true,"",false,false,""]}], +["<h3>foo[barbaz</h3>}", + [["stylewithcss","false"],["bold",""]], + "<h3>foo<span style=\"font-weight:normal\">[barbaz</span></h3>}", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,true,"",false,false,""]}], +["<h3>[foobarbaz]</h3>", + [["stylewithcss","true"],["bold",""]], + "<h3><span style=\"font-weight:normal\">[foobarbaz]</span></h3>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,true,"",false,false,""]}], +["<h3>[foobarbaz]</h3>", + [["stylewithcss","false"],["bold",""]], + "<h3><span style=\"font-weight:normal\">[foobarbaz]</span></h3>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,true,"",false,false,""]}], +["{<h3>foobarbaz]</h3>", + [["stylewithcss","true"],["bold",""]], + "{<h3><span style=\"font-weight:normal\">foobarbaz]</span></h3>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,true,"",false,false,""]}], +["{<h3>foobarbaz]</h3>", + [["stylewithcss","false"],["bold",""]], + "{<h3><span style=\"font-weight:normal\">foobarbaz]</span></h3>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,true,"",false,false,""]}], +["<h3>[foobarbaz</h3>}", + [["stylewithcss","true"],["bold",""]], + "<h3><span style=\"font-weight:normal\">[foobarbaz</span></h3>}", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,true,"",false,false,""]}], +["<h3>[foobarbaz</h3>}", + [["stylewithcss","false"],["bold",""]], + "<h3><span style=\"font-weight:normal\">[foobarbaz</span></h3>}", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,true,"",false,false,""]}], +["{<h3>foobarbaz</h3>}", + [["stylewithcss","true"],["bold",""]], + "{<h3><span style=\"font-weight:normal\">foobarbaz</span></h3>}", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,true,"",false,false,""]}], +["{<h3>foobarbaz</h3>}", + [["stylewithcss","false"],["bold",""]], + "{<h3><span style=\"font-weight:normal\">foobarbaz</span></h3>}", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,true,"",false,false,""]}], +["<b>foo<span style=\"font-weight: normal\">bar<b>[baz]</b>quz</span>qoz</b>", + [["stylewithcss","true"],["bold",""]], + "<b>foo<span style=\"font-weight:normal\">bar[baz]quz</span>qoz</b>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,true,"",false,false,""]}], +["<b>foo<span style=\"font-weight: normal\">bar<b>[baz]</b>quz</span>qoz</b>", + [["stylewithcss","false"],["bold",""]], + "<b>foo<span style=\"font-weight:normal\">bar[baz]quz</span>qoz</b>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,true,"",false,false,""]}], +["<b>foo<span style=\"font-weight: normal\">[bar]</span>baz</b>", + [["stylewithcss","true"],["bold",""]], + "<b>foo[bar]baz</b>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,false,"",false,true,""]}], +["<b>foo<span style=\"font-weight: normal\">[bar]</span>baz</b>", + [["stylewithcss","false"],["bold",""]], + "<b>foo[bar]baz</b>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], +["{<b>foo</b> <b>bar</b>}", + [["stylewithcss","true"],["bold",""]], + "{<span style=\"font-weight:bold\">foo bar}</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[true,false,"",false,true,""]}], +["{<b>foo</b> <b>bar</b>}", + [["stylewithcss","false"],["bold",""]], + "{<b>foo bar}</b>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[true,false,"",false,true,""]}], +["{<h3>foo</h3><b>bar</b>}", + [["stylewithcss","true"],["bold",""]], + "{<h3><span style=\"font-weight:normal\">foo</span></h3>bar}", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,true,"",false,false,""]}], +["{<h3>foo</h3><b>bar</b>}", + [["stylewithcss","false"],["bold",""]], + "{<h3><span style=\"font-weight:normal\">foo</span></h3>bar}", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,true,"",false,false,""]}], +["<i><b>foo</b></i>[bar]<i><b>baz</b></i>", + [["stylewithcss","true"],["bold",""]], + "<b><i>foo</i>[bar]<i>baz</i></b>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,false,"",false,true,""]}], +["<i><b>foo</b></i>[bar]<i><b>baz</b></i>", + [["stylewithcss","false"],["bold",""]], + "<b><i>foo</i>[bar]<i>baz</i></b>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], +["<i><b>foo</b></i>[bar]<b>baz</b>", + [["stylewithcss","true"],["bold",""]], + "<b><i>foo</i>[bar]baz</b>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,false,"",false,true,""]}], +["<i><b>foo</b></i>[bar]<b>baz</b>", + [["stylewithcss","false"],["bold",""]], + "<b><i>foo</i>[bar]baz</b>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], +["<b>foo</b>[bar]<i><b>baz</b></i>", + [["stylewithcss","true"],["bold",""]], + "<b>foo[bar]<i>baz</i></b>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,false,"",false,true,""]}], +["<b>foo</b>[bar]<i><b>baz</b></i>", + [["stylewithcss","false"],["bold",""]], + "<b>foo[bar]<i>baz</i></b>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], +["<font color=blue face=monospace><b>foo</b></font>[bar]", + [["bold",""]], + "<b><font color=\"blue\" face=\"monospace\">foo</font>[bar]</b>", + [true], + {"bold":[false,false,"",false,true,""]}], +["foo<span style=\"font-weight: normal\"><b>{bar}</b></span>baz", + [["stylewithcss","true"],["bold",""]], + "foo{bar}baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,true,"",false,false,""]}], +["foo<span style=\"font-weight: normal\"><b>{bar}</b></span>baz", + [["stylewithcss","false"],["bold",""]], + "foo{bar}baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,true,"",false,false,""]}], +["[foo<span class=notbold>bar</span>baz]", + [["stylewithcss","true"],["bold",""]], + "<span style=\"font-weight:bold\">[foo<span class=\"notbold\"><span style=\"font-weight:bold\">bar</span></span>baz]</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,false,"",false,true,""]}], +["[foo<span class=notbold>bar</span>baz]", + [["stylewithcss","false"],["bold",""]], + "<b>[foo<span class=\"notbold\"><b>bar</b></span>baz]</b>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], +["<b><span class=notbold>[foo]</span></b>", + [["stylewithcss","true"],["bold",""]], + "<span class=\"notbold\"><span style=\"font-weight:bold\">[foo]</span></span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,false,"",false,true,""]}], +["<b><span class=notbold>[foo]</span></b>", + [["stylewithcss","false"],["bold",""]], + "<span class=\"notbold\"><b>[foo]</b></span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], +["<b><span class=notbold>foo[bar]baz</span></b>", + [["stylewithcss","true"],["bold",""]], + "<b><span class=\"notbold\">foo<span style=\"font-weight:bold\">[bar]</span>baz</span></b>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,false,"",false,true,""]}], +["<b><span class=notbold>foo[bar]baz</span></b>", + [["stylewithcss","false"],["bold",""]], + "<b><span class=\"notbold\">foo<b>[bar]</b>baz</span></b>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], +["<p style=\"font-weight: bold\">foo[bar]baz</p>", + [["stylewithcss","true"],["bold",""]], + "<p><span style=\"font-weight:bold\">foo</span>[bar]<span style=\"font-weight:bold\">baz</span></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,true,"",false,false,""]}], +["<p style=\"font-weight: bold\">foo[bar]baz</p>", + [["stylewithcss","false"],["bold",""]], + "<p><b>foo</b>[bar]<b>baz</b></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,true,"",false,false,""]}], +["fo[o<b>b]ar</b>baz", + [["bold",""]], + "fo<b>[ob]ar</b>baz", + [true], + {"bold":[true,false,"",false,true,""]}], +["foo<b>ba[r</b>b]az", + [["bold",""]], + "foo<b>ba[rb]</b>az", + [true], + {"bold":[true,false,"",false,true,""]}], +["fo[o<b>bar</b>b]az", + [["stylewithcss","true"],["bold",""]], + "fo<span style=\"font-weight:bold\">[obarb]</span>az", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[true,false,"",false,true,""]}], +["fo[o<b>bar</b>b]az", + [["stylewithcss","false"],["bold",""]], + "fo<b>[obarb]</b>az", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[true,false,"",false,true,""]}], +["foo[<b>b]ar</b>baz", + [["stylewithcss","true"],["bold",""]], + "foo[b]<span style=\"font-weight:bold\">ar</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,true,"",false,false,""]}], +["foo[<b>b]ar</b>baz", + [["stylewithcss","false"],["bold",""]], + "foo[b]<b>ar</b>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,true,"",false,false,""]}], +["foo<b>ba[r</b>]baz", + [["stylewithcss","true"],["bold",""]], + "foo<span style=\"font-weight:bold\">ba</span>[r]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,true,"",false,false,""]}], +["foo<b>ba[r</b>]baz", + [["stylewithcss","false"],["bold",""]], + "foo<b>ba</b>[r]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,true,"",false,false,""]}], +["foo{<b>bar</b>}baz", + [["stylewithcss","true"],["bold",""]], + "foo{bar}baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,true,"",false,false,""]}], +["foo{<b>bar</b>}baz", + [["stylewithcss","false"],["bold",""]], + "foo{bar}baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,true,"",false,false,""]}], +["fo[o<span style=font-weight:bold>b]ar</span>baz", + [["bold",""]], + "fo<span style=\"font-weight:bold\">[ob]ar</span>baz", + [true], + {"bold":[true,false,"",false,true,""]}], +["<span style=font-weight:800>fo[o</span><span style=font-weight:900>b]ar</span>", + [["bold",""]], + "<span style=\"font-weight:800\">fo</span>[ob]<span style=\"font-weight:900\">ar</span>", + [true], + {"bold":[false,true,"",false,false,""]}], +["<span style=font-weight:700>fo[o</span><span style=font-weight:800>b]ar</span>", + [["stylewithcss","true"],["bold",""]], + "<span style=\"font-weight:700\">fo</span>[ob]<span style=\"font-weight:800\">ar</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,true,"",false,false,""]}], +["<span style=font-weight:700>fo[o</span><span style=font-weight:800>b]ar</span>", + [["stylewithcss","false"],["bold",""]], + "<b>fo</b>[ob]<span style=\"font-weight:800\">ar</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,true,"",false,false,""]}], +["<span style=font-weight:600>fo[o</span><span style=font-weight:700>b]ar</span>", + [["stylewithcss","true"],["bold",""]], + "<span style=\"font-weight:600\">fo</span>[ob]<span style=\"font-weight:700\">ar</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,true,"",false,false,""]}], +["<span style=font-weight:600>fo[o</span><span style=font-weight:700>b]ar</span>", + [["stylewithcss","false"],["bold",""]], + "<span style=\"font-weight:600\">fo</span>[ob]<b>ar</b>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,true,"",false,false,""]}], +["<span style=font-weight:500>fo[o</span><span style=font-weight:600>b]ar</span>", + [["stylewithcss","true"],["bold",""]], + "<span style=\"font-weight:500\">fo<span style=\"font-weight:bold\">[o</span></span><span style=\"font-weight:600\"><span style=\"font-weight:bold\">b]</span>ar</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[true,false,"",false,true,""]}], +["<span style=font-weight:500>fo[o</span><span style=font-weight:600>b]ar</span>", + [["stylewithcss","false"],["bold",""]], + "<span style=\"font-weight:500\">fo<b>[o</b></span><span style=\"font-weight:600\"><b>b]</b>ar</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[true,false,"",false,true,""]}], +["<span style=font-weight:400>fo[o</span><span style=font-weight:500>b]ar</span>", + [["stylewithcss","true"],["bold",""]], + "<span style=\"font-weight:400\">fo<span style=\"font-weight:bold\">[o</span></span><span style=\"font-weight:500\"><span style=\"font-weight:bold\">b]</span>ar</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,false,"",false,true,""]}], +["<span style=font-weight:400>fo[o</span><span style=font-weight:500>b]ar</span>", + [["stylewithcss","false"],["bold",""]], + "<span style=\"font-weight:400\">fo<b>[o</b></span><span style=\"font-weight:500\"><b>b]</b>ar</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], +["<span style=font-weight:300>fo[o</span><span style=font-weight:400>b]ar</span>", + [["stylewithcss","true"],["bold",""]], + "<span style=\"font-weight:300\">fo<span style=\"font-weight:bold\">[o</span></span><span style=\"font-weight:400\"><span style=\"font-weight:bold\">b]</span>ar</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,false,"",false,true,""]}], +["<span style=font-weight:300>fo[o</span><span style=font-weight:400>b]ar</span>", + [["stylewithcss","false"],["bold",""]], + "<span style=\"font-weight:300\">fo<b>[o</b></span><span style=\"font-weight:400\"><b>b]</b>ar</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], +["<span style=font-weight:200>fo[o</span><span style=font-weight:300>b]ar</span>", + [["stylewithcss","true"],["bold",""]], + "<span style=\"font-weight:200\">fo<span style=\"font-weight:bold\">[o</span></span><span style=\"font-weight:300\"><span style=\"font-weight:bold\">b]</span>ar</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,false,"",false,true,""]}], +["<span style=font-weight:200>fo[o</span><span style=font-weight:300>b]ar</span>", + [["stylewithcss","false"],["bold",""]], + "<span style=\"font-weight:200\">fo<b>[o</b></span><span style=\"font-weight:300\"><b>b]</b>ar</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], +["<span style=font-weight:100>fo[o</span><span style=font-weight:200>b]ar</span>", + [["stylewithcss","true"],["bold",""]], + "<span style=\"font-weight:100\">fo<span style=\"font-weight:bold\">[o</span></span><span style=\"font-weight:200\"><span style=\"font-weight:bold\">b]</span>ar</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"bold":[false,false,"",false,true,""]}], +["<span style=font-weight:100>fo[o</span><span style=font-weight:200>b]ar</span>", + [["stylewithcss","false"],["bold",""]], + "<span style=\"font-weight:100\">fo<b>[o</b></span><span style=\"font-weight:200\"><b>b]</b>ar</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"bold":[false,false,"",false,true,""]}], + +// Don't delete non-editable node. +["abc<b>[d<span contenteditable=\"false\"><b>e</b></span>f]</b>ghi", + [["stylewithcss","false"],["bold",""]], + "abcd<span contenteditable=\"false\"><b>e</b></span>fghi", + [true,true], + {}], +// but delete editable node in non-editable node. +["abc<b>[d<span contenteditable=\"false\"><span contenteditable><b>e</b></span></span>f]</b>ghi", + [["stylewithcss","false"],["bold",""]], + "abcd<span contenteditable=\"false\"><span contenteditable=\"\">e</span></span>fghi", + [true,true], + {}], + +// Check where the new style (<b>) will be applied. Basically, it should be +// applied to minimized range as far as possible, but should not shrink the +// range into the nodes entirely selected. +["abc<i>[def]</i>ghi", + [["stylewithcss","false"],["bold",""]], + "abc<i><b>def</b></i>ghi", + [true,true], + {}], +["abc[<i>def</i>]ghi", + [["stylewithcss","false"],["bold",""]], + "abc<b><i>def</i></b>ghi", + [true,true], + {}], +["abc<i>{def}</i>ghi", + [["stylewithcss","false"],["bold",""]], + "abc<i><b>def</b></i>ghi", + [true,true], + {}], +["abc{<i>def</i>}ghi", + [["stylewithcss","false"],["bold",""]], + "abc<b><i>def</i></b>ghi", + [true,true], + {}], +["abc<i>[def</i>]ghi", + [["stylewithcss","false"],["bold",""]], + "abc<i><b>def</b></i>ghi", + [true,true], + {}], +["abc[<i>def]</i>ghi", + [["stylewithcss","false"],["bold",""]], + "abc<i><b>def</b></i>ghi", + [true,true], + {}], +] diff --git a/testing/web-platform/tests/editing/data/createlink.js b/testing/web-platform/tests/editing/data/createlink.js new file mode 100644 index 0000000000..10734d950b --- /dev/null +++ b/testing/web-platform/tests/editing/data/createlink.js @@ -0,0 +1,248 @@ +// For documentation of the format, see README in this directory. +var browserTests = [ +["foo[]bar", + [["createlink","http://www.google.com/"]], + "foo[]bar", + [true], + {"createlink":[false,false,"",false,false,""]}], +["<p>[foo</p> <p>bar]</p>", + [["createlink","http://www.google.com/"]], + "<p><a href=\"http://www.google.com/\">[foo</a></p> <p><a href=\"http://www.google.com/\">bar]</a></p>", + [true], + {"createlink":[false,false,"",false,false,""]}], +["<span>[foo</span> <span>bar]</span>", + [["createlink","http://www.google.com/"]], + "<a href=\"http://www.google.com/\"><span>[foo</span> <span>bar]</span></a>", + [true], + {"createlink":[false,false,"",false,false,""]}], +["<p>[foo</p><p> <span>bar</span> </p><p>baz]</p>", + [["createlink","http://www.google.com/"]], + "<p><a href=\"http://www.google.com/\">[foo</a></p><p> <a href=\"http://www.google.com/\"><span>bar</span></a> </p><p><a href=\"http://www.google.com/\">baz]</a></p>", + [true], + {"createlink":[false,false,"",false,false,""]}], +["<p>[foo<p><br><p>bar]", + [["createlink","http://www.google.com/"]], + "<p><a href=\"http://www.google.com/\">[foo</a></p><p><a href=\"http://www.google.com/\"><br></a></p><p><a href=\"http://www.google.com/\">bar]</a></p>", + [true], + {"createlink":[false,false,"",false,false,""]}], +["<b>foo[]bar</b>", + [["createlink","http://www.google.com/"]], + "<b>foo[]bar</b>", + [true], + {"createlink":[false,false,"",false,false,""]}], +["<i>foo[]bar</i>", + [["createlink","http://www.google.com/"]], + "<i>foo[]bar</i>", + [true], + {"createlink":[false,false,"",false,false,""]}], +["<span>foo</span>{}<span>bar</span>", + [["createlink","http://www.google.com/"]], + "<span>foo</span>{}<span>bar</span>", + [true], + {"createlink":[false,false,"",false,false,""]}], +["<span>foo[</span><span>]bar</span>", + [["createlink","http://www.google.com/"]], + "<span>foo[</span><span>]bar</span>", + [true], + {"createlink":[false,false,"",false,false,""]}], +["foo[bar]baz", + [["createlink","http://www.google.com/"]], + "foo<a href=\"http://www.google.com/\">[bar]</a>baz", + [true], + {"createlink":[false,false,"",false,false,""]}], +["foo[bar<b>baz]qoz</b>quz", + [["createlink","http://www.google.com/"]], + "foo<a href=\"http://www.google.com/\">[bar</a><b><a href=\"http://www.google.com/\">baz]</a>qoz</b>quz", + [true], + {"createlink":[false,false,"",false,false,""]}], +["foo[bar<i>baz]qoz</i>quz", + [["createlink","http://www.google.com/"]], + "foo<a href=\"http://www.google.com/\">[bar</a><i><a href=\"http://www.google.com/\">baz]</a>qoz</i>quz", + [true], + {"createlink":[false,false,"",false,false,""]}], +["{<p><p> <p>foo</p>}", + [["createlink","http://www.google.com/"]], + "{<p></p><p> </p><p><a href=\"http://www.google.com/\">foo</a></p>}", + [true], + {"createlink":[false,false,"",false,false,""]}], +["<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>", + [["createlink","http://www.google.com/"]], + "<table><tbody><tr><td>foo</td><td>b<a href=\"http://www.google.com/\">[a]</a>r</td><td>baz</td></tr></tbody></table>", + [true], + {"createlink":[false,false,"",false,false,""]}], +["<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table>", + [["createlink","http://www.google.com/"]], + "<table><tbody><tr><td>foo</td>{<td><a href=\"http://www.google.com/\">bar</a></td>}<td>baz</td></tr></tbody></table>", + [true], + {"createlink":[false,false,"",false,false,""]}], +["<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table>", + [["createlink","http://www.google.com/"]], + "<table><tbody><tr>{<td><a href=\"http://www.google.com/\">foo</a></td><td><a href=\"http://www.google.com/\">bar</a></td>}<td>baz</td></tr></tbody></table>", + [true], + {"createlink":[false,false,"",false,false,""]}], +["<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>", + [["createlink","http://www.google.com/"]], + "<table><tbody>{<tr><td><a href=\"http://www.google.com/\">foo</a></td><td><a href=\"http://www.google.com/\">bar</a></td><td><a href=\"http://www.google.com/\">baz</a></td></tr>}</tbody></table>", + [true], + {"createlink":[false,false,"",false,false,""]}], +["<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>", + [["createlink","http://www.google.com/"]], + "<table>{<tbody><tr><td><a href=\"http://www.google.com/\">foo</a></td><td><a href=\"http://www.google.com/\">bar</a></td><td><a href=\"http://www.google.com/\">baz</a></td></tr></tbody>}</table>", + [true], + {"createlink":[false,false,"",false,false,""]}], +["{<table><tr><td>foo<td>bar<td>baz</table>}", + [["createlink","http://www.google.com/"]], + "{<table><tbody><tr><td><a href=\"http://www.google.com/\">foo</a></td><td><a href=\"http://www.google.com/\">bar</a></td><td><a href=\"http://www.google.com/\">baz</a></td></tr></tbody></table>}", + [true], + {"createlink":[false,false,"",false,false,""]}], +["<a href=http://www.google.com/>foo[bar]baz</a>", + [["createlink","http://www.google.com/"]], + "<a href=\"http://www.google.com/\">foo[bar]baz</a>", + [true], + {"createlink":[false,false,"",false,false,""]}], +["<a href=http://www.google.com/>foo[barbaz</a>}", + [["createlink","http://www.google.com/"]], + "<a href=\"http://www.google.com/\">foo[barbaz</a>}", + [true], + {"createlink":[false,false,"",false,false,""]}], +["{<a href=http://www.google.com/>foobar]baz</a>", + [["createlink","http://www.google.com/"]], + "{<a href=\"http://www.google.com/\">foobar]baz</a>", + [true], + {"createlink":[false,false,"",false,false,""]}], +["{<a href=http://www.google.com/>foobarbaz</a>}", + [["createlink","http://www.google.com/"]], + "{<a href=\"http://www.google.com/\">foobarbaz}</a>", + [true], + {"createlink":[false,false,"",false,false,""]}], +["<a href=http://www.google.com/>[foobarbaz]</a>", + [["createlink","http://www.google.com/"]], + "<a href=\"http://www.google.com/\">[foobarbaz]</a>", + [true], + {"createlink":[false,false,"",false,false,""]}], +["foo<a href=http://www.google.com/>[bar]</a>baz", + [["createlink","http://www.google.com/"]], + "foo<a href=\"http://www.google.com/\">[bar]</a>baz", + [true], + {"createlink":[false,false,"",false,false,""]}], +["[foo]<a href=http://www.google.com/>bar</a>baz", + [["createlink","http://www.google.com/"]], + "<a href=\"http://www.google.com/\">[foo]bar</a>baz", + [true], + {"createlink":[false,false,"",false,false,""]}], +["foo<a href=http://www.google.com/>bar</a>[baz]", + [["createlink","http://www.google.com/"]], + "foo<a href=\"http://www.google.com/\">bar[baz]</a>", + [true], + {"createlink":[false,false,"",false,false,""]}], +["foo[<a href=http://www.google.com/>bar</a>]baz", + [["createlink","http://www.google.com/"]], + "foo[<a href=\"http://www.google.com/\">bar</a>]baz", + [true], + {"createlink":[false,false,"",false,false,""]}], +["foo<a href=http://www.google.com/>[bar</a>baz]", + [["createlink","http://www.google.com/"]], + "foo<a href=\"http://www.google.com/\">[barbaz]</a>", + [true], + {"createlink":[false,false,"",false,false,""]}], +["[foo<a href=http://www.google.com/>bar]</a>baz", + [["createlink","http://www.google.com/"]], + "<a href=\"http://www.google.com/\">[foobar]</a>baz", + [true], + {"createlink":[false,false,"",false,false,""]}], +["[foo<a href=http://www.google.com/>bar</a>baz]", + [["createlink","http://www.google.com/"]], + "<a href=\"http://www.google.com/\">[foobarbaz]</a>", + [true], + {"createlink":[false,false,"",false,false,""]}], +["<a href=otherurl>foo[bar]baz</a>", + [["createlink","http://www.google.com/"]], + "<a href=\"http://www.google.com/\">foo[bar]baz</a>", + [true], + {"createlink":[false,false,"",false,false,""]}], +["<a href=otherurl>foo[barbaz</a>}", + [["createlink","http://www.google.com/"]], + "<a href=\"http://www.google.com/\">foo[barbaz</a>}", + [true], + {"createlink":[false,false,"",false,false,""]}], +["{<a href=otherurl>foobar]baz</a>", + [["createlink","http://www.google.com/"]], + "{<a href=\"http://www.google.com/\">foobar]baz</a>", + [true], + {"createlink":[false,false,"",false,false,""]}], +["{<a href=otherurl>foobarbaz</a>}", + [["createlink","http://www.google.com/"]], + "{<a href=\"http://www.google.com/\">foobarbaz}</a>", + [true], + {"createlink":[false,false,"",false,false,""]}], +["<a href=otherurl>[foobarbaz]</a>", + [["createlink","http://www.google.com/"]], + "<a href=\"http://www.google.com/\">[foobarbaz]</a>", + [true], + {"createlink":[false,false,"",false,false,""]}], +["foo<a href=otherurl>[bar]</a>baz", + [["createlink","http://www.google.com/"]], + "foo<a href=\"http://www.google.com/\">[bar]</a>baz", + [true], + {"createlink":[false,false,"",false,false,""]}], +["foo[<a href=otherurl>bar</a>]baz", + [["createlink","http://www.google.com/"]], + "foo[<a href=\"http://www.google.com/\">bar</a>]baz", + [true], + {"createlink":[false,false,"",false,false,""]}], +["foo<a href=otherurl>[bar</a>baz]", + [["createlink","http://www.google.com/"]], + "foo<a href=\"http://www.google.com/\">[barbaz]</a>", + [true], + {"createlink":[false,false,"",false,false,""]}], +["[foo<a href=otherurl>bar]</a>baz", + [["createlink","http://www.google.com/"]], + "<a href=\"http://www.google.com/\">[foobar]</a>baz", + [true], + {"createlink":[false,false,"",false,false,""]}], +["[foo<a href=otherurl>bar</a>baz]", + [["createlink","http://www.google.com/"]], + "<a href=\"http://www.google.com/\">[foobarbaz]</a>", + [true], + {"createlink":[false,false,"",false,false,""]}], +["<a href=otherurl><b>foo[bar]baz</b></a>", + [["createlink","http://www.google.com/"]], + "<a href=\"http://www.google.com/\"><b>foo[bar]baz</b></a>", + [true], + {"createlink":[false,false,"",false,false,""]}], +["<a href=otherurl><b>foo[barbaz</b></a>}", + [["createlink","http://www.google.com/"]], + "<a href=\"http://www.google.com/\"><b>foo[barbaz</b></a>}", + [true], + {"createlink":[false,false,"",false,false,""]}], +["{<a href=otherurl><b>foobar]baz</b></a>", + [["createlink","http://www.google.com/"]], + "{<a href=\"http://www.google.com/\"><b>foobar]baz</b></a>", + [true], + {"createlink":[false,false,"",false,false,""]}], +["<a href=otherurl><b>[foobarbaz]</b></a>", + [["createlink","http://www.google.com/"]], + "<a href=\"http://www.google.com/\"><b>[foobarbaz]</b></a>", + [true], + {"createlink":[false,false,"",false,false,""]}], +["<a name=abc>foo[bar]baz</a>", + [["createlink","http://www.google.com/"]], + "<span name=\"abc\">foo<a href=\"http://www.google.com/\">[bar]</a>baz</span>", + [true], + {"createlink":[false,false,"",false,false,""]}], +["<a name=abc><b>foo[bar]baz</b></a>", + [["createlink","http://www.google.com/"]], + "<span name=\"abc\"><b>foo<a href=\"http://www.google.com/\">[bar]</a>baz</b></span>", + [true], + {"createlink":[false,false,"",false,false,""]}], +["foo[bar]baz", + [["createlink",""]], + "foo[bar]baz", + [false], + {"createlink":[false,false,"",false,false,""]}], +["foo[bar]baz", + [["createlink","http://www.google.com/\u65E5\u672C\u8A9E\u30D1\u30B9"]], + "foo<a href=\"http://www.google.com/\u65E5\u672C\u8A9E\u30D1\u30B9\">[bar]</a>baz", + [true], + {"createlink":[false,false,"",false,false,""]}], +]
\ No newline at end of file diff --git a/testing/web-platform/tests/editing/data/delete-list-items-in-table-cells.js b/testing/web-platform/tests/editing/data/delete-list-items-in-table-cells.js new file mode 100644 index 0000000000..cd5670e585 --- /dev/null +++ b/testing/web-platform/tests/editing/data/delete-list-items-in-table-cells.js @@ -0,0 +1,23 @@ +// For documentation of the format, see README in this directory. +var browserTests = [ +['<div contenteditable="true"><table><tr><td><ol><li>a</li><li>{}</li></ol></td><td>b</td></tr></table></div>', + [["delete",""]], + '<div contenteditable="true"><table><tbody><tr><td><ol><li>a</li></ol></td><td>b</td></tr></tbody></table></div>', + [true], + {"delete":[false,false,"",false,false,""]}], +['<div contenteditable="true"><table><tr><td><ul><li>a</li><li>{}</li></ul></td><td>b</td></tr></table></div>', + [["delete",""]], + '<div contenteditable="true"><table><tbody><tr><td><ul><li>a</li></ul></td><td>b</td></tr></tbody></table></div>', + [true], + {"delete":[false,false,"",false,false,""]}], +['<div contenteditable="true"><table><tr><td><ol><li>{}</li></ol></td></tr></table></div></table></div>', + [["delete",""]], + '<div contenteditable="true"><table><tbody><tr><td><div><br></div></td></tr></tbody></table></div>', + [true], + {"delete":[false,false,"",false,false,""]}], +['<div contenteditable="true"><table><tr><td><ul><li>{}</li></ul></td></tr></table></div></table></div>', + [["delete",""]], + '<div contenteditable="true"><table><tbody><tr><td><div><br></div></td></tr></tbody></table></div>', + [true], + {"delete":[false,false,"",false,false,""]}], +] diff --git a/testing/web-platform/tests/editing/data/delete.js b/testing/web-platform/tests/editing/data/delete.js new file mode 100644 index 0000000000..131c99b1d5 --- /dev/null +++ b/testing/web-platform/tests/editing/data/delete.js @@ -0,0 +1,3104 @@ +class MyCustomElement extends HTMLElement {}; +customElements.define("custom-element", MyCustomElement); +// For documentation of the format, see README in this directory. +var browserTests = [ +["foo[]bar", + [["delete",""]], + "fo[]bar", + [true], + {"delete":[false,false,"",false,false,""]}], +["<span>foo</span>{}<span>bar</span>", + [["delete",""]], + "<span>fo[]</span><span>bar</span>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<span>foo[</span><span>]bar</span>", + [["delete",""]], + "<span>foo[]</span><span>bar</span>", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<span style=display:none>bar</span>[]baz", + [["stylewithcss","true"],["delete",""]], + "fo[]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"delete":[false,false,"",false,false,""]}], +["foo<span style=display:none>bar</span>[]baz", + [["stylewithcss","false"],["delete",""]], + "fo[]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"delete":[false,false,"",false,false,""]}], +["foo<script>bar</script>[]baz", + [["delete",""]], + "fo[]baz", + [true], + {"delete":[false,false,"",false,false,""]}], +["foö[]bar", + [["delete",""]], + "fo[]bar", + [true], + {"delete":[false,false,"",false,false,""]}], +["foö[]bar", + [["delete",""]], + "foo[]bar", + [true], + {"delete":[false,false,"",false,false,""]}], +["foö̧[]bar", + [["delete",""]], + "foö[]bar", + [true], + {"delete":[false,false,"",false,false,""]}], +["ö[]bar", + [["delete",""]], + "{}bar", + [true], + {"delete":[false,false,"",false,false,""]}], +["ö[]bar", + [["delete",""]], + "o[]bar", + [true], + {"delete":[false,false,"",false,false,""]}], +["ö̧[]bar", + [["delete",""]], + "ö[]bar", + [true], + {"delete":[false,false,"",false,false,""]}], +["שָׁ[]לוֹם", + [["delete",""]], + "שׁ[]לוֹם", + [true], + {"delete":[false,false,"",false,false,""]}], +["שָׁלוֹ[]ם", + [["delete",""]], + "שָׁלו[]ם", + [true], + {"delete":[false,false,"",false,false,""]}], +["<p>foo</p><p>[]bar</p>", + [["defaultparagraphseparator","div"],["delete",""]], + "<p>foo{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p>foo</p><p>[]bar</p>", + [["defaultparagraphseparator","p"],["delete",""]], + "<p>foo{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p>foo</p>[]bar", + [["delete",""]], + "<p>foo{}bar</p>", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<p>[]bar</p>", + [["defaultparagraphseparator","div"],["delete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["foo<p>[]bar</p>", + [["defaultparagraphseparator","p"],["delete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p>foo<br></p><p>[]bar</p>", + [["defaultparagraphseparator","div"],["delete",""]], + "<p>foo{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p>foo<br></p><p>[]bar</p>", + [["defaultparagraphseparator","p"],["delete",""]], + "<p>foo{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p>foo<br></p>[]bar", + [["delete",""]], + "<p>foo{}bar</p>", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<br><p>[]bar</p>", + [["defaultparagraphseparator","div"],["delete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["foo<br><p>[]bar</p>", + [["defaultparagraphseparator","p"],["delete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p>foo<br><br></p><p>[]bar</p>", + [["defaultparagraphseparator","div"],["delete",""]], + "<p>foo<br>{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p>foo<br><br></p><p>[]bar</p>", + [["defaultparagraphseparator","p"],["delete",""]], + "<p>foo<br>{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p>foo<br><br></p>[]bar", + [["delete",""]], + "<p>foo<br>{}bar</p>", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<br><br><p>[]bar</p>", + [["delete",""]], + "foo<br><p>{}bar</p>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div><p>foo</p></div><p>[]bar</p>", + [["defaultparagraphseparator","div"],["delete",""]], + "<div><p>foo{}bar</p></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<div><p>foo</p></div><p>[]bar</p>", + [["defaultparagraphseparator","p"],["delete",""]], + "<div><p>foo{}bar</p></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p>foo</p><div><p>[]bar</p></div>", + [["defaultparagraphseparator","div"],["delete",""]], + "<p>foo{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p>foo</p><div><p>[]bar</p></div>", + [["defaultparagraphseparator","p"],["delete",""]], + "<p>foo{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<div><p>foo</p></div><div><p>[]bar</p></div>", + [["defaultparagraphseparator","div"],["delete",""]], + "<div><p>foo{}bar</p></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<div><p>foo</p></div><div><p>[]bar</p></div>", + [["defaultparagraphseparator","p"],["delete",""]], + "<div><p>foo{}bar</p></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<div><p>foo</p></div>[]bar", + [["delete",""]], + "<div><p>foo{}bar</p></div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<div><p>[]bar</p></div>", + [["defaultparagraphseparator","div"],["delete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["foo<div><p>[]bar</p></div>", + [["defaultparagraphseparator","p"],["delete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<div>foo</div><div>[]bar</div>", + [["defaultparagraphseparator","div"],["delete",""]], + "<div>foo{}bar</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<div>foo</div><div>[]bar</div>", + [["defaultparagraphseparator","p"],["delete",""]], + "<div>foo{}bar</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<pre>foo</pre>[]bar", + [["delete",""]], + "<pre>foo{}bar</pre>", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<br>[]bar", + [["delete",""]], + "foo{}bar", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<br><b>[]bar</b>", + [["delete",""]], + "foo{}<b>bar</b>", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<hr>[]bar", + [["delete",""]], + "foo{}bar", + [true], + {"delete":[false,false,"",false,false,""]}], +["<p>foo<hr><p>[]bar", + [["delete",""]], + "<p>foo</p><p>{}bar</p>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<p>foo</p><br><p>[]bar</p>", + [["delete",""]], + "<p>foo</p><p>{}bar</p>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<p>foo</p><br><br><p>[]bar</p>", + [["delete",""]], + "<p>foo</p><br><p>{}bar</p>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<p>foo</p><img src=/img/lion.svg><p>[]bar", + [["defaultparagraphseparator","div"],["delete",""]], + "<p>foo</p><img src=\"/img/lion.svg\">{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p>foo</p><img src=/img/lion.svg><p>[]bar", + [["defaultparagraphseparator","p"],["delete",""]], + "<p>foo</p><img src=\"/img/lion.svg\">{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["foo<img src=/img/lion.svg>[]bar", + [["delete",""]], + "foo{}bar", + [true], + {"delete":[false,false,"",false,false,""]}], +["<a>foo</a>[]bar", + [["delete",""]], + "foo[]bar", + [true], + {"delete":[false,false,"",false,false,""]}], +["<a href=/>foo</a>[]bar", + [["delete",""]], + "foo[]bar", + [true], + {"delete":[false,false,"",false,false,""]}], +["<a name=abc>foo</a>[]bar", + [["delete",""]], + "foo[]bar", + [true], + {"delete":[false,false,"",false,false,""]}], +["<a href=/ name=abc>foo</a>[]bar", + [["delete",""]], + "foo[]bar", + [true], + {"delete":[false,false,"",false,false,""]}], +["<span><a>foo</a></span>[]bar", + [["delete",""]], + "<span>foo</span>[]bar", + [true], + {"delete":[false,false,"",false,false,""]}], +["<span><a href=/>foo</a></span>[]bar", + [["delete",""]], + "<span>foo</span>[]bar", + [true], + {"delete":[false,false,"",false,false,""]}], +["<span><a name=abc>foo</a></span>[]bar", + [["delete",""]], + "<span>foo</span>[]bar", + [true], + {"delete":[false,false,"",false,false,""]}], +["<span><a href=/ name=abc>foo</a></span>[]bar", + [["delete",""]], + "<span>foo</span>[]bar", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<a>[]bar</a>", + [["delete",""]], + "fo[]<a>bar</a>", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<a href=/>[]bar</a>", + [["delete",""]], + "fo[]<a href=\"/\">bar</a>", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<a name=abc>[]bar</a>", + [["delete",""]], + "fo[]<a name=\"abc\">bar</a>", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<a href=/ name=abc>[]bar</a>", + [["delete",""]], + "fo[]<a href=\"/\" name=\"abc\">bar</a>", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo []", + [["delete",""]], + "foo []", + [true], + {"delete":[false,false,"",false,false,""]}], +[" [] foo", + [["delete",""]], + "{} foo", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo []bar", + [["delete",""]], + "foo []bar", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo []bar", + [["delete",""]], + "foo []bar", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo []bar", + [["delete",""]], + "foo []bar", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo []bar", + [["delete",""]], + "foo[]bar", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo [] bar", + [["delete",""]], + "foo[] bar", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo [] bar", + [["delete",""]], + "foo [] bar", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo []bar", + [["delete",""]], + "foo []bar", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo []<span> </span> bar", + [["delete",""]], + "foo[]<span> </span> bar", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo <span> </span>[] bar", + [["delete",""]], + "foo {} bar", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo <span> </span> []bar", + [["delete",""]], + "foo <span> </span>{}bar", + [true], + {"delete":[false,false,"",false,false,""]}], +["<b>foo </b> []bar", + [["delete",""]], + "<b>foo </b>{}bar", + [true], + {"delete":[false,false,"",false,false,""]}], +["<b>foo </b> []bar", + [["delete",""]], + "<b>foo </b>{}bar", + [true], + {"delete":[false,false,"",false,false,""]}], +["<b>foo </b> []bar", + [["delete",""]], + "<b>foo </b>{}bar", + [true], + {"delete":[false,false,"",false,false,""]}], +["<b>foo </b> []bar", + [["delete",""]], + "<b>foo[]</b>bar", + [true], + {"delete":[false,false,"",false,false,""]}], +["<p>foo </p><p>[] bar</p>", + [["defaultparagraphseparator","div"],["delete",""]], + "<p>foo{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p>foo </p><p>[] bar</p>", + [["defaultparagraphseparator","p"],["delete",""]], + "<p>foo{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<pre>foo []</pre>", + [["delete",""]], + "<pre>foo []</pre>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<pre> [] foo</pre>", + [["delete",""]], + "<pre>{} foo</pre>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<pre>foo []bar</pre>", + [["delete",""]], + "<pre>foo []bar</pre>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<pre>foo []bar</pre>", + [["delete",""]], + "<pre>foo []bar</pre>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<pre>foo []bar</pre>", + [["delete",""]], + "<pre>foo []bar</pre>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div style=white-space:pre>foo []</div>", + [["delete",""]], + "<div style=\"white-space:pre\">foo []</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div style=white-space:pre> [] foo</div>", + [["delete",""]], + "<div style=\"white-space:pre\">{} foo</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div style=white-space:pre>foo []bar</div>", + [["delete",""]], + "<div style=\"white-space:pre\">foo []bar</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div style=white-space:pre>foo []bar</div>", + [["delete",""]], + "<div style=\"white-space:pre\">foo []bar</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div style=white-space:pre>foo []bar</div>", + [["delete",""]], + "<div style=\"white-space:pre\">foo []bar</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div style=white-space:pre-wrap>foo []</div>", + [["delete",""]], + "<div style=\"white-space:pre-wrap\">foo []</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div style=white-space:pre-wrap> [] foo</div>", + [["delete",""]], + "<div style=\"white-space:pre-wrap\">{} foo</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div style=white-space:pre-wrap>foo []bar</div>", + [["delete",""]], + "<div style=\"white-space:pre-wrap\">foo []bar</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div style=white-space:pre-wrap>foo []bar</div>", + [["delete",""]], + "<div style=\"white-space:pre-wrap\">foo []bar</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div style=white-space:pre-wrap>foo []bar</div>", + [["delete",""]], + "<div style=\"white-space:pre-wrap\">foo []bar</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div style=white-space:pre-line>foo []</div>", + [["delete",""]], + "<div style=\"white-space:pre-line\">foo []</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div style=white-space:pre-line> [] foo</div>", + [["delete",""]], + "<div style=\"white-space:pre-line\">{} foo</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div style=white-space:pre-line>foo []bar</div>", + [["delete",""]], + "<div style=\"white-space:pre-line\">foo []bar</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div style=white-space:pre-line>foo []bar</div>", + [["delete",""]], + "<div style=\"white-space:pre-line\">foo []bar</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div style=white-space:pre-line>foo []bar</div>", + [["delete",""]], + "<div style=\"white-space:pre-line\">foo[]bar</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div style=white-space:nowrap>foo []</div>", + [["delete",""]], + "<div style=\"white-space:nowrap\">foo []</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div style=white-space:nowrap> [] foo</div>", + [["delete",""]], + "<div style=\"white-space:nowrap\">{} foo</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div style=white-space:nowrap>foo []bar</div>", + [["delete",""]], + "<div style=\"white-space:nowrap\">foo []bar</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div style=white-space:nowrap>foo []bar</div>", + [["delete",""]], + "<div style=\"white-space:nowrap\">foo []bar</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div style=white-space:nowrap>foo []bar</div>", + [["delete",""]], + "<div style=\"white-space:nowrap\">foo[]bar</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<table><tr><td>b[]</table>baz", + [["delete",""]], + "foo<table><tbody><tr><td>[]<br></td></tr></tbody></table>baz", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<table><tr><td>[]bar</table>baz", + [["delete",""]], + "foo<table><tbody><tr><td>[]bar</td></tr></tbody></table>baz", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<table><tr><td>bar</table>[]baz", + [["delete",""]], + "foo{<table><tbody><tr><td>bar</td></tr></tbody></table>}baz", + [true], + {"delete":[false,false,"",false,false,""]}], +["<p>foo<table><tr><td>[]bar</table><p>baz", + [["delete",""]], + "<p>foo</p><table><tbody><tr><td>[]bar</td></tr></tbody></table><p>baz</p>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<p>foo<table><tr><td>bar</table><p>[]baz", + [["delete",""]], + "<p>foo</p>{<table><tbody><tr><td>bar</td></tr></tbody></table>}<p>baz</p>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<table><tr><td>foo<td>[]bar</table>", + [["delete",""]], + "<table><tbody><tr><td>foo</td><td>{}bar</td></tr></tbody></table>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<table><tr><td>foo<tr><td>[]bar</table>", + [["delete",""]], + "<table><tbody><tr><td>foo</td></tr><tr><td>{}bar</td></tr></tbody></table>", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<br><table><tr><td>[]bar</table>baz", + [["delete",""]], + "foo<table><tbody><tr><td>[]bar</td></tr></tbody></table>baz", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<table><tr><td>bar<br></table>[]baz", + [["delete",""]], + "foo{<table><tbody><tr><td>bar<br></td></tr></tbody></table>}baz", + [true], + {"delete":[false,false,"",false,false,""]}], +["<p>foo<br><table><tr><td>[]bar</table><p>baz", + [["delete",""]], + "<p>foo<br></p><table><tbody><tr><td>[]bar</td></tr></tbody></table><p>baz</p>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<p>foo<table><tr><td>bar<br></table><p>[]baz", + [["delete",""]], + "<p>foo</p>{<table><tbody><tr><td>bar<br></td></tr></tbody></table>}<p>baz</p>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<table><tr><td>foo<br><td>[]bar</table>", + [["delete",""]], + "<table><tbody><tr><td>foo</td><td>{}bar</td></tr></tbody></table>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<table><tr><td>foo<br><tr><td>[]bar</table>", + [["delete",""]], + "<table><tbody><tr><td>foo</td></tr><tr><td>{}bar</td></tr></tbody></table>", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<br><br><table><tr><td>[]bar</table>baz", + [["delete",""]], + "foo<br><br><table><tbody><tr><td>[]bar</td></tr></tbody></table>baz", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<table><tr><td>bar<br><br></table>[]baz", + [["delete",""]], + "foo{<table><tbody><tr><td>bar<br><br></td></tr></tbody></table>}baz", + [true], + {"delete":[false,false,"",false,false,""]}], +["<p>foo<br><br><table><tr><td>[]bar</table><p>baz", + [["delete",""]], + "<p>foo<br><br></p><table><tbody><tr><td>[]bar</td></tr></tbody></table><p>baz</p>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<p>foo<table><tr><td>bar<br><br></table><p>[]baz", + [["delete",""]], + "<p>foo</p>{<table><tbody><tr><td>bar<br><br></td></tr></tbody></table>}<p>baz</p>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<table><tr><td>foo<br><br><td>[]bar</table>", + [["delete",""]], + "<table><tbody><tr><td>foo<br><br></td><td>{}bar</td></tr></tbody></table>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<table><tr><td>foo<br><br><tr><td>[]bar</table>", + [["delete",""]], + "<table><tbody><tr><td>foo<br><br></td></tr><tr><td>{}bar</td></tr></tbody></table>", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<hr><table><tr><td>[]bar</table>baz", + [["delete",""]], + "foo<hr><table><tbody><tr><td>[]bar</td></tr></tbody></table>baz", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<table><tr><td>bar<hr></table>[]baz", + [["delete",""]], + "foo{<table><tbody><tr><td>bar<hr></td></tr></tbody></table>}baz", + [true], + {"delete":[false,false,"",false,false,""]}], +["<table><tr><td>foo<hr><td>[]bar</table>", + [["delete",""]], + "<table><tbody><tr><td>foo<hr></td><td>{}bar</td></tr></tbody></table>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<table><tr><td>foo<hr><tr><td>[]bar</table>", + [["delete",""]], + "<table><tbody><tr><td>foo<hr></td></tr><tr><td>{}bar</td></tr></tbody></table>", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<ol><li>[]bar<li>baz</ol>", + [["defaultparagraphseparator","div"],["delete",""]], + "foo<div>[]bar</div><ol><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["foo<ol><li>[]bar<li>baz</ol>", + [["defaultparagraphseparator","p"],["delete",""]], + "foo<p>[]bar</p><ol><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["foo<br><ol><li>[]bar<li>baz</ol>", + [["defaultparagraphseparator","div"],["delete",""]], + "foo<div>[]bar</div><ol><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["foo<br><ol><li>[]bar<li>baz</ol>", + [["defaultparagraphseparator","p"],["delete",""]], + "foo<p>[]bar</p><ol><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["foo<br><br><ol><li>[]bar<li>baz</ol>", + [["defaultparagraphseparator","div"],["delete",""]], + "foo<br><br><div>[]bar</div><ol><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["foo<br><br><ol><li>[]bar<li>baz</ol>", + [["defaultparagraphseparator","p"],["delete",""]], + "foo<br><br><p>[]bar</p><ol><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<ol><li>foo<li>[]bar</ol>", + [["delete",""]], + "<ol><li>foo<br>[]bar</li></ol>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<ol><li>foo<br><li>[]bar</ol>", + [["delete",""]], + "<ol><li>foo<br>[]bar</li></ol>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<ol><li>foo<br><br><li>[]bar</ol>", + [["delete",""]], + "<ol><li>foo<br><br>[]bar</li></ol>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<ol><li>foo<li>[]bar<br>baz</ol>", + [["delete",""]], + "<ol><li>foo<br>[]bar<br>baz</li></ol>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<ol><li>foo<br>bar<li>[]baz</ol>", + [["delete",""]], + "<ol><li>foo<br>bar<br>[]baz</li></ol>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<ol><li><p>foo</p>{}bar</ol>", + [["delete",""]], + "<ol><li><p>foo{}bar</p></li></ol>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<ol><li><p>foo<li>[]bar</ol>", + [["delete",""]], + "<ol><li><p>foo</p>[]bar</li></ol>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<ol><li>foo<li><p>[]bar</ol>", + [["delete",""]], + "<ol><li>foo<p>[]bar</p></li></ol>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<ol><li><p>foo<li><p>[]bar</ol>", + [["delete",""]], + "<ol><li><p>foo</p><p>[]bar</p></li></ol>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<ol><li>foo<ul><li>[]bar</ul></ol>", + [["delete",""]], + "<ol><li>foo</li><li>[]bar</li></ol>", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<ol><ol><li>[]bar</ol></ol>", + [["delete",""]], + "foo<ol><li>[]bar</li></ol>", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<div><ol><li>[]bar</ol></div>", + [["defaultparagraphseparator","div"],["delete",""]], + "foo<div><div>[]bar</div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["foo<div><ol><li>[]bar</ol></div>", + [["defaultparagraphseparator","p"],["delete",""]], + "foo<div><p>[]bar</p></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["foo<dl><dt>[]bar<dd>baz</dl>", + [["defaultparagraphseparator","div"],["delete",""]], + "foo<div>[]bar</div><dl><dd>baz</dd></dl>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["foo<dl><dt>[]bar<dd>baz</dl>", + [["defaultparagraphseparator","p"],["delete",""]], + "foo<p>[]bar</p><dl><dd>baz</dd></dl>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["foo<dl><dd>[]bar</dl>", + [["defaultparagraphseparator","div"],["delete",""]], + "foo<div>[]bar</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["foo<dl><dd>[]bar</dl>", + [["defaultparagraphseparator","p"],["delete",""]], + "foo<p>[]bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<dl><dt>foo<dd>[]bar</dl>", + [["delete",""]], + "<dl><dt>foo<br>[]bar</dt></dl>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<dl><dt>foo<dt>[]bar<dd>baz</dl>", + [["delete",""]], + "<dl><dt>foo<br>[]bar</dt><dd>baz</dd></dl>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<dl><dt>foo<dd>bar<dd>[]baz</dl>", + [["delete",""]], + "<dl><dt>foo</dt><dd>bar<br>[]baz</dd></dl>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<ol><li>foo</ol>[]bar", + [["delete",""]], + "<ol><li>foo{}bar</li></ol>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<ol><li>foo<br></ol>[]bar", + [["delete",""]], + "<ol><li>foo{}bar</li></ol>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<ol><li>foo<br><br></ol>[]bar", + [["delete",""]], + "<ol><li>foo<br>{}bar</li></ol>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<ol><li><br></ol>[]bar", + [["delete",""]], + "<ol><li>{}bar</li></ol>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<ol><li>foo<li><br></ol>[]bar", + [["delete",""]], + "<ol><li>foo</li><li>{}bar</li></ol>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<ol><li>foo</ol><p>[]bar", + [["defaultparagraphseparator","div"],["delete",""]], + "<ol><li>foo{}bar</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<ol><li>foo</ol><p>[]bar", + [["defaultparagraphseparator","p"],["delete",""]], + "<ol><li>foo{}bar</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<ol><li>foo<br></ol><p>[]bar", + [["defaultparagraphseparator","div"],["delete",""]], + "<ol><li>foo{}bar</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<ol><li>foo<br></ol><p>[]bar", + [["defaultparagraphseparator","p"],["delete",""]], + "<ol><li>foo{}bar</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<ol><li>foo<br><br></ol><p>[]bar", + [["defaultparagraphseparator","div"],["delete",""]], + "<ol><li>foo<br>{}bar</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<ol><li>foo<br><br></ol><p>[]bar", + [["defaultparagraphseparator","p"],["delete",""]], + "<ol><li>foo<br>{}bar</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<ol><li><br></ol><p>[]bar", + [["defaultparagraphseparator","div"],["delete",""]], + "<ol><li>{}bar</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<ol><li><br></ol><p>[]bar", + [["defaultparagraphseparator","p"],["delete",""]], + "<ol><li>{}bar</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<ol><li>foo<li><br></ol><p>[]bar", + [["defaultparagraphseparator","div"],["delete",""]], + "<ol><li>foo</li><li>{}bar</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<ol><li>foo<li><br></ol><p>[]bar", + [["defaultparagraphseparator","p"],["delete",""]], + "<ol><li>foo</li><li>{}bar</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<ol><li>foo</ol>{}<br>", + [["delete",""]], + "<ol><li>foo{}</li></ol>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<ol><li>foo<br></ol>{}<br>", + [["delete",""]], + "<ol><li>foo{}</li></ol>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<ol><li>foo<br><br></ol>{}<br>", + [["delete",""]], + "<ol><li>foo<br>{}<br></li></ol>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<ol><li><br></ol>{}<br>", + [["delete",""]], + "<ol><li>{}<br></li></ol>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<ol><li>foo<li><br></ol>{}<br>", + [["delete",""]], + "<ol><li>foo</li><li>{}<br></li></ol>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<ol><li>foo</ol><p>{}<br>", + [["defaultparagraphseparator","div"],["delete",""]], + "<ol><li>foo{}</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<ol><li>foo</ol><p>{}<br>", + [["defaultparagraphseparator","p"],["delete",""]], + "<ol><li>foo{}</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<ol><li>foo<br></ol><p>{}<br>", + [["defaultparagraphseparator","div"],["delete",""]], + "<ol><li>foo{}</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<ol><li>foo<br></ol><p>{}<br>", + [["defaultparagraphseparator","p"],["delete",""]], + "<ol><li>foo{}</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<ol><li>foo<br><br></ol><p>{}<br>", + [["defaultparagraphseparator","div"],["delete",""]], + "<ol><li>foo<br>{}<br></li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<ol><li>foo<br><br></ol><p>{}<br>", + [["defaultparagraphseparator","p"],["delete",""]], + "<ol><li>foo<br>{}<br></li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<ol><li><br></ol><p>{}<br>", + [["defaultparagraphseparator","div"],["delete",""]], + "<ol><li>{}<br></li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<ol><li><br></ol><p>{}<br>", + [["defaultparagraphseparator","p"],["delete",""]], + "<ol><li>{}<br></li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<ol><li>foo<li><br></ol><p>{}<br>", + [["defaultparagraphseparator","div"],["delete",""]], + "<ol><li>foo</li><li>{}<br></li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<ol><li>foo<li><br></ol><p>{}<br>", + [["defaultparagraphseparator","p"],["delete",""]], + "<ol><li>foo</li><li>{}<br></li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["foo<blockquote>[]bar</blockquote>", + [["delete",""]], + "foo<br>[]bar", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<blockquote><blockquote>[]bar</blockquote></blockquote>", + [["delete",""]], + "foo<blockquote>[]bar</blockquote>", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<blockquote><div>[]bar</div></blockquote>", + [["delete",""]], + "foo<div>[]bar</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<blockquote style=\"color: blue\">[]bar</blockquote>", + [["defaultparagraphseparator","div"],["delete",""]], + "foo<div style=\"color:rgb(0, 0, 255)\">[]bar</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["foo<blockquote style=\"color: blue\">[]bar</blockquote>", + [["defaultparagraphseparator","p"],["delete",""]], + "foo<div style=\"color:rgb(0, 0, 255)\">[]bar</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["foo<blockquote><blockquote><p>[]bar<p>baz</blockquote></blockquote>", + [["delete",""]], + "foo<blockquote><p>[]bar</p><blockquote><p>baz</p></blockquote></blockquote>", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<blockquote><div><p>[]bar<p>baz</div></blockquote>", + [["delete",""]], + "foo<div><p>[]bar</p><blockquote><p>baz</p></blockquote></div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<blockquote style=\"color: blue\"><p>[]bar<p>baz</blockquote>", + [["defaultparagraphseparator","div"],["delete",""]], + "foo<div style=\"color:rgb(0, 0, 255)\"><p>[]bar</p><blockquote><p>baz</p></blockquote></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["foo<blockquote style=\"color: blue\"><p>[]bar<p>baz</blockquote>", + [["defaultparagraphseparator","p"],["delete",""]], + "foo<div style=\"color:rgb(0, 0, 255)\"><p>[]bar</p><blockquote><p>baz</p></blockquote></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["foo<blockquote><p><b>[]bar</b><p>baz</blockquote>", + [["delete",""]], + "foo<p><b>[]bar</b></p><blockquote><p>baz</p></blockquote>", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<blockquote><p><strong>[]bar</strong><p>baz</blockquote>", + [["delete",""]], + "foo<p><strong>[]bar</strong></p><blockquote><p>baz</p></blockquote>", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<blockquote><p><span>[]bar</span><p>baz</blockquote>", + [["delete",""]], + "foo<p><span>[]bar</span></p><blockquote><p>baz</p></blockquote>", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<blockquote><ol><li>[]bar</ol></blockquote><p>extra", + [["defaultparagraphseparator","div"],["delete",""]], + "foo<blockquote><div>[]bar</div></blockquote><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["foo<blockquote><ol><li>[]bar</ol></blockquote><p>extra", + [["defaultparagraphseparator","p"],["delete",""]], + "foo<blockquote><p>[]bar</p></blockquote><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["foo<blockquote>bar<ol><li>[]baz</ol>quz</blockquote><p>extra", + [["defaultparagraphseparator","div"],["delete",""]], + "foo<blockquote>bar<div>[]baz</div>quz</blockquote><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["foo<blockquote>bar<ol><li>[]baz</ol>quz</blockquote><p>extra", + [["defaultparagraphseparator","p"],["delete",""]], + "foo<blockquote>bar<p>[]baz</p>quz</blockquote><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["foo<blockquote><ol><li>bar</li><ol><li>[]baz</ol><li>quz</ol></blockquote><p>extra", + [["delete",""]], + "foo<blockquote><ol><li>bar</li><li>[]baz</li><li>quz</li></ol></blockquote><p>extra</p>", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<span></span>[]bar", + [["delete",""]], + "fo[]bar", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<span><span></span></span>[]bar", + [["delete",""]], + "fo[]bar", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<quasit></quasit>[]bar", + [["delete",""]], + "fo[]bar", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<br><span></span>[]bar", + [["delete",""]], + "foo{}bar", + [true], + {"delete":[false,false,"",false,false,""]}], +["<span>foo<span></span></span>[]bar", + [["delete",""]], + "<span>fo[]</span>bar", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<span></span><span>[]bar</span>", + [["delete",""]], + "fo[]<span>bar</span>", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<div><div><p>[]bar</div></div>", + [["defaultparagraphseparator","div"],["delete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["foo<div><div><p>[]bar</div></div>", + [["defaultparagraphseparator","p"],["delete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["foo<div><div><p><!--abc-->[]bar</div></div>", + [["defaultparagraphseparator","div"],["delete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["foo<div><div><p><!--abc-->[]bar</div></div>", + [["defaultparagraphseparator","p"],["delete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["foo<div><div><!--abc--><p>[]bar</div></div>", + [["defaultparagraphseparator","div"],["delete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["foo<div><div><!--abc--><p>[]bar</div></div>", + [["defaultparagraphseparator","p"],["delete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["foo<div><!--abc--><div><p>[]bar</div></div>", + [["defaultparagraphseparator","div"],["delete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["foo<div><!--abc--><div><p>[]bar</div></div>", + [["defaultparagraphseparator","p"],["delete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["foo<!--abc--><div><div><p>[]bar</div></div>", + [["defaultparagraphseparator","div"],["delete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["foo<!--abc--><div><div><p>[]bar</div></div>", + [["defaultparagraphseparator","p"],["delete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<div><div><p>foo</div></div>[]bar", + [["delete",""]], + "<div><div><p>foo{}bar</p></div></div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div><div><p>foo</div></div><!--abc-->[]bar", + [["delete",""]], + "<div><div><p>foo{}bar</p></div></div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div><div><p>foo</div><!--abc--></div>[]bar", + [["delete",""]], + "<div><div><p>foo{}bar</p></div></div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div><div><p>foo</p><!--abc--></div></div>[]bar", + [["delete",""]], + "<div><div><p>foo{}bar</p></div></div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div><div><p>foo<!--abc--></div></div>[]bar", + [["delete",""]], + "<div><div><p>foo{}bar</p></div></div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div><div><p>foo</p></div></div><div><div><div>[]bar</div></div></div>", + [["defaultparagraphseparator","div"],["delete",""]], + "<div><div><p>foo{}bar</p></div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<div><div><p>foo</p></div></div><div><div><div>[]bar</div></div></div>", + [["defaultparagraphseparator","p"],["delete",""]], + "<div><div><p>foo{}bar</p></div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<div><div><p>foo<!--abc--></p></div></div><div><div><div>[]bar</div></div></div>", + [["defaultparagraphseparator","div"],["delete",""]], + "<div><div><p>foo{}bar</p></div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<div><div><p>foo<!--abc--></p></div></div><div><div><div>[]bar</div></div></div>", + [["defaultparagraphseparator","p"],["delete",""]], + "<div><div><p>foo{}bar</p></div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<div><div><p>foo</p><!--abc--></div></div><div><div><div>[]bar</div></div></div>", + [["defaultparagraphseparator","div"],["delete",""]], + "<div><div><p>foo{}bar</p></div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<div><div><p>foo</p><!--abc--></div></div><div><div><div>[]bar</div></div></div>", + [["defaultparagraphseparator","p"],["delete",""]], + "<div><div><p>foo{}bar</p></div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<div><div><p>foo</p></div><!--abc--></div><div><div><div>[]bar</div></div></div>", + [["defaultparagraphseparator","div"],["delete",""]], + "<div><div><p>foo{}bar</p></div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<div><div><p>foo</p></div><!--abc--></div><div><div><div>[]bar</div></div></div>", + [["defaultparagraphseparator","p"],["delete",""]], + "<div><div><p>foo{}bar</p></div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<div><div><p>foo</p></div></div><!--abc--><div><div><div>[]bar</div></div></div>", + [["defaultparagraphseparator","div"],["delete",""]], + "<div><div><p>foo{}bar</p></div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<div><div><p>foo</p></div></div><!--abc--><div><div><div>[]bar</div></div></div>", + [["defaultparagraphseparator","p"],["delete",""]], + "<div><div><p>foo{}bar</p></div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<div><div><p>foo</p></div></div><div><!--abc--><div><div>[]bar</div></div></div>", + [["defaultparagraphseparator","div"],["delete",""]], + "<div><div><p>foo{}bar</p></div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<div><div><p>foo</p></div></div><div><!--abc--><div><div>[]bar</div></div></div>", + [["defaultparagraphseparator","p"],["delete",""]], + "<div><div><p>foo{}bar</p></div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<div><div><p>foo</p></div></div><div><div><!--abc--><div>[]bar</div></div></div>", + [["defaultparagraphseparator","div"],["delete",""]], + "<div><div><p>foo{}bar</p></div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<div><div><p>foo</p></div></div><div><div><!--abc--><div>[]bar</div></div></div>", + [["defaultparagraphseparator","p"],["delete",""]], + "<div><div><p>foo{}bar</p></div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<div><div><p>foo</p></div></div><div><div><div><!--abc-->[]bar</div></div></div>", + [["defaultparagraphseparator","div"],["delete",""]], + "<div><div><p>foo{}bar</p></div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<div><div><p>foo</p></div></div><div><div><div><!--abc-->[]bar</div></div></div>", + [["defaultparagraphseparator","p"],["delete",""]], + "<div><div><p>foo{}bar</p></div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p style=color:blue>foo<p>[]bar", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["delete",""]], + "<p><span style=\"color:rgb(0, 0, 255)\">foo{}</span>bar</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p style=color:blue>foo<p>[]bar", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["delete",""]], + "<p><font color=\"#0000ff\">foo{}</font>bar</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p style=color:blue>foo<p>[]bar", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["delete",""]], + "<p><span style=\"color:rgb(0, 0, 255)\">foo{}</span>bar</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p style=color:blue>foo<p>[]bar", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["delete",""]], + "<p><font color=\"#0000ff\">foo{}</font>bar</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p style=color:blue>foo<p style=color:brown>[]bar", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["delete",""]], + "<p style=\"color:rgb(0, 0, 255)\">foo{}<span style=\"color:rgb(165, 42, 42)\">bar</span></p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p style=color:blue>foo<p style=color:brown>[]bar", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["delete",""]], + "<p style=\"color:rgb(0, 0, 255)\">foo{}<font color=\"#a52a2a\">bar</font></p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p style=color:blue>foo<p style=color:brown>[]bar", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["delete",""]], + "<p style=\"color:rgb(0, 0, 255)\">foo{}<span style=\"color:rgb(165, 42, 42)\">bar</span></p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p style=color:blue>foo<p style=color:brown>[]bar", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["delete",""]], + "<p style=\"color:rgb(0, 0, 255)\">foo{}<font color=\"#a52a2a\">bar</font></p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p style=color:blue>foo<p style=color:rgba(0,0,255,1)>[]bar", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["delete",""]], + "<p style=\"color:rgb(0, 0, 255)\">foo{}bar</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p style=color:blue>foo<p style=color:rgba(0,0,255,1)>[]bar", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["delete",""]], + "<p style=\"color:rgb(0, 0, 255)\">foo{}bar</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p style=color:blue>foo<p style=color:rgba(0,0,255,1)>[]bar", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["delete",""]], + "<p style=\"color:rgb(0, 0, 255)\">foo{}bar</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p style=color:blue>foo<p style=color:rgba(0,0,255,1)>[]bar", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["delete",""]], + "<p style=\"color:rgb(0, 0, 255)\">foo{}bar</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p style=color:transparent>foo<p style=color:rgba(0,0,0,0)>[]bar", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["delete",""]], + "<p style=\"color:rgba(0, 0, 0, 0)\">foo{}bar</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p style=color:transparent>foo<p style=color:rgba(0,0,0,0)>[]bar", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["delete",""]], + "<p style=\"color:rgba(0, 0, 0, 0)\">foo{}bar</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p style=color:transparent>foo<p style=color:rgba(0,0,0,0)>[]bar", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["delete",""]], + "<p style=\"color:rgba(0, 0, 0, 0)\">foo{}bar</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p style=color:transparent>foo<p style=color:rgba(0,0,0,0)>[]bar", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["delete",""]], + "<p style=\"color:rgba(0, 0, 0, 0)\">foo{}bar</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p>foo<p style=color:brown>[]bar", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["delete",""]], + "<p>foo{}<span style=\"color:rgb(165, 42, 42)\">bar</span></p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p>foo<p style=color:brown>[]bar", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["delete",""]], + "<p>foo{}<font color=\"#a52a2a\">bar</font></p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p>foo<p style=color:brown>[]bar", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["delete",""]], + "<p>foo{}<span style=\"color:rgb(165, 42, 42)\">bar</span></p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p>foo<p style=color:brown>[]bar", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["delete",""]], + "<p>foo{}<font color=\"#a52a2a\">bar</font></p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p><font color=blue>foo</font><p>[]bar", + [["defaultparagraphseparator","div"],["delete",""]], + "<p><font color=\"blue\">foo</font>{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p><font color=blue>foo</font><p>[]bar", + [["defaultparagraphseparator","p"],["delete",""]], + "<p><font color=\"blue\">foo</font>{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p><font color=blue>foo</font><p><font color=brown>[]bar</font>", + [["defaultparagraphseparator","div"],["delete",""]], + "<p><font color=\"blue\">foo</font>{}<font color=\"brown\">bar</font></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p><font color=blue>foo</font><p><font color=brown>[]bar</font>", + [["defaultparagraphseparator","p"],["delete",""]], + "<p><font color=\"blue\">foo</font>{}<font color=\"brown\">bar</font></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p>foo<p><font color=brown>[]bar</font>", + [["defaultparagraphseparator","div"],["delete",""]], + "<p>foo{}<font color=\"brown\">bar</font></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p>foo<p><font color=brown>[]bar</font>", + [["defaultparagraphseparator","p"],["delete",""]], + "<p>foo{}<font color=\"brown\">bar</font></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p><span style=color:blue>foo</font><p>[]bar", + [["defaultparagraphseparator","div"],["delete",""]], + "<p><span style=\"color:rgb(0, 0, 255)\">foo</span>{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p><span style=color:blue>foo</font><p>[]bar", + [["defaultparagraphseparator","p"],["delete",""]], + "<p><span style=\"color:rgb(0, 0, 255)\">foo</span>{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p><span style=color:blue>foo</font><p><span style=color:brown>[]bar</font>", + [["defaultparagraphseparator","div"],["delete",""]], + "<p><span style=\"color:rgb(0, 0, 255)\">foo</span>{}<span style=\"color:rgb(165, 42, 42)\">bar</span></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p><span style=color:blue>foo</font><p><span style=color:brown>[]bar</font>", + [["defaultparagraphseparator","p"],["delete",""]], + "<p><span style=\"color:rgb(0, 0, 255)\">foo</span>{}<span style=\"color:rgb(165, 42, 42)\">bar</span></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p>foo<p><span style=color:brown>[]bar</font>", + [["defaultparagraphseparator","div"],["delete",""]], + "<p>foo{}<span style=\"color:rgb(165, 42, 42)\">bar</span></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p>foo<p><span style=color:brown>[]bar</font>", + [["defaultparagraphseparator","p"],["delete",""]], + "<p>foo{}<span style=\"color:rgb(165, 42, 42)\">bar</span></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p style=background-color:aqua>foo<p>[]bar", + [["defaultparagraphseparator","div"],["delete",""]], + "<p style=\"background-color:rgb(0, 255, 255)\">foo{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p style=background-color:aqua>foo<p>[]bar", + [["defaultparagraphseparator","p"],["delete",""]], + "<p style=\"background-color:rgb(0, 255, 255)\">foo{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p style=background-color:aqua>foo<p style=background-color:tan>[]bar", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["delete",""]], + "<p style=\"background-color:rgb(0, 255, 255)\">foo{}bar</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p style=background-color:aqua>foo<p style=background-color:tan>[]bar", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["delete",""]], + "<p style=\"background-color:rgb(0, 255, 255)\">foo{}bar</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p style=background-color:aqua>foo<p style=background-color:tan>[]bar", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["delete",""]], + "<p style=\"background-color:rgb(0, 255, 255)\">foo{}bar</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p style=background-color:aqua>foo<p style=background-color:tan>[]bar", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["delete",""]], + "<p style=\"background-color:rgb(0, 255, 255)\">foo{}bar</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p>foo<p style=background-color:tan>[]bar", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["delete",""]], + "<p>foo{}bar</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p>foo<p style=background-color:tan>[]bar", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["delete",""]], + "<p>foo{}bar</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p>foo<p style=background-color:tan>[]bar", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["delete",""]], + "<p>foo{}bar</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p>foo<p style=background-color:tan>[]bar", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["delete",""]], + "<p>foo{}bar</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p><span style=background-color:aqua>foo</font><p>[]bar", + [["defaultparagraphseparator","div"],["delete",""]], + "<p><span style=\"background-color:rgb(0, 255, 255)\">foo</span>{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p><span style=background-color:aqua>foo</font><p>[]bar", + [["defaultparagraphseparator","p"],["delete",""]], + "<p><span style=\"background-color:rgb(0, 255, 255)\">foo</span>{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p><span style=background-color:aqua>foo</font><p><span style=background-color:tan>[]bar</font>", + [["defaultparagraphseparator","div"],["delete",""]], + "<p><span style=\"background-color:rgb(0, 255, 255)\">foo</span>{}<span style=\"background-color:rgb(210, 180, 140)\">bar</span></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p><span style=background-color:aqua>foo</font><p><span style=background-color:tan>[]bar</font>", + [["defaultparagraphseparator","p"],["delete",""]], + "<p><span style=\"background-color:rgb(0, 255, 255)\">foo</span>{}<span style=\"background-color:rgb(210, 180, 140)\">bar</span></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p>foo<p><span style=background-color:tan>[]bar</font>", + [["defaultparagraphseparator","div"],["delete",""]], + "<p>foo{}<span style=\"background-color:rgb(210, 180, 140)\">bar</span></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p>foo<p><span style=background-color:tan>[]bar</font>", + [["defaultparagraphseparator","p"],["delete",""]], + "<p>foo{}<span style=\"background-color:rgb(210, 180, 140)\">bar</span></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p style=text-decoration:underline>foo<p>[]bar", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["delete",""]], + "<p><span style=\"text-decoration:underline\">foo{}</span>bar</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p style=text-decoration:underline>foo<p>[]bar", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["delete",""]], + "<p><u>foo{}</u>bar</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p style=text-decoration:underline>foo<p>[]bar", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["delete",""]], + "<p><span style=\"text-decoration:underline\">foo{}</span>bar</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p style=text-decoration:underline>foo<p>[]bar", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["delete",""]], + "<p><u>foo{}</u>bar</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p style=text-decoration:underline>foo<p style=text-decoration:line-through>[]bar", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["delete",""]], + "<p><span style=\"text-decoration:underline\">foo{}</span><span style=\"text-decoration:line-through\">bar</span></p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p style=text-decoration:underline>foo<p style=text-decoration:line-through>[]bar", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["delete",""]], + "<p><u>foo{}</u><s>bar</s></p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p style=text-decoration:underline>foo<p style=text-decoration:line-through>[]bar", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["delete",""]], + "<p><span style=\"text-decoration:underline\">foo{}</span><span style=\"text-decoration:line-through\">bar</span></p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p style=text-decoration:underline>foo<p style=text-decoration:line-through>[]bar", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["delete",""]], + "<p><u>foo{}</u><s>bar</s></p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p>foo<p style=text-decoration:line-through>[]bar", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["delete",""]], + "<p>foo{}<span style=\"text-decoration:line-through\">bar</span></p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p>foo<p style=text-decoration:line-through>[]bar", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["delete",""]], + "<p>foo{}<s>bar</s></p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p>foo<p style=text-decoration:line-through>[]bar", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["delete",""]], + "<p>foo{}<span style=\"text-decoration:line-through\">bar</span></p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p>foo<p style=text-decoration:line-through>[]bar", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["delete",""]], + "<p>foo{}<s>bar</s></p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p><u>foo</u><p>[]bar", + [["defaultparagraphseparator","div"],["delete",""]], + "<p><u>foo</u>{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p><u>foo</u><p>[]bar", + [["defaultparagraphseparator","p"],["delete",""]], + "<p><u>foo</u>{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p><u>foo</u><p><s>[]bar</s>", + [["defaultparagraphseparator","div"],["delete",""]], + "<p><u>foo</u>{}<s>bar</s></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p><u>foo</u><p><s>[]bar</s>", + [["defaultparagraphseparator","p"],["delete",""]], + "<p><u>foo</u>{}<s>bar</s></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p>foo<p><s>[]bar</s>", + [["defaultparagraphseparator","div"],["delete",""]], + "<p>foo{}<s>bar</s></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p>foo<p><s>[]bar</s>", + [["defaultparagraphseparator","p"],["delete",""]], + "<p>foo{}<s>bar</s></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p style=color:blue>foo</p>[]bar", + [["stylewithcss","true"],["delete",""]], + "<p><span style=\"color:rgb(0, 0, 255)\">foo{}</span>bar</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"delete":[false,false,"",false,false,""]}], +["<p style=color:blue>foo</p>[]bar", + [["stylewithcss","false"],["delete",""]], + "<p><font color=\"#0000ff\">foo{}</font>bar</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"delete":[false,false,"",false,false,""]}], +["foo<p style=color:brown>[]bar", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["delete",""]], + "foo{}<span style=\"color:rgb(165, 42, 42)\">bar</span>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["foo<p style=color:brown>[]bar", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["delete",""]], + "foo{}<font color=\"#a52a2a\">bar</font>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["foo<p style=color:brown>[]bar", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["delete",""]], + "foo{}<span style=\"color:rgb(165, 42, 42)\">bar</span>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["foo<p style=color:brown>[]bar", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["delete",""]], + "foo{}<font color=\"#a52a2a\">bar</font>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<div style=color:blue><p style=color:green>foo</div>[]bar", + [["stylewithcss","true"],["delete",""]], + "<div><p><span style=\"color:rgb(0, 128, 0)\">foo{}</span>bar</p></div>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"delete":[false,false,"",false,false,""]}], +["<div style=color:blue><p style=color:green>foo</div>[]bar", + [["stylewithcss","false"],["delete",""]], + "<div><p><font color=\"#008000\">foo{}</font>bar</p></div>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"delete":[false,false,"",false,false,""]}], +["<div style=color:blue><p style=color:green>foo</div><p style=color:brown>[]bar", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["delete",""]], + "<div style=\"color:rgb(0, 0, 255)\"><p style=\"color:rgb(0, 128, 0)\">foo{}<span style=\"color:rgb(165, 42, 42)\">bar</span></p></div>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<div style=color:blue><p style=color:green>foo</div><p style=color:brown>[]bar", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["delete",""]], + "<div style=\"color:rgb(0, 0, 255)\"><p style=\"color:rgb(0, 128, 0)\">foo{}<font color=\"#a52a2a\">bar</font></p></div>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<div style=color:blue><p style=color:green>foo</div><p style=color:brown>[]bar", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["delete",""]], + "<div style=\"color:rgb(0, 0, 255)\"><p style=\"color:rgb(0, 128, 0)\">foo{}<span style=\"color:rgb(165, 42, 42)\">bar</span></p></div>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<div style=color:blue><p style=color:green>foo</div><p style=color:brown>[]bar", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["delete",""]], + "<div style=\"color:rgb(0, 0, 255)\"><p style=\"color:rgb(0, 128, 0)\">foo{}<font color=\"#a52a2a\">bar</font></p></div>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p style=color:blue>foo<div style=color:brown><p style=color:green>[]bar", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["delete",""]], + "<p style=\"color:rgb(0, 0, 255)\">foo{}<span style=\"color:rgb(0, 128, 0)\">bar</span></p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p style=color:blue>foo<div style=color:brown><p style=color:green>[]bar", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["delete",""]], + "<p style=\"color:rgb(0, 0, 255)\">foo{}<font color=\"#008000\">bar</font></p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p style=color:blue>foo<div style=color:brown><p style=color:green>[]bar", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["delete",""]], + "<p style=\"color:rgb(0, 0, 255)\">foo{}<span style=\"color:rgb(0, 128, 0)\">bar</span></p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p style=color:blue>foo<div style=color:brown><p style=color:green>[]bar", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["delete",""]], + "<p style=\"color:rgb(0, 0, 255)\">foo{}<font color=\"#008000\">bar</font></p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["foo[bar]baz", + [["delete",""]], + "foo[]baz", + [true], + {"delete":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>[bar]</span>baz", + [["stylewithcss","true"],["delete",""]], + "<p>foo{}baz</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"delete":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>[bar]</span>baz", + [["stylewithcss","false"],["delete",""]], + "<p>foo{}baz</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"delete":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>{bar}</span>baz", + [["stylewithcss","true"],["delete",""]], + "<p>foo{}baz</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"delete":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>{bar}</span>baz", + [["stylewithcss","false"],["delete",""]], + "<p>foo{}baz</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"delete":[false,false,"",false,false,""]}], +["<p>foo{<span style=color:#aBcDeF>bar</span>}baz", + [["stylewithcss","true"],["delete",""]], + "<p>foo{}baz</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"delete":[false,false,"",false,false,""]}], +["<p>foo{<span style=color:#aBcDeF>bar</span>}baz", + [["stylewithcss","false"],["delete",""]], + "<p>foo{}baz</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"delete":[false,false,"",false,false,""]}], +["<p>[foo<span style=color:#aBcDeF>bar]</span>baz", + [["stylewithcss","true"],["delete",""]], + "<p>{}baz</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"delete":[false,false,"",false,false,""]}], +["<p>[foo<span style=color:#aBcDeF>bar]</span>baz", + [["stylewithcss","false"],["delete",""]], + "<p>{}baz</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"delete":[false,false,"",false,false,""]}], +["<p>{foo<span style=color:#aBcDeF>bar}</span>baz", + [["stylewithcss","true"],["delete",""]], + "<p>{}baz</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"delete":[false,false,"",false,false,""]}], +["<p>{foo<span style=color:#aBcDeF>bar}</span>baz", + [["stylewithcss","false"],["delete",""]], + "<p>{}baz</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"delete":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>[bar</span>baz]", + [["stylewithcss","true"],["delete",""]], + "<p>foo{}</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"delete":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>[bar</span>baz]", + [["stylewithcss","false"],["delete",""]], + "<p>foo{}</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"delete":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>{bar</span>baz}", + [["stylewithcss","true"],["delete",""]], + "<p>foo{}</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"delete":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>{bar</span>baz}", + [["stylewithcss","false"],["delete",""]], + "<p>foo{}</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"delete":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>[bar</span><span style=color:#fEdCbA>baz]</span>quz", + [["stylewithcss","true"],["delete",""]], + "<p>foo{}quz</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"delete":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>[bar</span><span style=color:#fEdCbA>baz]</span>quz", + [["stylewithcss","false"],["delete",""]], + "<p>foo{}quz</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"delete":[false,false,"",false,false,""]}], +["foo<b>[bar]</b>baz", + [["stylewithcss","true"],["delete",""]], + "foo{}baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"delete":[false,false,"",false,false,""]}], +["foo<b>[bar]</b>baz", + [["stylewithcss","false"],["delete",""]], + "foo{}baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"delete":[false,false,"",false,false,""]}], +["foo<b>{bar}</b>baz", + [["stylewithcss","true"],["delete",""]], + "foo{}baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"delete":[false,false,"",false,false,""]}], +["foo<b>{bar}</b>baz", + [["stylewithcss","false"],["delete",""]], + "foo{}baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"delete":[false,false,"",false,false,""]}], +["foo{<b>bar</b>}baz", + [["stylewithcss","true"],["delete",""]], + "foo{}baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"delete":[false,false,"",false,false,""]}], +["foo{<b>bar</b>}baz", + [["stylewithcss","false"],["delete",""]], + "foo{}baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"delete":[false,false,"",false,false,""]}], +["foo<span>[bar]</span>baz", + [["delete",""]], + "foo{}baz", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<span>{bar}</span>baz", + [["delete",""]], + "foo{}baz", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo{<span>bar</span>}baz", + [["delete",""]], + "foo{}baz", + [true], + {"delete":[false,false,"",false,false,""]}], +["<b>foo[bar</b><i>baz]quz</i>", + [["delete",""]], + "<b>foo[]</b><i>quz</i>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<p>foo</p><p>[bar]</p><p>baz</p>", + [["delete",""]], + "<p>foo</p><p>{}<br></p><p>baz</p>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<p>foo</p><p>{bar}</p><p>baz</p>", + [["delete",""]], + "<p>foo</p><p>{}<br></p><p>baz</p>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<p>foo</p><p>{bar</p>}<p>baz</p>", + [["delete",""]], + "<p>foo</p><p>{}<br></p><p>baz</p>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<p>foo</p>{<p>bar}</p><p>baz</p>", + [["defaultparagraphseparator","div"],["delete",""]], + "<p>foo</p>{}<br><p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p>foo</p>{<p>bar}</p><p>baz</p>", + [["defaultparagraphseparator","p"],["delete",""]], + "<p>foo</p>{}<br><p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p>foo</p>{<p>bar</p>}<p>baz</p>", + [["defaultparagraphseparator","div"],["delete",""]], + "<p>foo</p>{}<p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p>foo</p>{<p>bar</p>}<p>baz</p>", + [["defaultparagraphseparator","p"],["delete",""]], + "<p>foo</p>{}<p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p>foo[bar<p>baz]quz", + [["defaultparagraphseparator","div"],["delete",""]], + "<p>foo{}quz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p>foo[bar<p>baz]quz", + [["defaultparagraphseparator","p"],["delete",""]], + "<p>foo{}quz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p>foo[bar<div>baz]quz</div>", + [["defaultparagraphseparator","div"],["delete",""]], + "<p>foo{}quz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p>foo[bar<div>baz]quz</div>", + [["defaultparagraphseparator","p"],["delete",""]], + "<p>foo{}quz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p>foo[bar<h1>baz]quz</h1>", + [["delete",""]], + "<p>foo{}quz</p>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div>foo[bar</div><p>baz]quz", + [["defaultparagraphseparator","div"],["delete",""]], + "<div>foo{}quz</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<div>foo[bar</div><p>baz]quz", + [["defaultparagraphseparator","p"],["delete",""]], + "<div>foo{}quz</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<blockquote>foo[bar</blockquote><pre>baz]quz</pre>", + [["delete",""]], + "<blockquote>foo{}quz</blockquote>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<p><b>foo[bar</b><p>baz]quz", + [["defaultparagraphseparator","div"],["delete",""]], + "<p><b>foo</b>{}quz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p><b>foo[bar</b><p>baz]quz", + [["defaultparagraphseparator","p"],["delete",""]], + "<p><b>foo</b>{}quz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<div><p>foo[bar</div><p>baz]quz", + [["defaultparagraphseparator","div"],["delete",""]], + "<div><p>foo{}quz</p></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<div><p>foo[bar</div><p>baz]quz", + [["defaultparagraphseparator","p"],["delete",""]], + "<div><p>foo{}quz</p></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p>foo[bar<blockquote><p>baz]quz<p>qoz</blockquote", + [["defaultparagraphseparator","div"],["delete",""]], + "<p>foo{}quz</p><blockquote><p>qoz</p></blockquote>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p>foo[bar<blockquote><p>baz]quz<p>qoz</blockquote", + [["defaultparagraphseparator","p"],["delete",""]], + "<p>foo{}quz</p><blockquote><p>qoz</p></blockquote>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p>foo[bar<p style=color:blue>baz]quz", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["delete",""]], + "<p>foo{}<span style=\"color:rgb(0, 0, 255)\">quz</span></p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p>foo[bar<p style=color:blue>baz]quz", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["delete",""]], + "<p>foo{}<font color=\"#0000ff\">quz</font></p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p>foo[bar<p style=color:blue>baz]quz", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["delete",""]], + "<p>foo{}<span style=\"color:rgb(0, 0, 255)\">quz</span></p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p>foo[bar<p style=color:blue>baz]quz", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["delete",""]], + "<p>foo{}<font color=\"#0000ff\">quz</font></p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p>foo[bar<p><b>baz]quz</b>", + [["defaultparagraphseparator","div"],["delete",""]], + "<p>foo{}<b>quz</b></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p>foo[bar<p><b>baz]quz</b>", + [["defaultparagraphseparator","p"],["delete",""]], + "<p>foo{}<b>quz</b></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<div><p>foo<p>[bar<p>baz]</div>", + [["defaultparagraphseparator","div"],["delete",""]], + "<div><p>foo</p><p>{}<br></p></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<div><p>foo<p>[bar<p>baz]</div>", + [["defaultparagraphseparator","p"],["delete",""]], + "<div><p>foo</p><p>{}<br></p></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["foo[<br>]bar", + [["delete",""]], + "foo{}bar", + [true], + {"delete":[false,false,"",false,false,""]}], +["<p>foo[</p><p>]bar</p>", + [["defaultparagraphseparator","div"],["delete",""]], + "<p>foo{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p>foo[</p><p>]bar</p>", + [["defaultparagraphseparator","p"],["delete",""]], + "<p>foo{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p>foo[</p><p>]bar<br>baz</p>", + [["defaultparagraphseparator","div"],["delete",""]], + "<p>foo{}bar<br>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p>foo[</p><p>]bar<br>baz</p>", + [["defaultparagraphseparator","p"],["delete",""]], + "<p>foo{}bar<br>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["foo[<p>]bar</p>", + [["defaultparagraphseparator","div"],["delete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["foo[<p>]bar</p>", + [["defaultparagraphseparator","p"],["delete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["foo{<p>}bar</p>", + [["defaultparagraphseparator","div"],["delete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["foo{<p>}bar</p>", + [["defaultparagraphseparator","p"],["delete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["foo[<p>]bar<br>baz</p>", + [["delete",""]], + "foo{}bar<p>baz</p>", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo[<p>]bar</p>baz", + [["defaultparagraphseparator","div"],["delete",""]], + "foo{}bar<br>baz", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["foo[<p>]bar</p>baz", + [["defaultparagraphseparator","p"],["delete",""]], + "foo{}bar<br>baz", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["foo{<p>bar</p>}baz", + [["defaultparagraphseparator","div"],["delete",""]], + "foo{}baz", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["foo{<p>bar</p>}baz", + [["defaultparagraphseparator","p"],["delete",""]], + "foo{}baz", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["foo<p>{bar</p>}baz", + [["delete",""]], + "foo<p>{}baz</p>", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo{<p>bar}</p>baz", + [["defaultparagraphseparator","div"],["delete",""]], + "foo{}<br>baz", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["foo{<p>bar}</p>baz", + [["defaultparagraphseparator","p"],["delete",""]], + "foo{}<br>baz", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p>foo[</p>]bar", + [["delete",""]], + "<p>foo{}bar</p>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<p>foo{</p>}bar", + [["delete",""]], + "<p>foo{}bar</p>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<p>foo[</p>]bar<br>baz", + [["delete",""]], + "<p>foo{}bar</p>baz", + [true], + {"delete":[false,false,"",false,false,""]}], +["<p>foo[</p>]bar<p>baz</p>", + [["delete",""]], + "<p>foo{}bar</p><p>baz</p>", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo[<div><p>]bar</div>", + [["defaultparagraphseparator","div"],["delete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["foo[<div><p>]bar</div>", + [["defaultparagraphseparator","p"],["delete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<div><p>foo[</p></div>]bar", + [["delete",""]], + "<div><p>foo{}bar</p></div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo[<div><p>]bar</p>baz</div>", + [["defaultparagraphseparator","div"],["delete",""]], + "foo{}bar<div>baz</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["foo[<div><p>]bar</p>baz</div>", + [["defaultparagraphseparator","p"],["delete",""]], + "foo{}bar<div>baz</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["foo[<div>]bar<p>baz</p></div>", + [["delete",""]], + "foo{}bar<div><p>baz</p></div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div><p>foo</p>bar[</div>]baz", + [["delete",""]], + "<div><p>foo</p>bar{}baz</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div>foo<p>bar[</p></div>]baz", + [["delete",""]], + "<div>foo<p>bar{}baz</p></div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<p>foo<br>{</p>]bar", + [["delete",""]], + "<p>foo{}bar</p>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<p>foo<br><br>{</p>]bar", + [["delete",""]], + "<p>foo<br>{}bar</p>", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<br>{<p>]bar</p>", + [["defaultparagraphseparator","div"],["delete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["foo<br>{<p>]bar</p>", + [["defaultparagraphseparator","p"],["delete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["foo<br><br>{<p>]bar</p>", + [["defaultparagraphseparator","div"],["delete",""]], + "foo<br>{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["foo<br><br>{<p>]bar</p>", + [["defaultparagraphseparator","p"],["delete",""]], + "foo<br>{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p>foo<br>{</p><p>}bar</p>", + [["defaultparagraphseparator","div"],["delete",""]], + "<p>foo{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p>foo<br>{</p><p>}bar</p>", + [["defaultparagraphseparator","p"],["delete",""]], + "<p>foo{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p>foo<br><br>{</p><p>}bar</p>", + [["defaultparagraphseparator","div"],["delete",""]], + "<p>foo<br>{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p>foo<br><br>{</p><p>}bar</p>", + [["defaultparagraphseparator","p"],["delete",""]], + "<p>foo<br>{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<table><tbody><tr><th>foo<th>[bar]<th>baz<tr><td>quz<td>qoz<td>qiz</table>", + [["delete",""]], + "<table><tbody><tr><th>foo</th><th>{}<br></th><th>baz</th></tr><tr><td>quz</td><td>qoz</td><td>qiz</td></tr></tbody></table>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<table><tbody><tr><th>foo<th>ba[r<th>b]az<tr><td>quz<td>qoz<td>qiz</table>", + [["delete",""]], + "<table><tbody><tr><th>foo</th><th>ba[]</th><th>az</th></tr><tr><td>quz</td><td>qoz</td><td>qiz</td></tr></tbody></table>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<table><tbody><tr><th>fo[o<th>bar<th>b]az<tr><td>quz<td>qoz<td>qiz</table>", + [["delete",""]], + "<table><tbody><tr><th>fo[]</th><th><br></th><th>az</th></tr><tr><td>quz</td><td>qoz</td><td>qiz</td></tr></tbody></table>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<table><tbody><tr><th>foo<th>bar<th>ba[z<tr><td>q]uz<td>qoz<td>qiz</table>", + [["delete",""]], + "<table><tbody><tr><th>foo</th><th>bar</th><th>ba[]</th></tr><tr><td>uz</td><td>qoz</td><td>qiz</td></tr></tbody></table>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<table><tbody><tr><th>[foo<th>bar<th>baz]<tr><td>quz<td>qoz<td>qiz</table>", + [["delete",""]], + "<table><tbody><tr><th>{}<br></th><th><br></th><th><br></th></tr><tr><td>quz</td><td>qoz</td><td>qiz</td></tr></tbody></table>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<table><tbody><tr><th>[foo<th>bar<th>baz<tr><td>quz<td>qoz<td>qiz]</table>", + [["delete",""]], + "<table><tbody><tr><th>{}<br></th><th><br></th><th><br></th></tr><tr><td><br></td><td><br></td><td><br></td></tr></tbody></table>", + [true], + {"delete":[false,false,"",false,false,""]}], +["{<table><tbody><tr><th>foo<th>bar<th>baz<tr><td>quz<td>qoz<td>qiz</table>}", + [["delete",""]], + "{}<br>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<table><tbody><tr><td>foo<td>ba[r<tr><td>baz<td>quz<tr><td>q]oz<td>qiz</table>", + [["delete",""]], + "<table><tbody><tr><td>foo</td><td>ba[]</td></tr><tr><td><br></td><td><br></td></tr><tr><td>oz</td><td>qiz</td></tr></tbody></table>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<p>fo[o<table><tr><td>b]ar</table><p>baz", + [["delete",""]], + "<p>fo[]</p><table><tbody><tr><td>ar</td></tr></tbody></table><p>baz</p>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<p>foo<table><tr><td>ba[r</table><p>b]az", + [["delete",""]], + "<p>foo</p><table><tbody><tr><td>ba[]</td></tr></tbody></table><p>az</p>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<p>fo[o<table><tr><td>bar</table><p>b]az", + [["defaultparagraphseparator","div"],["delete",""]], + "<p>fo{}az</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p>fo[o<table><tr><td>bar</table><p>b]az", + [["defaultparagraphseparator","p"],["delete",""]], + "<p>fo{}az</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p>foo<ol><li>ba[r<li>b]az</ol><p>quz", + [["delete",""]], + "<p>foo</p><ol><li>ba{}az</li></ol><p>quz</p>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<p>foo<ol><li>bar<li>[baz]</ol><p>quz", + [["delete",""]], + "<p>foo</p><ol><li>bar</li><li>{}<br></li></ol><p>quz</p>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<p>fo[o<ol><li>b]ar<li>baz</ol><p>quz", + [["delete",""]], + "<p>fo{}ar</p><ol><li>baz</li></ol><p>quz</p>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<p>foo<ol><li>bar<li>ba[z</ol><p>q]uz", + [["defaultparagraphseparator","div"],["delete",""]], + "<p>foo</p><ol><li>bar</li><li>ba{}uz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p>foo<ol><li>bar<li>ba[z</ol><p>q]uz", + [["defaultparagraphseparator","p"],["delete",""]], + "<p>foo</p><ol><li>bar</li><li>ba{}uz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p>fo[o<ol><li>bar<li>b]az</ol><p>quz", + [["delete",""]], + "<p>fo{}az</p><p>quz</p>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<p>fo[o<ol><li>bar<li>baz</ol><p>q]uz", + [["defaultparagraphseparator","div"],["delete",""]], + "<p>fo{}uz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<p>fo[o<ol><li>bar<li>baz</ol><p>q]uz", + [["defaultparagraphseparator","p"],["delete",""]], + "<p>fo{}uz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<ol><li>fo[o</ol><ol><li>b]ar</ol>", + [["delete",""]], + "<ol><li>fo{}ar</li></ol>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<ol><li>fo[o</ol><ul><li>b]ar</ul>", + [["delete",""]], + "<ol><li>fo{}ar</li></ol>", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo[<ol><li>]bar</ol>", + [["delete",""]], + "foo{}bar", + [true], + {"delete":[false,false,"",false,false,""]}], +["<ol><li>foo[<li>]bar</ol>", + [["delete",""]], + "<ol><li>foo{}bar</li></ol>", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo[<dl><dt>]bar<dd>baz</dl>", + [["delete",""]], + "foo{}bar<dl><dd>baz</dd></dl>", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo[<dl><dd>]bar</dl>", + [["delete",""]], + "foo{}bar", + [true], + {"delete":[false,false,"",false,false,""]}], +["<dl><dt>foo[<dd>]bar</dl>", + [["delete",""]], + "<dl><dt>foo{}bar</dt></dl>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<dl><dt>foo[<dt>]bar<dd>baz</dl>", + [["delete",""]], + "<dl><dt>foo{}bar</dt><dd>baz</dd></dl>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<dl><dt>foo<dd>bar[<dd>]baz</dl>", + [["delete",""]], + "<dl><dt>foo</dt><dd>bar{}baz</dd></dl>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<b>foo [ </b>bar]", + [["delete",""]], + "<b>foo []</b>", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<b> [ bar]</b>", + [["delete",""]], + "foo<b> []</b>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<b>[foo ] </b>bar", + [["delete",""]], + "<b>{} </b>bar", + [true], + {"delete":[false,false,"",false,false,""]}], +["[foo<b> ] bar</b>", + [["delete",""]], + "{}<b> bar</b>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<p style=display:inline>fo[o<p style=display:inline>b]ar", + [["delete",""]], + "<p style=\"display:inline\">fo[]</p><p style=\"display:inline\">ar</p>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<span style=display:block>fo[o</span><span style=display:block>b]ar</span>", + [["stylewithcss","true"],["delete",""]], + "<span style=\"display:block\">fo{}ar</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"delete":[false,false,"",false,false,""]}], +["<span style=display:block>fo[o</span><span style=display:block>b]ar</span>", + [["stylewithcss","false"],["delete",""]], + "<span style=\"display:block\">fo{}ar</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"delete":[false,false,"",false,false,""]}], +["<span style=display:inline-block>fo[o</span><span style=display:inline-block>b]ar</span>", + [["delete",""]], + "<span style=\"display:inline-block\">fo[]</span><span style=\"display:inline-block\">ar</span>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<span style=display:inline-table>fo[o</span><span style=display:inline-table>b]ar</span>", + [["delete",""]], + "<span style=\"display:inline-table\">fo[]</span><span style=\"display:inline-table\">ar</span>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<span style=display:none>fo[o</span><span style=display:none>b]ar</span>", + [["delete",""]], + "<span style=\"display:none\">fo[]</span><span style=\"display:none\">ar</span>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<quasit style=display:block>fo[o</quasit><quasit style=display:block>b]ar</quasit>", + [["stylewithcss","true"],["delete",""]], + "<quasit style=\"display:block\">fo{}ar</quasit>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"delete":[false,false,"",false,false,""]}], +["<quasit style=display:block>fo[o</quasit><quasit style=display:block>b]ar</quasit>", + [["stylewithcss","false"],["delete",""]], + "<quasit style=\"display:block\">fo{}ar</quasit>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"delete":[false,false,"",false,false,""]}], +["<ol><li>foo</ol>{}<br><ol><li>bar</ol>", + [["delete",""]], + "<ol><li>foo{}</li><li>bar</li></ol>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<ol><li>foo</ol><p>{}<br></p><ol><li>bar</ol>", + [["defaultparagraphseparator","div"],["delete",""]], + "<ol><li>foo{}</li><li>bar</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<ol><li>foo</ol><p>{}<br></p><ol><li>bar</ol>", + [["defaultparagraphseparator","p"],["delete",""]], + "<ol><li>foo{}</li><li>bar</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<ol><li><p>foo</ol><p>{}<br></p><ol><li>bar</ol>", + [["defaultparagraphseparator","div"],["delete",""]], + "<ol><li><p>foo{}</p></li><li>bar</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<ol><li><p>foo</ol><p>{}<br></p><ol><li>bar</ol>", + [["defaultparagraphseparator","p"],["delete",""]], + "<ol><li><p>foo{}</p></li><li>bar</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<ol id=a><li>foo</ol>{}<br><ol><li>bar</ol>", + [["delete",""]], + "<ol id=\"a\"><li>foo{}</li><li>bar</li></ol>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<ol><li>foo</ol>{}<br><ol id=b><li>bar</ol>", + [["delete",""]], + "<ol><li>foo{}</li><li>bar</li></ol>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<ol id=a><li>foo</ol>{}<br><ol id=b><li>bar</ol>", + [["delete",""]], + "<ol id=\"a\"><li>foo{}</li><li>bar</li></ol>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<ol class=a><li>foo</ol>{}<br><ol class=b><li>bar</ol>", + [["delete",""]], + "<ol class=\"a\"><li>foo{}</li><li>bar</li></ol>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<ol><ol><li>foo</ol><li>{}<br></li><ol><li>bar</ol></ol>", + [["delete",""]], + "<ol><ol><li>foo{}</li><li>bar</li></ol></ol>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<ol><li>foo[</ol>bar]<ol><li>baz</ol>", + [["delete",""]], + "<ol><li>foo{}</li><li>baz</li></ol>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<ol><li>foo[</ol><p>bar]<ol><li>baz</ol>", + [["defaultparagraphseparator","div"],["delete",""]], + "<ol><li>foo{}</li><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<ol><li>foo[</ol><p>bar]<ol><li>baz</ol>", + [["defaultparagraphseparator","p"],["delete",""]], + "<ol><li>foo{}</li><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<ol><li><p>foo[</ol><p>bar]<ol><li>baz</ol>", + [["defaultparagraphseparator","div"],["delete",""]], + "<ol><li><p>foo{}</p></li><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<ol><li><p>foo[</ol><p>bar]<ol><li>baz</ol>", + [["defaultparagraphseparator","p"],["delete",""]], + "<ol><li><p>foo{}</p></li><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<ol><li>foo[]</ol><ol><li>bar</ol>", + [["delete",""]], + "<ol><li>fo[]</li></ol><ol><li>bar</li></ol>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<ol><li>foo</ol>[bar<ol><li>]baz</ol>", + [["delete",""]], + "<ol><li>foo</li></ol>{}baz", + [true], + {"delete":[false,false,"",false,false,""]}], +["<ol><li>foo</ol><p>[bar<ol><li>]baz</ol>", + [["delete",""]], + "<ol><li>foo</li></ol><p>{}baz</p>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<ol><li>foo</ol><p>[bar<ol><li><p>]baz</ol>", + [["defaultparagraphseparator","div"],["delete",""]], + "<ol><li>foo</li></ol><p>{}baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<ol><li>foo</ol><p>[bar<ol><li><p>]baz</ol>", + [["defaultparagraphseparator","p"],["delete",""]], + "<ol><li>foo</li></ol><p>{}baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<ol><li>foo</ol><ol><li>b[]ar</ol>", + [["delete",""]], + "<ol><li>foo</li></ol><ol><li>{}ar</li></ol>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<ol><ol><li>foo[</ol><li>bar</ol>baz]<ol><li>quz</ol>", + [["delete",""]], + "<ol><ol><li>foo{}</li></ol><li>quz</li></ol>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<ul><li>foo</ul>{}<br><ul><li>bar</ul>", + [["delete",""]], + "<ul><li>foo{}</li><li>bar</li></ul>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<ul><li>foo</ul><p>{}<br></p><ul><li>bar</ul>", + [["defaultparagraphseparator","div"],["delete",""]], + "<ul><li>foo{}</li><li>bar</li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<ul><li>foo</ul><p>{}<br></p><ul><li>bar</ul>", + [["defaultparagraphseparator","p"],["delete",""]], + "<ul><li>foo{}</li><li>bar</li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<ol><li>foo[<li>bar]</ol><ol><li>baz</ol><ol><li>quz</ol>", + [["delete",""]], + "<ol><li>foo{}</li><li>baz</li><li>quz</li></ol>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<ol><li>foo</ol>{}<br><ul><li>bar</ul>", + [["delete",""]], + "<ol><li>foo{}</li></ol><ul><li>bar</li></ul>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<ol><li>foo</ol><p>{}<br></p><ul><li>bar</ul>", + [["defaultparagraphseparator","div"],["delete",""]], + "<ol><li>foo{}</li></ol><ul><li>bar</li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<ol><li>foo</ol><p>{}<br></p><ul><li>bar</ul>", + [["defaultparagraphseparator","p"],["delete",""]], + "<ol><li>foo{}</li></ol><ul><li>bar</li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<ul><li>foo</ul>{}<br><ol><li>bar</ol>", + [["delete",""]], + "<ul><li>foo{}</li></ul><ol><li>bar</li></ol>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<ul><li>foo</ul><p>{}<br></p><ol><li>bar</ol>", + [["defaultparagraphseparator","div"],["delete",""]], + "<ul><li>foo{}</li></ul><ol><li>bar</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], +["<ul><li>foo</ul><p>{}<br></p><ol><li>bar</ol>", + [["defaultparagraphseparator","p"],["delete",""]], + "<ul><li>foo{}</li></ul><ol><li>bar</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], +["<p><b>[foo]</b>", + [["delete",""]], + "<p>{}<br></p>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<p><quasit>[foo]</quasit>", + [["delete",""]], + "<p>{}<br></p>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<p><b><i>[foo]</i></b>", + [["delete",""]], + "<p>{}<br></p>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<p><b>{foo}</b>", + [["delete",""]], + "<p>{}<br></p>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<p>{<b>foo</b>}", + [["delete",""]], + "<p>{}<br></p>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<p><b>f[]</b>", + [["delete",""]], + "<p>{}<br></p>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<b>[foo]</b>", + [["delete",""]], + "{}<br>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div><b>[foo]</b></div>", + [["delete",""]], + "<div>{}<br></div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div><div><p>foo</p></div></div><div></div><div><div>[]bar</div></div></div>", + [["delete",""]], + "<div><div><p>foobar</p></div></div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div>foo</div><div></div><div>[]bar</div>", + [["delete",""]], + "<div>foobar</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div>foo</div><span></span><div>[]bar</div>", + [["delete",""]], + "<div>foobar</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div>foo</div><!-- comment --><div>[]bar</div>", + [["delete",""]], + "<div>foobar</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div> a[]bc</div>", + [["delete",""]], + "<div>bc</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div> a[]bc</div>", + [["delete",""]], + "<div>bc</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div> []abc</div>", + [["delete",""]], + "<div> abc</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div> [] abc</div>", + [["delete",""]], + "<div> abc</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div>abc</div><div> []def</div>", + [["delete",""]], + "<div>abcdef</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div>abc</div><div> [] def</div>", + [["delete",""]], + "<div>abcdef</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div>abc</div><div> []def</div>", + [["delete",""]], + "<div>abcdef</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div>abc </div><div>[]def</div>", + [["delete",""]], + "<div>abcdef</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div>abc </div><div>[]def</div>", + [["delete",""]], + "<div>abcdef</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div>abc </div><div> []def</div>", + [["delete",""]], + "<div>abcdef</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div>abc </div><div> [] def</div>", + [["delete",""]], + "<div>abcdef</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div>abc </div> <div> []def</div>", + [["delete",""]], + "<div>abcdef</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<img contenteditable=false src=/img/lion.svg>[]bar", + [["delete",""]], + "foo{}bar", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<span contenteditable=false>bar</span>[]baz", + [["delete",""]], + "foo{}baz", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<span contenteditable=false>bar</span><span contenteditable=false>baz</span>[]qux", + [["delete",""]], + "foo<span contenteditable=\"false\">bar</span>[]qux", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<span contenteditable=false><span>b</span><span>a</span><span>r</span></span>[]baz", + [["delete",""]], + "foo{}baz", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<div contenteditable=false>bar</div>[]baz", + [["delete",""]], + "foo{}baz", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<span contenteditable=false><b>bar</b></span>[]baz", + [["delete",""]], + "foo{}baz", + [true], + {"delete":[false,false,"",false,false,""]}], +["foo<span>bar<span contenteditable=false>baz</span></span>[]qux", + [["delete",""]], + "foo<span>bar{}</span>qux", + [true], + {"delete":[false,false,"",false,false,""]}], +["<span>[abc]</span>", + [["delete",""]], + "<br>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<span>[abc]</span><br>", + [["delete",""]], + "<br>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<p><span>[abc]</span></p>", + [["delete",""]], + "<p><br></p>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<p><span>[abc]</span><br></p>", + [["delete",""]], + "<p><br></p>", + [true], + {"delete":[false,false,"",false,false,""]}], +// XXX Perhaps, replacing with <br> element is better, but this is common behavior. +["<p contenteditable=false><span contenteditable=true>[abc]</span></p>", + [["delete",""]], + "<p contenteditable=\"false\"><span contenteditable=\"true\"></span></p>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div><div>{}<br></div></div>", + [["delete",""]], + ["", "<br>"], + [true], + {"delete":[false,false,"",false,false,""]}], +["<div><div contenteditable=false><div contenteditable><div>{}<br></div></div></div></div>", + [["delete",""]], + ["<div><div contenteditable=\"false\"><div contenteditable=\"\"></div></div></div>", + "<div><div contenteditable=\"false\"><div contenteditable=\"\"><br></div></div></div>"], + [true], + {"delete":[false,false,"",false,false,""]}], +["<div><div contenteditable=false><span contenteditable>{}<br></span></div></div></div>", + [["delete",""]], + ["<div><div contenteditable=\"false\"><span contenteditable=\"\"></span></div></div>", + "<div><div contenteditable=\"false\"><span contenteditable=\"\"><br></span></div></div>"], + [true], + {"delete":[false,false,"",false,false,""]}], +["<div style=white-space:pre>foo \n[]bar</div>", + [["delete",""]], + "<div style=\"white-space:pre\">foo []bar</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div style=white-space:pre>foo\n []bar</div>", + [["delete",""]], + "<div style=\"white-space:pre\">foo\n[]bar</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div style=white-space:pre>foo\n\n[]bar</div>", + [["delete",""]], + "<div style=\"white-space:pre\">foo\n[]bar</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div style=white-space:pre>foo\nb[]</div>", + [["delete",""]], + ["<div style=\"white-space:pre\">foo\n[]\n</div>", + "<div style=\"white-space:pre\">foo\n[]<br></div>"], + [true], + {"delete":[false,false,"",false,false,""]}], +["<div style=white-space:pre-wrap>foo \n[]bar</div>", + [["delete",""]], + "<div style=\"white-space:pre-wrap\">foo []bar</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div style=white-space:pre-wrap>foo\n []bar</div>", + [["delete",""]], + "<div style=\"white-space:pre-wrap\">foo\n[]bar</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div style=white-space:pre-wrap>foo\n\n[]bar</div>", + [["delete",""]], + "<div style=\"white-space:pre-wrap\">foo\n[]bar</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div style=white-space:pre-wrap>foo\nb[]</div>", + [["delete",""]], + ["<div style=\"white-space:pre-wrap\">foo\n[]\n</div>", + "<div style=\"white-space:pre-wrap\">foo\n[]<br></div>"], + [true], + {"delete":[false,false,"",false,false,""]}], +["<div style=white-space:pre-line>foo \n[]bar</div>", + [["delete",""]], + "<div style=\"white-space:pre-line\">foo[]bar</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div style=white-space:pre-line>foo\n []bar</div>", + [["delete",""]], + "<div style=\"white-space:pre-line\">foo[]bar</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div style=white-space:pre-line>foo\n\n[]bar</div>", + [["delete",""]], + "<div style=\"white-space:pre-line\">foo\n[]bar</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div style=white-space:pre-line>foo\nb[]</div>", + [["delete",""]], + ["<div style=\"white-space:pre-line\">foo\n[]\n</div>", + "<div style=\"white-space:pre-line\">foo\n[]<br></div>"], + [true], + {"delete":[false,false,"",false,false,""]}], +["<div style=white-space:nowrap>foo \n[]bar</div>", + [["delete",""]], + "<div style=\"white-space:nowrap\">foo[]bar</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div style=white-space:nowrap>foo\n []bar</div>", + [["delete",""]], + "<div style=\"white-space:nowrap\">foo[]bar</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div style=white-space:nowrap>foo\n\n[]bar</div>", + [["delete",""]], + "<div style=\"white-space:nowrap\">foo[]bar</div>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div style=white-space:nowrap>foo\nb[]</div>", + [["delete",""]], + ["<div style=\"white-space:nowrap\">foo[]\n</div>", + "<div style=\"white-space:nowrap\">foo[]<br></div>"], + [true], + {"delete":[false,false,"",false,false,""]}], +["<p contenteditable=\"false\"><span contenteditable>a[b]c</span></p>", + [["delete",""]], + "<p contenteditable=\"false\"><span contenteditable=\"\">ac</span></p>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<p contenteditable=\"false\"><unknown-element contenteditable>a[b]c</unknown-element></p>", + [["delete",""]], + "<p contenteditable=\"false\"><unknown-element contenteditable=\"\">ac</unknown-element></p>", + [true], + {"delete":[false,false,"",false,false,""]}], +// Although it seems that browsers should put <br> element to make the inline +// editing host has one-line height, but currently Blink and Firefox do not do +// it. +["<p contenteditable=\"false\"><span contenteditable>[abc]</span></p>", + [["delete",""]], + "<p contenteditable=\"false\"><span contenteditable=\"\"></span></p>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<p contenteditable=\"false\"><span contenteditable>a[bc<br>de]f</span></p>", + [["delete",""]], + ["<p contenteditable=\"false\"><span contenteditable=\"\">af</span></p>", + "<p contenteditable=\"false\"><span contenteditable=\"\">af<br></span></p>"], + [true], + {"delete":[false,false,"",false,false,""]}], +["<p contenteditable=\"false\"><unknown-element contenteditable>[abc]</unknown-element></p>", + [["delete",""]], + "<p contenteditable=\"false\"><unknown-element contenteditable=\"\"></unknown-element></p>", + [true], + {"delete":[false,false,"",false,false,""]}], +["<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p>[ab</p><p>c]d</p></custom-element></div>", + [["delete",""]], + ["<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p>d</p></custom-element></div>", + "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p>d<br></p></custom-element></div>"], + [true], + {"delete":[false,false,"",false,false,""]}], +["<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p>a[b</p><p>cd]</p></custom-element></div>", + [["delete",""]], + ["<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p>a</p></custom-element></div>", + "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p>a<br></p></custom-element></div>"], + [true], + {"delete":[false,false,"",false,false,""]}], +["<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p><b>[ab</b></p><p><i>c]d</i></p></custom-element></div>", + [["delete",""]], + ["<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p><i>d</i></p></custom-element></div>", + "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p><i>d</i><br></p></custom-element></div>"], + [true], + {"delete":[false,false,"",false,false,""]}], +["<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p><b>a[b</b></p><p><i>cd]</i></p></custom-element></div>", + [["delete",""]], + ["<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p><b>a</b></p></custom-element></div>", + "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p><b>a</b><br></p></custom-element></div>"], + [true], + {"delete":[false,false,"",false,false,""]}], + +// Non-editable elements in editable content should be removed by hitting the +// Backspace key. Delete the non-editable things, then, blocks should be +// merged. +["<p>abc</p><ul contenteditable=\"false\"><li>def</li></ul><p>[]ghi</p>", + [["delete",""]], + ["<p>abcghi</p>", + "<p>abcghi<br></p>"], + [true], + {"delete":[false,false,"",false,false,""]}], +["<p>abc</p><ul><li contenteditable=\"false\">def</li></ul><p>[]ghi</p>", + [["delete",""]], + ["<p>abcghi</p>", + "<p>abcghi<br></p>"], + [true], + {"delete":[false,false,"",false,false,""]}], +["<p>abc</p><ul><li contenteditable=\"false\">def</li><li>[]ghi</li></ul>", + [["delete",""]], + ["<p>abcghi</p>", + "<p>abcghi<br></p>"], + [true], + {"delete":[false,false,"",false,false,""]}], +["<ul><li>abc</li><li contenteditable=\"false\">def</li><li>[]ghi</li></ul>", + [["delete",""]], + ["<ul><li>abcghi</li></ul>", + "<ul><li>abcghi<br></li></ul>"], + [true], + {"delete":[false,false,"",false,false,""]}], +["<ul><li>abc</li><li contenteditable=\"false\">def</li></ul><p>[]ghi</p>", + [["delete",""]], + ["<ul><li>abcghi</li></ul>", + "<ul><li>abcghi<br></li></ul>"], + [true], + {"delete":[false,false,"",false,false,""]}], + +// <font>s shouldn't be joined if they have different attributes. +["<p><font color=blue>foo</font><p><font color=brown>[]bar</font>", + [["styleWithCSS","false"],["defaultparagraphseparator","div"],["delete",""]], + "<p><font color=\"blue\">foo[]</font><font color=\"brown\">bar</font></p>", + [true,true,true], + {"foreColor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}], +["<p><font color=blue>foo</font><p><font color=brown>[]bar</font>", + [["styleWithCSS","false"],["defaultparagraphseparator","p"],["delete",""]], + "<p><font color=\"blue\">foo[]</font><font color=\"brown\">bar</font></p>", + [true,true,true], + {"foreColor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}], +["<p><font size=3>foo</font><p><font size=5>[]bar</font>", + [["styleWithCSS","false"],["defaultparagraphseparator","div"],["delete",""]], + "<p><font size=\"3\">foo[]</font><font size=\"5\">bar</font></p>", + [true,true,true], + {"fontSize":[false,false,"5",false,false,"3"]}], +["<p><font size=3>foo</font><p><font size=5>[]bar</font>", + [["styleWithCSS","false"],["defaultparagraphseparator","p"],["delete",""]], + "<p><font size=\"3\">foo[]</font><font size=\"5\">bar</font></p>", + [true,true,true], + {"fontSize":[false,false,"5",false,false,"3"]}], +["<p><font size=4>foo</font><p><font size=5>[]bar</font>", + [["styleWithCSS","false"],["defaultparagraphseparator","div"],["delete",""]], + "<p><font size=\"4\">foo[]</font><font size=\"5\">bar</font></p>", + [true,true,true], + {"fontSize":[false,false,"5",false,false,"4"]}], +["<p><font size=4>foo</font><p><font size=5>[]bar</font>", + [["styleWithCSS","false"],["defaultparagraphseparator","p"],["delete",""]], + "<p><font size=\"4\">foo[]</font><font size=\"5\">bar</font></p>", + [true,true,true], + {"fontSize":[false,false,"5",false,false,"4"]}], +["<p><font color=blue>foo</font><p><font size=5>[]bar</font>", + [["styleWithCSS","false"],["defaultparagraphseparator","div"],["delete",""]], + "<p><font color=\"blue\">foo[]</font><font size=\"5\">bar</font></p>", + [true,true,true], + {"fontSize":[false,false,"5",false,false,"3"],"foreColor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["<p><font color=blue>foo</font><p><font size=5>[]bar</font>", + [["styleWithCSS","false"],["defaultparagraphseparator","p"],["delete",""]], + "<p><font color=\"blue\">foo[]</font><font size=\"5\">bar</font></p>", + [true,true,true], + {"fontSize":[false,false,"5",false,false,"3"],"foreColor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["<p><font size=5>foo</font><p><font color=blue>[]bar</font>", + [["styleWithCSS","false"],["defaultparagraphseparator","div"],["delete",""]], + "<p><font size=\"5\">foo[]</font><font color=\"blue\">bar</font></p>", + [true,true,true], + {"fontSize":[false,false,"3",false,false,"5"],"foreColor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 0)"]}], +["<p><font size=5>foo</font><p><font color=blue>[]bar</font>", + [["styleWithCSS","false"],["defaultparagraphseparator","p"],["delete",""]], + "<p><font size=\"5\">foo[]</font><font color=\"blue\">bar</font></p>", + [true,true,true], + {"fontSize":[false,false,"3",false,false,"5"],"foreColor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 0)"]}], +["<p><font face=monospace>foo</font><p><font face=sans-serif>[]bar</font>", + [["styleWithCSS","false"],["defaultparagraphseparator","div"],["delete",""]], + "<p><font face=\"monospace\">foo[]</font><font face=\"sans-serif\">bar</font></p>", + [true,true,true], + {"fontName":[false,false,"sans-serif",false,false,"monospace"]}], +["<p><font face=monospace>foo</font><p><font face=sans-serif>[]bar</font>", + [["styleWithCSS","false"],["defaultparagraphseparator","p"],["delete",""]], + "<p><font face=\"monospace\">foo[]</font><font face=\"sans-serif\">bar</font></p>", + [true,true,true], + {"fontName":[false,false,"sans-serif",false,false,"monospace"]}], + +// After joining blocks, caret should be end of the deepest left block end for +// making the following input will be styled with the style there. +["<p><span style=\"color:rgb(0, 0, 255)\">foo</span></p><p><span style=\"color:rgb(255, 0, 0)\">[]bar</span></p>", + [["styleWithCSS","false"],["delete",""]], + "<p><span style=\"color:rgb(0, 0, 255)\">foo[]</span><span style=\"color:rgb(255, 0, 0)\">bar</span></p>", + [true,true], + {"foreColor":[false,false,"rgb(255, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["<p><span style=\"color:rgb(0, 0, 255)\">foo</span><br></p><p><span style=\"color:rgb(255, 0, 0)\">[]bar</span></p>", + [["styleWithCSS","false"],["delete",""]], + "<p><span style=\"color:rgb(0, 0, 255)\">foo[]</span><span style=\"color:rgb(255, 0, 0)\">bar</span></p>", + [true,true], + {"foreColor":[false,false,"rgb(255, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["<p><span style=\"color:rgb(0, 0, 255)\">foo<br></span></p><p><span style=\"color:rgb(255, 0, 0)\">[]bar</span></p>", + [["styleWithCSS","false"],["delete",""]], + "<p><span style=\"color:rgb(0, 0, 255)\">foo[]</span><span style=\"color:rgb(255, 0, 0)\">bar</span></p>", + [true,true], + {"foreColor":[false,false,"rgb(255, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["<p><span style=\"color:rgb(0, 0, 255)\">foo</span></p><span style=\"color:rgb(255, 0, 0)\">[]bar</span>", + [["styleWithCSS","false"],["delete",""]], + "<p><span style=\"color:rgb(0, 0, 255)\">foo[]</span><span style=\"color:rgb(255, 0, 0)\">bar</span></p>", + [true,true], + {"foreColor":[false,false,"rgb(255, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["<p><span style=\"color:rgb(0, 0, 255)\">foo</span><br></p><span style=\"color:rgb(255, 0, 0)\">[]bar</span>", + [["styleWithCSS","false"],["delete",""]], + "<p><span style=\"color:rgb(0, 0, 255)\">foo[]</span><span style=\"color:rgb(255, 0, 0)\">bar</span></p>", + [true,true], + {"foreColor":[false,false,"rgb(255, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["<p><span style=\"color:rgb(0, 0, 255)\">foo<br></span></p><span style=\"color:rgb(255, 0, 0)\">[]bar</span>", + [["styleWithCSS","false"],["delete",""]], + "<p><span style=\"color:rgb(0, 0, 255)\">foo[]</span><span style=\"color:rgb(255, 0, 0)\">bar</span></p>", + [true,true], + {"foreColor":[false,false,"rgb(255, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["<span style=\"color:rgb(0, 0, 255)\">foo</span><br><p><span style=\"color:rgb(255, 0, 0)\">[]bar</span></p>", + [["styleWithCSS","false"],["delete",""]], + "<span style=\"color:rgb(0, 0, 255)\">foo[]</span><span style=\"color:rgb(255, 0, 0)\">bar</span>", + [true,true], + {"foreColor":[false,false,"rgb(255, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["<span style=\"color:rgb(0, 0, 255)\">foo<br></span><p><span style=\"color:rgb(255, 0, 0)\">[]bar</span></p>", + [["styleWithCSS","false"],["delete",""]], + "<span style=\"color:rgb(0, 0, 255)\">foo[]</span><span style=\"color:rgb(255, 0, 0)\">bar</span>", + [true,true], + {"foreColor":[false,false,"rgb(255, 0, 0)",false,false,"rgb(0, 0, 255)"]}], + +// If all list items are selected, keep one list item. +["<ul><li>[abc</li><li>def]</li></ul>", + [["delete",""]], + "<ul><li>{}<br></li></ul>", + [true], + {}], +["<ul><ol><li>[abc</li></ol><li>def]</li></ul>", + [["delete",""]], + "<ul><ol><li>{}<br></li></ol></ul>", + [true], + {}], +["<ul><ul><li>[abc</li></ul><li>def]</li></ul>", + [["delete",""]], + "<ul><ul><li>{}<br></li></ul></ul>", + [true], + {}], +["<ul><li>[abc</li><ul><li>def]</li></ul></ul>", + [["delete",""]], + "<ul><li>{}<br></li></ul>", + [true], + {}], +["<ul><ul><li>[abc</li></ul><ul><li>def]</li></ul></ul>", + [["delete",""]], + "<ul><ul><li>{}<br></li></ul></ul>", + [true], + {}], +["<ul><ol><li>[abc</li></ol><ul><li>def]</li></ul></ul>", + [["delete",""]], + "<ul><ol><li>{}<br></li></ol></ul>", + [true], + {}], +// Don't be confused at inner elements of the list items. +["<ul><li><span>[abc</span></li><li>def]</li></ul>", + [["delete",""]], + "<ul><li>{}<br></li></ul>", + [true], + {}], +["<ul><li>[abc</li><li><span>def]</span></li></ul>", + [["delete",""]], + "<ul><li>{}<br></li></ul>", + [true], + {}], +["<ul><li><span>[abc</span></li><li><span>def]</span></li></ul>", + [["delete",""]], + "<ul><li>{}<br></li></ul>", + [true], + {}], +// Don't be confused at white-spaces around first/last list items' boundaries. +["<ul><li> [abc</li><li>def]</li></ul>", + [["delete",""]], + "<ul><li>{}<br></li></ul>", + [true], + {}], +["<ul><li>[abc</li><li>def] </li></ul>", + [["delete",""]], + "<ul><li>{}<br></li></ul>", + [true], + {}], +["<ul><li> [abc</li><li>def] </li></ul>", + [["delete",""]], + "<ul><li>{}<br></li></ul>", + [true], + {}], +["<ul>\n<li>[abc</li><li>def]</li></ul>", + [["delete",""]], + ["<ul><li>{}<br></li></ul>", + "<ul>\n<li>{}<br></li></ul>"], + [true], + {}], +["<ul><li>[abc</li><li>def]</li>\n</ul>", + [["delete",""]], + ["<ul><li>{}<br></li></ul>", + "<ul><li>{}<br></li>\n</ul>"], + [true], + {}], +["<ul>\n<li>[abc</li><li>def]</li>\n</ul>", + [["delete",""]], + ["<ul><li>{}<br></li></ul>", + "<ul>\n<li>{}<br></li></ul>", + "<ul><li>{}<br></li>\n</ul>", + "<ul>\n<li>{}<br></li>\n</ul>"], + [true], + {}], +// Same things for non-sub-lists. +["<ol><li>[abc</li></ol><ul><li>def]</li></ul>", + [["delete",""]], + "<ol><li>{}<br></li></ol>", + [true], + {}], +["<ol><li> [abc</li></ol><ul><li>def]</li></ul>", + [["delete",""]], + "<ol><li>{}<br></li></ol>", + [true], + {}], +["<ol>\n<li>[abc</li></ol><ul><li>def]</li></ul>", + [["delete",""]], + ["<ol><li>{}<br></li></ol>", + "<ol>\n<li>{}<br></li></ol>"], + [true], + {}], + +// Select all list item children when list items have multiple nodes. +["{<ul><li>abc<span>def</span>ghi</li><li>jkl<span>opq</span>rst</li></ul>}", + [["delete",""]], + "<ul><li>{}<br></li></ul>", + [true], + {}], + +// inlined elements shouldn't be joined as <span>, etc +["<div style=\"display:inline\">abc</div><div style=\"display:inline\">[]def</div>", + [["delete",""]], + "<div style=\"display:inline\">ab</div><div style=\"display:inline\">def</div>", + [true], + {}], +["<ul><li style=\"display:inline\">abc</li><li style=\"display:inline\">[]def</li></ul>", + [["delete",""]], + "<ul><li style=\"display:inline\">ab</li><li style=\"display:inline\">def</li></ul>", + [true], + {}], +["<dl><dt style=\"display:inline\">abc</dt><dd style=\"display:inline\">[]def</dd></dl>", + [["delete",""]], + "<dl><dt style=\"display:inline\">ab</dt><dd style=\"display:inline\">def</dd></dl>", + [true], + {}], +// list-styled elements should work as list item elements +["<div><span style=\"display:list-item\">abc</span><span style=\"display:list-item\">[]def</span></div>", + [["delete",""]], + "<div><span style=\"display:list-item\">abcdef</span></div>", + [true], + {}], +// Don't remove parent blocks of selection start to insert new text into the +// selection start container. +["<div>{abc</div><div>def</div>}", + [["delete",""]], + "<div><br></div>", + [true], + {}], +["<div>abc</div><div>{def</div>}", + [["delete",""]], + "<div>abc</div><div><br></div>", + [true], + {}], +["<div style=display:flex><span>{abc</span><span>def</span>}</div>", + [["delete",""]], + "<div style=\"display:flex\"><span><br></span></div>", + [true], + {}], +["<div style=display:flex><span>abc</span><span>{def</span>}</div>", + [["delete",""]], + "<div style=\"display:flex\"><span>abc</span><span><br></span></div>", + [true], + {}], +["<div style=display:grid><span>{abc</span><span>def</span>}</div>", + [["delete",""]], + "<div style=\"display:grid\"><span><br></span></div>", + [true], + {}], +["<div style=display:grid><span>abc</span><span>{def</span>}</div>", + [["delete",""]], + "<div style=\"display:grid\"><span>abc</span><span><br></span></div>", + [true], + {}], +// Do not delete non-editable when deleting an editable character +["<b>X[]<span contenteditable=false>abc</span></b><i>def</i>", + [["delete",""]], + "<b><span contenteditable=\"false\">abc</span></b><i>def</i>", + [true], + {}], +["<b><span contenteditable=false>abc</span>X[]</b><i>def</i>", + [["delete",""]], + "<b><span contenteditable=\"false\">abc</span></b><i>def</i>", + [true], + {}], +["<p>X[]<span contenteditable=false>abc</span></p>", + [["delete",""]], + "<p><span contenteditable=\"false\">abc</span></p>", + [true], + {}], +["<p><span contenteditable=false>abc</span>X[]</p>", + [["delete",""]], + "<p><span contenteditable=\"false\">abc</span></p>", + [true], + {}], +// Do not delete ancestor blocks which still has non-editable content +["<p>{}<span contenteditable=false>ab</span></p>", + [["delete",""]], + "<p><span contenteditable=\"false\">ab</span></p>", + [true], + {}], +] diff --git a/testing/web-platform/tests/editing/data/fontname.js b/testing/web-platform/tests/editing/data/fontname.js new file mode 100644 index 0000000000..8c34a5a759 --- /dev/null +++ b/testing/web-platform/tests/editing/data/fontname.js @@ -0,0 +1,753 @@ +// For documentation of the format, see README in this directory. +var browserTests = [ +["foo[]bar", + [["fontname","sans-serif"]], + "foo[]bar", + [true], + {"fontname":[false,false,"serif",false,false,"sans-serif"]}], +["<p>[foo</p> <p>bar]</p>", + [["stylewithcss","true"],["fontname","sans-serif"]], + "<p><span style=\"font-family:sans-serif\">[foo</span></p> <p><span style=\"font-family:sans-serif\">bar]</span></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"serif",false,false,"sans-serif"]}], +["<p>[foo</p> <p>bar]</p>", + [["stylewithcss","false"],["fontname","sans-serif"]], + "<p><font face=\"sans-serif\">[foo</font></p> <p><font face=\"sans-serif\">bar]</font></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"serif",false,false,"sans-serif"]}], +["<span>[foo</span> <span>bar]</span>", + [["stylewithcss","true"],["fontname","sans-serif"]], + "<span style=\"font-family:sans-serif\"><span>[foo</span> <span>bar]</span></span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"serif",false,false,"sans-serif"]}], +["<span>[foo</span> <span>bar]</span>", + [["stylewithcss","false"],["fontname","sans-serif"]], + "<font face=\"sans-serif\"><span>[foo</span> <span>bar]</span></font>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"serif",false,false,"sans-serif"]}], +["<p>[foo</p><p> <span>bar</span> </p><p>baz]</p>", + [["stylewithcss","true"],["fontname","sans-serif"]], + "<p><span style=\"font-family:sans-serif\">[foo</span></p><p> <span style=\"font-family:sans-serif\"><span>bar</span></span> </p><p><span style=\"font-family:sans-serif\">baz]</span></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"serif",false,false,"sans-serif"]}], +["<p>[foo</p><p> <span>bar</span> </p><p>baz]</p>", + [["stylewithcss","false"],["fontname","sans-serif"]], + "<p><font face=\"sans-serif\">[foo</font></p><p> <font face=\"sans-serif\"><span>bar</span></font> </p><p><font face=\"sans-serif\">baz]</font></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"serif",false,false,"sans-serif"]}], +["<p>[foo<p><br><p>bar]", + [["stylewithcss","true"],["fontname","sans-serif"]], + "<p><span style=\"font-family:sans-serif\">[foo</span></p><p><span style=\"font-family:sans-serif\"><br></span></p><p><span style=\"font-family:sans-serif\">bar]</span></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"serif",false,false,"sans-serif"]}], +["<p>[foo<p><br><p>bar]", + [["stylewithcss","false"],["fontname","sans-serif"]], + "<p><font face=\"sans-serif\">[foo</font></p><p><font face=\"sans-serif\"><br></font></p><p><font face=\"sans-serif\">bar]</font></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"serif",false,false,"sans-serif"]}], +["<b>foo[]bar</b>", + [["fontname","sans-serif"]], + "<b>foo[]bar</b>", + [true], + {"fontname":[false,false,"serif",false,false,"sans-serif"]}], +["<i>foo[]bar</i>", + [["fontname","sans-serif"]], + "<i>foo[]bar</i>", + [true], + {"fontname":[false,false,"serif",false,false,"sans-serif"]}], +["<span>foo</span>{}<span>bar</span>", + [["fontname","sans-serif"]], + "<span>foo</span>{}<span>bar</span>", + [true], + {"fontname":[false,false,"serif",false,false,"sans-serif"]}], +["<span>foo[</span><span>]bar</span>", + [["fontname","sans-serif"]], + "<span>foo[</span><span>]bar</span>", + [true], + {"fontname":[false,false,"serif",false,false,"sans-serif"]}], +["foo[bar]baz", + [["stylewithcss","true"],["fontname","sans-serif"]], + "foo<span style=\"font-family:sans-serif\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"serif",false,false,"sans-serif"]}], +["foo[bar]baz", + [["stylewithcss","false"],["fontname","sans-serif"]], + "foo<font face=\"sans-serif\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"serif",false,false,"sans-serif"]}], +["foo[bar<b>baz]qoz</b>quz", + [["stylewithcss","true"],["fontname","sans-serif"]], + "foo<span style=\"font-family:sans-serif\">[bar</span><b><span style=\"font-family:sans-serif\">baz]</span>qoz</b>quz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"serif",false,false,"sans-serif"]}], +["foo[bar<b>baz]qoz</b>quz", + [["stylewithcss","false"],["fontname","sans-serif"]], + "foo<font face=\"sans-serif\">[bar</font><b><font face=\"sans-serif\">baz]</font>qoz</b>quz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"serif",false,false,"sans-serif"]}], +["foo[bar<i>baz]qoz</i>quz", + [["stylewithcss","true"],["fontname","sans-serif"]], + "foo<span style=\"font-family:sans-serif\">[bar</span><i><span style=\"font-family:sans-serif\">baz]</span>qoz</i>quz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"serif",false,false,"sans-serif"]}], +["foo[bar<i>baz]qoz</i>quz", + [["stylewithcss","false"],["fontname","sans-serif"]], + "foo<font face=\"sans-serif\">[bar</font><i><font face=\"sans-serif\">baz]</font>qoz</i>quz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"serif",false,false,"sans-serif"]}], +["{<p><p> <p>foo</p>}", + [["stylewithcss","true"],["fontname","sans-serif"]], + "{<p></p><p> </p><p><span style=\"font-family:sans-serif\">foo</span></p>}", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"serif",false,false,"sans-serif"]}], +["{<p><p> <p>foo</p>}", + [["stylewithcss","false"],["fontname","sans-serif"]], + "{<p></p><p> </p><p><font face=\"sans-serif\">foo</font></p>}", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"serif",false,false,"sans-serif"]}], +["<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>", + [["stylewithcss","true"],["fontname","sans-serif"]], + "<table><tbody><tr><td>foo</td><td>b<span style=\"font-family:sans-serif\">[a]</span>r</td><td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"serif",false,false,"sans-serif"]}], +["<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>", + [["stylewithcss","false"],["fontname","sans-serif"]], + "<table><tbody><tr><td>foo</td><td>b<font face=\"sans-serif\">[a]</font>r</td><td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"serif",false,false,"sans-serif"]}], +["<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table>", + [["stylewithcss","true"],["fontname","sans-serif"]], + "<table><tbody><tr><td>foo</td>{<td><span style=\"font-family:sans-serif\">bar</span></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"serif",false,false,"sans-serif"]}], +["<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table>", + [["stylewithcss","false"],["fontname","sans-serif"]], + "<table><tbody><tr><td>foo</td>{<td><font face=\"sans-serif\">bar</font></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"serif",false,false,"sans-serif"]}], +["<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table>", + [["stylewithcss","true"],["fontname","sans-serif"]], + "<table><tbody><tr>{<td><span style=\"font-family:sans-serif\">foo</span></td><td><span style=\"font-family:sans-serif\">bar</span></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"serif",false,false,"sans-serif"]}], +["<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table>", + [["stylewithcss","false"],["fontname","sans-serif"]], + "<table><tbody><tr>{<td><font face=\"sans-serif\">foo</font></td><td><font face=\"sans-serif\">bar</font></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"serif",false,false,"sans-serif"]}], +["<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>", + [["stylewithcss","true"],["fontname","sans-serif"]], + "<table><tbody>{<tr><td><span style=\"font-family:sans-serif\">foo</span></td><td><span style=\"font-family:sans-serif\">bar</span></td><td><span style=\"font-family:sans-serif\">baz</span></td></tr>}</tbody></table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"serif",false,false,"sans-serif"]}], +["<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>", + [["stylewithcss","false"],["fontname","sans-serif"]], + "<table><tbody>{<tr><td><font face=\"sans-serif\">foo</font></td><td><font face=\"sans-serif\">bar</font></td><td><font face=\"sans-serif\">baz</font></td></tr>}</tbody></table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"serif",false,false,"sans-serif"]}], +["<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>", + [["stylewithcss","true"],["fontname","sans-serif"]], + "<table>{<tbody><tr><td><span style=\"font-family:sans-serif\">foo</span></td><td><span style=\"font-family:sans-serif\">bar</span></td><td><span style=\"font-family:sans-serif\">baz</span></td></tr></tbody>}</table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"serif",false,false,"sans-serif"]}], +["<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>", + [["stylewithcss","false"],["fontname","sans-serif"]], + "<table>{<tbody><tr><td><font face=\"sans-serif\">foo</font></td><td><font face=\"sans-serif\">bar</font></td><td><font face=\"sans-serif\">baz</font></td></tr></tbody>}</table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"serif",false,false,"sans-serif"]}], +["{<table><tr><td>foo<td>bar<td>baz</table>}", + [["stylewithcss","true"],["fontname","sans-serif"]], + "{<table><tbody><tr><td><span style=\"font-family:sans-serif\">foo</span></td><td><span style=\"font-family:sans-serif\">bar</span></td><td><span style=\"font-family:sans-serif\">baz</span></td></tr></tbody></table>}", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"serif",false,false,"sans-serif"]}], +["{<table><tr><td>foo<td>bar<td>baz</table>}", + [["stylewithcss","false"],["fontname","sans-serif"]], + "{<table><tbody><tr><td><font face=\"sans-serif\">foo</font></td><td><font face=\"sans-serif\">bar</font></td><td><font face=\"sans-serif\">baz</font></td></tr></tbody></table>}", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"serif",false,false,"sans-serif"]}], +["foo<code>[bar]</code>baz", + [["stylewithcss","true"],["fontname","sans-serif"]], + "foo<code><span style=\"font-family:sans-serif\">[bar]</span></code>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["foo<code>[bar]</code>baz", + [["stylewithcss","false"],["fontname","sans-serif"]], + "foo<code><font face=\"sans-serif\">[bar]</font></code>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["foo<kbd>[bar]</kbd>baz", + [["stylewithcss","true"],["fontname","sans-serif"]], + "foo<kbd><span style=\"font-family:sans-serif\">[bar]</span></kbd>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["foo<kbd>[bar]</kbd>baz", + [["stylewithcss","false"],["fontname","sans-serif"]], + "foo<kbd><font face=\"sans-serif\">[bar]</font></kbd>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["foo<listing>[bar]</listing>baz", + [["stylewithcss","true"],["fontname","sans-serif"]], + "foo<listing><span style=\"font-family:sans-serif\">[bar]</span></listing>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["foo<listing>[bar]</listing>baz", + [["stylewithcss","false"],["fontname","sans-serif"]], + "foo<listing><font face=\"sans-serif\">[bar]</font></listing>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["foo<pre>[bar]</pre>baz", + [["stylewithcss","true"],["fontname","sans-serif"]], + "foo<pre><span style=\"font-family:sans-serif\">[bar]</span></pre>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["foo<pre>[bar]</pre>baz", + [["stylewithcss","false"],["fontname","sans-serif"]], + "foo<pre><font face=\"sans-serif\">[bar]</font></pre>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["foo<samp>[bar]</samp>baz", + [["stylewithcss","true"],["fontname","sans-serif"]], + "foo<samp><span style=\"font-family:sans-serif\">[bar]</span></samp>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["foo<samp>[bar]</samp>baz", + [["stylewithcss","false"],["fontname","sans-serif"]], + "foo<samp><font face=\"sans-serif\">[bar]</font></samp>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["foo<tt>[bar]</tt>baz", + [["stylewithcss","true"],["fontname","sans-serif"]], + "foo<tt><span style=\"font-family:sans-serif\">[bar]</span></tt>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["foo<tt>[bar]</tt>baz", + [["stylewithcss","false"],["fontname","sans-serif"]], + "foo<tt><font face=\"sans-serif\">[bar]</font></tt>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["foo<code>b[a]r</code>baz", + [["stylewithcss","true"],["fontname","sans-serif"]], + "foo<code>b<span style=\"font-family:sans-serif\">[a]</span>r</code>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["foo<code>b[a]r</code>baz", + [["stylewithcss","false"],["fontname","sans-serif"]], + "foo<code>b<font face=\"sans-serif\">[a]</font>r</code>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["foo<kbd>b[a]r</kbd>baz", + [["stylewithcss","true"],["fontname","sans-serif"]], + "foo<kbd>b<span style=\"font-family:sans-serif\">[a]</span>r</kbd>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["foo<kbd>b[a]r</kbd>baz", + [["stylewithcss","false"],["fontname","sans-serif"]], + "foo<kbd>b<font face=\"sans-serif\">[a]</font>r</kbd>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["foo<listing>b[a]r</listing>baz", + [["stylewithcss","true"],["fontname","sans-serif"]], + "foo<listing>b<span style=\"font-family:sans-serif\">[a]</span>r</listing>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["foo<listing>b[a]r</listing>baz", + [["stylewithcss","false"],["fontname","sans-serif"]], + "foo<listing>b<font face=\"sans-serif\">[a]</font>r</listing>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["foo<pre>b[a]r</pre>baz", + [["stylewithcss","true"],["fontname","sans-serif"]], + "foo<pre>b<span style=\"font-family:sans-serif\">[a]</span>r</pre>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["foo<pre>b[a]r</pre>baz", + [["stylewithcss","false"],["fontname","sans-serif"]], + "foo<pre>b<font face=\"sans-serif\">[a]</font>r</pre>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["foo<samp>b[a]r</samp>baz", + [["stylewithcss","true"],["fontname","sans-serif"]], + "foo<samp>b<span style=\"font-family:sans-serif\">[a]</span>r</samp>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["foo<samp>b[a]r</samp>baz", + [["stylewithcss","false"],["fontname","sans-serif"]], + "foo<samp>b<font face=\"sans-serif\">[a]</font>r</samp>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["foo<tt>b[a]r</tt>baz", + [["stylewithcss","true"],["fontname","sans-serif"]], + "foo<tt>b<span style=\"font-family:sans-serif\">[a]</span>r</tt>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["foo<tt>b[a]r</tt>baz", + [["stylewithcss","false"],["fontname","sans-serif"]], + "foo<tt>b<font face=\"sans-serif\">[a]</font>r</tt>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["[foo<code>bar</code>baz]", + [["stylewithcss","true"],["fontname","sans-serif"]], + "<span style=\"font-family:sans-serif\">[foo<code><span style=\"font-family:sans-serif\">bar</span></code>baz]</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}], +["[foo<code>bar</code>baz]", + [["stylewithcss","false"],["fontname","sans-serif"]], + "<font face=\"sans-serif\">[foo<code><font face=\"sans-serif\">bar</font></code>baz]</font>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}], +["[foo<kbd>bar</kbd>baz]", + [["stylewithcss","true"],["fontname","sans-serif"]], + "<span style=\"font-family:sans-serif\">[foo<kbd><span style=\"font-family:sans-serif\">bar</span></kbd>baz]</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}], +["[foo<kbd>bar</kbd>baz]", + [["stylewithcss","false"],["fontname","sans-serif"]], + "<font face=\"sans-serif\">[foo<kbd><font face=\"sans-serif\">bar</font></kbd>baz]</font>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}], +["[foo<listing>bar</listing>baz]", + [["stylewithcss","true"],["fontname","sans-serif"]], + "<span style=\"font-family:sans-serif\">[foo</span><listing><span style=\"font-family:sans-serif\">bar</span></listing><span style=\"font-family:sans-serif\">baz]</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}], +["[foo<listing>bar</listing>baz]", + [["stylewithcss","false"],["fontname","sans-serif"]], + "<font face=\"sans-serif\">[foo</font><listing><font face=\"sans-serif\">bar</font></listing><font face=\"sans-serif\">baz]</font>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}], +["[foo<pre>bar</pre>baz]", + [["stylewithcss","true"],["fontname","sans-serif"]], + "<span style=\"font-family:sans-serif\">[foo</span><pre><span style=\"font-family:sans-serif\">bar</span></pre><span style=\"font-family:sans-serif\">baz]</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}], +["[foo<pre>bar</pre>baz]", + [["stylewithcss","false"],["fontname","sans-serif"]], + "<font face=\"sans-serif\">[foo</font><pre><font face=\"sans-serif\">bar</font></pre><font face=\"sans-serif\">baz]</font>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}], +["[foo<samp>bar</samp>baz]", + [["stylewithcss","true"],["fontname","sans-serif"]], + "<span style=\"font-family:sans-serif\">[foo<samp><span style=\"font-family:sans-serif\">bar</span></samp>baz]</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}], +["[foo<samp>bar</samp>baz]", + [["stylewithcss","false"],["fontname","sans-serif"]], + "<font face=\"sans-serif\">[foo<samp><font face=\"sans-serif\">bar</font></samp>baz]</font>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}], +["[foo<tt>bar</tt>baz]", + [["stylewithcss","true"],["fontname","sans-serif"]], + "<span style=\"font-family:sans-serif\">[foo<tt><span style=\"font-family:sans-serif\">bar</span></tt>baz]</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}], +["[foo<tt>bar</tt>baz]", + [["stylewithcss","false"],["fontname","sans-serif"]], + "<font face=\"sans-serif\">[foo<tt><font face=\"sans-serif\">bar</font></tt>baz]</font>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}], +["[foo<code>ba]r</code>baz", + [["stylewithcss","true"],["fontname","sans-serif"]], + "<span style=\"font-family:sans-serif\">[foo</span><code><span style=\"font-family:sans-serif\">ba]</span>r</code>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}], +["[foo<code>ba]r</code>baz", + [["stylewithcss","false"],["fontname","sans-serif"]], + "<font face=\"sans-serif\">[foo</font><code><font face=\"sans-serif\">ba]</font>r</code>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}], +["[foo<kbd>ba]r</kbd>baz", + [["stylewithcss","true"],["fontname","sans-serif"]], + "<span style=\"font-family:sans-serif\">[foo</span><kbd><span style=\"font-family:sans-serif\">ba]</span>r</kbd>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}], +["[foo<kbd>ba]r</kbd>baz", + [["stylewithcss","false"],["fontname","sans-serif"]], + "<font face=\"sans-serif\">[foo</font><kbd><font face=\"sans-serif\">ba]</font>r</kbd>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}], +["[foo<listing>ba]r</listing>baz", + [["stylewithcss","true"],["fontname","sans-serif"]], + "<span style=\"font-family:sans-serif\">[foo</span><listing><span style=\"font-family:sans-serif\">ba]</span>r</listing>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}], +["[foo<listing>ba]r</listing>baz", + [["stylewithcss","false"],["fontname","sans-serif"]], + "<font face=\"sans-serif\">[foo</font><listing><font face=\"sans-serif\">ba]</font>r</listing>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}], +["[foo<pre>ba]r</pre>baz", + [["stylewithcss","true"],["fontname","sans-serif"]], + "<span style=\"font-family:sans-serif\">[foo</span><pre><span style=\"font-family:sans-serif\">ba]</span>r</pre>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}], +["[foo<pre>ba]r</pre>baz", + [["stylewithcss","false"],["fontname","sans-serif"]], + "<font face=\"sans-serif\">[foo</font><pre><font face=\"sans-serif\">ba]</font>r</pre>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}], +["[foo<samp>ba]r</samp>baz", + [["stylewithcss","true"],["fontname","sans-serif"]], + "<span style=\"font-family:sans-serif\">[foo</span><samp><span style=\"font-family:sans-serif\">ba]</span>r</samp>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}], +["[foo<samp>ba]r</samp>baz", + [["stylewithcss","false"],["fontname","sans-serif"]], + "<font face=\"sans-serif\">[foo</font><samp><font face=\"sans-serif\">ba]</font>r</samp>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}], +["[foo<tt>ba]r</tt>baz", + [["stylewithcss","true"],["fontname","sans-serif"]], + "<span style=\"font-family:sans-serif\">[foo</span><tt><span style=\"font-family:sans-serif\">ba]</span>r</tt>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}], +["[foo<tt>ba]r</tt>baz", + [["stylewithcss","false"],["fontname","sans-serif"]], + "<font face=\"sans-serif\">[foo</font><tt><font face=\"sans-serif\">ba]</font>r</tt>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}], +["foo<code>b[ar</code>baz]", + [["stylewithcss","true"],["fontname","sans-serif"]], + "foo<code>b<span style=\"font-family:sans-serif\">[ar</span></code><span style=\"font-family:sans-serif\">baz]</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[true,false,"monospace",false,false,"sans-serif"]}], +["foo<code>b[ar</code>baz]", + [["stylewithcss","false"],["fontname","sans-serif"]], + "foo<code>b<font face=\"sans-serif\">[ar</font></code><font face=\"sans-serif\">baz]</font>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[true,false,"monospace",false,false,"sans-serif"]}], +["foo<kbd>b[ar</kbd>baz]", + [["stylewithcss","true"],["fontname","sans-serif"]], + "foo<kbd>b<span style=\"font-family:sans-serif\">[ar</span></kbd><span style=\"font-family:sans-serif\">baz]</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[true,false,"monospace",false,false,"sans-serif"]}], +["foo<kbd>b[ar</kbd>baz]", + [["stylewithcss","false"],["fontname","sans-serif"]], + "foo<kbd>b<font face=\"sans-serif\">[ar</font></kbd><font face=\"sans-serif\">baz]</font>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[true,false,"monospace",false,false,"sans-serif"]}], +["foo<listing>b[ar</listing>baz]", + [["stylewithcss","true"],["fontname","sans-serif"]], + "foo<listing>b<span style=\"font-family:sans-serif\">[ar</span></listing><span style=\"font-family:sans-serif\">baz]</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[true,false,"monospace",false,false,"sans-serif"]}], +["foo<listing>b[ar</listing>baz]", + [["stylewithcss","false"],["fontname","sans-serif"]], + "foo<listing>b<font face=\"sans-serif\">[ar</font></listing><font face=\"sans-serif\">baz]</font>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[true,false,"monospace",false,false,"sans-serif"]}], +["foo<pre>b[ar</pre>baz]", + [["stylewithcss","true"],["fontname","sans-serif"]], + "foo<pre>b<span style=\"font-family:sans-serif\">[ar</span></pre><span style=\"font-family:sans-serif\">baz]</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[true,false,"monospace",false,false,"sans-serif"]}], +["foo<pre>b[ar</pre>baz]", + [["stylewithcss","false"],["fontname","sans-serif"]], + "foo<pre>b<font face=\"sans-serif\">[ar</font></pre><font face=\"sans-serif\">baz]</font>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[true,false,"monospace",false,false,"sans-serif"]}], +["foo<samp>b[ar</samp>baz]", + [["stylewithcss","true"],["fontname","sans-serif"]], + "foo<samp>b<span style=\"font-family:sans-serif\">[ar</span></samp><span style=\"font-family:sans-serif\">baz]</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[true,false,"monospace",false,false,"sans-serif"]}], +["foo<samp>b[ar</samp>baz]", + [["stylewithcss","false"],["fontname","sans-serif"]], + "foo<samp>b<font face=\"sans-serif\">[ar</font></samp><font face=\"sans-serif\">baz]</font>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[true,false,"monospace",false,false,"sans-serif"]}], +["foo<tt>b[ar</tt>baz]", + [["stylewithcss","true"],["fontname","sans-serif"]], + "foo<tt>b<span style=\"font-family:sans-serif\">[ar</span></tt><span style=\"font-family:sans-serif\">baz]</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[true,false,"monospace",false,false,"sans-serif"]}], +["foo<tt>b[ar</tt>baz]", + [["stylewithcss","false"],["fontname","sans-serif"]], + "foo<tt>b<font face=\"sans-serif\">[ar</font></tt><font face=\"sans-serif\">baz]</font>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[true,false,"monospace",false,false,"sans-serif"]}], +["foo<span style=\"font-family: sans-serif\">[bar]</span>baz", + [["stylewithcss","true"],["fontname","sans-serif"]], + "foo<span style=\"font-family:sans-serif\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"sans-serif",false,false,"sans-serif"]}], +["foo<span style=\"font-family: sans-serif\">[bar]</span>baz", + [["stylewithcss","false"],["fontname","sans-serif"]], + "foo<font face=\"sans-serif\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"sans-serif",false,false,"sans-serif"]}], +["foo<span style=\"font-family: sans-serif\">b[a]r</span>baz", + [["fontname","sans-serif"]], + "foo<span style=\"font-family:sans-serif\">b[a]r</span>baz", + [true], + {"fontname":[false,false,"sans-serif",false,false,"sans-serif"]}], +["foo<span style=\"font-family: monospace\">[bar]</span>baz", + [["stylewithcss","true"],["fontname","sans-serif"]], + "foo<span style=\"font-family:sans-serif\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["foo<span style=\"font-family: monospace\">[bar]</span>baz", + [["stylewithcss","false"],["fontname","sans-serif"]], + "foo<font face=\"sans-serif\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["foo<span style=\"font-family: monospace\">b[a]r</span>baz", + [["stylewithcss","true"],["fontname","sans-serif"]], + "foo<span style=\"font-family:monospace\">b</span><span style=\"font-family:sans-serif\">[a]</span><span style=\"font-family:monospace\">r</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["foo<span style=\"font-family: monospace\">b[a]r</span>baz", + [["stylewithcss","false"],["fontname","sans-serif"]], + "foo<span style=\"font-family:monospace\">b</span><font face=\"sans-serif\">[a]</font><span style=\"font-family:monospace\">r</span>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["foo<tt contenteditable=false>ba[r</tt>b]az", + [["fontname","sans-serif"]], + "foo<tt contenteditable=\"false\">ba[r</tt>b]az", + [false], + {"fontname":[false,false,"serif",false,false,"serif"]}], +["fo[o<tt contenteditable=false>b]ar</tt>baz", + [["fontname","sans-serif"]], + "fo[o<tt contenteditable=\"false\">b]ar</tt>baz", + [false], + {"fontname":[false,false,"serif",false,false,"serif"]}], +["foo<tt>{}<br></tt>bar", + [["fontname","sans-serif"]], + "foo<tt>{}<br></tt>bar", + [true], + {"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["foo<tt>{<br></tt>}bar", + [["stylewithcss","true"],["fontname","sans-serif"]], + "foo<tt>{<span style=\"font-family:sans-serif\"><br></span></tt>}bar", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["foo<tt>{<br></tt>}bar", + [["stylewithcss","false"],["fontname","sans-serif"]], + "foo<tt>{<font face=\"sans-serif\"><br></font></tt>}bar", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["foo<tt>{<br></tt>b]ar", + [["stylewithcss","true"],["fontname","sans-serif"]], + "foo<tt>{<span style=\"font-family:sans-serif\"><br></span></tt><span style=\"font-family:sans-serif\">b]</span>ar", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[true,false,"monospace",false,false,"sans-serif"]}], +["foo<tt>{<br></tt>b]ar", + [["stylewithcss","false"],["fontname","sans-serif"]], + "foo<tt>{<font face=\"sans-serif\"><br></font></tt><font face=\"sans-serif\">b]</font>ar", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[true,false,"monospace",false,false,"sans-serif"]}], +["fo[o<span style=font-family:monospace>b]ar</span>baz", + [["stylewithcss","true"],["fontname","sans-serif"]], + "fo<span style=\"font-family:sans-serif\">[ob]</span><span style=\"font-family:monospace\">ar</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}], +["fo[o<span style=font-family:monospace>b]ar</span>baz", + [["stylewithcss","false"],["fontname","sans-serif"]], + "fo<font face=\"sans-serif\">[ob]</font><span style=\"font-family:monospace\">ar</span>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}], +["foo<span style=font-family:monospace>ba[r</span>b]az", + [["stylewithcss","true"],["fontname","sans-serif"]], + "foo<span style=\"font-family:monospace\">ba</span><span style=\"font-family:sans-serif\">[rb]</span>az", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[true,false,"monospace",false,false,"sans-serif"]}], +["foo<span style=font-family:monospace>ba[r</span>b]az", + [["stylewithcss","false"],["fontname","sans-serif"]], + "foo<span style=\"font-family:monospace\">ba</span><font face=\"sans-serif\">[rb]</font>az", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[true,false,"monospace",false,false,"sans-serif"]}], +["fo[o<span style=font-family:monospace>bar</span>b]az", + [["stylewithcss","true"],["fontname","sans-serif"]], + "fo<span style=\"font-family:sans-serif\">[obarb]</span>az", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}], +["fo[o<span style=font-family:monospace>bar</span>b]az", + [["stylewithcss","false"],["fontname","sans-serif"]], + "fo<font face=\"sans-serif\">[obarb]</font>az", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}], +["foo[<span style=font-family:monospace>b]ar</span>baz", + [["stylewithcss","true"],["fontname","sans-serif"]], + "foo<span style=\"font-family:sans-serif\">[b]</span><span style=\"font-family:monospace\">ar</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["foo[<span style=font-family:monospace>b]ar</span>baz", + [["stylewithcss","false"],["fontname","sans-serif"]], + "foo<font face=\"sans-serif\">[b]</font><span style=\"font-family:monospace\">ar</span>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["foo<span style=font-family:monospace>ba[r</span>]baz", + [["stylewithcss","true"],["fontname","sans-serif"]], + "foo<span style=\"font-family:monospace\">ba</span><span style=\"font-family:sans-serif\">[r]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["foo<span style=font-family:monospace>ba[r</span>]baz", + [["stylewithcss","false"],["fontname","sans-serif"]], + "foo<span style=\"font-family:monospace\">ba</span><font face=\"sans-serif\">[r]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["foo[<span style=font-family:monospace>bar</span>]baz", + [["stylewithcss","true"],["fontname","sans-serif"]], + "foo[<span style=\"font-family:sans-serif\">bar</span>]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["foo[<span style=font-family:monospace>bar</span>]baz", + [["stylewithcss","false"],["fontname","sans-serif"]], + "foo[<font face=\"sans-serif\">bar</font>]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["foo<span style=font-family:monospace>[bar]</span>baz", + [["stylewithcss","true"],["fontname","sans-serif"]], + "foo<span style=\"font-family:sans-serif\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["foo<span style=font-family:monospace>[bar]</span>baz", + [["stylewithcss","false"],["fontname","sans-serif"]], + "foo<font face=\"sans-serif\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["foo{<span style=font-family:monospace>bar</span>}baz", + [["stylewithcss","true"],["fontname","sans-serif"]], + "foo{<span style=\"font-family:sans-serif\">bar}</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["foo{<span style=font-family:monospace>bar</span>}baz", + [["stylewithcss","false"],["fontname","sans-serif"]], + "foo{<font face=\"sans-serif\">bar}</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["fo[o<code>b]ar</code>", + [["stylewithcss","true"],["fontname","sans-serif"]], + "fo<span style=\"font-family:sans-serif\">[o</span><code><span style=\"font-family:sans-serif\">b]</span>ar</code>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}], +["fo[o<code>b]ar</code>", + [["stylewithcss","false"],["fontname","sans-serif"]], + "fo<font face=\"sans-serif\">[o</font><code><font face=\"sans-serif\">b]</font>ar</code>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}], +["fo[o<kbd>b]ar</kbd>", + [["stylewithcss","true"],["fontname","sans-serif"]], + "fo<span style=\"font-family:sans-serif\">[o</span><kbd><span style=\"font-family:sans-serif\">b]</span>ar</kbd>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}], +["fo[o<kbd>b]ar</kbd>", + [["stylewithcss","false"],["fontname","sans-serif"]], + "fo<font face=\"sans-serif\">[o</font><kbd><font face=\"sans-serif\">b]</font>ar</kbd>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}], +["fo[o<listing>b]ar</listing>", + [["stylewithcss","true"],["fontname","sans-serif"]], + "fo<span style=\"font-family:sans-serif\">[o</span><listing><span style=\"font-family:sans-serif\">b]</span>ar</listing>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}], +["fo[o<listing>b]ar</listing>", + [["stylewithcss","false"],["fontname","sans-serif"]], + "fo<font face=\"sans-serif\">[o</font><listing><font face=\"sans-serif\">b]</font>ar</listing>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}], +["fo[o<pre>b]ar</pre>", + [["stylewithcss","true"],["fontname","sans-serif"]], + "fo<span style=\"font-family:sans-serif\">[o</span><pre><span style=\"font-family:sans-serif\">b]</span>ar</pre>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}], +["fo[o<pre>b]ar</pre>", + [["stylewithcss","false"],["fontname","sans-serif"]], + "fo<font face=\"sans-serif\">[o</font><pre><font face=\"sans-serif\">b]</font>ar</pre>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}], +["fo[o<samp>b]ar</samp>", + [["stylewithcss","true"],["fontname","sans-serif"]], + "fo<span style=\"font-family:sans-serif\">[o</span><samp><span style=\"font-family:sans-serif\">b]</span>ar</samp>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}], +["fo[o<samp>b]ar</samp>", + [["stylewithcss","false"],["fontname","sans-serif"]], + "fo<font face=\"sans-serif\">[o</font><samp><font face=\"sans-serif\">b]</font>ar</samp>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}], +["fo[o<tt>b]ar</tt>", + [["stylewithcss","true"],["fontname","sans-serif"]], + "fo<span style=\"font-family:sans-serif\">[o</span><tt><span style=\"font-family:sans-serif\">b]</span>ar</tt>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}], +["fo[o<tt>b]ar</tt>", + [["stylewithcss","false"],["fontname","sans-serif"]], + "fo<font face=\"sans-serif\">[o</font><tt><font face=\"sans-serif\">b]</font>ar</tt>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[true,false,"serif",false,false,"sans-serif"]}], +["<tt>fo[o</tt><code>b]ar</code>", + [["stylewithcss","true"],["fontname","sans-serif"]], + "<tt>fo<span style=\"font-family:sans-serif\">[o</span></tt><code><span style=\"font-family:sans-serif\">b]</span>ar</code>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["<tt>fo[o</tt><code>b]ar</code>", + [["stylewithcss","false"],["fontname","sans-serif"]], + "<tt>fo<font face=\"sans-serif\">[o</font></tt><code><font face=\"sans-serif\">b]</font>ar</code>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["<pre>fo[o</pre><samp>b]ar</samp>", + [["stylewithcss","true"],["fontname","sans-serif"]], + "<pre>fo<span style=\"font-family:sans-serif\">[o</span></pre><samp><span style=\"font-family:sans-serif\">b]</span>ar</samp>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["<pre>fo[o</pre><samp>b]ar</samp>", + [["stylewithcss","false"],["fontname","sans-serif"]], + "<pre>fo<font face=\"sans-serif\">[o</font></pre><samp><font face=\"sans-serif\">b]</font>ar</samp>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["<span style=font-family:monospace>fo[o</span><kbd>b]ar</kbd>", + [["stylewithcss","true"],["fontname","sans-serif"]], + "<span style=\"font-family:monospace\">fo</span><span style=\"font-family:sans-serif\">[o</span><kbd><span style=\"font-family:sans-serif\">b]</span>ar</kbd>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], +["<span style=font-family:monospace>fo[o</span><kbd>b]ar</kbd>", + [["stylewithcss","false"],["fontname","sans-serif"]], + "<span style=\"font-family:monospace\">fo</span><font face=\"sans-serif\">[o</font><kbd><font face=\"sans-serif\">b]</font>ar</kbd>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontname":[false,false,"monospace",false,false,"sans-serif"]}], + +// If contents of <font> are entirely selected, it should be reused. +["<font size=7>[abc]</font>", + [["styleWithCSS","false"],["fontName","monospace"]], + ["<font face=\"monospace\" size=\"7\">[abc]</font>", + "<font size=\"7\" face=\"monospace\">[abc]</font>"], + [true,true], + {}], +["<font color=#ff0000>[abc]</font>", + [["styleWithCSS","false"],["fontName","monospace"]], + ["<font face=\"monospace\" color=\"#ff0000\">[abc]</font>", + "<font color=\"#ff0000\" face=\"monospace\">[abc]</font>"], + [true,true], + {}], +["<font size=\"7\" color=#ff0000>[abc]</font>", + [["styleWithCSS","false"],["fontName","monospace"]], + ["<font color=\"#ff0000\" face=\"monospace\" size=\"7\">[abc]</font>", + "<font color=\"#ff0000\" size=\"7\" face=\"monospace\">[abc]</font>", + "<font face=\"monospace\" color=\"#ff0000\" size=\"7\">[abc]</font>", + "<font face=\"monospace\" size=\"7\" color=\"#ff0000\">[abc]</font>", + "<font size=\"7\" color=\"#ff0000\" face=\"monospace\">[abc]</font>", + "<font size=\"7\" face=\"monospace\" color=\"#ff0000\">[abc]</font>"], + [true,true], + {}], +// but don't split existing <font> if partially selected. +["<font size=7>[a]bc</font>", + [["styleWithCSS","false"],["fontName","monospace"]], + "<font size=\"7\"><font face=\"monospace\">[a]</font>bc</font>", + [true,true], + {}], +["<font size=7>ab[c]</font>", + [["styleWithCSS","false"],["fontName","monospace"]], + "<font size=\"7\">ab<font face=\"monospace\">[c]</font></font>", + [true,true], + {}], +["<font color=#ff0000>[a]bc</font>", + [["styleWithCSS","false"],["fontName","monospace"]], + "<font color=\"#ff0000\"><font face=\"monospace\">[a]</font>bc</font>", + [true,true], + {}], +["<font color=#ff0000>ab[c]</font>", + [["styleWithCSS","false"],["fontName","monospace"]], + "<font color=\"#ff0000\">ab<font face=\"monospace\">[c]</font></font>", + [true,true], + {}], +] diff --git a/testing/web-platform/tests/editing/data/fontsize.js b/testing/web-platform/tests/editing/data/fontsize.js new file mode 100644 index 0000000000..d048375b7a --- /dev/null +++ b/testing/web-platform/tests/editing/data/fontsize.js @@ -0,0 +1,865 @@ +// For documentation of the format, see README in this directory. +var browserTests = [ +["foo[]bar", + [["fontsize","4"]], + "foo[]bar", + [true], + {"fontsize":[false,false,"3",false,false,"4"]}], +["<p>[foo</p> <p>bar]</p>", + [["stylewithcss","true"],["fontsize","4"]], + "<p><span style=\"font-size:large\">[foo</span></p> <p><span style=\"font-size:large\">bar]</span></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"4"]}], +["<p>[foo</p> <p>bar]</p>", + [["stylewithcss","false"],["fontsize","4"]], + "<p><font size=\"4\">[foo</font></p> <p><font size=\"4\">bar]</font></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"4"]}], +["<span>[foo</span> <span>bar]</span>", + [["stylewithcss","true"],["fontsize","4"]], + "<span style=\"font-size:large\"><span>[foo</span> <span>bar]</span></span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"4"]}], +["<span>[foo</span> <span>bar]</span>", + [["stylewithcss","false"],["fontsize","4"]], + "<font size=\"4\"><span>[foo</span> <span>bar]</span></font>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"4"]}], +["<p>[foo</p><p> <span>bar</span> </p><p>baz]</p>", + [["stylewithcss","true"],["fontsize","4"]], + "<p><span style=\"font-size:large\">[foo</span></p><p> <span style=\"font-size:large\"><span>bar</span></span> </p><p><span style=\"font-size:large\">baz]</span></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"4"]}], +["<p>[foo</p><p> <span>bar</span> </p><p>baz]</p>", + [["stylewithcss","false"],["fontsize","4"]], + "<p><font size=\"4\">[foo</font></p><p> <font size=\"4\"><span>bar</span></font> </p><p><font size=\"4\">baz]</font></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"4"]}], +["<p>[foo<p><br><p>bar]", + [["stylewithcss","true"],["fontsize","4"]], + "<p><span style=\"font-size:large\">[foo</span></p><p><br></p><p><span style=\"font-size:large\">bar]</span></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"3",true,false,"4"]}], +["<p>[foo<p><br><p>bar]", + [["stylewithcss","false"],["fontsize","4"]], + "<p><font size=\"4\">[foo</font></p><p><br></p><p><font size=\"4\">bar]</font></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",true,false,"4"]}], +["<b>foo[]bar</b>", + [["fontsize","4"]], + "<b>foo[]bar</b>", + [true], + {"fontsize":[false,false,"3",false,false,"4"]}], +["<i>foo[]bar</i>", + [["fontsize","4"]], + "<i>foo[]bar</i>", + [true], + {"fontsize":[false,false,"3",false,false,"4"]}], +["<span>foo</span>{}<span>bar</span>", + [["fontsize","4"]], + "<span>foo</span>{}<span>bar</span>", + [true], + {"fontsize":[false,false,"3",false,false,"4"]}], +["<span>foo[</span><span>]bar</span>", + [["fontsize","4"]], + "<span>foo[</span><span>]bar</span>", + [true], + {"fontsize":[false,false,"3",false,false,"4"]}], +["foo[bar]baz", + [["stylewithcss","true"],["fontsize","4"]], + "foo<span style=\"font-size:large\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"4"]}], +["foo[bar]baz", + [["stylewithcss","false"],["fontsize","4"]], + "foo<font size=\"4\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"4"]}], +["foo[bar<b>baz]qoz</b>quz", + [["stylewithcss","true"],["fontsize","4"]], + "foo<span style=\"font-size:large\">[bar</span><b><span style=\"font-size:large\">baz]</span>qoz</b>quz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"4"]}], +["foo[bar<b>baz]qoz</b>quz", + [["stylewithcss","false"],["fontsize","4"]], + "foo<font size=\"4\">[bar</font><b><font size=\"4\">baz]</font>qoz</b>quz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"4"]}], +["foo[bar<i>baz]qoz</i>quz", + [["stylewithcss","true"],["fontsize","4"]], + "foo<span style=\"font-size:large\">[bar</span><i><span style=\"font-size:large\">baz]</span>qoz</i>quz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"4"]}], +["foo[bar<i>baz]qoz</i>quz", + [["stylewithcss","false"],["fontsize","4"]], + "foo<font size=\"4\">[bar</font><i><font size=\"4\">baz]</font>qoz</i>quz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"4"]}], +["{<p><p> <p>foo</p>}", + [["stylewithcss","true"],["fontsize","4"]], + "{<p></p><p> </p><p><span style=\"font-size:large\">foo</span></p>}", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"4"]}], +["{<p><p> <p>foo</p>}", + [["stylewithcss","false"],["fontsize","4"]], + "{<p></p><p> </p><p><font size=\"4\">foo</font></p>}", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"4"]}], +["foo[bar]baz", + [["stylewithcss","true"],["fontsize","1"]], + "foo<span style=\"font-size:x-small\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"1"]}], +["foo[bar]baz", + [["stylewithcss","false"],["fontsize","1"]], + "foo<font size=\"1\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"1"]}], +["foo[bar]baz", + [["stylewithcss","true"],["fontsize","0"]], + "foo<span style=\"font-size:x-small\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"1"]}], +["foo[bar]baz", + [["stylewithcss","false"],["fontsize","0"]], + "foo<font size=\"1\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"1"]}], +["foo[bar]baz", + [["stylewithcss","true"],["fontsize","-5"]], + "foo<span style=\"font-size:x-small\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"1"]}], +["foo[bar]baz", + [["stylewithcss","false"],["fontsize","-5"]], + "foo<font size=\"1\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"1"]}], +["foo[bar]baz", + [["stylewithcss","true"],["fontsize","6"]], + "foo<span style=\"font-size:xx-large\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"6"]}], +["foo[bar]baz", + [["stylewithcss","false"],["fontsize","6"]], + "foo<font size=\"6\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"6"]}], +["foo[bar]baz", + [["stylewithcss","true"],["fontsize","7"]], + "foo<font size=\"7\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"7"]}], +["foo[bar]baz", + [["stylewithcss","false"],["fontsize","7"]], + "foo<font size=\"7\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"7"]}], +["foo[bar]baz", + [["stylewithcss","true"],["fontsize","8"]], + "foo<font size=\"7\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"7"]}], +["foo[bar]baz", + [["stylewithcss","false"],["fontsize","8"]], + "foo<font size=\"7\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"7"]}], +["foo[bar]baz", + [["stylewithcss","true"],["fontsize","100"]], + "foo<font size=\"7\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"7"]}], +["foo[bar]baz", + [["stylewithcss","false"],["fontsize","100"]], + "foo<font size=\"7\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"7"]}], +["foo[bar]baz", + [["fontsize","2em"]], + "foo[bar]baz", + [false], + {"fontsize":[false,false,"3",false,false,"3"]}], +["foo[bar]baz", + [["fontsize","20pt"]], + "foo[bar]baz", + [false], + {"fontsize":[false,false,"3",false,false,"3"]}], +["foo[bar]baz", + [["fontsize","xx-large"]], + "foo[bar]baz", + [false], + {"fontsize":[false,false,"3",false,false,"3"]}], +["foo[bar]baz", + [["stylewithcss","true"],["fontsize"," 1 "]], + "foo<span style=\"font-size:x-small\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"1"]}], +["foo[bar]baz", + [["stylewithcss","false"],["fontsize"," 1 "]], + "foo<font size=\"1\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"1"]}], +["foo[bar]baz", + [["fontsize","1."]], + "foo[bar]baz", + [false], + {"fontsize":[false,false,"3",false,false,"3"]}], +["foo[bar]baz", + [["stylewithcss","true"],["fontsize","1.0"]], + "foo<span style=\"font-size:x-small\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"1"]}], +["foo[bar]baz", + [["stylewithcss","false"],["fontsize","1.0"]], + "foo<font size=\"1\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"1"]}], +["foo[bar]baz", + [["stylewithcss","true"],["fontsize","1.0e2"]], + "foo<span style=\"font-size:x-small\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"1"]}], +["foo[bar]baz", + [["stylewithcss","false"],["fontsize","1.0e2"]], + "foo<font size=\"1\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"1"]}], +["foo[bar]baz", + [["stylewithcss","true"],["fontsize","1.1"]], + "foo<span style=\"font-size:x-small\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"1"]}], +["foo[bar]baz", + [["stylewithcss","false"],["fontsize","1.1"]], + "foo<font size=\"1\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"1"]}], +["foo[bar]baz", + [["stylewithcss","true"],["fontsize","1.9"]], + "foo<span style=\"font-size:x-small\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"1"]}], +["foo[bar]baz", + [["stylewithcss","false"],["fontsize","1.9"]], + "foo<font size=\"1\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"1"]}], +["foo[bar]baz", + [["fontsize","+0"]], + "foo[bar]baz", + [true], + {"fontsize":[false,false,"3",false,false,"3"]}], +["foo[bar]baz", + [["stylewithcss","true"],["fontsize","+1"]], + "foo<span style=\"font-size:large\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"4"]}], +["foo[bar]baz", + [["stylewithcss","false"],["fontsize","+1"]], + "foo<font size=\"4\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"4"]}], +["foo[bar]baz", + [["stylewithcss","true"],["fontsize","+9"]], + "foo<font size=\"7\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"7"]}], +["foo[bar]baz", + [["stylewithcss","false"],["fontsize","+9"]], + "foo<font size=\"7\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"7"]}], +["foo[bar]baz", + [["fontsize","-0"]], + "foo[bar]baz", + [true], + {"fontsize":[false,false,"3",false,false,"3"]}], +["foo[bar]baz", + [["stylewithcss","true"],["fontsize","-1"]], + "foo<span style=\"font-size:small\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"2"]}], +["foo[bar]baz", + [["stylewithcss","false"],["fontsize","-1"]], + "foo<font size=\"2\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"2"]}], +["foo[bar]baz", + [["stylewithcss","true"],["fontsize","-9"]], + "foo<span style=\"font-size:x-small\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"1"]}], +["foo[bar]baz", + [["stylewithcss","false"],["fontsize","-9"]], + "foo<font size=\"1\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"1"]}], +["foo[bar]baz", + [["fontsize",""]], + "foo[bar]baz", + [false], + {"fontsize":[false,false,"3",false,false,"3"]}], +["<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>", + [["stylewithcss","true"],["fontsize","4"]], + "<table><tbody><tr><td>foo</td><td>b<span style=\"font-size:large\">[a]</span>r</td><td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"4"]}], +["<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>", + [["stylewithcss","false"],["fontsize","4"]], + "<table><tbody><tr><td>foo</td><td>b<font size=\"4\">[a]</font>r</td><td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"4"]}], +["<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table>", + [["stylewithcss","true"],["fontsize","4"]], + "<table><tbody><tr><td>foo</td>{<td><span style=\"font-size:large\">bar</span></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"4"]}], +["<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table>", + [["stylewithcss","false"],["fontsize","4"]], + "<table><tbody><tr><td>foo</td>{<td><font size=\"4\">bar</font></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"4"]}], +["<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table>", + [["stylewithcss","true"],["fontsize","4"]], + "<table><tbody><tr>{<td><span style=\"font-size:large\">foo</span></td><td><span style=\"font-size:large\">bar</span></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"4"]}], +["<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table>", + [["stylewithcss","false"],["fontsize","4"]], + "<table><tbody><tr>{<td><font size=\"4\">foo</font></td><td><font size=\"4\">bar</font></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"4"]}], +["<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>", + [["stylewithcss","true"],["fontsize","4"]], + "<table><tbody>{<tr><td><span style=\"font-size:large\">foo</span></td><td><span style=\"font-size:large\">bar</span></td><td><span style=\"font-size:large\">baz</span></td></tr>}</tbody></table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"4"]}], +["<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>", + [["stylewithcss","false"],["fontsize","4"]], + "<table><tbody>{<tr><td><font size=\"4\">foo</font></td><td><font size=\"4\">bar</font></td><td><font size=\"4\">baz</font></td></tr>}</tbody></table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"4"]}], +["<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>", + [["stylewithcss","true"],["fontsize","4"]], + "<table>{<tbody><tr><td><span style=\"font-size:large\">foo</span></td><td><span style=\"font-size:large\">bar</span></td><td><span style=\"font-size:large\">baz</span></td></tr></tbody>}</table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"4"]}], +["<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>", + [["stylewithcss","false"],["fontsize","4"]], + "<table>{<tbody><tr><td><font size=\"4\">foo</font></td><td><font size=\"4\">bar</font></td><td><font size=\"4\">baz</font></td></tr></tbody>}</table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"4"]}], +["{<table><tr><td>foo<td>bar<td>baz</table>}", + [["stylewithcss","true"],["fontsize","4"]], + "{<table><tbody><tr><td><span style=\"font-size:large\">foo</span></td><td><span style=\"font-size:large\">bar</span></td><td><span style=\"font-size:large\">baz</span></td></tr></tbody></table>}", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"4"]}], +["{<table><tr><td>foo<td>bar<td>baz</table>}", + [["stylewithcss","false"],["fontsize","4"]], + "{<table><tbody><tr><td><font size=\"4\">foo</font></td><td><font size=\"4\">bar</font></td><td><font size=\"4\">baz</font></td></tr></tbody></table>}", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"4"]}], +["foo<font size=1>[bar]</font>baz", + [["stylewithcss","true"],["fontsize","4"]], + "foo<span style=\"font-size:large\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"1",false,false,"4"]}], +["foo<font size=1>[bar]</font>baz", + [["stylewithcss","false"],["fontsize","4"]], + "foo<font size=\"4\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"1",false,false,"4"]}], +["<font size=1>foo[bar]baz</font>", + [["stylewithcss","true"],["fontsize","4"]], + "<font size=\"1\">foo</font><span style=\"font-size:large\">[bar]</span><font size=\"1\">baz</font>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"1",false,false,"4"]}], +["<font size=1>foo[bar]baz</font>", + [["stylewithcss","false"],["fontsize","4"]], + "<font size=\"1\">foo</font><font size=\"4\">[bar]</font><font size=\"1\">baz</font>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"1",false,false,"4"]}], +["foo<font size=3>[bar]</font>baz", + [["stylewithcss","true"],["fontsize","4"]], + "foo<span style=\"font-size:large\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"4"]}], +["foo<font size=3>[bar]</font>baz", + [["stylewithcss","false"],["fontsize","4"]], + "foo<font size=\"4\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"4"]}], +["<font size=3>foo[bar]baz</font>", + [["stylewithcss","true"],["fontsize","4"]], + "<font size=\"3\">foo</font><span style=\"font-size:large\">[bar]</span><font size=\"3\">baz</font>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"4"]}], +["<font size=3>foo[bar]baz</font>", + [["stylewithcss","false"],["fontsize","4"]], + "<font size=\"3\">foo</font><font size=\"4\">[bar]</font><font size=\"3\">baz</font>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"4"]}], +["foo<font size=4>[bar]</font>baz", + [["stylewithcss","true"],["fontsize","4"]], + "foo<span style=\"font-size:large\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"4",false,false,"4"]}], +["foo<font size=4>[bar]</font>baz", + [["stylewithcss","false"],["fontsize","4"]], + "foo<font size=\"4\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"4",false,false,"4"]}], +["<font size=4>foo[bar]baz</font>", + [["fontsize","4"]], + "<font size=\"4\">foo[bar]baz</font>", + [true], + {"fontsize":[false,false,"4",false,false,"4"]}], +["foo<font size=+1>[bar]</font>baz", + [["stylewithcss","true"],["fontsize","4"]], + "foo<span style=\"font-size:large\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"4",false,false,"4"]}], +["foo<font size=+1>[bar]</font>baz", + [["stylewithcss","false"],["fontsize","4"]], + "foo<font size=\"4\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"4",false,false,"4"]}], +["<font size=+1>foo[bar]baz</font>", + [["fontsize","4"]], + "<font size=\"+1\">foo[bar]baz</font>", + [true], + {"fontsize":[false,false,"4",false,false,"4"]}], +["<font size=4>foo<font size=1>b[a]r</font>baz</font>", + [["stylewithcss","true"],["fontsize","4"]], + "<font size=\"4\">foo<span style=\"font-size:x-small\">b</span>[a]<span style=\"font-size:x-small\">r</span>baz</font>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"1",false,false,"4"]}], +["<font size=4>foo<font size=1>b[a]r</font>baz</font>", + [["stylewithcss","false"],["fontsize","4"]], + "<font size=\"4\">foo<font size=\"1\">b</font>[a]<font size=\"1\">r</font>baz</font>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"1",false,false,"4"]}], +["foo<span style=\"font-size: xx-small\">[bar]</span>baz", + [["stylewithcss","true"],["fontsize","4"]], + "foo<span style=\"font-size:large\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"1",false,false,"4"]}], +["foo<span style=\"font-size: xx-small\">[bar]</span>baz", + [["stylewithcss","false"],["fontsize","4"]], + "foo<font size=\"4\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"1",false,false,"4"]}], +["<span style=\"font-size: xx-small\">foo[bar]baz</span>", + [["stylewithcss","true"],["fontsize","4"]], + "<span style=\"font-size:xx-small\">foo</span><span style=\"font-size:large\">[bar]</span><span style=\"font-size:xx-small\">baz</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"1",false,false,"4"]}], +["<span style=\"font-size: xx-small\">foo[bar]baz</span>", + [["stylewithcss","false"],["fontsize","4"]], + "<span style=\"font-size:xx-small\">foo</span><font size=\"4\">[bar]</font><span style=\"font-size:xx-small\">baz</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"1",false,false,"4"]}], +["foo<span style=\"font-size: medium\">[bar]</span>baz", + [["stylewithcss","true"],["fontsize","4"]], + "foo<span style=\"font-size:large\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"4"]}], +["foo<span style=\"font-size: medium\">[bar]</span>baz", + [["stylewithcss","false"],["fontsize","4"]], + "foo<font size=\"4\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"4"]}], +["<span style=\"font-size: medium\">foo[bar]baz</span>", + [["stylewithcss","true"],["fontsize","4"]], + "<span style=\"font-size:medium\">foo</span><span style=\"font-size:large\">[bar]</span><span style=\"font-size:medium\">baz</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"4"]}], +["<span style=\"font-size: medium\">foo[bar]baz</span>", + [["stylewithcss","false"],["fontsize","4"]], + "<span style=\"font-size:medium\">foo</span><font size=\"4\">[bar]</font><span style=\"font-size:medium\">baz</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"4"]}], +["foo<span style=\"font-size: large\">[bar]</span>baz", + [["stylewithcss","true"],["fontsize","4"]], + "foo<span style=\"font-size:large\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"4",false,false,"4"]}], +["foo<span style=\"font-size: large\">[bar]</span>baz", + [["stylewithcss","false"],["fontsize","4"]], + "foo<font size=\"4\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"4",false,false,"4"]}], +["<span style=\"font-size: large\">foo[bar]baz</span>", + [["fontsize","4"]], + "<span style=\"font-size:large\">foo[bar]baz</span>", + [true], + {"fontsize":[false,false,"4",false,false,"4"]}], +["<span style=\"font-size: large\">foo<span style=\"font-size: xx-small\">b[a]r</span>baz</span>", + [["stylewithcss","true"],["fontsize","4"]], + "<span style=\"font-size:large\">foo<span style=\"font-size:xx-small\">b</span>[a]<span style=\"font-size:xx-small\">r</span>baz</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"1",false,false,"4"]}], +["<span style=\"font-size: large\">foo<span style=\"font-size: xx-small\">b[a]r</span>baz</span>", + [["stylewithcss","false"],["fontsize","4"]], + "<span style=\"font-size:large\">foo<span style=\"font-size:xx-small\">b</span>[a]<span style=\"font-size:xx-small\">r</span>baz</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"1",false,false,"4"]}], +["foo<span style=\"font-size: 2em\">[bar]</span>baz", + [["stylewithcss","true"],["fontsize","4"]], + "foo<span style=\"font-size:large\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"6",false,false,"4"]}], +["foo<span style=\"font-size: 2em\">[bar]</span>baz", + [["stylewithcss","false"],["fontsize","4"]], + "foo<font size=\"4\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"6",false,false,"4"]}], +["<span style=\"font-size: 2em\">foo[bar]baz</span>", + [["stylewithcss","true"],["fontsize","4"]], + "<span style=\"font-size:2em\">foo</span><span style=\"font-size:large\">[bar]</span><span style=\"font-size:2em\">baz</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"6",false,false,"4"]}], +["<span style=\"font-size: 2em\">foo[bar]baz</span>", + [["stylewithcss","false"],["fontsize","4"]], + "<span style=\"font-size:2em\">foo</span><font size=\"4\">[bar]</font><span style=\"font-size:2em\">baz</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"6",false,false,"4"]}], +["<p style=\"font-size: xx-small\">foo[bar]baz</p>", + [["stylewithcss","true"],["fontsize","4"]], + "<p style=\"font-size:xx-small\">foo<span style=\"font-size:large\">[bar]</span>baz</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"1",false,false,"4"]}], +["<p style=\"font-size: xx-small\">foo[bar]baz</p>", + [["stylewithcss","false"],["fontsize","4"]], + "<p style=\"font-size:xx-small\">foo<font size=\"4\">[bar]</font>baz</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"1",false,false,"4"]}], +["<p style=\"font-size: medium\">foo[bar]baz</p>", + [["stylewithcss","true"],["fontsize","4"]], + "<p style=\"font-size:medium\">foo<span style=\"font-size:large\">[bar]</span>baz</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"4"]}], +["<p style=\"font-size: medium\">foo[bar]baz</p>", + [["stylewithcss","false"],["fontsize","4"]], + "<p style=\"font-size:medium\">foo<font size=\"4\">[bar]</font>baz</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"4"]}], +["<p style=\"font-size: large\">foo[bar]baz</p>", + [["fontsize","4"]], + "<p style=\"font-size:large\">foo[bar]baz</p>", + [true], + {"fontsize":[false,false,"4",false,false,"4"]}], +["<p style=\"font-size: 2em\">foo[bar]baz</p>", + [["stylewithcss","true"],["fontsize","4"]], + "<p style=\"font-size:2em\">foo<span style=\"font-size:large\">[bar]</span>baz</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"6",false,false,"4"]}], +["<p style=\"font-size: 2em\">foo[bar]baz</p>", + [["stylewithcss","false"],["fontsize","4"]], + "<p style=\"font-size:2em\">foo<font size=\"4\">[bar]</font>baz</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"6",false,false,"4"]}], +["<p style=\"font-size: xx-small\">foo[bar]baz</p>", + [["stylewithcss","true"],["fontsize","3"]], + "<p><span style=\"font-size:xx-small\">foo</span>[bar]<span style=\"font-size:xx-small\">baz</span></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"1",false,false,"3"]}], +["<p style=\"font-size: xx-small\">foo[bar]baz</p>", + [["stylewithcss","false"],["fontsize","3"]], + "<p><span style=\"font-size:xx-small\">foo</span>[bar]<span style=\"font-size:xx-small\">baz</span></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"1",false,false,"3"]}], +["<p style=\"font-size: medium\">foo[bar]baz</p>", + [["fontsize","3"]], + "<p style=\"font-size:medium\">foo[bar]baz</p>", + [true], + {"fontsize":[false,false,"3",false,false,"3"]}], +["<p style=\"font-size: large\">foo[bar]baz</p>", + [["stylewithcss","true"],["fontsize","3"]], + "<p><span style=\"font-size:large\">foo</span>[bar]<span style=\"font-size:large\">baz</span></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"4",false,false,"3"]}], +["<p style=\"font-size: large\">foo[bar]baz</p>", + [["stylewithcss","false"],["fontsize","3"]], + "<p><font size=\"4\">foo</font>[bar]<font size=\"4\">baz</font></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"4",false,false,"3"]}], +["<p style=\"font-size: 2em\">foo[bar]baz</p>", + [["stylewithcss","true"],["fontsize","3"]], + "<p><span style=\"font-size:2em\">foo</span>[bar]<span style=\"font-size:2em\">baz</span></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"6",false,false,"3"]}], +["<p style=\"font-size: 2em\">foo[bar]baz</p>", + [["stylewithcss","false"],["fontsize","3"]], + "<p><span style=\"font-size:2em\">foo</span>[bar]<span style=\"font-size:2em\">baz</span></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"6",false,false,"3"]}], +["<font size=6>foo <span style=\"font-size: 2em\">b[a]r</span> baz</font>", + [["stylewithcss","true"],["fontsize","3"]], + "<span style=\"font-size:xx-large\">foo </span><span style=\"font-size:2em\">b</span>[a]<span style=\"font-size:2em\">r</span><span style=\"font-size:xx-large\"> baz</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"7",false,false,"3"]}], +["<font size=6>foo <span style=\"font-size: 2em\">b[a]r</span> baz</font>", + [["stylewithcss","false"],["fontsize","3"]], + "<font size=\"6\">foo </font><span style=\"font-size:2em\">b</span>[a]<span style=\"font-size:2em\">r</span><font size=\"6\"> baz</font>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"7",false,false,"3"]}], +["foo<big>[bar]</big>baz", + [["stylewithcss","true"],["fontsize","3"]], + "foo<big><span style=\"font-size:medium\">[bar]</span></big>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"4",false,false,"3"]}], +["foo<big>[bar]</big>baz", + [["stylewithcss","false"],["fontsize","3"]], + "foo<big><font size=\"3\">[bar]</font></big>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"4",false,false,"3"]}], +["foo<big>b[a]r</big>baz", + [["stylewithcss","true"],["fontsize","3"]], + "foo<big>b<span style=\"font-size:medium\">[a]</span>r</big>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"4",false,false,"3"]}], +["foo<big>b[a]r</big>baz", + [["stylewithcss","false"],["fontsize","3"]], + "foo<big>b<font size=\"3\">[a]</font>r</big>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"4",false,false,"3"]}], +["foo<small>[bar]</small>baz", + [["stylewithcss","true"],["fontsize","3"]], + "foo<small><span style=\"font-size:medium\">[bar]</span></small>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"2",false,false,"3"]}], +["foo<small>[bar]</small>baz", + [["stylewithcss","false"],["fontsize","3"]], + "foo<small><font size=\"3\">[bar]</font></small>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"2",false,false,"3"]}], +["foo<small>b[a]r</small>baz", + [["stylewithcss","true"],["fontsize","3"]], + "foo<small>b<span style=\"font-size:medium\">[a]</span>r</small>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"2",false,false,"3"]}], +["foo<small>b[a]r</small>baz", + [["stylewithcss","false"],["fontsize","3"]], + "foo<small>b<font size=\"3\">[a]</font>r</small>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"2",false,false,"3"]}], +["fo[o<font size=2>b]ar</font>baz", + [["stylewithcss","true"],["fontsize","4"]], + "fo<span style=\"font-size:large\">[ob]</span><font size=\"2\">ar</font>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[true,false,"3",false,false,"4"]}], +["fo[o<font size=2>b]ar</font>baz", + [["stylewithcss","false"],["fontsize","4"]], + "fo<font size=\"4\">[ob]</font><font size=\"2\">ar</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[true,false,"3",false,false,"4"]}], +["foo<font size=2>ba[r</font>b]az", + [["stylewithcss","true"],["fontsize","4"]], + "foo<font size=\"2\">ba</font><span style=\"font-size:large\">[rb]</span>az", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[true,false,"2",false,false,"4"]}], +["foo<font size=2>ba[r</font>b]az", + [["stylewithcss","false"],["fontsize","4"]], + "foo<font size=\"2\">ba</font><font size=\"4\">[rb]</font>az", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[true,false,"2",false,false,"4"]}], +["fo[o<font size=2>bar</font>b]az", + [["stylewithcss","true"],["fontsize","4"]], + "fo<span style=\"font-size:large\">[obarb]</span>az", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[true,false,"3",false,false,"4"]}], +["fo[o<font size=2>bar</font>b]az", + [["stylewithcss","false"],["fontsize","4"]], + "fo<font size=\"4\">[obarb]</font>az", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[true,false,"3",false,false,"4"]}], +["foo[<font size=2>b]ar</font>baz", + [["stylewithcss","true"],["fontsize","4"]], + "foo<span style=\"font-size:large\">b</span><font size=\"2\">ar</font>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"2",false,false,"4"]}], +["foo[<font size=2>b]ar</font>baz", + [["stylewithcss","false"],["fontsize","4"]], + "foo<font size=\"4\">[b]</font><font size=\"2\">ar</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"2",false,false,"4"]}], +["foo<font size=2>ba[r</font>]baz", + [["stylewithcss","true"],["fontsize","4"]], + "foo<font size=\"2\">ba</font><span style=\"font-size:large\">r</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"2",false,false,"4"]}], +["foo<font size=2>ba[r</font>]baz", + [["stylewithcss","false"],["fontsize","4"]], + "foo<font size=\"2\">ba</font><font size=\"4\">[r]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"2",false,false,"4"]}], +["foo[<font size=2>bar</font>]baz", + [["stylewithcss","true"],["fontsize","4"]], + "foo[<span style=\"font-size:large\">bar</span>]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"2",false,false,"4"]}], +["foo[<font size=2>bar</font>]baz", + [["stylewithcss","false"],["fontsize","4"]], + "foo[<font size=\"4\">bar</font>]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"2",false,false,"4"]}], +["foo<font size=2>[bar]</font>baz", + [["stylewithcss","true"],["fontsize","4"]], + "foo<span style=\"font-size:large\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"2",false,false,"4"]}], +["foo<font size=2>[bar]</font>baz", + [["stylewithcss","false"],["fontsize","4"]], + "foo<font size=\"4\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"2",false,false,"4"]}], +["foo{<font size=2>bar</font>}baz", + [["stylewithcss","true"],["fontsize","4"]], + "foo{<span style=\"font-size:large\">bar}</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"2",false,false,"4"]}], +["foo{<font size=2>bar</font>}baz", + [["stylewithcss","false"],["fontsize","4"]], + "foo{<font size=\"4\">bar}</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"2",false,false,"4"]}], +["<font size=1>fo[o</font><span style=font-size:xx-small>b]ar</span>", + [["stylewithcss","true"],["fontsize","4"]], + "<font size=\"1\">fo</font><span style=\"font-size:large\">[ob]</span><span style=\"font-size:xx-small\">ar</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[true,false,"1",false,false,"4"]}], +["<font size=1>fo[o</font><span style=font-size:xx-small>b]ar</span>", + [["stylewithcss","false"],["fontsize","4"]], + "<font size=\"1\">fo</font><font size=\"4\">[ob]</font><span style=\"font-size:xx-small\">ar</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[true,false,"1",false,false,"4"]}], +["<font size=2>fo[o</font><span style=font-size:small>b]ar</span>", + [["stylewithcss","true"],["fontsize","4"]], + "<font size=\"2\">fo</font><span style=\"font-size:large\">[ob]</span><span style=\"font-size:small\">ar</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"2",false,false,"4"]}], +["<font size=2>fo[o</font><span style=font-size:small>b]ar</span>", + [["stylewithcss","false"],["fontsize","4"]], + "<font size=\"2\">fo</font><font size=\"4\">[ob]</font><span style=\"font-size:small\">ar</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"2",false,false,"4"]}], +["<font size=3>fo[o</font><span style=font-size:medium>b]ar</span>", + [["stylewithcss","true"],["fontsize","4"]], + "<font size=\"3\">fo</font><span style=\"font-size:large\">[ob]</span><span style=\"font-size:medium\">ar</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"4"]}], +["<font size=3>fo[o</font><span style=font-size:medium>b]ar</span>", + [["stylewithcss","false"],["fontsize","4"]], + "<font size=\"3\">fo</font><font size=\"4\">ob</font><span style=\"font-size:medium\">ar</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"3",false,false,"4"]}], +["<font size=4>fo[o</font><span style=font-size:large>b]ar</span>", + [["fontsize","4"]], + "<font size=\"4\">fo[o</font><span style=\"font-size:large\">b]ar</span>", + [true], + {"fontsize":[false,false,"4",false,false,"4"]}], +["<font size=5>fo[o</font><span style=font-size:x-large>b]ar</span>", + [["stylewithcss","true"],["fontsize","4"]], + "<font size=\"5\">fo</font><span style=\"font-size:large\">[ob]</span><span style=\"font-size:x-large\">ar</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"5",false,false,"4"]}], +["<font size=5>fo[o</font><span style=font-size:x-large>b]ar</span>", + [["stylewithcss","false"],["fontsize","4"]], + "<font size=\"5\">fo</font><font size=\"4\">[ob]</font><span style=\"font-size:x-large\">ar</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"5",false,false,"4"]}], +["<font size=6>fo[o</font><span style=font-size:xx-large>b]ar</span>", + [["stylewithcss","true"],["fontsize","4"]], + "<font size=\"6\">fo</font><span style=\"font-size:large\">ob</span><span style=\"font-size:xx-large\">ar</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"fontsize":[false,false,"6",false,false,"4"]}], +["<font size=6>fo[o</font><span style=font-size:xx-large>b]ar</span>", + [["stylewithcss","false"],["fontsize","4"]], + "<font size=\"6\">fo</font><font size=\"4\">ob</font><span style=\"font-size:xx-large\">ar</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"fontsize":[false,false,"6",false,false,"4"]}], + +// If contents of <font> are entirely selected, it should be reused. +["<font color=#ff0000>[abc]</font>", + [["styleWithCSS","false"],["fontSize","7"]], + ["<font color=\"#ff0000\" size=\"7\">[abc]</font>", + "<font size=\"7\" color=\"#ff0000\">[abc]</font>"], + [true,true], + {}], +["<font face=monospace>[abc]</font>", + [["styleWithCSS","false"],["fontSize","7"]], + ["<font face=\"monospace\" size=\"7\">[abc]</font>", + "<font size=\"7\" face=\"monospace\">[abc]</font>"], + [true,true], + {}], +["<font color=#ff0000 face=monospace>[abc]</font>", + [["styleWithCSS","false"],["fontSize","7"]], + ["<font color=\"#ff0000\" face=\"monospace\" size=\"7\">[abc]</font>", + "<font color=\"#ff0000\" size=\"7\" face=\"monospace\">[abc]</font>", + "<font face=\"monospace\" color=\"#ff0000\" size=\"7\">[abc]</font>", + "<font face=\"monospace\" size=\"7\" color=\"#ff0000\">[abc]</font>", + "<font size=\"7\" color=\"#ff0000\" face=\"monospace\">[abc]</font>", + "<font size=\"7\" face=\"monospace\" color=\"#ff0000\">[abc]</font>"], + [true,true], + {}], +// but don't split existing <font> if partially selected. +["<font color=#ff0000>[a]bc</font>", + [["styleWithCSS","false"],["fontSize","7"]], + "<font color=\"#ff0000\"><font size=\"7\">[a]</font>bc</font>", + [true,true], + {}], +["<font color=#ff0000>ab[c]</font>", + [["styleWithCSS","false"],["fontSize","7"]], + "<font color=\"#ff0000\">ab<font size=\"7\">[c]</font></font>", + [true,true], + {}], +["<font face=monospace>[a]bc</font>", + [["styleWithCSS","false"],["fontSize","7"]], + "<font face=\"monospace\"><font size=\"7\">[a]</font>bc</font>", + [true,true], + {}], +["<font face=monospace>ab[c]</font>", + [["styleWithCSS","false"],["fontSize","7"]], + "<font face=\"monospace\">ab<font size=\"7\">[c]</font></font>", + [true,true], + {}], + +// font-size should be removed when applying fontsize without CSS. +// Blink and WebKit puts <font size="..."> into the <span> element in these +// test cases. However, this behavior may cause the background color is +// partially applied to the text because the height is computed without the +// <font>. Therefore, it may be better to put <font> outside any inline +// ancestors. +["<span style=\"font-size:32px; background-color:rgb(0, 128, 128)\">[abc]</span>", + [["styleWithCSS","false"],["fontSize","5"]], + ["<span style=\"background-color:rgb(0, 128, 128)\"><font size=\"5\">[abc]</font></span>", + "<font size=\"5\"><span style=\"background-color:rgb(0, 128, 128)\">[abc]</span></font>"], + [true,true], + {}], +["<span style=\"font-size:32px; background-color:rgb(0, 128, 128)\">[a]bc</span>", + [["styleWithCSS","false"],["fontSize","5"]], + ["<span style=\"background-color:rgb(0, 128, 128)\"><font size=\"5\">[a]</font></span><span style=\"font-size:32px; background-color:rgb(0, 128, 128)\">bc</span>", + "<font size=\"5\"><span style=\"background-color:rgb(0, 128, 128)\">[a]</span></font><span style=\"font-size:32px; background-color:rgb(0, 128, 128)\">bc</span>"], + [true,true], + {}], +["<span style=\"font-size:32px; background-color:rgb(0, 128, 128)\">a[b]c</span>", + [["styleWithCSS","false"],["fontSize","5"]], + ["<span style=\"font-size:32px; background-color:rgb(0, 128, 128)\">a</span><span style=\"background-color:rgb(0, 128, 128)\"><font size=\"5\">[b]</font></span><span style=\"font-size:32px; background-color:rgb(0, 128, 128)\">c</span>", + "<span style=\"font-size:32px; background-color:rgb(0, 128, 128)\">a</span><font size=\"5\"><span style=\"background-color:rgb(0, 128, 128)\">[b]</span></font><span style=\"font-size:32px; background-color:rgb(0, 128, 128)\">c</span>"], + [true,true], + {}], +["<span style=\"font-size:32px; background-color:rgb(0, 128, 128)\">ab[c]</span>", + [["styleWithCSS","false"],["fontSize","5"]], + ["<span style=\"font-size:32px; background-color:rgb(0, 128, 128)\">ab</span><span style=\"background-color:rgb(0, 128, 128)\"><font size=\"5\">[c]</font></span>", + "<span style=\"font-size:32px; background-color:rgb(0, 128, 128)\">ab</span><font size=\"5\"><span style=\"background-color:rgb(0, 128, 128)\">[c]</span></font>"], + [true,true], + {}], +["<p><span style=\"font-size:32px; background-color:rgb(0, 128, 128)\">[abc</span></p><p><span style=\"font-size:64px; background-color:rgb(128, 128, 0)\">def]</span></p>", + [["styleWithCSS","false"],["fontSize","5"]], + ["<p><span style=\"background-color:rgb(0, 128, 128)\"><font size=\"5\">[abc</font></span></p><p><span style=\"background-color:rgb(128, 128, 0)\"><font size=\"5\">def]</font></span></p>", + "<p><font size=\"5\"><span style=\"background-color:rgb(0, 128, 128)\">[abc</span></font></p><p><font size=\"5\"><span style=\"background-color:rgb(128, 128, 0)\">def]</span></font></p>"], + [true,true], + {}], +] diff --git a/testing/web-platform/tests/editing/data/forecolor.js b/testing/web-platform/tests/editing/data/forecolor.js new file mode 100644 index 0000000000..aa390a9f64 --- /dev/null +++ b/testing/web-platform/tests/editing/data/forecolor.js @@ -0,0 +1,837 @@ +// For documentation of the format, see README in this directory. +var browserTests = [ +["foo[]bar", + [["forecolor","#0000FF"]], + "foo[]bar", + [true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["<p>[foo</p> <p>bar]</p>", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "<p><span style=\"color:rgb(0, 0, 255)\">[foo</span></p> <p><span style=\"color:rgb(0, 0, 255)\">bar]</span></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["<p>[foo</p> <p>bar]</p>", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "<p><font color=\"#0000ff\">[foo</font></p> <p><font color=\"#0000ff\">bar]</font></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["<span>[foo</span> <span>bar]</span>", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "<span style=\"color:rgb(0, 0, 255)\"><span>[foo</span> <span>bar]</span></span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["<span>[foo</span> <span>bar]</span>", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "<font color=\"#0000ff\"><span>[foo</span> <span>bar]</span></font>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["<p>[foo</p><p> <span>bar</span> </p><p>baz]</p>", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "<p><span style=\"color:rgb(0, 0, 255)\">[foo</span></p><p> <span style=\"color:rgb(0, 0, 255)\"><span>bar</span></span> </p><p><span style=\"color:rgb(0, 0, 255)\">baz]</span></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["<p>[foo</p><p> <span>bar</span> </p><p>baz]</p>", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "<p><font color=\"#0000ff\">[foo</font></p><p> <font color=\"#0000ff\"><span>bar</span></font> </p><p><font color=\"#0000ff\">baz]</font></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["<p>[foo<p><br><p>bar]", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "<p><span style=\"color:rgb(0, 0, 255)\">[foo</span></p><p><span style=\"color:rgb(0, 0, 255)\"><br></span></p><p><span style=\"color:rgb(0, 0, 255)\">bar]</span></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["<p>[foo<p><br><p>bar]", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "<p><font color=\"#0000ff\">[foo</font></p><p><font color=\"#0000ff\"><br></font></p><p><font color=\"#0000ff\">bar]</font></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["<b>foo[]bar</b>", + [["forecolor","#0000FF"]], + "<b>foo[]bar</b>", + [true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["<i>foo[]bar</i>", + [["forecolor","#0000FF"]], + "<i>foo[]bar</i>", + [true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["<span>foo</span>{}<span>bar</span>", + [["forecolor","#0000FF"]], + "<span>foo</span>{}<span>bar</span>", + [true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["<span>foo[</span><span>]bar</span>", + [["forecolor","#0000FF"]], + "<span>foo[</span><span>]bar</span>", + [true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["foo[bar]baz", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "foo<span style=\"color:rgb(0, 0, 255)\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["foo[bar]baz", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "foo<font color=\"#0000ff\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["foo[bar<b>baz]qoz</b>quz", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "foo<span style=\"color:rgb(0, 0, 255)\">[bar</span><b><span style=\"color:rgb(0, 0, 255)\">baz]</span>qoz</b>quz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["foo[bar<b>baz]qoz</b>quz", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "foo<font color=\"#0000ff\">[bar</font><b><font color=\"#0000ff\">baz]</font>qoz</b>quz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["foo[bar<i>baz]qoz</i>quz", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "foo<span style=\"color:rgb(0, 0, 255)\">[bar</span><i><span style=\"color:rgb(0, 0, 255)\">baz]</span>qoz</i>quz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["foo[bar<i>baz]qoz</i>quz", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "foo<font color=\"#0000ff\">[bar</font><i><font color=\"#0000ff\">baz]</font>qoz</i>quz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["{<p><p> <p>foo</p>}", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "{<p></p><p> </p><p><span style=\"color:rgb(0, 0, 255)\">foo</span></p>}", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["{<p><p> <p>foo</p>}", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "{<p></p><p> </p><p><font color=\"#0000ff\">foo</font></p>}", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["foo[bar]baz", + [["stylewithcss","true"],["forecolor","blue"]], + "foo<span style=\"color:rgb(0, 0, 255)\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["foo[bar]baz", + [["stylewithcss","false"],["forecolor","blue"]], + "foo<font color=\"#0000ff\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["foo[bar]baz", + [["forecolor","f"]], + "foo[bar]baz", + [true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 0)"]}], +["foo[bar]baz", + [["forecolor","#f"]], + "foo[bar]baz", + [true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 0)"]}], +["foo[bar]baz", + [["stylewithcss","true"],["forecolor","00f"]], + "foo<span style=\"color:rgb(0, 0, 255)\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["foo[bar]baz", + [["stylewithcss","false"],["forecolor","00f"]], + "foo<font color=\"#0000ff\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["foo[bar]baz", + [["stylewithcss","true"],["forecolor","#00f"]], + "foo<span style=\"color:rgb(0, 0, 255)\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["foo[bar]baz", + [["stylewithcss","false"],["forecolor","#00f"]], + "foo<font color=\"#0000ff\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["foo[bar]baz", + [["stylewithcss","true"],["forecolor","0000ff"]], + "foo<span style=\"color:rgb(0, 0, 255)\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["foo[bar]baz", + [["stylewithcss","false"],["forecolor","0000ff"]], + "foo<font color=\"#0000ff\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["foo[bar]baz", + [["stylewithcss","true"],["forecolor","#0000ff"]], + "foo<span style=\"color:rgb(0, 0, 255)\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["foo[bar]baz", + [["stylewithcss","false"],["forecolor","#0000ff"]], + "foo<font color=\"#0000ff\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["foo[bar]baz", + [["forecolor","000000fff"]], + "foo[bar]baz", + [true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 0)"]}], +["foo[bar]baz", + [["forecolor","#000000fff"]], + "foo[bar]baz", + [true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 0)"]}], +["foo[bar]baz", + [["stylewithcss","true"],["forecolor","rgb(0, 0, 255)"]], + "foo<span style=\"color:rgb(0, 0, 255)\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["foo[bar]baz", + [["stylewithcss","false"],["forecolor","rgb(0, 0, 255)"]], + "foo<font color=\"#0000ff\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["foo[bar]baz", + [["stylewithcss","true"],["forecolor","rgb(0%, 0%, 100%)"]], + "foo<span style=\"color:rgb(0, 0, 255)\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["foo[bar]baz", + [["stylewithcss","false"],["forecolor","rgb(0%, 0%, 100%)"]], + "foo<font color=\"#0000ff\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["foo[bar]baz", + [["stylewithcss","true"],["forecolor","rgb( 0 ,0 ,255)"]], + "foo<span style=\"color:rgb(0, 0, 255)\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["foo[bar]baz", + [["stylewithcss","false"],["forecolor","rgb( 0 ,0 ,255)"]], + "foo<font color=\"#0000ff\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["foo[bar]baz", + [["stylewithcss","true"],["forecolor","rgba(0, 0, 255, 0.0)"]], + "foo<span style=\"color:rgba(0, 0, 0, 0)\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgba(0, 0, 255, 0)"]}], +["foo[bar]baz", + [["stylewithcss","false"],["forecolor","rgba(0, 0, 255, 0.0)"]], + "foo<span style=\"color:rgba(0, 0, 0, 0)\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgba(0, 0, 255, 0)"]}], +["foo[bar]baz", + [["stylewithcss","true"],["forecolor","rgb(15, -10, 375)"]], + "foo<span style=\"color:rgb(15, 0, 255)\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(15, 0, 255)"]}], +["foo[bar]baz", + [["stylewithcss","false"],["forecolor","rgb(15, -10, 375)"]], + "foo<font color=\"#0f00ff\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(15, 0, 255)"]}], +["foo[bar]baz", + [["forecolor","rgba(0, 0, 0, 1)"]], + "foo[bar]baz", + [true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 0)"]}], +["foo[bar]baz", + [["stylewithcss","true"],["forecolor","rgba(255, 255, 255, 1)"]], + "foo<span style=\"color:rgb(255, 255, 255)\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(255, 255, 255)"]}], +["foo[bar]baz", + [["stylewithcss","false"],["forecolor","rgba(255, 255, 255, 1)"]], + "foo<font color=\"#ffffff\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(255, 255, 255)"]}], +["foo[bar]baz", + [["stylewithcss","true"],["forecolor","rgba(0, 0, 255, 0.5)"]], + "foo<span style=\"color:rgba(0, 0, 255, 0.5)\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgba(0, 0, 255, 0.5)"]}], +["foo[bar]baz", + [["stylewithcss","false"],["forecolor","rgba(0, 0, 255, 0.5)"]], + "foo<span style=\"color:rgba(0, 0, 255, 0.5)\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgba(0, 0, 255, 0.5)"]}], +["foo[bar]baz", + [["stylewithcss","true"],["forecolor","hsl(240, 100%, 50%)"]], + "foo<span style=\"color:rgb(0, 0, 255)\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["foo[bar]baz", + [["stylewithcss","false"],["forecolor","hsl(240, 100%, 50%)"]], + "foo<font color=\"#0000ff\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["foo[bar]baz", + [["stylewithcss","true"],["forecolor","cornsilk"]], + "foo<span style=\"color:rgb(255, 248, 220)\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(255, 248, 220)"]}], +["foo[bar]baz", + [["stylewithcss","false"],["forecolor","cornsilk"]], + "foo<font color=\"#fff8dc\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(255, 248, 220)"]}], +["foo[bar]baz", + [["forecolor","potato quiche"]], + "foo[bar]baz", + [true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 0)"]}], +["foo[bar]baz", + [["stylewithcss","true"],["forecolor","transparent"]], + "foo<span style=\"color:rgba(0, 0, 0, 0)\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgba(0, 0, 0, 0)"]}], +["foo[bar]baz", + [["stylewithcss","false"],["forecolor","transparent"]], + "foo<span style=\"color:rgba(0, 0, 0, 0)\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgba(0, 0, 0, 0)"]}], +["foo[bar]baz", + [["forecolor","currentColor"]], + "foo[bar]baz", + [false], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 0)"]}], +["<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "<table><tbody><tr><td>foo</td><td>b<span style=\"color:rgb(0, 0, 255)\">[a]</span>r</td><td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "<table><tbody><tr><td>foo</td><td>b<font color=\"#0000ff\">[a]</font>r</td><td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table>", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "<table><tbody><tr><td>foo</td>{<td><span style=\"color:rgb(0, 0, 255)\">bar</span></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table>", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "<table><tbody><tr><td>foo</td>{<td><font color=\"#0000ff\">bar</font></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table>", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "<table><tbody><tr>{<td><span style=\"color:rgb(0, 0, 255)\">foo</span></td><td><span style=\"color:rgb(0, 0, 255)\">bar</span></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table>", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "<table><tbody><tr>{<td><font color=\"#0000ff\">foo</font></td><td><font color=\"#0000ff\">bar</font></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "<table><tbody>{<tr><td><span style=\"color:rgb(0, 0, 255)\">foo</span></td><td><span style=\"color:rgb(0, 0, 255)\">bar</span></td><td><span style=\"color:rgb(0, 0, 255)\">baz</span></td></tr>}</tbody></table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "<table><tbody>{<tr><td><font color=\"#0000ff\">foo</font></td><td><font color=\"#0000ff\">bar</font></td><td><font color=\"#0000ff\">baz</font></td></tr>}</tbody></table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "<table>{<tbody><tr><td><span style=\"color:rgb(0, 0, 255)\">foo</span></td><td><span style=\"color:rgb(0, 0, 255)\">bar</span></td><td><span style=\"color:rgb(0, 0, 255)\">baz</span></td></tr></tbody>}</table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "<table>{<tbody><tr><td><font color=\"#0000ff\">foo</font></td><td><font color=\"#0000ff\">bar</font></td><td><font color=\"#0000ff\">baz</font></td></tr></tbody>}</table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["{<table><tr><td>foo<td>bar<td>baz</table>}", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "{<table><tbody><tr><td><span style=\"color:rgb(0, 0, 255)\">foo</span></td><td><span style=\"color:rgb(0, 0, 255)\">bar</span></td><td><span style=\"color:rgb(0, 0, 255)\">baz</span></td></tr></tbody></table>}", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["{<table><tr><td>foo<td>bar<td>baz</table>}", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "{<table><tbody><tr><td><font color=\"#0000ff\">foo</font></td><td><font color=\"#0000ff\">bar</font></td><td><font color=\"#0000ff\">baz</font></td></tr></tbody></table>}", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["foo<font color=blue>[bar]</font>baz", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "foo<span style=\"color:rgb(0, 0, 255)\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 255)"]}], +["foo<font color=blue>[bar]</font>baz", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "foo<font color=\"#0000ff\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 255)"]}], +["foo{<font color=blue>bar</font>}baz", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "foo{<span style=\"color:rgb(0, 0, 255)\">bar}</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 255)"]}], +["foo{<font color=blue>bar</font>}baz", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "foo{<font color=\"#0000ff\">bar}</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 255)"]}], +// Once the inner <span> style is updated, it has same style as the outer one. +// Therefore, it may be okay to use the outer one is the only container of the +// text nodes or it may be okay to split the outer one and keep 3 <span>s. +["<span style=\"color: blue\">foo<span style=\"color: brown\">[bar]</span>baz</span>", + [["stylewithcss","true"],["forecolor","#0000FF"]], + ["<span style=\"color:rgb(0, 0, 255)\">foo</span><span style=\"color:rgb(0, 0, 255)\">bar</span><span style=\"color:rgb(0, 0, 255)\">baz</span>", + "<span style=\"color:rgb(0, 0, 255)\">foo[bar]baz</span>"], + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}], +["<span style=\"color: blue\">foo<span style=\"color: brown\">[bar]</span>baz</span>", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "<span style=\"color:rgb(0, 0, 255)\">foo</span><font color=\"#0000ff\">[bar]</font><span style=\"color:rgb(0, 0, 255)\">baz</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}], +["<span style=\"color: #00f\">foo<span style=\"color: brown\">[bar]</span>baz</span>", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "<span style=\"color:rgb(0, 0, 255)\">foo[bar]baz</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}], +["<span style=\"color: #00f\">foo<span style=\"color: brown\">[bar]</span>baz</span>", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "<span style=\"color:rgb(0, 0, 255)\">foo[bar]baz</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}], +["<span style=\"color: #0000ff\">foo<span style=\"color: brown\">[bar]</span>baz</span>", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "<span style=\"color:rgb(0, 0, 255)\">foo[bar]baz</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}], +["<span style=\"color: #0000ff\">foo<span style=\"color: brown\">[bar]</span>baz</span>", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "<span style=\"color:rgb(0, 0, 255)\">foo[bar]baz</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}], +["<span style=\"color: rgb(0, 0, 255)\">foo<span style=\"color: brown\">[bar]</span>baz</span>", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "<span style=\"color:rgb(0, 0, 255)\">foo[bar]baz</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}], +["<span style=\"color: rgb(0, 0, 255)\">foo<span style=\"color: brown\">[bar]</span>baz</span>", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "<span style=\"color:rgb(0, 0, 255)\">foo[bar]baz</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}], +// Use the inner <font> for the `style` attribute container. Then, the outer +// <font> should be split and may be serialized. +["<font color=blue>foo<font color=brown>[bar]</font>baz</font>", + [["stylewithcss","true"],["forecolor","#0000FF"]], + ["<span style=\"color:rgb(0, 0, 255)\">foo</span><font style=\"color:rgb(0, 0, 255)\">bar</font><span style=\"color:rgb(0, 0, 255)\">baz</span>", + "<font color=\"blue\">foo</font><span style=\"color:rgb(0, 0, 255)\">bar</span><font color=\"blue\">baz</font>"], + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}], +["<font color=blue>foo<font color=brown>[bar]</font>baz</font>", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "<font color=\"blue\">foo[bar]baz</font>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}], +["<span style=\"color: rgb(0, 0, 255)\">foo<span style=\"color: brown\">b[ar]</span>baz</span>", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "<span style=\"color:rgb(0, 0, 255)\">foo<span style=\"color:rgb(165, 42, 42)\">b</span>[ar]baz</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}], +["<span style=\"color: rgb(0, 0, 255)\">foo<span style=\"color: brown\">b[ar]</span>baz</span>", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "<span style=\"color:rgb(0, 0, 255)\">foo<font color=\"#a52a2a\">b</font>[ar]baz</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}], +["foo<span id=purple>ba[r</span>ba]z", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "foo<span id=\"purple\">ba<span style=\"color:rgb(0, 0, 255)\">[r</span></span><span style=\"color:rgb(0, 0, 255)\">ba]</span>z", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[true,false,"rgb(128, 0, 128)",false,false,"rgb(0, 0, 255)"]}], +["foo<span id=purple>ba[r</span>ba]z", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "foo<span id=\"purple\">ba<font color=\"#0000ff\">[r</font></span><font color=\"#0000ff\">ba]</font>z", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[true,false,"rgb(128, 0, 128)",false,false,"rgb(0, 0, 255)"]}], +// XXX Looks like that there is no good solution for this case because id=purple +// may affect the style, but it's unclear for builtin editors of the browsers. +["<span style=\"color: rgb(0, 0, 255)\">foo<span id=purple>b[a]r</span>baz</span>", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "<span style=\"color:rgb(0, 0, 255)\">foo<span id=\"purple\">b<span style=\"color:rgb(0, 0, 255)\">[a]</span>r</span>baz</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(128, 0, 128)",false,false,"rgb(0, 0, 255)"]}], +["<span style=\"color: rgb(0, 0, 255)\">foo<span id=purple>b[a]r</span>baz</span>", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "<span style=\"color:rgb(0, 0, 255)\">foo<span id=\"purple\">b<font color=\"#0000ff\">[a]</font>r</span>baz</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(128, 0, 128)",false,false,"rgb(0, 0, 255)"]}], +["<a href=http://www.google.com>foo[bar]baz</a>", + [["forecolor","blue"]], + "<a href=\"http://www.google.com\">foo[bar]baz</a>", + [true], + {"forecolor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 255)"]}], +["<a href=http://www.google.com>foo[bar]baz</a>", + [["forecolor","#0000ff"]], + "<a href=\"http://www.google.com\">foo[bar]baz</a>", + [true], + {"forecolor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 255)"]}], +["<a href=http://www.google.com>foo[bar]baz</a>", + [["forecolor","rgb(0,0,255)"]], + "<a href=\"http://www.google.com\">foo[bar]baz</a>", + [true], + {"forecolor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 255)"]}], +["<font color=\"blue\">[foo]</font>", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "<span style=\"color:rgb(0, 0, 255)\">[foo]</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 255)"]}], +["<font color=\"blue\">[foo]</font>", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "<font color=\"#0000ff\">[foo]</font>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 255)"]}], +["<font color=\"0000ff\">[foo]</font>", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "<span style=\"color:rgb(0, 0, 255)\">[foo]</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 255)"]}], +["<font color=\"0000ff\">[foo]</font>", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "<font color=\"#0000ff\">[foo]</font>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 255)"]}], +["<font color=\"#0000ff\">[foo]</font>", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "<span style=\"color:rgb(0, 0, 255)\">[foo]</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 255)"]}], +["<font color=\"#0000ff\">[foo]</font>", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "<font color=\"#0000ff\">[foo]</font>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 255)"]}], +["<span style=\"color: blue\">[foo]</span>", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "<span style=\"color:rgb(0, 0, 255)\">[foo]</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 255)"]}], +["<span style=\"color: blue\">[foo]</span>", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "<font color=\"#0000ff\">[foo]</font>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 255)"]}], +["<span style=\"color: #0000ff\">[foo]</span>", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "<span style=\"color:rgb(0, 0, 255)\">[foo]</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 255)"]}], +["<span style=\"color: #0000ff\">[foo]</span>", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "<font color=\"#0000ff\">[foo]</font>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 255)"]}], +["<span style=\"color: rgb(0, 0, 255)\">[foo]</span>", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "<span style=\"color:rgb(0, 0, 255)\">[foo]</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 255)"]}], +["<span style=\"color: rgb(0, 0, 255)\">[foo]</span>", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "<font color=\"#0000ff\">[foo]</font>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 255)"]}], +["<span style=\"color: rgb(0%, 0%, 100%)\">[foo]</span>", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "<span style=\"color:rgb(0, 0, 255)\">[foo]</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 255)"]}], +["<span style=\"color: rgb(0%, 0%, 100%)\">[foo]</span>", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "<font color=\"#0000ff\">[foo]</font>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 255)"]}], +["<span style=\"color: rgb( 0 ,0 ,255)\">[foo]</span>", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "<span style=\"color:rgb(0, 0, 255)\">[foo]</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 255)"]}], +["<span style=\"color: rgb( 0 ,0 ,255)\">[foo]</span>", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "<font color=\"#0000ff\">[foo]</font>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 255)"]}], +["<span style=\"color: rgba(0, 0, 255, 0.0)\">[foo]</span>", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "<span style=\"color:rgb(0, 0, 255)\">[foo]</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgba(0, 0, 255, 0)",false,false,"rgb(0, 0, 255)"]}], +["<span style=\"color: rgba(0, 0, 255, 0.0)\">[foo]</span>", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "<font color=\"#0000ff\">[foo]</font>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgba(0, 0, 255, 0)",false,false,"rgb(0, 0, 255)"]}], +["<span style=\"color: rgb(15, -10, 375)\">[foo]</span>", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "<span style=\"color:rgb(0, 0, 255)\">[foo]</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(15, 0, 255)",false,false,"rgb(0, 0, 255)"]}], +["<span style=\"color: rgb(15, -10, 375)\">[foo]</span>", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "<font color=\"#0000ff\">[foo]</font>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(15, 0, 255)",false,false,"rgb(0, 0, 255)"]}], +["<span style=\"color: rgba(0, 0, 0, 1)\">[foo]</span>", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "<span style=\"color:rgb(0, 0, 255)\">[foo]</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["<span style=\"color: rgba(0, 0, 0, 1)\">[foo]</span>", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "<font color=\"#0000ff\">[foo]</font>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["<span style=\"color: rgba(255, 255, 255, 1)\">[foo]</span>", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "<span style=\"color:rgb(0, 0, 255)\">[foo]</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(255, 255, 255)",false,false,"rgb(0, 0, 255)"]}], +["<span style=\"color: rgba(255, 255, 255, 1)\">[foo]</span>", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "<font color=\"#0000ff\">[foo]</font>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(255, 255, 255)",false,false,"rgb(0, 0, 255)"]}], +["<span style=\"color: rgba(0, 0, 255, 0.5)\">[foo]</span>", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "<span style=\"color:rgb(0, 0, 255)\">[foo]</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgba(0, 0, 255, 0.5)",false,false,"rgb(0, 0, 255)"]}], +["<span style=\"color: rgba(0, 0, 255, 0.5)\">[foo]</span>", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "<font color=\"#0000ff\">[foo]</font>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgba(0, 0, 255, 0.5)",false,false,"rgb(0, 0, 255)"]}], +["<span style=\"color: hsl(240, 100%, 50%)\">[foo]</span>", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "<span style=\"color:rgb(0, 0, 255)\">[foo]</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 255)"]}], +["<span style=\"color: hsl(240, 100%, 50%)\">[foo]</span>", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "<font color=\"#0000ff\">[foo]</font>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 255)"]}], +["<span style=\"color: cornsilk\">[foo]</span>", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "<span style=\"color:rgb(0, 0, 255)\">[foo]</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(255, 248, 220)",false,false,"rgb(0, 0, 255)"]}], +["<span style=\"color: cornsilk\">[foo]</span>", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "<font color=\"#0000ff\">[foo]</font>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(255, 248, 220)",false,false,"rgb(0, 0, 255)"]}], +["<span style=\"color: transparent\">[foo]</span>", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "<span style=\"color:rgb(0, 0, 255)\">[foo]</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["<span style=\"color: transparent\">[foo]</span>", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "<font color=\"#0000ff\">[foo]</font>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["<span style=\"color: currentColor\">[foo]</span>", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "<span style=\"color:rgb(0, 0, 255)\">[foo]</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["<span style=\"color: currentColor\">[foo]</span>", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "<font color=\"#0000ff\">[foo]</font>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["fo[o<font color=brown>b]ar</font>baz", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "fo<span style=\"color:rgb(0, 0, 255)\">[ob]</span><font color=\"brown\">ar</font>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[true,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["fo[o<font color=brown>b]ar</font>baz", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "fo<font color=\"#0000ff\">[ob]</font><font color=\"brown\">ar</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[true,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["foo<font color=brown>ba[r</font>b]az", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "foo<font color=\"brown\">ba</font><span style=\"color:rgb(0, 0, 255)\">[rb]</span>az", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[true,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}], +["foo<font color=brown>ba[r</font>b]az", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "foo<font color=\"brown\">ba</font><font color=\"#0000ff\">[rb]</font>az", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[true,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}], +["fo[o<font color=brown>bar</font>b]az", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "fo<span style=\"color:rgb(0, 0, 255)\">[obarb]</span>az", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[true,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["fo[o<font color=brown>bar</font>b]az", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "fo<font color=\"#0000ff\">[obarb]</font>az", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[true,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"]}], +["foo[<font color=brown>b]ar</font>baz", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "foo<span style=\"color:rgb(0, 0, 255)\">[b]</span><font color=\"brown\">ar</font>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}], +["foo[<font color=brown>b]ar</font>baz", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "foo<font color=\"#0000ff\">[b]</font><font color=\"brown\">ar</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}], +["foo<font color=brown>ba[r</font>]baz", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "foo<font color=\"brown\">ba</font><span style=\"color:rgb(0, 0, 255)\">[r]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}], +["foo<font color=brown>ba[r</font>]baz", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "foo<font color=\"brown\">ba</font><font color=\"#0000ff\">[r]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}], +["foo[<font color=brown>bar</font>]baz", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "foo[<span style=\"color:rgb(0, 0, 255)\">bar</span>]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}], +["foo[<font color=brown>bar</font>]baz", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "foo[<font color=\"#0000ff\">bar</font>]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}], +["foo<font color=brown>[bar]</font>baz", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "foo<span style=\"color:rgb(0, 0, 255)\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}], +["foo<font color=brown>[bar]</font>baz", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "foo<font color=\"#0000ff\">[bar]</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}], +["foo{<font color=brown>bar</font>}baz", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "foo{<span style=\"color:rgb(0, 0, 255)\">bar}</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}], +["foo{<font color=brown>bar</font>}baz", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "foo{<font color=\"#0000ff\">bar}</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}], +["<font color=brown>fo[o</font><span style=color:brown>b]ar</span>", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "<font color=\"brown\">fo</font><span style=\"color:rgb(0, 0, 255)\">[ob]</span><span style=\"color:rgb(165, 42, 42)\">ar</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}], +["<font color=brown>fo[o</font><span style=color:brown>b]ar</span>", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "<font color=\"brown\">fo</font><font color=\"#0000ff\">ob</font><span style=\"color:rgb(165, 42, 42)\">ar</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[false,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}], +["<span style=color:brown>fo[o</span><span style=color:#0000ff>b]ar</span>", + [["stylewithcss","true"],["forecolor","#0000FF"]], + "<span style=\"color:rgb(165, 42, 42)\">fo</span><span style=\"color:rgb(0, 0, 255)\">[ob]ar</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forecolor":[true,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}], +["<span style=color:brown>fo[o</span><span style=color:#0000ff>b]ar</span>", + [["stylewithcss","false"],["forecolor","#0000FF"]], + "<span style=\"color:rgb(165, 42, 42)\">fo</span><font color=\"#0000ff\">[ob]</font><span style=\"color:rgb(0, 0, 255)\">ar</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forecolor":[true,false,"rgb(165, 42, 42)",false,false,"rgb(0, 0, 255)"]}], + +// If contents of <font> are entirely selected, it should be reused. +["<font size=7>[abc]</font>", + [["styleWithCSS","false"],["foreColor","#ff0000"]], + ["<font color=\"#ff0000\" size=\"7\">[abc]</font>", + "<font size=\"7\" color=\"#ff0000\">[abc]</font>"], + [true,true], + {}], +["<font face=monospace>[abc]</font>", + [["styleWithCSS","false"],["foreColor","#ff0000"]], + ["<font face=\"monospace\" color=\"#ff0000\">[abc]</font>", + "<font color=\"#ff0000\" face=\"monospace\">[abc]</font>"], + [true,true], + {}], +["<font size=\"7\" face=monospace>[abc]</font>", + [["styleWithCSS","false"],["foreColor","#ff0000"]], + ["<font color=\"#ff0000\" face=\"monospace\" size=\"7\">[abc]</font>", + "<font color=\"#ff0000\" size=\"7\" face=\"monospace\">[abc]</font>", + "<font face=\"monospace\" color=\"#ff0000\" size=\"7\">[abc]</font>", + "<font face=\"monospace\" size=\"7\" color=\"#ff0000\">[abc]</font>", + "<font size=\"7\" color=\"#ff0000\" face=\"monospace\">[abc]</font>", + "<font size=\"7\" face=\"monospace\" color=\"#ff0000\">[abc]</font>"], + [true,true], + {}], +// but don't split existing <font> if partially selected. +["<font size=7>[a]bc</font>", + [["styleWithCSS","false"],["foreColor","#ff0000"]], + "<font size=\"7\"><font color=\"#ff0000\">[a]</font>bc</font>", + [true,true], + {}], +["<font size=7>ab[c]</font>", + [["styleWithCSS","false"],["foreColor","#ff0000"]], + "<font size=\"7\">ab<font color=\"#ff0000\">[c]</font></font>", + [true,true], + {}], +["<font face=monospace>[a]bc</font>", + [["styleWithCSS","false"],["foreColor","#ff0000"]], + "<font face=\"monospace\"><font color=\"#ff0000\">[a]</font>bc</font>", + [true,true], + {}], +["<font face=monospace>ab[c]</font>", + [["styleWithCSS","false"],["foreColor","#ff0000"]], + "<font face=\"monospace\">ab<font color=\"#ff0000\">[c]</font></font>", + [true,true], + {}], + +// When typing text, `styleWithCSS` value may have been changed at setting the +// style. In the cases, consider to use HTML or CSS style when typing text, +// but if it's impossible to set with `<font color="...">`, use +// `<span style="color:rgba(...)">` even if `styleWithCSS` is "false". +["a[]c", + [["styleWithCSS","true"],["foreColor","#0000FF"],["styleWithCSS","false"],["insertText","b"]], + "a<font color=\"#0000ff\">b</font>c", + [true,true,true,true], + {}], +["a[]c", + [["styleWithCSS","true"],["foreColor","rgb(0, 0, 255)"],["styleWithCSS","false"],["insertText","b"]], + "a<font color=\"#0000ff\">b</font>c", + [true,true,true,true], + {}], +["a[]c", + [["styleWithCSS","true"],["foreColor","rgba(0, 0, 255, 0.5)"],["styleWithCSS","false"],["insertText","b"]], + "a<span style=\"color:rgba(0, 0, 255, 0.5)\">b</span>c", + [true,true,true,true], + {}], +["a[]c", + [["styleWithCSS","true"],["foreColor","transparent"],["styleWithCSS","false"],["insertText","b"]], + "a<span style=\"color:rgba(0, 0, 0, 0)\">b</span>c", + [true,true,true,true], + {}], +["a[]c", + [["styleWithCSS","false"],["foreColor","#0000FF"],["styleWithCSS","true"],["insertText","b"]], + "a<span style=\"color:rgb(0, 0, 255)\">b</span>c", + [true,true,true,true], + {}], +["a[]c", + [["styleWithCSS","false"],["foreColor","rgb(0, 0, 255)"],["styleWithCSS","true"],["insertText","b"]], + "a<span style=\"color:rgb(0, 0, 255)\">b</span>c", + [true,true,true,true], + {}], +["a[]c", + [["styleWithCSS","false"],["foreColor","rgba(0, 0, 255, 0.5)"],["styleWithCSS","true"],["insertText","b"]], + "a<span style=\"color:rgba(0, 0, 255, 0.5)\">b</span>c", + [true,true,true,true], + {}], +["a[]c", + [["styleWithCSS","false"],["foreColor","transparent"],["styleWithCSS","true"],["insertText","b"]], + "a<span style=\"color:rgba(0, 0, 0, 0)\">b</span>c", + [true,true,true,true], + {}], +] diff --git a/testing/web-platform/tests/editing/data/formatblock.js b/testing/web-platform/tests/editing/data/formatblock.js new file mode 100644 index 0000000000..5cc040b1f1 --- /dev/null +++ b/testing/web-platform/tests/editing/data/formatblock.js @@ -0,0 +1,1895 @@ +// For documentation of the format, see README in this directory. +var browserTests = [ +["foo[]bar<p>extra", + [["defaultparagraphseparator","div"],["formatblock","<div>"]], + "<div>foo[]bar</div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"div"],"formatblock":[false,false,"",false,false,"div"]}], +["foo[]bar<p>extra", + [["defaultparagraphseparator","p"],["formatblock","<div>"]], + "<div>foo[]bar</div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"div"]}], +["<span>foo</span>{}<span>bar</span><p>extra", + [["defaultparagraphseparator","div"],["formatblock","<div>"]], + "<div><span>foo</span>{}<span>bar</span></div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"div"]}], +["<span>foo</span>{}<span>bar</span><p>extra", + [["defaultparagraphseparator","p"],["formatblock","<div>"]], + "<div><span>foo</span>{}<span>bar</span></div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"div"]}], +["<span>foo[</span><span>]bar</span><p>extra", + [["defaultparagraphseparator","div"],["formatblock","<div>"]], + "<div><span>foo[</span><span>]bar</span></div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"div"]}], +["<span>foo[</span><span>]bar</span><p>extra", + [["defaultparagraphseparator","p"],["formatblock","<div>"]], + "<div><span>foo[</span><span>]bar</span></div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"div"]}], +["foo[bar]baz<p>extra", + [["defaultparagraphseparator","div"],["formatblock","<div>"]], + "<div>foo[bar]baz</div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"div"]}], +["foo[bar]baz<p>extra", + [["defaultparagraphseparator","p"],["formatblock","<div>"]], + "<div>foo[bar]baz</div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"div"]}], +["foo]bar[baz<p>extra", + [["defaultparagraphseparator","div"],["formatblock","<div>"]], + "<div>foo[bar]baz</div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"div"]}], +["foo]bar[baz<p>extra", + [["defaultparagraphseparator","p"],["formatblock","<div>"]], + "<div>foo[bar]baz</div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"div"]}], +["{<p><p> <p>foo</p>}", + [["defaultparagraphseparator","div"],["formatblock","<div>"]], + "<div>{ foo}</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"p",false,false,"div"]}], +["{<p><p> <p>foo</p>}", + [["defaultparagraphseparator","p"],["formatblock","<div>"]], + "<div>{ foo}</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"p",false,false,"div"]}], +["foo[bar<i>baz]qoz</i>quz<p>extra", + [["defaultparagraphseparator","div"],["formatblock","<div>"]], + "<div>foo[bar<i>baz]qoz</i>quz</div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"div"]}], +["foo[bar<i>baz]qoz</i>quz<p>extra", + [["defaultparagraphseparator","p"],["formatblock","<div>"]], + "<div>foo[bar<i>baz]qoz</i>quz</div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"div"]}], +["<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>", + [["defaultparagraphseparator","div"],["formatblock","<div>"]], + "<table><tbody><tr><td>foo</td><td><div>b[a]r</div></td><td>baz</td></tr></tbody></table>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"div"]}], +["<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>", + [["defaultparagraphseparator","p"],["formatblock","<div>"]], + "<table><tbody><tr><td>foo</td><td><div>b[a]r</div></td><td>baz</td></tr></tbody></table>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"div"]}], +["<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table>", + [["defaultparagraphseparator","div"],["formatblock","<div>"]], + "<table><tbody><tr><td>foo</td>{<td><div>bar</div></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"div"]}], +["<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table>", + [["defaultparagraphseparator","p"],["formatblock","<div>"]], + "<table><tbody><tr><td>foo</td>{<td><div>bar</div></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"div"]}], +["<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table>", + [["defaultparagraphseparator","div"],["formatblock","<div>"]], + "<table><tbody><tr>{<td><div>foo</div></td><td><div>bar</div></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"div"]}], +["<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table>", + [["defaultparagraphseparator","p"],["formatblock","<div>"]], + "<table><tbody><tr>{<td><div>foo</div></td><td><div>bar</div></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"div"]}], +["<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>", + [["defaultparagraphseparator","div"],["formatblock","<div>"]], + "<table><tbody>{<tr><td><div>foo</div></td><td><div>bar</div></td><td><div>baz</div></td></tr>}</tbody></table>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"div"]}], +["<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>", + [["defaultparagraphseparator","p"],["formatblock","<div>"]], + "<table><tbody>{<tr><td><div>foo</div></td><td><div>bar</div></td><td><div>baz</div></td></tr>}</tbody></table>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"div"]}], +["<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>", + [["defaultparagraphseparator","div"],["formatblock","<div>"]], + "<table>{<tbody><tr><td><div>foo</div></td><td><div>bar</div></td><td><div>baz</div></td></tr></tbody>}</table>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"div"]}], +["<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>", + [["defaultparagraphseparator","p"],["formatblock","<div>"]], + "<table>{<tbody><tr><td><div>foo</div></td><td><div>bar</div></td><td><div>baz</div></td></tr></tbody>}</table>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"div"]}], +["{<table><tr><td>foo<td>bar<td>baz</table>}", + [["defaultparagraphseparator","div"],["formatblock","<div>"]], + "{<table><tbody><tr><td><div>foo</div></td><td><div>bar</div></td><td><div>baz</div></td></tr></tbody></table>}", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"div"]}], +["{<table><tr><td>foo<td>bar<td>baz</table>}", + [["defaultparagraphseparator","p"],["formatblock","<div>"]], + "{<table><tbody><tr><td><div>foo</div></td><td><div>bar</div></td><td><div>baz</div></td></tr></tbody></table>}", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"div"]}], +["<div>[foobar]</div>", + [["formatblock","<div>"]], + "<div>[foobar]</div>", + [true], + {"formatblock":[false,false,"div",false,false,"div"]}], +["<p>[foobar]</p>", + [["defaultparagraphseparator","div"],["formatblock","<div>"]], + "<div>[foobar]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"p",false,false,"div"]}], +["<p>[foobar]</p>", + [["defaultparagraphseparator","p"],["formatblock","<div>"]], + "<div>[foobar]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"p",false,false,"div"]}], +["<blockquote>[foobar]</blockquote>", + [["defaultparagraphseparator","div"],["formatblock","<div>"]], + "<div>[foobar]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"blockquote",false,false,"div"]}], +["<blockquote>[foobar]</blockquote>", + [["defaultparagraphseparator","p"],["formatblock","<div>"]], + "<div>[foobar]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"blockquote",false,false,"div"]}], +["<h1>[foobar]</h1>", + [["defaultparagraphseparator","div"],["formatblock","<div>"]], + "<div>[foobar]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"h1",false,false,"div"]}], +["<h1>[foobar]</h1>", + [["defaultparagraphseparator","p"],["formatblock","<div>"]], + "<div>[foobar]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"h1",false,false,"div"]}], +["<h2>[foobar]</h2>", + [["defaultparagraphseparator","div"],["formatblock","<div>"]], + "<div>[foobar]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"h2",false,false,"div"]}], +["<h2>[foobar]</h2>", + [["defaultparagraphseparator","p"],["formatblock","<div>"]], + "<div>[foobar]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"h2",false,false,"div"]}], +["<h3>[foobar]</h3>", + [["defaultparagraphseparator","div"],["formatblock","<div>"]], + "<div>[foobar]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"h3",false,false,"div"]}], +["<h3>[foobar]</h3>", + [["defaultparagraphseparator","p"],["formatblock","<div>"]], + "<div>[foobar]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"h3",false,false,"div"]}], +["<h4>[foobar]</h4>", + [["defaultparagraphseparator","div"],["formatblock","<div>"]], + "<div>[foobar]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"h4",false,false,"div"]}], +["<h4>[foobar]</h4>", + [["defaultparagraphseparator","p"],["formatblock","<div>"]], + "<div>[foobar]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"h4",false,false,"div"]}], +["<h5>[foobar]</h5>", + [["defaultparagraphseparator","div"],["formatblock","<div>"]], + "<div>[foobar]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"h5",false,false,"div"]}], +["<h5>[foobar]</h5>", + [["defaultparagraphseparator","p"],["formatblock","<div>"]], + "<div>[foobar]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"h5",false,false,"div"]}], +["<h6>[foobar]</h6>", + [["defaultparagraphseparator","div"],["formatblock","<div>"]], + "<div>[foobar]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"h6",false,false,"div"]}], +["<h6>[foobar]</h6>", + [["defaultparagraphseparator","p"],["formatblock","<div>"]], + "<div>[foobar]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"h6",false,false,"div"]}], +["<dl><dt>[foo]<dd>bar</dl>", + [["defaultparagraphseparator","div"],["formatblock","<div>"]], + "<div>[foo]</div><dl><dd>bar</dd></dl>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"dt",false,false,"div"]}], +["<dl><dt>[foo]<dd>bar</dl>", + [["defaultparagraphseparator","p"],["formatblock","<div>"]], + "<div>[foo]</div><dl><dd>bar</dd></dl>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"dt",false,false,"div"]}], +["<dl><dt>foo<dd>[bar]</dl>", + [["defaultparagraphseparator","div"],["formatblock","<div>"]], + "<dl><dt>foo</dt></dl><div>[bar]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"dd",false,false,"div"]}], +["<dl><dt>foo<dd>[bar]</dl>", + [["defaultparagraphseparator","p"],["formatblock","<div>"]], + "<dl><dt>foo</dt></dl><div>[bar]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"dd",false,false,"div"]}], +["<dl><dt>[foo<dd>bar]</dl>", + [["defaultparagraphseparator","div"],["formatblock","<div>"]], + "<div>[foo</div><div>bar]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"dl",false,false,"div"]}], +["<dl><dt>[foo<dd>bar]</dl>", + [["defaultparagraphseparator","p"],["formatblock","<div>"]], + "<div>[foo</div><div>bar]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"dl",false,false,"div"]}], +["<ol><li>[foobar]</ol>", + [["defaultparagraphseparator","div"],["formatblock","<div>"]], + "<ol><li><div>[foobar]</div></li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"div"]}], +["<ol><li>[foobar]</ol>", + [["defaultparagraphseparator","p"],["formatblock","<div>"]], + "<ol><li><div>[foobar]</div></li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"div"]}], +["<ul><li>[foobar]</ul>", + [["defaultparagraphseparator","div"],["formatblock","<div>"]], + "<ul><li><div>[foobar]</div></li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"div"]}], +["<ul><li>[foobar]</ul>", + [["defaultparagraphseparator","p"],["formatblock","<div>"]], + "<ul><li><div>[foobar]</div></li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"div"]}], +["<address>[foobar]</address>", + [["defaultparagraphseparator","div"],["formatblock","<div>"]], + "<div>[foobar]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"address",false,false,"div"]}], +["<address>[foobar]</address>", + [["defaultparagraphseparator","p"],["formatblock","<div>"]], + "<div>[foobar]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"address",false,false,"div"]}], +["<pre>[foobar]</pre>", + [["defaultparagraphseparator","div"],["formatblock","<div>"]], + "<div>[foobar]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"pre",false,false,"div"]}], +["<pre>[foobar]</pre>", + [["defaultparagraphseparator","p"],["formatblock","<div>"]], + "<div>[foobar]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"pre",false,false,"div"]}], +["<article>[foobar]</article>", + [["defaultparagraphseparator","div"],["formatblock","<div>"]], + "<div>[foobar]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"article",false,false,"div"]}], +["<article>[foobar]</article>", + [["defaultparagraphseparator","p"],["formatblock","<div>"]], + "<div>[foobar]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"article",false,false,"div"]}], +["<ins>[foobar]</ins>", + [["defaultparagraphseparator","div"],["formatblock","<div>"]], + "<div><ins>[foobar]</ins></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"div"]}], +["<ins>[foobar]</ins>", + [["defaultparagraphseparator","p"],["formatblock","<div>"]], + "<div><ins>[foobar]</ins></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"div"]}], +["<del>[foobar]</del>", + [["defaultparagraphseparator","div"],["formatblock","<div>"]], + "<div><del>[foobar]</del></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"div"]}], +["<del>[foobar]</del>", + [["defaultparagraphseparator","p"],["formatblock","<div>"]], + "<div><del>[foobar]</del></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"div"]}], +["<quasit>[foobar]</quasit>", + [["defaultparagraphseparator","div"],["formatblock","<div>"]], + "<div><quasit>[foobar]</quasit></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"div"]}], +["<quasit>[foobar]</quasit>", + [["defaultparagraphseparator","p"],["formatblock","<div>"]], + "<div><quasit>[foobar]</quasit></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"div"]}], +["<quasit style=\"display: block\">[foobar]</quasit>", + [["defaultparagraphseparator","div"],["formatblock","<div>"]], + "<div><quasit style=\"display:block\">[foobar]</quasit></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"div"]}], +["<quasit style=\"display: block\">[foobar]</quasit>", + [["defaultparagraphseparator","p"],["formatblock","<div>"]], + "<div><quasit style=\"display:block\">[foobar]</quasit></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"div"]}], +["foo[]bar<p>extra", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<p>foo[]bar</p><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"p"]}], +["foo[]bar<p>extra", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<p>foo[]bar</p><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"p"]}], +["<span>foo</span>{}<span>bar</span><p>extra", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<p><span>foo</span>{}<span>bar</span></p><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"p"]}], +["<span>foo</span>{}<span>bar</span><p>extra", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<p><span>foo</span>{}<span>bar</span></p><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"p"]}], +["<span>foo[</span><span>]bar</span><p>extra", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<p><span>foo[</span><span>]bar</span></p><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"p"]}], +["<span>foo[</span><span>]bar</span><p>extra", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<p><span>foo[</span><span>]bar</span></p><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"p"]}], +["foo[bar]baz<p>extra", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<p>foo[bar]baz</p><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"p"]}], +["foo[bar]baz<p>extra", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<p>foo[bar]baz</p><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"p"]}], +["foo]bar[baz<p>extra", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<p>foo[bar]baz</p><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"p"]}], +["foo]bar[baz<p>extra", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<p>foo[bar]baz</p><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"p"]}], +["{<p><p> <p>foo</p>}", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<p>{ foo}</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"p",false,false,"p"]}], +["{<p><p> <p>foo</p>}", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<p>{ foo}</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"p",false,false,"p"]}], +["foo[bar<i>baz]qoz</i>quz<p>extra", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<p>foo[bar<i>baz]qoz</i>quz</p><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"p"]}], +["foo[bar<i>baz]qoz</i>quz<p>extra", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<p>foo[bar<i>baz]qoz</i>quz</p><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"p"]}], +["<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<table><tbody><tr><td>foo</td><td><p>b[a]r</p></td><td>baz</td></tr></tbody></table>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"p"]}], +["<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<table><tbody><tr><td>foo</td><td><p>b[a]r</p></td><td>baz</td></tr></tbody></table>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"p"]}], +["<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table>", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<table><tbody><tr><td>foo</td>{<td><p>bar</p></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"p"]}], +["<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table>", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<table><tbody><tr><td>foo</td>{<td><p>bar</p></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"p"]}], +["<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table>", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<table><tbody><tr>{<td><p>foo</p></td><td><p>bar</p></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"p"]}], +["<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table>", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<table><tbody><tr>{<td><p>foo</p></td><td><p>bar</p></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"p"]}], +["<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<table><tbody>{<tr><td><p>foo</p></td><td><p>bar</p></td><td><p>baz</p></td></tr>}</tbody></table>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"p"]}], +["<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<table><tbody>{<tr><td><p>foo</p></td><td><p>bar</p></td><td><p>baz</p></td></tr>}</tbody></table>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"p"]}], +["<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<table>{<tbody><tr><td><p>foo</p></td><td><p>bar</p></td><td><p>baz</p></td></tr></tbody>}</table>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"p"]}], +["<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<table>{<tbody><tr><td><p>foo</p></td><td><p>bar</p></td><td><p>baz</p></td></tr></tbody>}</table>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"p"]}], +["{<table><tr><td>foo<td>bar<td>baz</table>}", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "{<table><tbody><tr><td><p>foo</p></td><td><p>bar</p></td><td><p>baz</p></td></tr></tbody></table>}", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"p"]}], +["{<table><tr><td>foo<td>bar<td>baz</table>}", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "{<table><tbody><tr><td><p>foo</p></td><td><p>bar</p></td><td><p>baz</p></td></tr></tbody></table>}", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"p"]}], +["<div>[foobar]</div>", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<p>[foobar]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"div",false,false,"p"]}], +["<div>[foobar]</div>", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<p>[foobar]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"div",false,false,"p"]}], +["<p>[foobar]</p>", + [["formatblock","<p>"]], + "<p>[foobar]</p>", + [true], + {"formatblock":[false,false,"p",false,false,"p"]}], +["<blockquote>[foobar]</blockquote>", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<p>[foobar]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"blockquote",false,false,"p"]}], +["<blockquote>[foobar]</blockquote>", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<p>[foobar]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"blockquote",false,false,"p"]}], +["<h1>[foobar]</h1>", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<p>[foobar]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"h1",false,false,"p"]}], +["<h1>[foobar]</h1>", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<p>[foobar]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"h1",false,false,"p"]}], +["<h2>[foobar]</h2>", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<p>[foobar]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"h2",false,false,"p"]}], +["<h2>[foobar]</h2>", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<p>[foobar]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"h2",false,false,"p"]}], +["<h3>[foobar]</h3>", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<p>[foobar]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"h3",false,false,"p"]}], +["<h3>[foobar]</h3>", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<p>[foobar]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"h3",false,false,"p"]}], +["<h4>[foobar]</h4>", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<p>[foobar]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"h4",false,false,"p"]}], +["<h4>[foobar]</h4>", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<p>[foobar]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"h4",false,false,"p"]}], +["<h5>[foobar]</h5>", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<p>[foobar]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"h5",false,false,"p"]}], +["<h5>[foobar]</h5>", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<p>[foobar]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"h5",false,false,"p"]}], +["<h6>[foobar]</h6>", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<p>[foobar]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"h6",false,false,"p"]}], +["<h6>[foobar]</h6>", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<p>[foobar]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"h6",false,false,"p"]}], +["<dl><dt>[foo]<dd>bar</dl>", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<p>[foo]</p><dl><dd>bar</dd></dl>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"dt",false,false,"p"]}], +["<dl><dt>[foo]<dd>bar</dl>", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<p>[foo]</p><dl><dd>bar</dd></dl>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"dt",false,false,"p"]}], +["<dl><dt>foo<dd>[bar]</dl>", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<dl><dt>foo</dt></dl><p>[bar]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"dd",false,false,"p"]}], +["<dl><dt>foo<dd>[bar]</dl>", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<dl><dt>foo</dt></dl><p>[bar]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"dd",false,false,"p"]}], +["<dl><dt>[foo<dd>bar]</dl>", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<p>[foo</p><p>bar]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[true,false,"dl",false,false,"p"]}], +["<dl><dt>[foo<dd>bar]</dl>", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<p>[foo</p><p>bar]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[true,false,"dl",false,false,"p"]}], +["<ol><li>[foobar]</ol>", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<ol><li><p>[foobar]</p></li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"p"]}], +["<ol><li>[foobar]</ol>", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<ol><li><p>[foobar]</p></li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"p"]}], +["<ul><li>[foobar]</ul>", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<ul><li><p>[foobar]</p></li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"p"]}], +["<ul><li>[foobar]</ul>", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<ul><li><p>[foobar]</p></li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"p"]}], +["<address>[foobar]</address>", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<p>[foobar]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"address",false,false,"p"]}], +["<address>[foobar]</address>", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<p>[foobar]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"address",false,false,"p"]}], +["<pre>[foobar]</pre>", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<p>[foobar]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"pre",false,false,"p"]}], +["<pre>[foobar]</pre>", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<p>[foobar]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"pre",false,false,"p"]}], +["<listing>[foobar]</listing>", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<p><listing>[foobar]</listing></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"p"]}], +["<listing>[foobar]</listing>", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<p><listing>[foobar]</listing></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"p"]}], +["<xmp>[foobar]</xmp>", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<p><xmp>[foobar]</xmp></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"p"]}], +["<xmp>[foobar]</xmp>", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<p><xmp>[foobar]</xmp></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"p"]}], +["<article>[foobar]</article>", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<p>[foobar]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"article",false,false,"p"]}], +["<article>[foobar]</article>", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<p>[foobar]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"article",false,false,"p"]}], +["<ins>[foobar]</ins>", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<p><ins>[foobar]</ins></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"p"]}], +["<ins>[foobar]</ins>", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<p><ins>[foobar]</ins></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"p"]}], +["<del>[foobar]</del>", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<p><del>[foobar]</del></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"p"]}], +["<del>[foobar]</del>", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<p><del>[foobar]</del></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"p"]}], +["<quasit>[foobar]</quasit>", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<p><quasit>[foobar]</quasit></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"p"]}], +["<quasit>[foobar]</quasit>", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<p><quasit>[foobar]</quasit></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"p"]}], +["<quasit style=\"display: block\">[foobar]</quasit>", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<p><quasit style=\"display:block\">[foobar]</quasit></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"p"]}], +["<quasit style=\"display: block\">[foobar]</quasit>", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<p><quasit style=\"display:block\">[foobar]</quasit></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"p"]}], +["<blockquote>[foo]</blockquote><p>extra", + [["formatblock","<blockquote>"]], + "<blockquote>[foo]</blockquote><p>extra</p>", + [true], + {"formatblock":[false,false,"blockquote",false,false,"blockquote"]}], +["<blockquote><p>[foo]<p>bar</blockquote><p>extra", + [["formatblock","<blockquote>"]], + "<blockquote><blockquote>[foo]</blockquote><p>bar</p></blockquote><p>extra</p>", + [true], + {"formatblock":[false,false,"p",false,false,"blockquote"]}], +["[foo]<blockquote>bar</blockquote><p>extra", + [["formatblock","<blockquote>"]], + "<blockquote>[foo]</blockquote><blockquote>bar</blockquote><p>extra</p>", + [true], + {"formatblock":[false,false,"",false,false,"blockquote"]}], +["<p>[foo<p>bar]<p>baz", + [["formatblock","<blockquote>"]], + [ + "<blockquote>[foo<br>bar]</blockquote><p>baz</p>", + "<blockquote>[foo</blockquote><blockquote>bar]</blockquote><p>baz</p>", + ], + [true], + {"formatblock":[false,false,"",false,false,"blockquote"]}], +["<section>[foo]</section>", + [["formatblock","<blockquote>"]], + "<blockquote>[foo]</blockquote>", + [true], + {"formatblock":[false,false,"section",false,false,"blockquote"]}], +["<section><p>[foo]</section>", + [["formatblock","<blockquote>"]], + "<section><blockquote>[foo]</blockquote></section>", + [true], + {"formatblock":[false,false,"p",false,false,"blockquote"]}], +["<section><hgroup><h1>[foo]</h1><h2>bar</h2></hgroup><p>baz</section>", + [["formatblock","<blockquote>"]], + "<section><hgroup><blockquote>[foo]</blockquote><h2>bar</h2></hgroup><p>baz</p></section>", + [true], + {"formatblock":[false,false,"h1",false,false,"blockquote"]}], +["<section>[foo]</section>", + [["formatblock","<article>"]], + "<article>[foo]</article>", + [true], + {"formatblock":[false,false,"section",false,false,"article"]}], +["<div>[foobar]</div>", + [["defaultparagraphseparator","div"],["formatblock","<address>"]], + "<address>[foobar]</address>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"div",false,false,"address"]}], +["<div>[foobar]</div>", + [["defaultparagraphseparator","p"],["formatblock","<address>"]], + "<address>[foobar]</address>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"div",false,false,"address"]}], +["<div>[foobar]</div>", + [["formatblock","<article>"]], + "<article>[foobar]</article>", + [true], + {"formatblock":[false,false,"div",false,false,"article"]}], +["<div>[foobar]</div>", + [["formatblock","<blockquote>"]], + "<blockquote>[foobar]</blockquote>", + [true], + {"formatblock":[false,false,"div",false,false,"blockquote"]}], +["<div>[foobar]</div>", + [["defaultparagraphseparator","div"],["formatblock","<dd>"]], + "<dl><dd>[foobar]</dd></dl>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"div",false,false,"dd"]}], +["<div>[foobar]</div>", + [["defaultparagraphseparator","p"],["formatblock","<dd>"]], + "<dl><dd>[foobar]</dd></dl>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"div",false,false,"dd"]}], +["<div>[foobar]</div>", + [["formatblock","<del>"]], + "<div>[foobar]</div>", + [false], + {"formatblock":[false,false,"div",false,false,"div"]}], +["<div>[foobar]</div>", + [["formatblock","<dl>"]], + "<div>[foobar]</div>", + [false], + {"formatblock":[false,false,"div",false,false,"div"]}], +["<div>[foobar]</div>", + [["defaultparagraphseparator","div"],["formatblock","<dt>"]], + "<dl><dt>[foobar]</dt></dl>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"div",false,false,"dt"]}], +["<div>[foobar]</div>", + [["defaultparagraphseparator","p"],["formatblock","<dt>"]], + "<dl><dt>[foobar]</dt></dl>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"div",false,false,"dt"]}], +["<div>[foobar]</div>", + [["defaultparagraphseparator","div"],["formatblock","<h1>"]], + "<h1>[foobar]</h1>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"div",false,false,"h1"]}], +["<div>[foobar]</div>", + [["defaultparagraphseparator","p"],["formatblock","<h1>"]], + "<h1>[foobar]</h1>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"div",false,false,"h1"]}], +["<div>[foobar]</div>", + [["defaultparagraphseparator","div"],["formatblock","<h2>"]], + "<h2>[foobar]</h2>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"div",false,false,"h2"]}], +["<div>[foobar]</div>", + [["defaultparagraphseparator","p"],["formatblock","<h2>"]], + "<h2>[foobar]</h2>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"div",false,false,"h2"]}], +["<div>[foobar]</div>", + [["defaultparagraphseparator","div"],["formatblock","<h3>"]], + "<h3>[foobar]</h3>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"div",false,false,"h3"]}], +["<div>[foobar]</div>", + [["defaultparagraphseparator","p"],["formatblock","<h3>"]], + "<h3>[foobar]</h3>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"div",false,false,"h3"]}], +["<div>[foobar]</div>", + [["defaultparagraphseparator","div"],["formatblock","<h4>"]], + "<h4>[foobar]</h4>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"div",false,false,"h4"]}], +["<div>[foobar]</div>", + [["defaultparagraphseparator","p"],["formatblock","<h4>"]], + "<h4>[foobar]</h4>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"div",false,false,"h4"]}], +["<div>[foobar]</div>", + [["defaultparagraphseparator","div"],["formatblock","<h5>"]], + "<h5>[foobar]</h5>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"div",false,false,"h5"]}], +["<div>[foobar]</div>", + [["defaultparagraphseparator","p"],["formatblock","<h5>"]], + "<h5>[foobar]</h5>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"div",false,false,"h5"]}], +["<div>[foobar]</div>", + [["defaultparagraphseparator","div"],["formatblock","<h6>"]], + "<h6>[foobar]</h6>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"div",false,false,"h6"]}], +["<div>[foobar]</div>", + [["defaultparagraphseparator","p"],["formatblock","<h6>"]], + "<h6>[foobar]</h6>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"div",false,false,"h6"]}], +["<div>[foobar]</div>", + [["formatblock","<ins>"]], + "<div>[foobar]</div>", + [false], + {"formatblock":[false,false,"div",false,false,"div"]}], +["<div>[foobar]</div>", + [["formatblock","<li>"]], + "<div>[foobar]</div>", + [false], + {"formatblock":[false,false,"div",false,false,"div"]}], +["<div>[foobar]</div>", + [["formatblock","<ol>"]], + "<div>[foobar]</div>", + [false], + {"formatblock":[false,false,"div",false,false,"div"]}], +["<div>[foobar]</div>", + [["defaultparagraphseparator","p"],["formatblock","<pre>"]], + "<pre>[foobar]</pre>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"div",false,false,"pre"]}], +["<div>[foobar]</div>", + [["formatblock","<ul>"]], + "<div>[foobar]</div>", + [false], + {"formatblock":[false,false,"div",false,false,"div"]}], +["<div>[foobar]</div>", + [["formatblock","<quasit>"]], + "<div>[foobar]</div>", + [false], + {"formatblock":[false,false,"div",false,false,"div"]}], +["<p>[foobar]</p>", + [["defaultparagraphseparator","div"],["formatblock","<address>"]], + "<address>[foobar]</address>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"p",false,false,"address"]}], +["<p>[foobar]</p>", + [["defaultparagraphseparator","p"],["formatblock","<address>"]], + "<address>[foobar]</address>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"p",false,false,"address"]}], +["<p>[foobar]</p>", + [["formatblock","<article>"]], + "<article>[foobar]</article>", + [true], + {"formatblock":[false,false,"p",false,false,"article"]}], +["<p>[foobar]</p>", + [["formatblock","<aside>"]], + "<aside>[foobar]</aside>", + [true], + {"formatblock":[false,false,"p",false,false,"aside"]}], +["<p>[foobar]</p>", + [["formatblock","<blockquote>"]], + "<blockquote>[foobar]</blockquote>", + [true], + {"formatblock":[false,false,"p",false,false,"blockquote"]}], +["<p>[foobar]</p>", + [["formatblock","<body>"]], + "<p>[foobar]</p>", + [false], + {"formatblock":[false,false,"p",false,false,"p"]}], +["<p>[foobar]</p>", + [["defaultparagraphseparator","div"],["formatblock","<dd>"]], + "<dl><dd>[foobar]</dd></dl>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"p",false,false,"dd"]}], +["<p>[foobar]</p>", + [["defaultparagraphseparator","p"],["formatblock","<dd>"]], + "<dl><dd>[foobar]</dd></dl>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"p",false,false,"dd"]}], +["<p>[foobar]</p>", + [["formatblock","<del>"]], + "<p>[foobar]</p>", + [false], + {"formatblock":[false,false,"p",false,false,"p"]}], +["<p>[foobar]</p>", + [["formatblock","<details>"]], + "<p>[foobar]</p>", + [false], + {"formatblock":[false,false,"p",false,false,"p"]}], +["<p>[foobar]</p>", + [["formatblock","<dir>"]], + "<p>[foobar]</p>", + [false], + {"formatblock":[false,false,"p",false,false,"p"]}], +["<p>[foobar]</p>", + [["formatblock","<dl>"]], + "<p>[foobar]</p>", + [false], + {"formatblock":[false,false,"p",false,false,"p"]}], +["<p>[foobar]</p>", + [["defaultparagraphseparator","div"],["formatblock","<dt>"]], + "<dl><dt>[foobar]</dt></dl>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"p",false,false,"dt"]}], +["<p>[foobar]</p>", + [["defaultparagraphseparator","p"],["formatblock","<dt>"]], + "<dl><dt>[foobar]</dt></dl>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"p",false,false,"dt"]}], +["<p>[foobar]</p>", + [["formatblock","<fieldset>"]], + "<p>[foobar]</p>", + [false], + {"formatblock":[false,false,"p",false,false,"p"]}], +["<p>[foobar]</p>", + [["formatblock","<figcaption>"]], + "<p>[foobar]</p>", + [false], + {"formatblock":[false,false,"p",false,false,"p"]}], +["<p>[foobar]</p>", + [["formatblock","<figure>"]], + "<p>[foobar]</p>", + [false], + {"formatblock":[false,false,"p",false,false,"p"]}], +["<p>[foobar]</p>", + [["formatblock","<footer>"]], + "<footer>[foobar]</footer>", + [true], + {"formatblock":[false,false,"p",false,false,"footer"]}], +["<p>[foobar]</p>", + [["formatblock","<form>"]], + "<p>[foobar]</p>", + [false], + {"formatblock":[false,false,"p",false,false,"p"]}], +["<p>[foobar]</p>", + [["defaultparagraphseparator","div"],["formatblock","<h1>"]], + "<h1>[foobar]</h1>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"p",false,false,"h1"]}], +["<p>[foobar]</p>", + [["defaultparagraphseparator","p"],["formatblock","<h1>"]], + "<h1>[foobar]</h1>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"p",false,false,"h1"]}], +["<p>[foobar]</p>", + [["defaultparagraphseparator","div"],["formatblock","<h2>"]], + "<h2>[foobar]</h2>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"p",false,false,"h2"]}], +["<p>[foobar]</p>", + [["defaultparagraphseparator","p"],["formatblock","<h2>"]], + "<h2>[foobar]</h2>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"p",false,false,"h2"]}], +["<p>[foobar]</p>", + [["defaultparagraphseparator","div"],["formatblock","<h3>"]], + "<h3>[foobar]</h3>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"p",false,false,"h3"]}], +["<p>[foobar]</p>", + [["defaultparagraphseparator","p"],["formatblock","<h3>"]], + "<h3>[foobar]</h3>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"p",false,false,"h3"]}], +["<p>[foobar]</p>", + [["defaultparagraphseparator","div"],["formatblock","<h4>"]], + "<h4>[foobar]</h4>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"p",false,false,"h4"]}], +["<p>[foobar]</p>", + [["defaultparagraphseparator","p"],["formatblock","<h4>"]], + "<h4>[foobar]</h4>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"p",false,false,"h4"]}], +["<p>[foobar]</p>", + [["defaultparagraphseparator","div"],["formatblock","<h5>"]], + "<h5>[foobar]</h5>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"p",false,false,"h5"]}], +["<p>[foobar]</p>", + [["defaultparagraphseparator","p"],["formatblock","<h5>"]], + "<h5>[foobar]</h5>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"p",false,false,"h5"]}], +["<p>[foobar]</p>", + [["defaultparagraphseparator","div"],["formatblock","<h6>"]], + "<h6>[foobar]</h6>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"p",false,false,"h6"]}], +["<p>[foobar]</p>", + [["defaultparagraphseparator","p"],["formatblock","<h6>"]], + "<h6>[foobar]</h6>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"p",false,false,"h6"]}], +["<p>[foobar]</p>", + [["formatblock","<header>"]], + "<header>[foobar]</header>", + [true], + {"formatblock":[false,false,"p",false,false,"header"]}], +["<p>[foobar]</p>", + [["formatblock","<head>"]], + "<p>[foobar]</p>", + [false], + {"formatblock":[false,false,"p",false,false,"p"]}], +["<p>[foobar]</p>", + [["formatblock","<hgroup>"]], + "<hgroup>[foobar]</hgroup>", + [true], + {"formatblock":[false,false,"p",false,false,"hgroup"]}], +["<p>[foobar]</p>", + [["formatblock","<hr>"]], + "<p>[foobar]</p>", + [false], + {"formatblock":[false,false,"p",false,false,"p"]}], +["<p>[foobar]</p>", + [["formatblock","<html>"]], + "<p>[foobar]</p>", + [false], + {"formatblock":[false,false,"p",false,false,"p"]}], +["<p>[foobar]</p>", + [["formatblock","<ins>"]], + "<p>[foobar]</p>", + [false], + {"formatblock":[false,false,"p",false,false,"p"]}], +["<p>[foobar]</p>", + [["formatblock","<li>"]], + "<p>[foobar]</p>", + [false], + {"formatblock":[false,false,"p",false,false,"p"]}], +["<p>[foobar]</p>", + [["formatblock","<listing>"]], + "<p>[foobar]</p>", + [false], + {"formatblock":[false,false,"p",false,false,"p"]}], +["<p>[foobar]</p>", + [["formatblock","<menu>"]], + "<p>[foobar]</p>", + [false], + {"formatblock":[false,false,"p",false,false,"p"]}], +["<p>[foobar]</p>", + [["formatblock","<nav>"]], + "<nav>[foobar]</nav>", + [true], + {"formatblock":[false,false,"p",false,false,"nav"]}], +["<p>[foobar]</p>", + [["formatblock","<ol>"]], + "<p>[foobar]</p>", + [false], + {"formatblock":[false,false,"p",false,false,"p"]}], +["<p>[foobar]</p>", + [["formatblock","<plaintext>"]], + "<p>[foobar]</p>", + [false], + {"formatblock":[false,false,"p",false,false,"p"]}], +["<p>[foobar]</p>", + [["defaultparagraphseparator","div"],["formatblock","<pre>"]], + "<pre>[foobar]</pre>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"p",false,false,"pre"]}], +["<p>[foobar]</p>", + [["defaultparagraphseparator","p"],["formatblock","<pre>"]], + "<pre>[foobar]</pre>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"p",false,false,"pre"]}], +["<p>[foobar]</p>", + [["formatblock","<section>"]], + "<section>[foobar]</section>", + [true], + {"formatblock":[false,false,"p",false,false,"section"]}], +["<p>[foobar]</p>", + [["formatblock","<ul>"]], + "<p>[foobar]</p>", + [false], + {"formatblock":[false,false,"p",false,false,"p"]}], +["<p>[foobar]</p>", + [["formatblock","<xmp>"]], + "<p>[foobar]</p>", + [false], + {"formatblock":[false,false,"p",false,false,"p"]}], +["<p>[foobar]</p>", + [["formatblock","<quasit>"]], + "<p>[foobar]</p>", + [false], + {"formatblock":[false,false,"p",false,false,"p"]}], +["<p>[foo<p>bar]", + [["defaultparagraphseparator","div"],["formatblock","<address>"]], + [ + "<address>[foo<br>bar]</address>", + "<address>[foo</address><address>bar]</address>", + ], + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"p",false,false,"address"]}], +["<p>[foo<p>bar]", + [["defaultparagraphseparator","p"],["formatblock","<address>"]], + [ + "<address>[foo<br>bar]</address>", + "<address>[foo</address><address>bar]</address>", + ], + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"p",false,false,"address"]}], +["<p>[foo<p>bar]", + [["formatblock","<article>"]], + [ + "<article>[foo<br>bar]</article>", + "<article>[foo</article><article>bar]</article>", + ], + [true], + {"formatblock":[false,false,"p",false,false,"article"]}], +["<p>[foo<p>bar]", + [["formatblock","<aside>"]], + [ + "<aside>[foo<br>bar]</aside>", + "<aside>[foo</aside><aside>bar]</aside>", + ], + [true], + {"formatblock":[false,false,"p",false,false,"aside"]}], +["<p>[foo<p>bar]", + [["formatblock","<blockquote>"]], + [ + "<blockquote>[foo<br>bar]</blockquote>", + "<blockquote>[foo</blockquote><blockquote>bar]</blockquote>", + ], + [true], + {"formatblock":[false,false,"p",false,false,"blockquote"]}], +["<p>[foo<p>bar]", + [["formatblock","<body>"]], + "<p>[foo</p><p>bar]</p>", + [false], + {"formatblock":[false,false,"p",false,false,"p"]}], +["<p>[foo<p>bar]", + [["defaultparagraphseparator","div"],["formatblock","<dd>"]], + "<dl><dd>[foo</dd><dd>bar]</dd></dl>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"p",false,false,"dd"]}], +["<p>[foo<p>bar]", + [["defaultparagraphseparator","p"],["formatblock","<dd>"]], + "<dl><dd>[foo</dd><dd>bar]</dd></dl>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"p",false,false,"dd"]}], +["<p>[foo<p>bar]", + [["formatblock","<del>"]], + "<p>[foo</p><p>bar]</p>", + [false], + {"formatblock":[false,false,"p",false,false,"p"]}], +["<p>[foo<p>bar]", + [["formatblock","<details>"]], + "<p>[foo</p><p>bar]</p>", + [false], + {"formatblock":[false,false,"p",false,false,"p"]}], +["<p>[foo<p>bar]", + [["formatblock","<dir>"]], + "<p>[foo</p><p>bar]</p>", + [false], + {"formatblock":[false,false,"p",false,false,"p"]}], +["<p>[foo<p>bar]", + [["defaultparagraphseparator","div"],["formatblock","<div>"]], + [ + "<div>[foo<br>bar]</div>", + "<div>[foo</div><div>bar]</div>", + ], + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"p",false,false,"div"]}], +["<p>[foo<p>bar]", + [["defaultparagraphseparator","p"],["formatblock","<div>"]], + [ + "<div>[foo<br>bar]</div>", + "<div>[foo</div><div>bar]</div>", + ], + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"p",false,false,"div"]}], +["<p>[foo<p>bar]", + [["formatblock","<dl>"]], + "<p>[foo</p><p>bar]</p>", + [false], + {"formatblock":[false,false,"p",false,false,"p"]}], +["<p>[foo<p>bar]", + [["defaultparagraphseparator","div"],["formatblock","<dt>"]], + "<dl><dt>[foo</dt><dt>bar]</dt></dl>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"p",false,false,"dt"]}], +["<p>[foo<p>bar]", + [["defaultparagraphseparator","p"],["formatblock","<dt>"]], + "<dl><dt>[foo</dt><dt>bar]</dt></dl>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"p",false,false,"dt"]}], +["<p>[foo<p>bar]", + [["formatblock","<fieldset>"]], + "<p>[foo</p><p>bar]</p>", + [false], + {"formatblock":[false,false,"p",false,false,"p"]}], +["<p>[foo<p>bar]", + [["formatblock","<figcaption>"]], + "<p>[foo</p><p>bar]</p>", + [false], + {"formatblock":[false,false,"p",false,false,"p"]}], +["<p>[foo<p>bar]", + [["formatblock","<figure>"]], + "<p>[foo</p><p>bar]</p>", + [false], + {"formatblock":[false,false,"p",false,false,"p"]}], +["<p>[foo<p>bar]", + [["formatblock","<footer>"]], + [ + "<footer>[foo<br>bar]</footer>", + "<footer>[foo</footer><footer>bar]</footer>", + ], + [true], + {"formatblock":[false,false,"p",false,false,"footer"]}], +["<p>[foo<p>bar]", + [["formatblock","<form>"]], + "<p>[foo</p><p>bar]</p>", + [false], + {"formatblock":[false,false,"p",false,false,"p"]}], +["<p>[foo<p>bar]", + [["defaultparagraphseparator","div"],["formatblock","<h1>"]], + [ + "<h1>[foo<br>bar]</h1>", + "<h1>[foo</h1><h1>bar]</h1>", + ], + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"p",false,false,"h1"]}], +["<p>[foo<p>bar]", + [["defaultparagraphseparator","p"],["formatblock","<h1>"]], + [ + "<h1>[foo<br>bar]</h1>", + "<h1>[foo</h1><h1>bar]</h1>", + ], + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"p",false,false,"h1"]}], +["<p>[foo<p>bar]", + [["defaultparagraphseparator","div"],["formatblock","<h2>"]], + [ + "<h2>[foo<br>bar]</h2>", + "<h2>[foo</h2><h2>bar]</h2>", + ], + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"p",false,false,"h2"]}], +["<p>[foo<p>bar]", + [["defaultparagraphseparator","p"],["formatblock","<h2>"]], + [ + "<h2>[foo<br>bar]</h2>", + "<h2>[foo</h2><h2>bar]</h2>", + ], + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"p",false,false,"h2"]}], +["<p>[foo<p>bar]", + [["defaultparagraphseparator","div"],["formatblock","<h3>"]], + [ + "<h3>[foo<br>bar]</h3>", + "<h3>[foo</h3><h3>bar]</h3>", + ], + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"p",false,false,"h3"]}], +["<p>[foo<p>bar]", + [["defaultparagraphseparator","p"],["formatblock","<h3>"]], + [ + "<h3>[foo<br>bar]</h3>", + "<h3>[foo</h3><h3>bar]</h3>", + ], + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"p",false,false,"h3"]}], +["<p>[foo<p>bar]", + [["defaultparagraphseparator","div"],["formatblock","<h4>"]], + [ + "<h4>[foo<br>bar]</h4>", + "<h4>[foo</h4><h4>bar]</h4>", + ], + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"p",false,false,"h4"]}], +["<p>[foo<p>bar]", + [["defaultparagraphseparator","p"],["formatblock","<h4>"]], + [ + "<h4>[foo<br>bar]</h4>", + "<h4>[foo</h4><h4>bar]</h4>", + ], + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"p",false,false,"h4"]}], +["<p>[foo<p>bar]", + [["defaultparagraphseparator","div"],["formatblock","<h5>"]], + [ + "<h5>[foo<br>bar]</h5>", + "<h5>[foo</h5><h5>bar]</h5>", + ], + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"p",false,false,"h5"]}], +["<p>[foo<p>bar]", + [["defaultparagraphseparator","p"],["formatblock","<h5>"]], + [ + "<h5>[foo<br>bar]</h5>", + "<h5>[foo</h5><h5>bar]</h5>", + ], + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"p",false,false,"h5"]}], +["<p>[foo<p>bar]", + [["defaultparagraphseparator","div"],["formatblock","<h6>"]], + [ + "<h6>[foo<br>bar]</h6>", + "<h6>[foo</h6><h6>bar]</h6>", + ], + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"p",false,false,"h6"]}], +["<p>[foo<p>bar]", + [["defaultparagraphseparator","p"],["formatblock","<h6>"]], + [ + "<h6>[foo<br>bar]</h6>", + "<h6>[foo</h6><h6>bar]</h6>", + ], + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"p",false,false,"h6"]}], +["<p>[foo<p>bar]", + [["formatblock","<header>"]], + [ + "<header>[foo<br>bar]</header>", + "<header>[foo</header><header>bar]</header>", + ], + [true], + {"formatblock":[false,false,"p",false,false,"header"]}], +["<p>[foo<p>bar]", + [["formatblock","<head>"]], + "<p>[foo</p><p>bar]</p>", + [false], + {"formatblock":[false,false,"p",false,false,"p"]}], +["<p>[foo<p>bar]", + [["formatblock","<hgroup>"]], + [ + "<hgroup>[foo<br>bar]</hgroup>", + "<hgroup>[foo</hgroup><hgroup>bar]</hgroup>", + ], + [true], + {"formatblock":[false,false,"p",false,false,"hgroup"]}], +["<p>[foo<p>bar]", + [["formatblock","<hr>"]], + "<p>[foo</p><p>bar]</p>", + [false], + {"formatblock":[false,false,"p",false,false,"p"]}], +["<p>[foo<p>bar]", + [["formatblock","<html>"]], + "<p>[foo</p><p>bar]</p>", + [false], + {"formatblock":[false,false,"p",false,false,"p"]}], +["<p>[foo<p>bar]", + [["formatblock","<ins>"]], + "<p>[foo</p><p>bar]</p>", + [false], + {"formatblock":[false,false,"p",false,false,"p"]}], +["<p>[foo<p>bar]", + [["formatblock","<li>"]], + "<p>[foo</p><p>bar]</p>", + [false], + {"formatblock":[false,false,"p",false,false,"p"]}], +["<p>[foo<p>bar]", + [["formatblock","<listing>"]], + "<p>[foo</p><p>bar]</p>", + [false], + {"formatblock":[false,false,"p",false,false,"p"]}], +["<p>[foo<p>bar]", + [["formatblock","<menu>"]], + "<p>[foo</p><p>bar]</p>", + [false], + {"formatblock":[false,false,"p",false,false,"p"]}], +["<p>[foo<p>bar]", + [["formatblock","<nav>"]], + [ + "<nav>[foo<br>bar]</nav>", + "<nav>[foo</nav><nav>bar]</nav>", + ], + [true], + {"formatblock":[false,false,"p",false,false,"nav"]}], +["<p>[foo<p>bar]", + [["formatblock","<ol>"]], + "<p>[foo</p><p>bar]</p>", + [false], + {"formatblock":[false,false,"p",false,false,"p"]}], +["<p>[foo<p>bar]", + [["formatblock","<p>"]], + "<p>[foo</p><p>bar]</p>", + [true], + {"formatblock":[false,false,"p",false,false,"p"]}], +["<p>[foo<p>bar]", + [["formatblock","<plaintext>"]], + "<p>[foo</p><p>bar]</p>", + [false], + {"formatblock":[false,false,"p",false,false,"p"]}], +["<p>[foo<p>bar]", + [["defaultparagraphseparator","div"],["formatblock","<pre>"]], + [ + "<pre>[foo<br>bar]</pre>", + "<pre>[foo</pre><pre>bar]</pre>", + ], + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"p",false,false,"pre"]}], +["<p>[foo<p>bar]", + [["defaultparagraphseparator","p"],["formatblock","<pre>"]], + [ + "<pre>[foo<br>bar]</pre>", + "<pre>[foo</pre><pre>bar]</pre>", + ], + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"p",false,false,"pre"]}], +["<p>[foo<p>bar]", + [["formatblock","<section>"]], + [ + "<section>[foo<br>bar]</section>", + "<section>[foo</section><section>bar]</section>", + ], + [true], + {"formatblock":[false,false,"p",false,false,"section"]}], +["<p>[foo<p>bar]", + [["formatblock","<ul>"]], + "<p>[foo</p><p>bar]</p>", + [false], + {"formatblock":[false,false,"p",false,false,"p"]}], +["<p>[foo<p>bar]", + [["formatblock","<xmp>"]], + "<p>[foo</p><p>bar]</p>", + [false], + {"formatblock":[false,false,"p",false,false,"p"]}], +["<p>[foo<p>bar]", + [["formatblock","<quasit>"]], + "<p>[foo</p><p>bar]</p>", + [false], + {"formatblock":[false,false,"p",false,false,"p"]}], +["<div>[foobar]</div>", + [["defaultparagraphseparator","div"],["formatblock","p"]], + "<p>[foobar]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"div",false,false,"p"]}], +["<div>[foobar]</div>", + [["defaultparagraphseparator","p"],["formatblock","p"]], + "<p>[foobar]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"div",false,false,"p"]}], +["<ol><li>[foo]<li>bar</ol>", + [["defaultparagraphseparator","div"],["formatblock","<div>"]], + "<ol><li><div>[foo]</div></li><li>bar</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"div"]}], +["<ol><li>[foo]<li>bar</ol>", + [["defaultparagraphseparator","p"],["formatblock","<div>"]], + "<ol><li><div>[foo]</div></li><li>bar</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"div"]}], +["<h1>[foo]<br>bar</h1>", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<p>[foo]</p><h1>bar</h1>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"h1",false,false,"p"]}], +["<h1>[foo]<br>bar</h1>", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<p>[foo]</p><h1>bar</h1>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"h1",false,false,"p"]}], +["<h1>foo<br>[bar]</h1>", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<h1>foo</h1><p>[bar]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"h1",false,false,"p"]}], +["<h1>foo<br>[bar]</h1>", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<h1>foo</h1><p>[bar]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"h1",false,false,"p"]}], +["<h1>[foo<br>bar]</h1>", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<p>[foo<br>bar]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"h1",false,false,"p"]}], +["<h1>[foo<br>bar]</h1>", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<p>[foo<br>bar]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"h1",false,false,"p"]}], +["<h1>[foo]<br>bar</h1>", + [["formatblock","<address>"]], + "<address>[foo]</address><h1>bar</h1>", + [true], + {"formatblock":[false,false,"h1",false,false,"address"]}], +["<h1>foo<br>[bar]</h1>", + [["formatblock","<address>"]], + "<h1>foo</h1><address>[bar]</address>", + [true], + {"formatblock":[false,false,"h1",false,false,"address"]}], +["<h1>[foo<br>bar]</h1>", + [["formatblock","<address>"]], + "<address>[foo<br>bar]</address>", + [true], + {"formatblock":[false,false,"h1",false,false,"address"]}], +["<h1>[foo]<br>bar</h1>", + [["formatblock","<pre>"]], + "<pre>[foo]</pre><h1>bar</h1>", + [true], + {"formatblock":[false,false,"h1",false,false,"pre"]}], +["<h1>foo<br>[bar]</h1>", + [["formatblock","<pre>"]], + "<h1>foo</h1><pre>[bar]</pre>", + [true], + {"formatblock":[false,false,"h1",false,false,"pre"]}], +["<h1>[foo<br>bar]</h1>", + [["formatblock","<pre>"]], + "<pre>[foo<br>bar]</pre>", + [true], + {"formatblock":[false,false,"h1",false,false,"pre"]}], +["<h1>[foo]<br>bar</h1>", + [["formatblock","<h2>"]], + "<h2>[foo]</h2><h1>bar</h1>", + [true], + {"formatblock":[false,false,"h1",false,false,"h2"]}], +["<h1>foo<br>[bar]</h1>", + [["formatblock","<h2>"]], + "<h1>foo</h1><h2>[bar]</h2>", + [true], + {"formatblock":[false,false,"h1",false,false,"h2"]}], +["<h1>[foo<br>bar]</h1>", + [["formatblock","<h2>"]], + "<h2>[foo<br>bar]</h2>", + [true], + {"formatblock":[false,false,"h1",false,false,"h2"]}], +["<p>[foo]<br>bar</p>", + [["formatblock","<h1>"]], + "<h1>[foo]</h1><p>bar</p>", + [true], + {"formatblock":[false,false,"p",false,false,"h1"]}], +["<p>foo<br>[bar]</p>", + [["formatblock","<h1>"]], + "<p>foo</p><h1>[bar]</h1>", + [true], + {"formatblock":[false,false,"p",false,false,"h1"]}], +["<p>[foo<br>bar]</p>", + [["defaultparagraphseparator","div"],["formatblock","<h1>"]], + "<h1>[foo<br>bar]</h1>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"p",false,false,"h1"]}], +["<p>[foo<br>bar]</p>", + [["defaultparagraphseparator","p"],["formatblock","<h1>"]], + "<h1>[foo<br>bar]</h1>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"p",false,false,"h1"]}], +["<p>[foo]<br>bar</p>", + [["formatblock","<address>"]], + "<address>[foo]</address><p>bar</p>", + [true], + {"formatblock":[false,false,"p",false,false,"address"]}], +["<p>foo<br>[bar]</p>", + [["formatblock","<address>"]], + "<p>foo</p><address>[bar]</address>", + [true], + {"formatblock":[false,false,"p",false,false,"address"]}], +["<p>[foo<br>bar]</p>", + [["defaultparagraphseparator","div"],["formatblock","<address>"]], + "<address>[foo<br>bar]</address>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"p",false,false,"address"]}], +["<p>[foo<br>bar]</p>", + [["defaultparagraphseparator","p"],["formatblock","<address>"]], + "<address>[foo<br>bar]</address>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"p",false,false,"address"]}], +["<p>[foo]<br>bar</p>", + [["formatblock","<pre>"]], + "<pre>[foo]</pre><p>bar</p>", + [true], + {"formatblock":[false,false,"p",false,false,"pre"]}], +["<p>foo<br>[bar]</p>", + [["formatblock","<pre>"]], + "<p>foo</p><pre>[bar]</pre>", + [true], + {"formatblock":[false,false,"p",false,false,"pre"]}], +["<p>[foo<br>bar]</p>", + [["defaultparagraphseparator","div"],["formatblock","<pre>"]], + "<pre>[foo<br>bar]</pre>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"p",false,false,"pre"]}], +["<p>[foo<br>bar]</p>", + [["defaultparagraphseparator","p"],["formatblock","<pre>"]], + "<pre>[foo<br>bar]</pre>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"p",false,false,"pre"]}], +["<address>[foo]<br>bar</address>", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<p>[foo]</p><address>bar</address>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"address",false,false,"p"]}], +["<address>[foo]<br>bar</address>", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<p>[foo]</p><address>bar</address>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"address",false,false,"p"]}], +["<address>foo<br>[bar]</address>", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<address>foo</address><p>[bar]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"address",false,false,"p"]}], +["<address>foo<br>[bar]</address>", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<address>foo</address><p>[bar]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"address",false,false,"p"]}], +["<address>[foo<br>bar]</address>", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<p>[foo<br>bar]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"address",false,false,"p"]}], +["<address>[foo<br>bar]</address>", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<p>[foo<br>bar]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"address",false,false,"p"]}], +["<address>[foo]<br>bar</address>", + [["formatblock","<pre>"]], + "<pre>[foo]</pre><address>bar</address>", + [true], + {"formatblock":[false,false,"address",false,false,"pre"]}], +["<address>foo<br>[bar]</address>", + [["formatblock","<pre>"]], + "<address>foo</address><pre>[bar]</pre>", + [true], + {"formatblock":[false,false,"address",false,false,"pre"]}], +["<address>[foo<br>bar]</address>", + [["formatblock","<pre>"]], + "<pre>[foo<br>bar]</pre>", + [true], + {"formatblock":[false,false,"address",false,false,"pre"]}], +["<address>[foo]<br>bar</address>", + [["formatblock","<h1>"]], + "<h1>[foo]</h1><address>bar</address>", + [true], + {"formatblock":[false,false,"address",false,false,"h1"]}], +["<address>foo<br>[bar]</address>", + [["formatblock","<h1>"]], + "<address>foo</address><h1>[bar]</h1>", + [true], + {"formatblock":[false,false,"address",false,false,"h1"]}], +["<address>[foo<br>bar]</address>", + [["formatblock","<h1>"]], + "<h1>[foo<br>bar]</h1>", + [true], + {"formatblock":[false,false,"address",false,false,"h1"]}], +["<pre>[foo]<br>bar</pre>", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<p>[foo]</p><pre>bar</pre>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"pre",false,false,"p"]}], +["<pre>[foo]<br>bar</pre>", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<p>[foo]</p><pre>bar</pre>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"pre",false,false,"p"]}], +["<pre>foo<br>[bar]</pre>", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<pre>foo</pre><p>[bar]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"pre",false,false,"p"]}], +["<pre>foo<br>[bar]</pre>", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<pre>foo</pre><p>[bar]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"pre",false,false,"p"]}], +["<pre>[foo<br>bar]</pre>", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<p>[foo<br>bar]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"pre",false,false,"p"]}], +["<pre>[foo<br>bar]</pre>", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<p>[foo<br>bar]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"pre",false,false,"p"]}], +["<pre>[foo]<br>bar</pre>", + [["formatblock","<address>"]], + "<address>[foo]</address><pre>bar</pre>", + [true], + {"formatblock":[false,false,"pre",false,false,"address"]}], +["<pre>foo<br>[bar]</pre>", + [["formatblock","<address>"]], + "<pre>foo</pre><address>[bar]</address>", + [true], + {"formatblock":[false,false,"pre",false,false,"address"]}], +["<pre>[foo<br>bar]</pre>", + [["formatblock","<address>"]], + "<address>[foo<br>bar]</address>", + [true], + {"formatblock":[false,false,"pre",false,false,"address"]}], +["<pre>[foo]<br>bar</pre>", + [["formatblock","<h1>"]], + "<h1>[foo]</h1><pre>bar</pre>", + [true], + {"formatblock":[false,false,"pre",false,false,"h1"]}], +["<pre>foo<br>[bar]</pre>", + [["formatblock","<h1>"]], + "<pre>foo</pre><h1>[bar]</h1>", + [true], + {"formatblock":[false,false,"pre",false,false,"h1"]}], +["<pre>[foo<br>bar]</pre>", + [["formatblock","<h1>"]], + "<h1>[foo<br>bar]</h1>", + [true], + {"formatblock":[false,false,"pre",false,false,"h1"]}], +["<p>[foo</p>bar]", + [["defaultparagraphseparator","div"],["formatblock","<h1>"]], + "<h1>[foo<br>bar]</h1>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[true,false,"",false,false,"h1"]}], +["<p>[foo</p>bar]", + [["defaultparagraphseparator","p"],["formatblock","<h1>"]], + "<h1>[foo<br>bar]</h1>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[true,false,"",false,false,"h1"]}], +["[foo<p>bar]</p>", + [["defaultparagraphseparator","div"],["formatblock","<h1>"]], + "<h1>[foo<br>bar]</h1>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[true,false,"",false,false,"h1"]}], +["[foo<p>bar]</p>", + [["defaultparagraphseparator","p"],["formatblock","<h1>"]], + "<h1>[foo<br>bar]</h1>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[true,false,"",false,false,"h1"]}], +["<div>[foo<p>bar]</p></div>", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<p>[foo</p><div><p>bar]</p></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[true,false,"",false,false,"p"]}], +["<div>[foo<p>bar]</p></div>", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<p>[foo</p><div><p>bar]</p></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[true,false,"",false,false,"p"]}], +["<xmp>[foo]</xmp>", + [["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<p><xmp>[foo]</xmp></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"p"]}], +["<xmp>[foo]</xmp>", + [["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<p><xmp>[foo]</xmp></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"p"]}], +["<xmp>[foo]</xmp>", + [["defaultparagraphseparator","div"],["formatblock","<div>"]], + "<div><xmp>[foo]</xmp></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"div"]}], +["<xmp>[foo]</xmp>", + [["defaultparagraphseparator","p"],["formatblock","<div>"]], + "<div><xmp>[foo]</xmp></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"div"]}], +["<div><ol><li>[foo]</ol></div>", + [["defaultparagraphseparator","div"],["formatblock","<div>"]], + "<div><ol><li>[foo]</li></ol></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"div",false,false,"div"]}], +["<div><ol><li>[foo]</ol></div>", + [["defaultparagraphseparator","p"],["formatblock","<div>"]], + "<div><ol><li>[foo]</li></ol></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"div",false,false,"div"]}], +["<div><table><tr><td>[foo]</table></div>", + [["defaultparagraphseparator","div"],["formatblock","<div>"]], + "<div><table><tbody><tr><td><div>[foo]</div></td></tr></tbody></table></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"div"]}], +["<div><table><tr><td>[foo]</table></div>", + [["defaultparagraphseparator","p"],["formatblock","<div>"]], + "<div><table><tbody><tr><td><div>[foo]</div></td></tr></tbody></table></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"div"]}], +["<p>[foo<h1>bar]</h1>", + [["defaultparagraphseparator","div"],["formatblock","<div>"]], + "<div>[foo</div><div>bar]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[true,false,"",false,false,"div"]}], +["<p>[foo<h1>bar]</h1>", + [["defaultparagraphseparator","p"],["formatblock","<div>"]], + "<div>[foo</div><div>bar]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[true,false,"",false,false,"div"]}], +["<h1>[foo</h1><h2>bar]</h2>", + [["defaultparagraphseparator","div"],["formatblock","<div>"]], + "<div>[foo</div><div>bar]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[true,false,"",false,false,"div"]}], +["<h1>[foo</h1><h2>bar]</h2>", + [["defaultparagraphseparator","p"],["formatblock","<div>"]], + "<div>[foo</div><div>bar]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[true,false,"",false,false,"div"]}], +["<div>[foo</div>bar]", + [["defaultparagraphseparator","div"],["formatblock","<div>"]], + "<div>[foo</div><div>bar]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[true,false,"",false,false,"div"]}], +["<div>[foo</div>bar]", + [["defaultparagraphseparator","p"],["formatblock","<div>"]], + "<div>[foo</div><div>bar]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[true,false,"",false,false,"div"]}], +["<div style=color:blue>[foo]</div>", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<p style=\"color:rgb(0, 0, 255)\">[foo]</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"div",false,false,"p"]}], +["<div style=color:blue>[foo]</div>", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["formatblock","<p>"]], + "<p style=\"color:rgb(0, 0, 255)\">[foo]</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"formatblock":[false,false,"div",false,false,"p"]}], +["<div style=color:blue>[foo]</div>", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<p style=\"color:rgb(0, 0, 255)\">[foo]</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"div",false,false,"p"]}], +["<div style=color:blue>[foo]</div>", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["formatblock","<p>"]], + "<p style=\"color:rgb(0, 0, 255)\">[foo]</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"formatblock":[false,false,"div",false,false,"p"]}], +["{<p>foo</p>ba]r", + [["defaultparagraphseparator","div"],["formatblock","<h1>"]], + "<h1>{foo<br>ba]r</h1>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[true,false,"",false,false,"h1"]}], +["{<p>foo</p>ba]r", + [["defaultparagraphseparator","p"],["formatblock","<h1>"]], + "<h1>{foo<br>ba]r</h1>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[true,false,"",false,false,"h1"]}], +["<div><div contenteditable=false><span contenteditable>[foo]</span></div></div>", + [["formatblock","p"]], + "<div><div contenteditable=\"false\"><span contenteditable=\"\">[foo]</span></div></div>", // <span> cannot have <p>, so, do nothing + [false], + {"formatblock":[false,false,"",false,false,""]}], +["<div><p contenteditable=false><span contenteditable>[foo]</span></p></div>", + [["formatblock","p"]], + "<div><p contenteditable=\"false\"><span contenteditable=\"\">[foo]</span></p></div>", // <span> cannot have <p>, so, do nothing + [false], + {"formatblock":[false,false,"",false,false,""]}], +["<div><div contenteditable=false><p contenteditable>[foo]</p></div></div>", + [["formatblock","div"]], + "<div><div contenteditable=\"false\"><p contenteditable=\"\">[foo]</p></div></div>", // <p> cannot have <div>, so, do nothing + [false], + {"formatblock":[false,false,"",false,false,""]}], +["<div><div contenteditable=false><div contenteditable>[foo]</div></div></div>", + [["formatblock","p"]], + "<div><div contenteditable=\"false\"><div contenteditable=\"\"><p>[foo]</p></div></div></div>", // <div> can have <p>, so, wrap it with <p> + [true], + {"formatblock":[false,false,"",false,false,"p"]}], +["<div><div contenteditable=false><div contenteditable>[foo]</div></div></div>", + [["formatblock","div"]], + "<div><div contenteditable=\"false\"><div contenteditable=\"\"><div>[foo]</div></div></div></div>", // <div> can have <div>, so, wrap it with <div> + [true], + {"formatblock":[false,false,"",false,false,"div"]}], + +["<span style=display:block>abc</span><span style=display:block>[def]</span><span style=display:block>ghi</span>", + [["formatblock","div"]], + "<span style=\"display:block\">abc</span><div><span style=\"display:block\">def</span></div><span style=\"display:block\">ghi</span>", + [true], + {"formatblock":[false,false,"",false,false,"div"]}], +] diff --git a/testing/web-platform/tests/editing/data/forwarddelete.js b/testing/web-platform/tests/editing/data/forwarddelete.js new file mode 100644 index 0000000000..ea590a4fbb --- /dev/null +++ b/testing/web-platform/tests/editing/data/forwarddelete.js @@ -0,0 +1,2984 @@ +class MyCustomElement extends HTMLElement {}; +customElements.define("custom-element", MyCustomElement); +// For documentation of the format, see README in this directory. +var browserTests = [ +["foo[]", + [["forwarddelete",""]], + "foo{}", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<span>foo[]</span>", + [["forwarddelete",""]], + "<span>foo</span>{}", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[]</p>", + [["forwarddelete",""]], + "<p>foo{}</p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[]bar", + [["forwarddelete",""]], + "foo[]ar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<span>foo</span>{}<span>bar</span>", + [["forwarddelete",""]], + "<span>foo</span><span>{}ar</span>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<span>foo[</span><span>]bar</span>", + [["forwarddelete",""]], + "<span>foo[]</span><span>bar</span>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<span style=display:none>bar</span>baz", + [["stylewithcss","true"],["forwarddelete",""]], + "foo{}az", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<span style=display:none>bar</span>baz", + [["stylewithcss","false"],["forwarddelete",""]], + "foo{}az", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<script>bar</script>baz", + [["forwarddelete",""]], + "foo{}az", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["fo[]öbar", + [["forwarddelete",""]], + "fo[]bar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["fo[]öbar", + [["forwarddelete",""]], + "fo[]bar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["fo[]ö̧bar", + [["forwarddelete",""]], + "fo[]bar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["[]öbar", + [["forwarddelete",""]], + "{}bar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["[]öbar", + [["forwarddelete",""]], + "{}bar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["[]ö̧bar", + [["forwarddelete",""]], + "{}bar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["[]שָׁלוֹם", + [["forwarddelete",""]], + "{}לוֹם", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["שָׁל[]וֹם", + [["forwarddelete",""]], + "שָׁל[]ם", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[]</p><p>bar</p>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p>foo{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[]</p><p>bar</p>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p>foo{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[]</p>bar", + [["forwarddelete",""]], + "<p>foo{}bar</p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<p>bar</p>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<p>bar</p>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[]<br></p><p>bar</p>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p>foo{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[]<br></p><p>bar</p>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p>foo{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[]<br></p>bar", + [["forwarddelete",""]], + "<p>foo{}bar</p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<br><p>bar</p>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<br><p>bar</p>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>{}<br></p>foo", + [["forwarddelete",""]], + "<p>{}foo</p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<p>{}<span><br></span></p>foo", + [["forwarddelete",""]], + "<p>{}foo</p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo{}<p><br>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "foo{}", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["foo{}<p><br>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "foo{}", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["foo{}<p><span><br></span>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "foo{}", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["foo{}<p><span><br></span>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "foo{}", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["foo{}<br><p><br>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "foo{}", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["foo{}<br><p><br>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "foo{}", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["foo{}<span><br></span><p><br>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "foo{}", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["foo{}<span><br></span><p><br>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "foo{}", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["foo{}<br><p><span><br></span>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "foo{}", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["foo{}<br><p><span><br></span>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "foo{}", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["foo{}<span><br></span><p><span><br></span>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "foo{}", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["foo{}<span><br></span><p><span><br></span>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "foo{}", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["foo{}<p>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "foo{}", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["foo{}<p>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "foo{}", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<table><tr><td>[]b</table>foo", + [["forwarddelete",""]], + "<table><tbody><tr><td>[]<br></td></tr></tbody></table>foo", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<table><tr><td>{}</table>foo", + [["forwarddelete",""]], + "<table><tbody><tr><td>{}</td></tr></tbody></table>foo", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<table><tr><td>{}<br></table>foo", + [["forwarddelete",""]], + "<table><tbody><tr><td>{}<br></td></tr></tbody></table>foo", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<table><tr><td>{}<span><br></span></table>foo", + [["forwarddelete",""]], + "<table><tbody><tr><td>{}<span><br></span></td></tr></tbody></table>foo", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div><p>foo[]</p></div><p>bar</p>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<div><p>foo{}bar</p></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<div><p>foo[]</p></div><p>bar</p>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<div><p>foo{}bar</p></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[]</p><div><p>bar</p></div>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p>foo{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[]</p><div><p>bar</p></div>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p>foo{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<div><p>foo[]</p></div><div><p>bar</p></div>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<div><p>foo{}bar</p></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<div><p>foo[]</p></div><div><p>bar</p></div>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<div><p>foo{}bar</p></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<div><p>foo[]</p></div>bar", + [["forwarddelete",""]], + "<div><p>foo{}bar</p></div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<div><p>bar</p></div>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<div><p>bar</p></div>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<div>foo[]</div><div>bar</div>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<div>foo{}bar</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<div>foo[]</div><div>bar</div>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<div>foo{}bar</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<pre>foo[]</pre>bar", + [["forwarddelete",""]], + "<pre>foo{}bar</pre>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<br>bar", + [["forwarddelete",""]], + "foo{}bar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<b>foo[]</b><br>bar", + [["forwarddelete",""]], + "<b>foo</b>{}bar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<hr>bar", + [["forwarddelete",""]], + "foo{}bar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[]<hr><p>bar", + [["forwarddelete",""]], + "<p>foo{}</p><p>bar</p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[]</p><br><p>bar</p>", + [["forwarddelete",""]], + "<p>foo{}</p><p>bar</p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[]</p><br><br><p>bar</p>", + [["forwarddelete",""]], + "<p>foo{}</p><br><p>bar</p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[]</p><img src=/img/lion.svg><p>bar", + [["forwarddelete",""]], + "<p>foo{}<img src=\"/img/lion.svg\"></p><p>bar</p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<img src=/img/lion.svg>bar", + [["forwarddelete",""]], + "foo{}bar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<a>bar</a>", + [["forwarddelete",""]], + "foo<a>{}ar</a>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<a href=/>bar</a>", + [["forwarddelete",""]], + "foo<a href=\"/\">{}ar</a>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<a name=abc>bar</a>", + [["forwarddelete",""]], + "foo<a name=\"abc\">{}ar</a>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<a href=/ name=abc>bar</a>", + [["forwarddelete",""]], + "foo<a href=\"/\" name=\"abc\">{}ar</a>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<span><a>bar</a></span>", + [["forwarddelete",""]], + "foo<span><a>{}ar</a></span>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<span><a href=/>bar</a></span>", + [["forwarddelete",""]], + "foo<span><a href=\"/\">{}ar</a></span>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<span><a name=abc>bar</a></span>", + [["forwarddelete",""]], + "foo<span><a name=\"abc\">{}ar</a></span>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<span><a href=/ name=abc>bar</a></span>", + [["forwarddelete",""]], + "foo<span><a href=\"/\" name=\"abc\">{}ar</a></span>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<a>foo[]</a>bar", + [["forwarddelete",""]], + "<a>foo</a>{}ar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<a href=/>foo[]</a>bar", + [["forwarddelete",""]], + "<a href=\"/\">foo</a>{}ar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<a name=abc>foo[]</a>bar", + [["forwarddelete",""]], + "<a name=\"abc\">foo</a>{}ar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<a href=/ name=abc>foo[]</a>bar", + [["forwarddelete",""]], + "<a href=\"/\" name=\"abc\">foo</a>{}ar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo [] ", + [["forwarddelete",""]], + "foo []", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["[] foo", + [["forwarddelete",""]], + "{} foo", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[] bar", + [["forwarddelete",""]], + "foo[] bar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[] bar", + [["forwarddelete",""]], + "foo[] bar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[] bar", + [["forwarddelete",""]], + "foo[] bar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[] bar", + [["forwarddelete",""]], + "foo[]bar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[] bar", + [["forwarddelete",""]], + "foo[] bar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo [] bar", + [["forwarddelete",""]], + "foo [] bar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo [] bar", + [["forwarddelete",""]], + "foo []bar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[] <span> </span> bar", + [["forwarddelete",""]], + "foo[]<span> </span> bar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo []<span> </span> bar", + [["forwarddelete",""]], + "foo {} bar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo <span> </span>[] bar", + [["forwarddelete",""]], + "foo <span> </span>{}bar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<b>foo[] </b> bar", + [["forwarddelete",""]], + "<b>foo[]</b> bar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<b>foo[] </b> bar", + [["forwarddelete",""]], + "<b>foo[]</b> bar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<b>foo[] </b> bar", + [["forwarddelete",""]], + "<b>foo[]</b> bar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<b>foo[] </b> bar", + [["forwarddelete",""]], + "<b>foo[]</b>bar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<pre>foo [] </pre>", + [["forwarddelete",""]], + "<pre>foo []</pre>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<pre>[] foo</pre>", + [["forwarddelete",""]], + "<pre>{} foo</pre>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<pre>foo[] bar</pre>", + [["forwarddelete",""]], + "<pre>foo[] bar</pre>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<pre>foo[] bar</pre>", + [["forwarddelete",""]], + "<pre>foo[] bar</pre>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<pre>foo[] bar</pre>", + [["forwarddelete",""]], + "<pre>foo[] bar</pre>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div style=white-space:pre>foo [] </div>", + [["forwarddelete",""]], + "<div style=\"white-space:pre\">foo []</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div style=white-space:pre>[] foo</div>", + [["forwarddelete",""]], + "<div style=\"white-space:pre\">{} foo</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div style=white-space:pre>foo[] bar</div>", + [["forwarddelete",""]], + "<div style=\"white-space:pre\">foo[] bar</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div style=white-space:pre>foo[] bar</div>", + [["forwarddelete",""]], + "<div style=\"white-space:pre\">foo[] bar</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div style=white-space:pre>foo[] bar</div>", + [["forwarddelete",""]], + "<div style=\"white-space:pre\">foo[] bar</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div style=white-space:pre-wrap>foo [] </div>", + [["forwarddelete",""]], + "<div style=\"white-space:pre-wrap\">foo []</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div style=white-space:pre-wrap>[] foo</div>", + [["forwarddelete",""]], + "<div style=\"white-space:pre-wrap\">{} foo</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div style=white-space:pre-wrap>foo[] bar</div>", + [["forwarddelete",""]], + "<div style=\"white-space:pre-wrap\">foo[] bar</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div style=white-space:pre-wrap>foo[] bar</div>", + [["forwarddelete",""]], + "<div style=\"white-space:pre-wrap\">foo[] bar</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div style=white-space:pre-wrap>foo[] bar</div>", + [["forwarddelete",""]], + "<div style=\"white-space:pre-wrap\">foo[] bar</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div style=white-space:pre-line>foo [] </div>", + [["forwarddelete",""]], + "<div style=\"white-space:pre-line\">foo []</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div style=white-space:pre-line>[] foo</div>", + [["forwarddelete",""]], + "<div style=\"white-space:pre-line\">{} foo</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div style=white-space:pre-line>foo[] bar</div>", + [["forwarddelete",""]], + "<div style=\"white-space:pre-line\">foo[] bar</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div style=white-space:pre-line>foo[] bar</div>", + [["forwarddelete",""]], + "<div style=\"white-space:pre-line\">foo[] bar</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div style=white-space:pre-line>foo[] bar</div>", + [["forwarddelete",""]], + "<div style=\"white-space:pre-line\">foo[]bar</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div style=white-space:nowrap>foo [] </div>", + [["forwarddelete",""]], + "<div style=\"white-space:nowrap\">foo []</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div style=white-space:nowrap>[] foo</div>", + [["forwarddelete",""]], + "<div style=\"white-space:nowrap\">{} foo</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div style=white-space:nowrap>foo[] bar</div>", + [["forwarddelete",""]], + "<div style=\"white-space:nowrap\">foo[] bar</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div style=white-space:nowrap>foo[] bar</div>", + [["forwarddelete",""]], + "<div style=\"white-space:nowrap\">foo[] bar</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div style=white-space:nowrap>foo[] bar</div>", + [["forwarddelete",""]], + "<div style=\"white-space:nowrap\">foo[]bar</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<table><tr><td>bar</table>baz", + [["forwarddelete",""]], + "foo{<table><tbody><tr><td>bar</td></tr></tbody></table>}baz", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo<table><tr><td>bar[]</table>baz", + [["forwarddelete",""]], + "foo<table><tbody><tr><td>bar[]</td></tr></tbody></table>baz", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[]<table><tr><td>bar</table><p>baz", + [["forwarddelete",""]], + "<p>foo</p>{<table><tbody><tr><td>bar</td></tr></tbody></table>}<p>baz</p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<table><tr><td>foo[]<td>bar</table>", + [["forwarddelete",""]], + "<table><tbody><tr><td>foo{}</td><td>bar</td></tr></tbody></table>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<table><tr><td>foo[]<tr><td>bar</table>", + [["forwarddelete",""]], + "<table><tbody><tr><td>foo{}</td></tr><tr><td>bar</td></tr></tbody></table>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<br><table><tr><td>bar</table>baz", + [["forwarddelete",""]], + "foo{<table><tbody><tr><td>bar</td></tr></tbody></table>}baz", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo<table><tr><td>bar[]<br></table>baz", + [["forwarddelete",""]], + "foo<table><tbody><tr><td>bar[]</td></tr></tbody></table>baz", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[]<br><table><tr><td>bar</table><p>baz", + [["forwarddelete",""]], + "<p>foo</p>{<table><tbody><tr><td>bar</td></tr></tbody></table>}<p>baz</p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo<table><tr><td>bar[]<br></table><p>baz", + [["forwarddelete",""]], + "<p>foo</p><table><tbody><tr><td>bar[]</td></tr></tbody></table><p>baz</p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<table><tr><td>foo[]<br><td>bar</table>", + [["forwarddelete",""]], + "<table><tbody><tr><td>foo{}</td><td>bar</td></tr></tbody></table>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<table><tr><td>foo[]<br><tr><td>bar</table>", + [["forwarddelete",""]], + "<table><tbody><tr><td>foo{}</td></tr><tr><td>bar</td></tr></tbody></table>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo<table><tr><td>bar[]</table><br>baz", + [["forwarddelete",""]], + "foo<table><tbody><tr><td>bar[]</td></tr></tbody></table><br>baz", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<table><tr><td><hr>bar</table>baz", + [["forwarddelete",""]], + "foo{<table><tbody><tr><td><hr>bar</td></tr></tbody></table>}baz", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<table><tr><td>foo[]<td><hr>bar</table>", + [["forwarddelete",""]], + "<table><tbody><tr><td>foo{}</td><td><hr>bar</td></tr></tbody></table>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<table><tr><td>foo[]<tr><td><hr>bar</table>", + [["forwarddelete",""]], + "<table><tbody><tr><td>foo{}</td></tr><tr><td><hr>bar</td></tr></tbody></table>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<ol><li>bar<li>baz</ol>", + [["forwarddelete",""]], + "foo{}bar<ol><li>baz</li></ol>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<br><ol><li>bar<li>baz</ol>", + [["forwarddelete",""]], + "foo{}bar<ol><li>baz</li></ol>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>foo[]<li>bar</ol>", + [["forwarddelete",""]], + "<ol><li>foo{}bar</li></ol>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>foo[]<br><li>bar</ol>", + [["forwarddelete",""]], + "<ol><li>foo{}bar</li></ol>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>foo[]<li>bar<br>baz</ol>", + [["forwarddelete",""]], + "<ol><li>foo{}bar<br>baz</li></ol>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li><p>foo[]<li>bar</ol>", + [["forwarddelete",""]], + "<ol><li><p>foo{}bar</p></li></ol>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>foo[]<li><p>bar</ol>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<ol><li>foo{}bar</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>foo[]<li><p>bar</ol>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<ol><li>foo{}bar</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li><p>foo[]<li><p>bar</ol>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<ol><li><p>foo{}bar</p></li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li><p>foo[]<li><p>bar</ol>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<ol><li><p>foo{}bar</p></li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>foo[]<ul><li>bar</ul></ol>", + [["forwarddelete",""]], + "<ol><li>foo{}bar</li></ol>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<ol><ol><li>bar</ol></ol>", + [["forwarddelete",""]], + "foo{}bar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<div><ol><li>bar</ol></div>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<div><ol><li>bar</ol></div>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<dl><dt>bar<dd>baz</dl>", + [["forwarddelete",""]], + "foo{}bar<dl><dd>baz</dd></dl>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<dl><dd>bar</dl>", + [["forwarddelete",""]], + "foo{}bar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<dl><dt>foo[]<dd>bar</dl>", + [["forwarddelete",""]], + "<dl><dt>foo{}bar</dt></dl>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<dl><dt>foo[]<dt>bar<dd>baz</dl>", + [["forwarddelete",""]], + "<dl><dt>foo{}bar</dt><dd>baz</dd></dl>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<dl><dt>foo<dd>bar[]<dd>baz</dl>", + [["forwarddelete",""]], + "<dl><dt>foo</dt><dd>bar{}baz</dd></dl>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>foo[]</ol>bar", + [["forwarddelete",""]], + "<ol><li>foo{}bar</li></ol>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>foo[]<br></ol>bar", + [["forwarddelete",""]], + "<ol><li>foo{}bar</li></ol>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>{}<br></ol>bar", + [["forwarddelete",""]], + "<ol><li>{}bar</li></ol>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>foo<li>{}<br></ol>bar", + [["forwarddelete",""]], + "<ol><li>foo</li><li>{}bar</li></ol>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>foo[]</ol><p>bar", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<ol><li>foo{}bar</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>foo[]</ol><p>bar", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<ol><li>foo{}bar</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>foo[]<br></ol><p>bar", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<ol><li>foo{}bar</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>foo[]<br></ol><p>bar", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<ol><li>foo{}bar</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>{}<br></ol><p>bar", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<ol><li>{}bar</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>{}<br></ol><p>bar", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<ol><li>{}bar</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>foo<li>{}<br></ol><p>bar", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<ol><li>foo</li><li>{}bar</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>foo<li>{}<br></ol><p>bar", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<ol><li>foo</li><li>{}bar</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>foo[]</ol><br>", + [["forwarddelete",""]], + "<ol><li>foo{}</li></ol>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>foo[]<br></ol><br>", + [["forwarddelete",""]], + "<ol><li>foo{}</li></ol>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>{}<br></ol><br>", + [["forwarddelete",""]], + "<ol><li>{}<br></li></ol>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>foo<li>{}<br></ol><br>", + [["forwarddelete",""]], + "<ol><li>foo</li><li>{}<br></li></ol>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>foo[]</ol><p><br>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<ol><li>foo{}</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>foo[]</ol><p><br>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<ol><li>foo{}</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>foo[]<br></ol><p><br>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<ol><li>foo{}</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>foo[]<br></ol><p><br>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<ol><li>foo{}</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>{}<br></ol><p><br>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<ol><li>{}<br></li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>{}<br></ol><p><br>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<ol><li>{}<br></li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>foo<li>{}<br></ol><p><br>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<ol><li>foo</li><li>{}<br></li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>foo<li>{}<br></ol><p><br>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<ol><li>foo</li><li>{}<br></li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<blockquote>bar</blockquote>", + [["forwarddelete",""]], + "foo{}bar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<blockquote><blockquote>bar</blockquote></blockquote>", + [["forwarddelete",""]], + "foo{}bar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<blockquote><div>bar</div></blockquote>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<blockquote><div>bar</div></blockquote>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<blockquote style=\"color: blue\">bar</blockquote>", + [["stylewithcss","true"],["forwarddelete",""]], + "foo{}<span style=\"color:rgb(0, 0, 255)\">bar</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<blockquote style=\"color: blue\">bar</blockquote>", + [["stylewithcss","false"],["forwarddelete",""]], + "foo{}<font color=\"#0000ff\">bar</font>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<blockquote><blockquote><p>bar<p>baz</blockquote></blockquote>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "foo{}bar<blockquote><blockquote><p>baz</p></blockquote></blockquote>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<blockquote><blockquote><p>bar<p>baz</blockquote></blockquote>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "foo{}bar<blockquote><blockquote><p>baz</p></blockquote></blockquote>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<blockquote><div><p>bar<p>baz</div></blockquote>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "foo{}bar<blockquote><div><p>baz</p></div></blockquote>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<blockquote><div><p>bar<p>baz</div></blockquote>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "foo{}bar<blockquote><div><p>baz</p></div></blockquote>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<blockquote style=\"color: blue\"><p>bar<p>baz</blockquote>", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["forwarddelete",""]], + "foo{}<span style=\"color:rgb(0, 0, 255)\">bar</span><blockquote style=\"color:rgb(0, 0, 255)\"><p>baz</p></blockquote>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<blockquote style=\"color: blue\"><p>bar<p>baz</blockquote>", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["forwarddelete",""]], + "foo{}<font color=\"#0000ff\">bar</font><blockquote style=\"color:rgb(0, 0, 255)\"><p>baz</p></blockquote>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<blockquote style=\"color: blue\"><p>bar<p>baz</blockquote>", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["forwarddelete",""]], + "foo{}<span style=\"color:rgb(0, 0, 255)\">bar</span><blockquote style=\"color:rgb(0, 0, 255)\"><p>baz</p></blockquote>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<blockquote style=\"color: blue\"><p>bar<p>baz</blockquote>", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["forwarddelete",""]], + "foo{}<font color=\"#0000ff\">bar</font><blockquote style=\"color:rgb(0, 0, 255)\"><p>baz</p></blockquote>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<blockquote><p><b>bar</b><p>baz</blockquote>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "foo{}<b>bar</b><blockquote><p>baz</p></blockquote>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<blockquote><p><b>bar</b><p>baz</blockquote>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "foo{}<b>bar</b><blockquote><p>baz</p></blockquote>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<blockquote><p><strong>bar</strong><p>baz</blockquote>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "foo{}<strong>bar</strong><blockquote><p>baz</p></blockquote>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<blockquote><p><strong>bar</strong><p>baz</blockquote>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "foo{}<strong>bar</strong><blockquote><p>baz</p></blockquote>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<blockquote><p><span>bar</span><p>baz</blockquote>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "foo{}<span>bar</span><blockquote><p>baz</p></blockquote>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<blockquote><p><span>bar</span><p>baz</blockquote>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "foo{}<span>bar</span><blockquote><p>baz</p></blockquote>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<blockquote><ol><li>bar</ol></blockquote><p>extra", + [["forwarddelete",""]], + "foo{}bar<p>extra</p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<blockquote>bar<ol><li>baz</ol>quz</blockquote><p>extra", + [["forwarddelete",""]], + "foo{}bar<blockquote><ol><li>baz</li></ol>quz</blockquote><p>extra</p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo<blockquote><ol><li>bar[]</li><ol><li>baz</ol><li>quz</ol></blockquote><p>extra", + [["forwarddelete",""]], + "foo<blockquote><ol><li>bar{}baz</li><li>quz</li></ol></blockquote><p>extra</p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<span></span>bar", + [["forwarddelete",""]], + "foo{}ar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<span><span></span></span>bar", + [["forwarddelete",""]], + "foo{}ar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<quasit></quasit>bar", + [["forwarddelete",""]], + "foo{}ar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<span></span><br>bar", + [["forwarddelete",""]], + "foo{}bar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<span>foo[]<span></span></span>bar", + [["forwarddelete",""]], + "<span>foo</span>{}ar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<span></span><span>bar</span>", + [["forwarddelete",""]], + "foo<span>{}ar</span>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<div><div><p>bar</div></div>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<div><div><p>bar</div></div>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<div><div><p><!--abc-->bar</div></div>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<div><div><p><!--abc-->bar</div></div>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<div><div><!--abc--><p>bar</div></div>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<div><div><!--abc--><p>bar</div></div>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<div><!--abc--><div><p>bar</div></div>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<div><!--abc--><div><p>bar</div></div>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<!--abc--><div><div><p>bar</div></div>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<!--abc--><div><div><p>bar</div></div>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<div><div><p>foo[]</div></div>bar", + [["forwarddelete",""]], + "<div><div><p>foo{}bar</p></div></div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div><div><p>foo[]</div></div><!--abc-->bar", + [["forwarddelete",""]], + "<div><div><p>foo{}bar</p></div></div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div><div><p>foo[]</div><!--abc--></div>bar", + [["forwarddelete",""]], + "<div><div><p>foo{}bar</p></div></div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div><div><p>foo[]</p><!--abc--></div></div>bar", + [["forwarddelete",""]], + "<div><div><p>foo{}bar</p></div></div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div><div><p>foo[]<!--abc--></div></div>bar", + [["forwarddelete",""]], + "<div><div><p>foo{}bar</p></div></div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div><div><p>foo[]</p></div></div><div><div><div>bar</div></div></div>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<div><div><p>foo{}bar</p></div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<div><div><p>foo[]</p></div></div><div><div><div>bar</div></div></div>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<div><div><p>foo{}bar</p></div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<div><div><p>foo[]<!--abc--></p></div></div><div><div><div>bar</div></div></div>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<div><div><p>foo{}bar</p></div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<div><div><p>foo[]<!--abc--></p></div></div><div><div><div>bar</div></div></div>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<div><div><p>foo{}bar</p></div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<div><div><p>foo[]</p><!--abc--></div></div><div><div><div>bar</div></div></div>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<div><div><p>foo{}bar</p></div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<div><div><p>foo[]</p><!--abc--></div></div><div><div><div>bar</div></div></div>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<div><div><p>foo{}bar</p></div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<div><div><p>foo[]</p></div><!--abc--></div><div><div><div>bar</div></div></div>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<div><div><p>foo{}bar</p></div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<div><div><p>foo[]</p></div><!--abc--></div><div><div><div>bar</div></div></div>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<div><div><p>foo{}bar</p></div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<div><div><p>foo[]</p></div></div><!--abc--><div><div><div>bar</div></div></div>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<div><div><p>foo{}bar</p></div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<div><div><p>foo[]</p></div></div><!--abc--><div><div><div>bar</div></div></div>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<div><div><p>foo{}bar</p></div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<div><div><p>foo[]</p></div></div><div><!--abc--><div><div>bar</div></div></div>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<div><div><p>foo{}bar</p></div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<div><div><p>foo[]</p></div></div><div><!--abc--><div><div>bar</div></div></div>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<div><div><p>foo{}bar</p></div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<div><div><p>foo[]</p></div></div><div><div><!--abc--><div>bar</div></div></div>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<div><div><p>foo{}bar</p></div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<div><div><p>foo[]</p></div></div><div><div><!--abc--><div>bar</div></div></div>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<div><div><p>foo{}bar</p></div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<div><div><p>foo[]</p></div></div><div><div><div><!--abc-->bar</div></div></div>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<div><div><p>foo{}bar</p></div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<div><div><p>foo[]</p></div></div><div><div><div><!--abc-->bar</div></div></div>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<div><div><p>foo{}bar</p></div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p style=color:blue>foo[]<p>bar", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p><span style=\"color:rgb(0, 0, 255)\">foo{}</span>bar</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p style=color:blue>foo[]<p>bar", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p><font color=\"#0000ff\">foo{}</font>bar</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p style=color:blue>foo[]<p>bar", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p><span style=\"color:rgb(0, 0, 255)\">foo{}</span>bar</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p style=color:blue>foo[]<p>bar", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p><font color=\"#0000ff\">foo{}</font>bar</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p style=color:blue>foo[]<p style=color:brown>bar", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p style=\"color:rgb(0, 0, 255)\">foo{}<span style=\"color:rgb(165, 42, 42)\">bar</span></p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p style=color:blue>foo[]<p style=color:brown>bar", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p style=\"color:rgb(0, 0, 255)\">foo{}<font color=\"#a52a2a\">bar</font></p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p style=color:blue>foo[]<p style=color:brown>bar", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p style=\"color:rgb(0, 0, 255)\">foo{}<span style=\"color:rgb(165, 42, 42)\">bar</span></p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p style=color:blue>foo[]<p style=color:brown>bar", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p style=\"color:rgb(0, 0, 255)\">foo{}<font color=\"#a52a2a\">bar</font></p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[]<p style=color:brown>bar", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p>foo{}<span style=\"color:rgb(165, 42, 42)\">bar</span></p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[]<p style=color:brown>bar", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p>foo{}<font color=\"#a52a2a\">bar</font></p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[]<p style=color:brown>bar", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p>foo{}<span style=\"color:rgb(165, 42, 42)\">bar</span></p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[]<p style=color:brown>bar", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p>foo{}<font color=\"#a52a2a\">bar</font></p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p><font color=blue>foo[]</font><p>bar", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p><font color=\"blue\">foo</font>{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p><font color=blue>foo[]</font><p>bar", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p><font color=\"blue\">foo</font>{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p><font color=blue>foo[]</font><p><font color=brown>bar</font>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p><font color=\"blue\">foo</font>{}<font color=\"brown\">bar</font></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p><font color=blue>foo[]</font><p><font color=brown>bar</font>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p><font color=\"blue\">foo</font>{}<font color=\"brown\">bar</font></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[]<p><font color=brown>bar</font>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p>foo{}<font color=\"brown\">bar</font></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[]<p><font color=brown>bar</font>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p>foo{}<font color=\"brown\">bar</font></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p><span style=color:blue>foo[]</font><p>bar", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p><span style=\"color:rgb(0, 0, 255)\">foo</span>{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p><span style=color:blue>foo[]</font><p>bar", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p><span style=\"color:rgb(0, 0, 255)\">foo</span>{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p><span style=color:blue>foo[]</font><p><span style=color:brown>bar</font>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p><span style=\"color:rgb(0, 0, 255)\">foo</span>{}<span style=\"color:rgb(165, 42, 42)\">bar</span></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p><span style=color:blue>foo[]</font><p><span style=color:brown>bar</font>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p><span style=\"color:rgb(0, 0, 255)\">foo</span>{}<span style=\"color:rgb(165, 42, 42)\">bar</span></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[]<p><span style=color:brown>bar</font>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p>foo{}<span style=\"color:rgb(165, 42, 42)\">bar</span></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[]<p><span style=color:brown>bar</font>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p>foo{}<span style=\"color:rgb(165, 42, 42)\">bar</span></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p style=background-color:aqua>foo[]<p>bar", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p style=\"background-color:rgb(0, 255, 255)\">foo{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p style=background-color:aqua>foo[]<p>bar", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p style=\"background-color:rgb(0, 255, 255)\">foo{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p style=background-color:aqua>foo[]<p style=background-color:tan>bar", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p style=\"background-color:rgb(0, 255, 255)\">foo{}bar</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p style=background-color:aqua>foo[]<p style=background-color:tan>bar", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p style=\"background-color:rgb(0, 255, 255)\">foo{}bar</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p style=background-color:aqua>foo[]<p style=background-color:tan>bar", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p style=\"background-color:rgb(0, 255, 255)\">foo{}bar</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p style=background-color:aqua>foo[]<p style=background-color:tan>bar", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p style=\"background-color:rgb(0, 255, 255)\">foo{}bar</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[]<p style=background-color:tan>bar", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p>foo{}bar</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[]<p style=background-color:tan>bar", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p>foo{}bar</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[]<p style=background-color:tan>bar", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p>foo{}bar</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[]<p style=background-color:tan>bar", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p>foo{}bar</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p><span style=background-color:aqua>foo[]</font><p>bar", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p><span style=\"background-color:rgb(0, 255, 255)\">foo</span>{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p><span style=background-color:aqua>foo[]</font><p>bar", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p><span style=\"background-color:rgb(0, 255, 255)\">foo</span>{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p><span style=background-color:aqua>foo[]</font><p><span style=background-color:tan>bar</font>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p><span style=\"background-color:rgb(0, 255, 255)\">foo</span>{}<span style=\"background-color:rgb(210, 180, 140)\">bar</span></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p><span style=background-color:aqua>foo[]</font><p><span style=background-color:tan>bar</font>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p><span style=\"background-color:rgb(0, 255, 255)\">foo</span>{}<span style=\"background-color:rgb(210, 180, 140)\">bar</span></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[]<p><span style=background-color:tan>bar</font>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p>foo{}<span style=\"background-color:rgb(210, 180, 140)\">bar</span></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[]<p><span style=background-color:tan>bar</font>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p>foo{}<span style=\"background-color:rgb(210, 180, 140)\">bar</span></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p style=text-decoration:underline>foo[]<p>bar", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p><span style=\"text-decoration:underline\">foo{}</span>bar</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p style=text-decoration:underline>foo[]<p>bar", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p><u>foo{}</u>bar</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p style=text-decoration:underline>foo[]<p>bar", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p><span style=\"text-decoration:underline\">foo{}</span>bar</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p style=text-decoration:underline>foo[]<p>bar", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p><u>foo{}</u>bar</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p style=text-decoration:underline>foo[]<p style=text-decoration:line-through>bar", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p><span style=\"text-decoration:underline\">foo{}</span><span style=\"text-decoration:line-through\">bar</span></p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p style=text-decoration:underline>foo[]<p style=text-decoration:line-through>bar", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p><u>foo{}</u><s>bar</s></p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p style=text-decoration:underline>foo[]<p style=text-decoration:line-through>bar", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p><span style=\"text-decoration:underline\">foo{}</span><span style=\"text-decoration:line-through\">bar</span></p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p style=text-decoration:underline>foo[]<p style=text-decoration:line-through>bar", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p><u>foo{}</u><s>bar</s></p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[]<p style=text-decoration:line-through>bar", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p>foo{}<span style=\"text-decoration:line-through\">bar</span></p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[]<p style=text-decoration:line-through>bar", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p>foo{}<s>bar</s></p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[]<p style=text-decoration:line-through>bar", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p>foo{}<span style=\"text-decoration:line-through\">bar</span></p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[]<p style=text-decoration:line-through>bar", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p>foo{}<s>bar</s></p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p><u>foo[]</u><p>bar", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p><u>foo</u>{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p><u>foo[]</u><p>bar", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p><u>foo</u>{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p><u>foo[]</u><p><s>bar</s>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p><u>foo</u>{}<s>bar</s></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p><u>foo[]</u><p><s>bar</s>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p><u>foo</u>{}<s>bar</s></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[]<p><s>bar</s>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p>foo{}<s>bar</s></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[]<p><s>bar</s>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p>foo{}<s>bar</s></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p style=color:blue>foo[]</p>bar", + [["stylewithcss","true"],["forwarddelete",""]], + "<p><span style=\"color:rgb(0, 0, 255)\">foo{}</span>bar</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forwarddelete":[false,false,"",false,false,""]}], +["<p style=color:blue>foo[]</p>bar", + [["stylewithcss","false"],["forwarddelete",""]], + "<p><font color=\"#0000ff\">foo{}</font>bar</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<p style=color:brown>bar", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["forwarddelete",""]], + "foo{}<span style=\"color:rgb(165, 42, 42)\">bar</span>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<p style=color:brown>bar", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["forwarddelete",""]], + "foo{}<font color=\"#a52a2a\">bar</font>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<p style=color:brown>bar", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["forwarddelete",""]], + "foo{}<span style=\"color:rgb(165, 42, 42)\">bar</span>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<p style=color:brown>bar", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["forwarddelete",""]], + "foo{}<font color=\"#a52a2a\">bar</font>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<div style=color:blue><p style=color:green>foo[]</div>bar", + [["stylewithcss","true"],["forwarddelete",""]], + "<div><p><span style=\"color:rgb(0, 128, 0)\">foo{}</span>bar</p></div>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forwarddelete":[false,false,"",false,false,""]}], +["<div style=color:blue><p style=color:green>foo[]</div>bar", + [["stylewithcss","false"],["forwarddelete",""]], + "<div><p><font color=\"#008000\">foo{}</font>bar</p></div>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forwarddelete":[false,false,"",false,false,""]}], +["<div style=color:blue><p style=color:green>foo[]</div><p style=color:brown>bar", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["forwarddelete",""]], + "<div style=\"color:rgb(0, 0, 255)\"><p style=\"color:rgb(0, 128, 0)\">foo{}<span style=\"color:rgb(165, 42, 42)\">bar</span></p></div>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<div style=color:blue><p style=color:green>foo[]</div><p style=color:brown>bar", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["forwarddelete",""]], + "<div style=\"color:rgb(0, 0, 255)\"><p style=\"color:rgb(0, 128, 0)\">foo{}<font color=\"#a52a2a\">bar</font></p></div>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<div style=color:blue><p style=color:green>foo[]</div><p style=color:brown>bar", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["forwarddelete",""]], + "<div style=\"color:rgb(0, 0, 255)\"><p style=\"color:rgb(0, 128, 0)\">foo{}<span style=\"color:rgb(165, 42, 42)\">bar</span></p></div>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<div style=color:blue><p style=color:green>foo[]</div><p style=color:brown>bar", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["forwarddelete",""]], + "<div style=\"color:rgb(0, 0, 255)\"><p style=\"color:rgb(0, 128, 0)\">foo{}<font color=\"#a52a2a\">bar</font></p></div>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p style=color:blue>foo[]<div style=color:brown><p style=color:green>bar", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p style=\"color:rgb(0, 0, 255)\">foo{}<span style=\"color:rgb(0, 128, 0)\">bar</span></p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p style=color:blue>foo[]<div style=color:brown><p style=color:green>bar", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p style=\"color:rgb(0, 0, 255)\">foo{}<font color=\"#008000\">bar</font></p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p style=color:blue>foo[]<div style=color:brown><p style=color:green>bar", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p style=\"color:rgb(0, 0, 255)\">foo{}<span style=\"color:rgb(0, 128, 0)\">bar</span></p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p style=color:blue>foo[]<div style=color:brown><p style=color:green>bar", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p style=\"color:rgb(0, 0, 255)\">foo{}<font color=\"#008000\">bar</font></p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[bar]baz", + [["forwarddelete",""]], + "foo[]baz", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>[bar]</span>baz", + [["stylewithcss","true"],["forwarddelete",""]], + "<p>foo{}baz</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>[bar]</span>baz", + [["stylewithcss","false"],["forwarddelete",""]], + "<p>foo{}baz</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>{bar}</span>baz", + [["stylewithcss","true"],["forwarddelete",""]], + "<p>foo{}baz</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>{bar}</span>baz", + [["stylewithcss","false"],["forwarddelete",""]], + "<p>foo{}baz</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo{<span style=color:#aBcDeF>bar</span>}baz", + [["stylewithcss","true"],["forwarddelete",""]], + "<p>foo{}baz</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo{<span style=color:#aBcDeF>bar</span>}baz", + [["stylewithcss","false"],["forwarddelete",""]], + "<p>foo{}baz</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forwarddelete":[false,false,"",false,false,""]}], +["<p>[foo<span style=color:#aBcDeF>bar]</span>baz", + [["stylewithcss","true"],["forwarddelete",""]], + "<p>{}baz</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forwarddelete":[false,false,"",false,false,""]}], +["<p>[foo<span style=color:#aBcDeF>bar]</span>baz", + [["stylewithcss","false"],["forwarddelete",""]], + "<p>{}baz</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forwarddelete":[false,false,"",false,false,""]}], +["<p>{foo<span style=color:#aBcDeF>bar}</span>baz", + [["stylewithcss","true"],["forwarddelete",""]], + "<p>{}baz</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forwarddelete":[false,false,"",false,false,""]}], +["<p>{foo<span style=color:#aBcDeF>bar}</span>baz", + [["stylewithcss","false"],["forwarddelete",""]], + "<p>{}baz</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>[bar</span>baz]", + [["stylewithcss","true"],["forwarddelete",""]], + "<p>foo{}</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>[bar</span>baz]", + [["stylewithcss","false"],["forwarddelete",""]], + "<p>foo{}</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>{bar</span>baz}", + [["stylewithcss","true"],["forwarddelete",""]], + "<p>foo{}</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>{bar</span>baz}", + [["stylewithcss","false"],["forwarddelete",""]], + "<p>foo{}</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>[bar</span><span style=color:#fEdCbA>baz]</span>quz", + [["stylewithcss","true"],["forwarddelete",""]], + "<p>foo{}quz</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>[bar</span><span style=color:#fEdCbA>baz]</span>quz", + [["stylewithcss","false"],["forwarddelete",""]], + "<p>foo{}quz</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forwarddelete":[false,false,"",false,false,""]}], +["foo<b>[bar]</b>baz", + [["stylewithcss","true"],["forwarddelete",""]], + "foo{}baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forwarddelete":[false,false,"",false,false,""]}], +["foo<b>[bar]</b>baz", + [["stylewithcss","false"],["forwarddelete",""]], + "foo{}baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forwarddelete":[false,false,"",false,false,""]}], +["foo<b>{bar}</b>baz", + [["stylewithcss","true"],["forwarddelete",""]], + "foo{}baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forwarddelete":[false,false,"",false,false,""]}], +["foo<b>{bar}</b>baz", + [["stylewithcss","false"],["forwarddelete",""]], + "foo{}baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forwarddelete":[false,false,"",false,false,""]}], +["foo{<b>bar</b>}baz", + [["stylewithcss","true"],["forwarddelete",""]], + "foo{}baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"forwarddelete":[false,false,"",false,false,""]}], +["foo{<b>bar</b>}baz", + [["stylewithcss","false"],["forwarddelete",""]], + "foo{}baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"forwarddelete":[false,false,"",false,false,""]}], +["foo<span>[bar]</span>baz", + [["forwarddelete",""]], + "foo{}baz", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo<span>{bar}</span>baz", + [["forwarddelete",""]], + "foo{}baz", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo{<span>bar</span>}baz", + [["forwarddelete",""]], + "foo{}baz", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<b>foo[bar</b><i>baz]quz</i>", + [["forwarddelete",""]], + "<b>foo[]</b><i>quz</i>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo</p><p>[bar]</p><p>baz</p>", + [["forwarddelete",""]], + "<p>foo</p><p>{}<br></p><p>baz</p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo</p><p>{bar}</p><p>baz</p>", + [["forwarddelete",""]], + "<p>foo</p><p>{}<br></p><p>baz</p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo</p><p>{bar</p>}<p>baz</p>", + [["forwarddelete",""]], + "<p>foo</p><p>{}<br></p><p>baz</p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo</p>{<p>bar}</p><p>baz</p>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p>foo</p>{}<br><p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo</p>{<p>bar}</p><p>baz</p>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p>foo</p>{}<br><p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo</p>{<p>bar</p>}<p>baz</p>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p>foo</p>{}<p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo</p>{<p>bar</p>}<p>baz</p>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p>foo</p>{}<p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[bar<p>baz]quz", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p>foo{}quz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[bar<p>baz]quz", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p>foo{}quz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[bar<div>baz]quz</div>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p>foo{}quz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[bar<div>baz]quz</div>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p>foo{}quz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[bar<h1>baz]quz</h1>", + [["forwarddelete",""]], + "<p>foo{}quz</p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div>foo[bar</div><p>baz]quz", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<div>foo{}quz</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<div>foo[bar</div><p>baz]quz", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<div>foo{}quz</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<blockquote>foo[bar</blockquote><pre>baz]quz</pre>", + [["forwarddelete",""]], + "<blockquote>foo{}quz</blockquote>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<p><b>foo[bar</b><p>baz]quz", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p><b>foo</b>{}quz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p><b>foo[bar</b><p>baz]quz", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p><b>foo</b>{}quz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<div><p>foo[bar</div><p>baz]quz", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<div><p>foo{}quz</p></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<div><p>foo[bar</div><p>baz]quz", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<div><p>foo{}quz</p></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[bar<blockquote><p>baz]quz<p>qoz</blockquote", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p>foo{}quz</p><blockquote><p>qoz</p></blockquote>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[bar<blockquote><p>baz]quz<p>qoz</blockquote", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p>foo{}quz</p><blockquote><p>qoz</p></blockquote>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[bar<p style=color:blue>baz]quz", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p>foo{}<span style=\"color:rgb(0, 0, 255)\">quz</span></p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[bar<p style=color:blue>baz]quz", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p>foo{}<font color=\"#0000ff\">quz</font></p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[bar<p style=color:blue>baz]quz", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p>foo{}<span style=\"color:rgb(0, 0, 255)\">quz</span></p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[bar<p style=color:blue>baz]quz", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p>foo{}<font color=\"#0000ff\">quz</font></p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[bar<p><b>baz]quz</b>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p>foo{}<b>quz</b></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[bar<p><b>baz]quz</b>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p>foo{}<b>quz</b></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<div><p>foo<p>[bar<p>baz]</div>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<div><p>foo</p><p>{}<br></p></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<div><p>foo<p>[bar<p>baz]</div>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<div><p>foo</p><p>{}<br></p></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[<br>]bar", + [["forwarddelete",""]], + "foo{}bar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[</p><p>]bar</p>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p>foo{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[</p><p>]bar</p>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p>foo{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[</p><p>]bar<br>baz</p>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p>foo{}bar<br>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[</p><p>]bar<br>baz</p>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p>foo{}bar<br>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[<p>]bar</p>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[<p>]bar</p>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["foo{<p>}bar</p>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["foo{<p>}bar</p>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[<p>]bar<br>baz</p>", + [["forwarddelete",""]], + "foo{}bar<p>baz</p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[<p>]bar</p>baz", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "foo{}bar<br>baz", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[<p>]bar</p>baz", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "foo{}bar<br>baz", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["foo{<p>bar</p>}baz", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "foo{}baz", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["foo{<p>bar</p>}baz", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "foo{}baz", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["foo<p>{bar</p>}baz", + [["forwarddelete",""]], + "foo<p>{}baz</p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo{<p>bar}</p>baz", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "foo{}<br>baz", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["foo{<p>bar}</p>baz", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "foo{}<br>baz", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[</p>]bar", + [["forwarddelete",""]], + "<p>foo{}bar</p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo{</p>}bar", + [["forwarddelete",""]], + "<p>foo{}bar</p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[</p>]bar<br>baz", + [["forwarddelete",""]], + "<p>foo{}bar</p>baz", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo[</p>]bar<p>baz</p>", + [["forwarddelete",""]], + "<p>foo{}bar</p><p>baz</p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[<div><p>]bar</div>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[<div><p>]bar</div>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<div><p>foo[</p></div>]bar", + [["forwarddelete",""]], + "<div><p>foo{}bar</p></div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[<div><p>]bar</p>baz</div>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "foo{}bar<div>baz</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[<div><p>]bar</p>baz</div>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "foo{}bar<div>baz</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[<div>]bar<p>baz</p></div>", + [["forwarddelete",""]], + "foo{}bar<div><p>baz</p></div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div><p>foo</p>bar[</div>]baz", + [["forwarddelete",""]], + "<div><p>foo</p>bar{}baz</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div>foo<p>bar[</p></div>]baz", + [["forwarddelete",""]], + "<div>foo<p>bar{}baz</p></div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo<br>{</p>]bar", + [["forwarddelete",""]], + "<p>foo{}bar</p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo<br><br>{</p>]bar", + [["forwarddelete",""]], + "<p>foo<br>{}bar</p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo<br>{<p>]bar</p>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["foo<br>{<p>]bar</p>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "foo{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["foo<br><br>{<p>]bar</p>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "foo<br>{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["foo<br><br>{<p>]bar</p>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "foo<br>{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo<br>{</p><p>}bar</p>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p>foo{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo<br>{</p><p>}bar</p>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p>foo{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo<br><br>{</p><p>}bar</p>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p>foo<br>{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo<br><br>{</p><p>}bar</p>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p>foo<br>{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<table><tbody><tr><th>foo<th>[bar]<th>baz<tr><td>quz<td>qoz<td>qiz</table>", + [["forwarddelete",""]], + "<table><tbody><tr><th>foo</th><th>{}<br></th><th>baz</th></tr><tr><td>quz</td><td>qoz</td><td>qiz</td></tr></tbody></table>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<table><tbody><tr><th>foo<th>ba[r<th>b]az<tr><td>quz<td>qoz<td>qiz</table>", + [["forwarddelete",""]], + "<table><tbody><tr><th>foo</th><th>ba[]</th><th>az</th></tr><tr><td>quz</td><td>qoz</td><td>qiz</td></tr></tbody></table>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<table><tbody><tr><th>fo[o<th>bar<th>b]az<tr><td>quz<td>qoz<td>qiz</table>", + [["forwarddelete",""]], + "<table><tbody><tr><th>fo[]</th><th><br></th><th>az</th></tr><tr><td>quz</td><td>qoz</td><td>qiz</td></tr></tbody></table>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<table><tbody><tr><th>foo<th>bar<th>ba[z<tr><td>q]uz<td>qoz<td>qiz</table>", + [["forwarddelete",""]], + "<table><tbody><tr><th>foo</th><th>bar</th><th>ba[]</th></tr><tr><td>uz</td><td>qoz</td><td>qiz</td></tr></tbody></table>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<table><tbody><tr><th>[foo<th>bar<th>baz]<tr><td>quz<td>qoz<td>qiz</table>", + [["forwarddelete",""]], + "<table><tbody><tr><th>{}<br></th><th><br></th><th><br></th></tr><tr><td>quz</td><td>qoz</td><td>qiz</td></tr></tbody></table>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<table><tbody><tr><th>[foo<th>bar<th>baz<tr><td>quz<td>qoz<td>qiz]</table>", + [["forwarddelete",""]], + "<table><tbody><tr><th>{}<br></th><th><br></th><th><br></th></tr><tr><td><br></td><td><br></td><td><br></td></tr></tbody></table>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["{<table><tbody><tr><th>foo<th>bar<th>baz<tr><td>quz<td>qoz<td>qiz</table>}", + [["forwarddelete",""]], + "{}<br>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<table><tbody><tr><td>foo<td>ba[r<tr><td>baz<td>quz<tr><td>q]oz<td>qiz</table>", + [["forwarddelete",""]], + "<table><tbody><tr><td>foo</td><td>ba[]</td></tr><tr><td><br></td><td><br></td></tr><tr><td>oz</td><td>qiz</td></tr></tbody></table>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<p>fo[o<table><tr><td>b]ar</table><p>baz", + [["forwarddelete",""]], + "<p>fo[]</p><table><tbody><tr><td>ar</td></tr></tbody></table><p>baz</p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo<table><tr><td>ba[r</table><p>b]az", + [["forwarddelete",""]], + "<p>foo</p><table><tbody><tr><td>ba[]</td></tr></tbody></table><p>az</p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<p>fo[o<table><tr><td>bar</table><p>b]az", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p>fo{}az</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>fo[o<table><tr><td>bar</table><p>b]az", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p>fo{}az</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo<ol><li>ba[r<li>b]az</ol><p>quz", + [["forwarddelete",""]], + "<p>foo</p><ol><li>ba{}az</li></ol><p>quz</p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo<ol><li>bar<li>[baz]</ol><p>quz", + [["forwarddelete",""]], + "<p>foo</p><ol><li>bar</li><li>{}<br></li></ol><p>quz</p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<p>fo[o<ol><li>b]ar<li>baz</ol><p>quz", + [["forwarddelete",""]], + "<p>fo{}ar</p><ol><li>baz</li></ol><p>quz</p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo<ol><li>bar<li>ba[z</ol><p>q]uz", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p>foo</p><ol><li>bar</li><li>ba{}uz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>foo<ol><li>bar<li>ba[z</ol><p>q]uz", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p>foo</p><ol><li>bar</li><li>ba{}uz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>fo[o<ol><li>bar<li>b]az</ol><p>quz", + [["forwarddelete",""]], + "<p>fo{}az</p><p>quz</p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<p>fo[o<ol><li>bar<li>baz</ol><p>q]uz", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p>fo{}uz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<p>fo[o<ol><li>bar<li>baz</ol><p>q]uz", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p>fo{}uz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>fo[o</ol><ol><li>b]ar</ol>", + [["forwarddelete",""]], + "<ol><li>fo{}ar</li></ol>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>fo[o</ol><ul><li>b]ar</ul>", + [["forwarddelete",""]], + "<ol><li>fo{}ar</li></ol>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[<ol><li>]bar</ol>", + [["forwarddelete",""]], + "foo{}bar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>foo[<li>]bar</ol>", + [["forwarddelete",""]], + "<ol><li>foo{}bar</li></ol>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[<dl><dt>]bar<dd>baz</dl>", + [["forwarddelete",""]], + "foo{}bar<dl><dd>baz</dd></dl>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[<dl><dd>]bar</dl>", + [["forwarddelete",""]], + "foo{}bar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<dl><dt>foo[<dd>]bar</dl>", + [["forwarddelete",""]], + "<dl><dt>foo{}bar</dt></dl>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<dl><dt>foo[<dt>]bar<dd>baz</dl>", + [["forwarddelete",""]], + "<dl><dt>foo{}bar</dt><dd>baz</dd></dl>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<dl><dt>foo<dd>bar[<dd>]baz</dl>", + [["forwarddelete",""]], + "<dl><dt>foo</dt><dd>bar{}baz</dd></dl>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>foo</ol>{}<br><ol><li>bar</ol>", + [["forwarddelete",""]], + "<ol><li>foo</li></ol>{}bar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>foo</ol><p>{}<br></p><ol><li>bar</ol>", + [["forwarddelete",""]], + "<ol><li>foo</li></ol><p>{}bar</p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li><p>foo</ol><p>{}<br></p><ol><li>bar</ol>", + [["forwarddelete",""]], + "<ol><li><p>foo</p></li></ol><p>{}bar</p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<ol id=a><li>foo</ol>{}<br><ol><li>bar</ol>", + [["forwarddelete",""]], + "<ol id=\"a\"><li>foo</li></ol>{}bar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>foo</ol>{}<br><ol id=b><li>bar</ol>", + [["forwarddelete",""]], + "<ol><li>foo</li></ol>{}bar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<ol id=a><li>foo</ol>{}<br><ol id=b><li>bar</ol>", + [["forwarddelete",""]], + "<ol id=\"a\"><li>foo</li></ol>{}bar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<ol class=a><li>foo</ol>{}<br><ol class=b><li>bar</ol>", + [["forwarddelete",""]], + "<ol class=\"a\"><li>foo</li></ol>{}bar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<ol><ol><li>foo</ol><li>{}<br><ol><li>bar</ol></ol>", + [["forwarddelete",""]], + "<ol><ol><li>foo</li></ol><li>{}bar</li></ol>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<ol><ol><li>foo</ol><li>{}<br></li><ol><li>bar</ol></ol>", + [["forwarddelete",""]], + "<ol><ol><li>foo</li></ol><li>{}bar</li></ol>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>foo[</ol>bar]<ol><li>baz</ol>", + [["forwarddelete",""]], + "<ol><li>foo{}</li><li>baz</li></ol>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>foo[</ol><p>bar]<ol><li>baz</ol>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<ol><li>foo{}</li><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>foo[</ol><p>bar]<ol><li>baz</ol>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<ol><li>foo{}</li><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li><p>foo[</ol><p>bar]<ol><li>baz</ol>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<ol><li><p>foo{}</p></li><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li><p>foo[</ol><p>bar]<ol><li>baz</ol>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<ol><li><p>foo{}</p></li><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>fo[]o</ol><ol><li>bar</ol>", + [["forwarddelete",""]], + "<ol><li>fo[]</li></ol><ol><li>bar</li></ol>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>foo</ol>[bar<ol><li>]baz</ol>", + [["forwarddelete",""]], + "<ol><li>foo</li></ol>{}baz", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>foo</ol><p>[bar<ol><li>]baz</ol>", + [["forwarddelete",""]], + "<ol><li>foo</li></ol><p>{}baz</p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>foo</ol><p>[bar<ol><li><p>]baz</ol>", + [["defaultparagraphseparator","div"],["forwarddelete",""]], + "<ol><li>foo</li></ol><p>{}baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>foo</ol><p>[bar<ol><li><p>]baz</ol>", + [["defaultparagraphseparator","p"],["forwarddelete",""]], + "<ol><li>foo</li></ol><p>{}baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>foo</ol><ol><li>[]bar</ol>", + [["forwarddelete",""]], + "<ol><li>foo</li></ol><ol><li>{}ar</li></ol>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<ol><ol><li>foo[</ol><li>bar</ol>baz]<ol><li>quz</ol>", + [["forwarddelete",""]], + "<ol><ol><li>foo{}</li></ol><li>quz</li></ol>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<ul><li>foo</ul>{}<br><ul><li>bar</ul>", + [["forwarddelete",""]], + "<ul><li>foo</li></ul>{}bar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<ul><li>foo</ul><p>{}<br></p><ul><li>bar</ul>", + [["forwarddelete",""]], + "<ul><li>foo</li></ul><p>{}bar</p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>foo[<li>bar]</ol><ol><li>baz</ol><ol><li>quz</ol>", + [["forwarddelete",""]], + "<ol><li>foo{}</li><li>baz</li><li>quz</li></ol>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>foo</ol>{}<br><ul><li>bar</ul>", + [["forwarddelete",""]], + "<ol><li>foo</li></ol>{}bar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<ol><li>foo</ol><p>{}<br></p><ul><li>bar</ul>", + [["forwarddelete",""]], + "<ol><li>foo</li></ol><p>{}bar</p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<ul><li>foo</ul>{}<br><ol><li>bar</ol>", + [["forwarddelete",""]], + "<ul><li>foo</li></ul>{}bar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<ul><li>foo</ul><p>{}<br></p><ol><li>bar</ol>", + [["forwarddelete",""]], + "<ul><li>foo</li></ul><p>{}bar</p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<p><b>[foo]</b>", + [["forwarddelete",""]], + "<p>{}<br></p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<p><quasit>[foo]</quasit>", + [["forwarddelete",""]], + "<p>{}<br></p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<p><b><i>[foo]</i></b>", + [["forwarddelete",""]], + "<p>{}<br></p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<p><b>{foo}</b>", + [["forwarddelete",""]], + "<p>{}<br></p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<p>{<b>foo</b>}", + [["forwarddelete",""]], + "<p>{}<br></p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<p><b>[]f</b>", + [["forwarddelete",""]], + "<p>{}<br></p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<b>[foo]</b>", + [["forwarddelete",""]], + "{}<br>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div><b>[foo]</b></div>", + [["forwarddelete",""]], + "<div>{}<br></div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div><div><p>foo[]</p></div></div><div></div><div><div>bar</div></div></div>", + [["forwarddelete",""]], + "<div><div><p>foobar</p></div></div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div>foo[]</div><div></div><div>bar</div>", + [["forwarddelete",""]], + "<div>foobar</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div>foo[]</div><span></span><div>bar</div>", + [["forwarddelete",""]], + "<div>foobar</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div>foo[]</div><!-- comment --><div>bar</div>", + [["forwarddelete",""]], + "<div>foobar</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div>ab[]c </div>", + [["forwarddelete",""]], + "<div>ab</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div>ab[]c </div>", + [["forwarddelete",""]], + "<div>ab</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div>abc[] </div>", + [["forwarddelete",""]], + "<div>abc </div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div>abc [] </div>", + [["forwarddelete",""]], + "<div>abc </div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div>abc[] </div><div>def</div>", + [["forwarddelete",""]], + "<div>abcdef</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div>abc[] </div><div>def</div>", + [["forwarddelete",""]], + "<div>abcdef</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div>abc [] </div><div>def</div>", + [["forwarddelete",""]], + "<div>abcdef</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div>abc[]</div><div> def</div>", + [["forwarddelete",""]], + "<div>abcdef</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div>abc[]</div><div> def</div>", + [["forwarddelete",""]], + "<div>abcdef</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div>abc[] </div><div> def</div>", + [["forwarddelete",""]], + "<div>abcdef</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div>abc [] </div><div> def</div>", + [["forwarddelete",""]], + "<div>abcdef</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div>abc[] </div> <div> def</div>", + [["forwarddelete",""]], + "<div>abcdef</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<img contenteditable=false src=/img/lion.svg>bar", + [["forwarddelete",""]], + "foo{}bar", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<span contenteditable=false>bar</span>baz", + [["forwarddelete",""]], + "foo{}baz", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<span contenteditable=false>bar</span><span contenteditable=false>baz</span>qux", + [["forwarddelete",""]], + "foo[]<span contenteditable=\"false\">baz</span>qux", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<span contenteditable=false><span>b</span><span>a</span><span>r</span></span>baz", + [["forwarddelete",""]], + "foo{}baz", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<div contenteditable=false>bar</div>baz", + [["forwarddelete",""]], + "foo{}baz", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo[]<span contenteditable=false><b>bar</b></span>baz", + [["forwarddelete",""]], + "foo{}baz", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["foo<span>bar[]<span contenteditable=false>baz</span></span>qux", + [["forwarddelete",""]], + "foo<span>bar{}</span>qux", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<span>[abc]</span>", + [["forwarddelete",""]], + "<br>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<span>[abc]</span><br>", + [["forwarddelete",""]], + "<br>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<p><span>[abc]</span></p>", + [["forwarddelete",""]], + "<p><br></p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<p><span>[abc]</span><br></p>", + [["forwarddelete",""]], + "<p><br></p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +// XXX Perhaps, replacing with <br> element is better, but this is common behavior. +["<p contenteditable=false><span contenteditable=true>[abc]</span></p>", + [["forwarddelete",""]], + "<p contenteditable=\"false\"><span contenteditable=\"true\"></span></p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div><div>{}<br></div></div>", + [["forwarddelete",""]], + ["", "<br>"], + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div><div contenteditable=false><div contenteditable><div>{}<br></div></div></div></div>", + [["forwarddelete",""]], + ["<div><div contenteditable=\"false\"><div contenteditable=\"\"></div></div></div>", + "<div><div contenteditable=\"false\"><div contenteditable=\"\"><br></div></div></div>"], + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div><div contenteditable=false><span contenteditable>{}<br></span></div></div>", + [["forwarddelete",""]], + ["<div><div contenteditable=\"false\"><span contenteditable=\"\"></span></div></div>", + "<div><div contenteditable=\"false\"><span contenteditable=\"\"><br></span></div></div>"], + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div style=white-space:pre>foo[] \nbar</div>", + [["forwarddelete",""]], + "<div style=\"white-space:pre\">foo[]\nbar</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div style=white-space:pre>foo[]\n bar</div>", + [["forwarddelete",""]], + "<div style=\"white-space:pre\">foo[] bar</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div style=white-space:pre>foo[]\n\nbar</div>", + [["forwarddelete",""]], + "<div style=\"white-space:pre\">foo[]\nbar</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div style=white-space:pre>[]f\nbar</div>", + [["forwarddelete",""]], + "<div style=\"white-space:pre\">[]\nbar</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div style=white-space:pre-wrap>foo[] \nbar</div>", + [["forwarddelete",""]], + "<div style=\"white-space:pre-wrap\">foo[]\nbar</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div style=white-space:pre-wrap>foo[]\n bar</div>", + [["forwarddelete",""]], + "<div style=\"white-space:pre-wrap\">foo[] bar</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div style=white-space:pre-wrap>foo[]\n\nbar</div>", + [["forwarddelete",""]], + "<div style=\"white-space:pre-wrap\">foo[]\nbar</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div style=white-space:pre-wrap>[]f\nbar</div>", + [["forwarddelete",""]], + "<div style=\"white-space:pre-wrap\">[]\nbar</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div style=white-space:pre-line>foo[] \nbar</div>", + [["forwarddelete",""]], + "<div style=\"white-space:pre-line\">foo[]bar</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div style=white-space:pre-line>foo[]\n bar</div>", + [["forwarddelete",""]], + "<div style=\"white-space:pre-line\">foo[]bar</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div style=white-space:pre-line>foo[]\n\nbar</div>", + [["forwarddelete",""]], + "<div style=\"white-space:pre-line\">foo[]\nbar</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div style=white-space:pre-line>[]f\nbar</div>", + [["forwarddelete",""]], + "<div style=\"white-space:pre-line\">[]\nbar</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div style=white-space:nowrap>foo[] \nbar</div>", + [["forwarddelete",""]], + "<div style=\"white-space:nowrap\">foo[]bar</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div style=white-space:nowrap>foo[]\n bar</div>", + [["forwarddelete",""]], + "<div style=\"white-space:nowrap\">foo[]bar</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div style=white-space:nowrap>foo[]\n\nbar</div>", + [["forwarddelete",""]], + "<div style=\"white-space:nowrap\">foo[]bar</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div style=white-space:nowrap>[]f\nbar</div>", + [["forwarddelete",""]], + "<div style=\"white-space:nowrap\">[]bar</div>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<p contenteditable=\"false\"><span contenteditable>a[b]c</span></p>", + [["forwarddelete",""]], + "<p contenteditable=\"false\"><span contenteditable=\"\">ac</span></p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<p contenteditable=\"false\"><unknown-element contenteditable>a[b]c</unknown-element></p>", + [["forwarddelete",""]], + "<p contenteditable=\"false\"><unknown-element contenteditable=\"\">ac</unknown-element></p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +// Although it seems that browsers should put <br> element to make the inline +// editing host has one-line height, but currently Blink and Firefox do not do +// it. +["<p contenteditable=\"false\"><span contenteditable>[abc]</span></p>", + [["forwarddelete",""]], + "<p contenteditable=\"false\"><span contenteditable=\"\"></span></p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<p contenteditable=\"false\"><span contenteditable>a[bc<br>de]f</span></p>", + [["forwarddelete",""]], + ["<p contenteditable=\"false\"><span contenteditable=\"\">af</span></p>", + "<p contenteditable=\"false\"><span contenteditable=\"\">a<br>f</span></p>"], + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<p contenteditable=\"false\"><unknown-element contenteditable>[abc]</unknown-element></p>", + [["forwarddelete",""]], + "<p contenteditable=\"false\"><unknown-element contenteditable=\"\"></unknown-element></p>", + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p>[ab</p><p>c]d</p></custom-element></div>", + [["forwarddelete",""]], + ["<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p>d</p></custom-element></div>", + "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p>d<br></p></custom-element></div>"], + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p>a[b</p><p>cd]</p></custom-element></div>", + [["forwarddelete",""]], + ["<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p>a</p></custom-element></div>", + "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p>a<br></p></custom-element></div>"], + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p><b>[ab</b></p><p><i>c]d</i></p></custom-element></div>", + [["forwarddelete",""]], + ["<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p><i>d</i></p></custom-element></div>", + "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p><i>d</i><br></p></custom-element></div>"], + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p><b>a[b</b></p><p><i>cd]</i></p></custom-element></div>", + [["forwarddelete",""]], + ["<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p><b>a</b></p></custom-element></div>", + "<div contenteditable=\"false\"><custom-element contenteditable=\"\"><p><b>a</b><br></p></custom-element></div>"], + [true], + {"forwarddelete":[false,false,"",false,false,""]}], + +// Non-editable elements in editable content should be removed by hitting the +// Delete key. Delete the non-editable things, then, blocks should be merged. +["<p>abc[]</p><ul contenteditable=\"false\"><li>def</li></ul><p>ghi</p>", + [["forwarddelete",""]], + ["<p>abcghi</p>", + "<p>abcghi<br></p>"], + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<p>abc[]</p><ul><li contenteditable=\"false\">def</li></ul><p>ghi</p>", + [["forwarddelete",""]], + ["<p>abcghi</p>", + "<p>abcghi<br></p>"], + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<ul><li>abc[]</li><li contenteditable=\"false\">def</li><li>ghi</li></ul>", + [["forwarddelete",""]], + ["<ul><li>abcghi</li></ul>", + "<ul><li>abcghi<br></li></ul>"], + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<p>abc[]</p><ul><li contenteditable=\"false\">def</li><li>ghi</li></ul>", + [["forwarddelete",""]], + ["<p>abcghi</p>", + "<p>abcghi<br></p>"], + [true], + {"forwarddelete":[false,false,"",false,false,""]}], +["<ul><li>abc[]</li><li contenteditable=\"false\">def</li></ul><p>ghi</p>", + [["forwarddelete",""]], + ["<ul><li>abcghi</li></ul>", + "<ul><li>abcghi<br></li></ul>"], + [true], + {"forwarddelete":[false,false,"",false,false,""]}], + +// <font>s shouldn't be joined if they have different attributes. +["<p><font color=blue>foo[]</font><p><font color=brown>bar</font>", + [["styleWithCSS","false"],["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p><font color=\"blue\">foo[]</font><font color=\"brown\">bar</font></p>", + [true,true,true], + {"foreColor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 255)"]}], +["<p><font color=blue>foo[]</font><p><font color=brown>bar</font>", + [["styleWithCSS","false"],["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p><font color=\"blue\">foo[]</font><font color=\"brown\">bar</font></p>", + [true,true,true], + {"foreColor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 255)"]}], +["<p><font size=3>foo[]</font><p><font size=5>bar</font>", + [["styleWithCSS","false"],["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p><font size=\"3\">foo[]</font><font size=\"5\">bar</font></p>", + [true,true,true], + {"fontSize":[false,false,"3",false,false,"3"]}], +["<p><font size=3>foo[]</font><p><font size=5>bar</font>", + [["styleWithCSS","false"],["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p><font size=\"3\">foo[]</font><font size=\"5\">bar</font></p>", + [true,true,true], + {"fontSize":[false,false,"3",false,false,"3"]}], +["<p><font size=4>foo[]</font><p><font size=5>bar</font>", + [["styleWithCSS","false"],["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p><font size=\"4\">foo[]</font><font size=\"5\">bar</font></p>", + [true,true,true], + {"fontSize":[false,false,"4",false,false,"4"]}], +["<p><font size=4>foo[]</font><p><font size=5>bar</font>", + [["styleWithCSS","false"],["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p><font size=\"4\">foo[]</font><font size=\"5\">bar</font></p>", + [true,true,true], + {"fontSize":[false,false,"4",false,false,"4"]}], +["<p><font color=blue>foo[]</font><p><font size=5>bar</font>", + [["styleWithCSS","false"],["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p><font color=\"blue\">foo[]</font><font size=\"5\">bar</font></p>", + [true,true,true], + {"fontSize":[false,false,"3",false,false,"3"],"foreColor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 255)"]}], +["<p><font color=blue>foo[]</font><p><font size=5>bar</font>", + [["styleWithCSS","false"],["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p><font color=\"blue\">foo[]</font><font size=\"5\">bar</font></p>", + [true,true,true], + {"fontSize":[false,false,"3",false,false,"3"],"foreColor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 255)"]}], +["<p><font size=5>foo[]</font><p><font color=blue>bar</font>", + [["styleWithCSS","false"],["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p><font size=\"5\">foo[]</font><font color=\"blue\">bar</font></p>", + [true,true,true], + {"fontSize":[false,false,"5",false,false,"5"],"foreColor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 0)"]}], +["<p><font size=5>foo[]</font><p><font color=blue>bar</font>", + [["styleWithCSS","false"],["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p><font size=\"5\">foo[]</font><font color=\"blue\">bar</font></p>", + [true,true,true], + {"fontSize":[false,false,"5",false,false,"5"],"foreColor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 0)"]}], +["<p><font face=monospace>foo[]</font><p><font face=sans-serif>bar</font>", + [["styleWithCSS","false"],["defaultparagraphseparator","div"],["forwarddelete",""]], + "<p><font face=\"monospace\">foo[]</font><font face=\"sans-serif\">bar</font></p>", + [true,true,true], + {"fontName":[false,false,"monospace",false,false,"monospace"]}], +["<p><font face=monospace>foo[]</font><p><font face=sans-serif>bar</font>", + [["styleWithCSS","false"],["defaultparagraphseparator","p"],["forwarddelete",""]], + "<p><font face=\"monospace\">foo[]</font><font face=\"sans-serif\">bar</font></p>", + [true,true,true], + {"fontName":[false,false,"monospace",false,false,"monospace"]}], + +// After joining blocks, caret should be end of the deepest left block end for +// making the following input will be styled with the style there. +["<p><span style=\"color:rgb(0, 0, 255)\">foo[]</span></p><p><span style=\"color:rgb(255, 0, 0)\">bar</span></p>", + [["styleWithCSS","false"],["forwarddelete",""]], + "<p><span style=\"color:rgb(0, 0, 255)\">foo[]</span><span style=\"color:rgb(255, 0, 0)\">bar</span></p>", + [true,true], + {"foreColor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 255)"]}], +["<p><span style=\"color:rgb(0, 0, 255)\">foo[]</span><br></p><p><span style=\"color:rgb(255, 0, 0)\">bar</span></p>", + [["styleWithCSS","false"],["forwarddelete",""]], + "<p><span style=\"color:rgb(0, 0, 255)\">foo[]</span><span style=\"color:rgb(255, 0, 0)\">bar</span></p>", + [true,true], + {"foreColor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 255)"]}], +["<p><span style=\"color:rgb(0, 0, 255)\">foo[]<br></span></p><p><span style=\"color:rgb(255, 0, 0)\">bar</span></p>", + [["styleWithCSS","false"],["forwarddelete",""]], + "<p><span style=\"color:rgb(0, 0, 255)\">foo[]</span><span style=\"color:rgb(255, 0, 0)\">bar</span></p>", + [true,true], + {"foreColor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 255)"]}], +["<p><span style=\"color:rgb(0, 0, 255)\">foo[]</span></p><span style=\"color:rgb(255, 0, 0)\">bar</span>", + [["styleWithCSS","false"],["forwarddelete",""]], + "<p><span style=\"color:rgb(0, 0, 255)\">foo[]</span><span style=\"color:rgb(255, 0, 0)\">bar</span></p>", + [true,true], + {"foreColor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 255)"]}], +["<p><span style=\"color:rgb(0, 0, 255)\">foo[]</span><br></p><span style=\"color:rgb(255, 0, 0)\">bar</span>", + [["styleWithCSS","false"],["forwarddelete",""]], + "<p><span style=\"color:rgb(0, 0, 255)\">foo[]</span><span style=\"color:rgb(255, 0, 0)\">bar</span></p>", + [true,true], + {"foreColor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 255)"]}], +["<p><span style=\"color:rgb(0, 0, 255)\">foo[]<br></span></p><span style=\"color:rgb(255, 0, 0)\">bar</span>", + [["styleWithCSS","false"],["forwarddelete",""]], + "<p><span style=\"color:rgb(0, 0, 255)\">foo[]</span><span style=\"color:rgb(255, 0, 0)\">bar</span></p>", + [true,true], + {"foreColor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 255)"]}], +["<span style=\"color:rgb(0, 0, 255)\">foo[]</span><br><p><span style=\"color:rgb(255, 0, 0)\">bar</span></p>", + [["styleWithCSS","false"],["forwarddelete",""]], + "<span style=\"color:rgb(0, 0, 255)\">foo[]</span><span style=\"color:rgb(255, 0, 0)\">bar</span>", + [true,true], + {"foreColor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 255)"]}], +["<span style=\"color:rgb(0, 0, 255)\">foo[]<br></span><p><span style=\"color:rgb(255, 0, 0)\">bar</span></p>", + [["styleWithCSS","false"],["forwarddelete",""]], + "<span style=\"color:rgb(0, 0, 255)\">foo[]</span><span style=\"color:rgb(255, 0, 0)\">bar</span>", + [true,true], + {"foreColor":[false,false,"rgb(0, 0, 255)",false,false,"rgb(0, 0, 255)"]}], + +// If all list items are selected, keep one list item. +["<ul><li>[abc</li><li>def]</li></ul>", + [["forwarddelete",""]], + "<ul><li>{}<br></li></ul>", + [true], + {}], +["<ul><ol><li>[abc</li></ol><li>def]</li></ul>", + [["forwarddelete",""]], + "<ul><ol><li>{}<br></li></ol></ul>", + [true], + {}], +["<ul><ul><li>[abc</li></ul><li>def]</li></ul>", + [["forwarddelete",""]], + "<ul><ul><li>{}<br></li></ul></ul>", + [true], + {}], +["<ul><li>[abc</li><ul><li>def]</li></ul></ul>", + [["forwarddelete",""]], + "<ul><li>{}<br></li></ul>", + [true], + {}], +["<ul><ul><li>[abc</li></ul><ul><li>def]</li></ul></ul>", + [["forwarddelete",""]], + "<ul><ul><li>{}<br></li></ul></ul>", + [true], + {}], +["<ul><ol><li>[abc</li></ol><ul><li>def]</li></ul></ul>", + [["forwarddelete",""]], + "<ul><ol><li>{}<br></li></ol></ul>", + [true], + {}], +// Don't be confused at inner elements of the list items. +["<ul><li><span>[abc</span></li><li>def]</li></ul>", + [["forwarddelete",""]], + "<ul><li>{}<br></li></ul>", + [true], + {}], +["<ul><li>[abc</li><li><span>def]</span></li></ul>", + [["forwarddelete",""]], + "<ul><li>{}<br></li></ul>", + [true], + {}], +["<ul><li><span>[abc</span></li><li><span>def]</span></li></ul>", + [["forwarddelete",""]], + "<ul><li>{}<br></li></ul>", + [true], + {}], +// Don't be confused at white-spaces around first/last list items' boundaries. +["<ul><li> [abc</li><li>def]</li></ul>", + [["forwarddelete",""]], + "<ul><li>{}<br></li></ul>", + [true], + {}], +["<ul><li>[abc</li><li>def] </li></ul>", + [["forwarddelete",""]], + "<ul><li>{}<br></li></ul>", + [true], + {}], +["<ul><li> [abc</li><li>def] </li></ul>", + [["forwarddelete",""]], + "<ul><li>{}<br></li></ul>", + [true], + {}], +["<ul>\n<li>[abc</li><li>def]</li></ul>", + [["forwarddelete",""]], + ["<ul><li>{}<br></li></ul>", + "<ul>\n<li>{}<br></li></ul>"], + [true], + {}], +["<ul><li>[abc</li><li>def]</li>\n</ul>", + [["forwarddelete",""]], + ["<ul><li>{}<br></li></ul>", + "<ul><li>{}<br></li>\n</ul>"], + [true], + {}], +["<ul>\n<li>[abc</li><li>def]</li>\n</ul>", + [["forwarddelete",""]], + ["<ul><li>{}<br></li></ul>", + "<ul>\n<li>{}<br></li></ul>", + "<ul><li>{}<br></li>\n</ul>", + "<ul>\n<li>{}<br></li>\n</ul>"], + [true], + {}], +// Same things for non-sub-lists. +["<ol><li>[abc</li></ol><ul><li>def]</li></ul>", + [["forwarddelete",""]], + "<ol><li>{}<br></li></ol>", + [true], + {}], +["<ol><li> [abc</li></ol><ul><li>def]</li></ul>", + [["forwarddelete",""]], + "<ol><li>{}<br></li></ol>", + [true], + {}], +["<ol>\n<li>[abc</li></ol><ul><li>def]</li></ul>", + [["forwarddelete",""]], + ["<ol><li>{}<br></li></ol>", + "<ol>\n<li>{}<br></li></ol>"], + [true], + {}], + +// Select all list item children when list items have multiple nodes. +["{<ul><li>abc<span>def</span>ghi</li><li>jkl<span>opq</span>rst</li></ul>}", + [["forwarddelete",""]], + "<ul><li>{}<br></li></ul>", + [true], + {}], + +// inlined elements shouldn't be joined as <span>, etc +["<div style=\"display:inline\">abc[]</div><div style=\"display:inline\">def</div>", + [["forwarddelete",""]], + "<div style=\"display:inline\">abc</div><div style=\"display:inline\">ef</div>", + [true], + {}], +["<ul><li style=\"display:inline\">abc[]</li><li style=\"display:inline\">def</li></ul>", + [["forwarddelete",""]], + "<ul><li style=\"display:inline\">abc</li><li style=\"display:inline\">ef</li></ul>", + [true], + {}], +["<dl><dt style=\"display:inline\">abc[]</dt><dd style=\"display:inline\">def</dd></dl>", + [["forwarddelete",""]], + "<dl><dt style=\"display:inline\">abc</dt><dd style=\"display:inline\">ef</dd></dl>", + [true], + {}], +// list-styled elements should work as list item elements +["<div><span style=\"display:list-item\">abc[]</span><span style=\"display:list-item\">def</span></div>", + [["forwarddelete",""]], + "<div><span style=\"display:list-item\">abcdef</span></div>", + [true], + {}], +// Don't remove parent blocks of selection start to insert new text into the +// selection start container. +["<div>{abc</div><div>def</div>}", + [["forwarddelete",""]], + "<div><br></div>", + [true], + {}], +["<div>abc</div><div>{def</div>}", + [["forwarddelete",""]], + "<div>abc</div><div><br></div>", + [true], + {}], +["<div style=display:flex><span>{abc</span><span>def</span>}</div>", + [["forwarddelete",""]], + "<div style=\"display:flex\"><span><br></span></div>", + [true], + {}], +["<div style=display:flex><span>abc</span><span>{def</span>}</div>", + [["forwarddelete",""]], + "<div style=\"display:flex\"><span>abc</span><span><br></span></div>", + [true], + {}], +["<div style=display:grid><span>{abc</span><span>def</span>}</div>", + [["forwarddelete",""]], + "<div style=\"display:grid\"><span><br></span></div>", + [true], + {}], +["<div style=display:grid><span>abc</span><span>{def</span>}</div>", + [["forwarddelete",""]], + "<div style=\"display:grid\"><span>abc</span><span><br></span></div>", + [true], + {}], +// Do not delete non-editable when deleting an editable character +["<b>[]X<span contenteditable=false>abc</span></b><i>def</i>", + [["forwarddelete",""]], + "<b><span contenteditable=\"false\">abc</span></b><i>def</i>", + [true], + {}], +["<b><span contenteditable=false>abc</span>[]X</b><i>def</i>", + [["forwarddelete",""]], + "<b><span contenteditable=\"false\">abc</span></b><i>def</i>", + [true], + {}], +["<p>[]X<span contenteditable=false>abc</span></p>", + [["forwarddelete",""]], + "<p><span contenteditable=\"false\">abc</span></p>", + [true], + {}], +["<p><span contenteditable=false>abc</span>[]X</p>", + [["forwarddelete",""]], + "<p><span contenteditable=\"false\">abc</span></p>", + [true], + {}], +// Do not delete ancestor blocks which still has non-editable content +["<p><span contenteditable=false>ab</span>{}</p>", + [["forwarddelete",""]], + "<p><span contenteditable=\"false\">ab</span></p>", + [true], + {}], +] diff --git a/testing/web-platform/tests/editing/data/hilitecolor.js b/testing/web-platform/tests/editing/data/hilitecolor.js new file mode 100644 index 0000000000..7f9f4949dc --- /dev/null +++ b/testing/web-platform/tests/editing/data/hilitecolor.js @@ -0,0 +1,415 @@ +// For documentation of the format, see README in this directory. +var browserTests = [ +["foo[]bar", + [["hilitecolor","#00FFFF"]], + "foo[]bar", + [true], + {"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<p>[foo</p> <p>bar]</p>", + [["stylewithcss","true"],["hilitecolor","#00FFFF"]], + "<p><span style=\"background-color:rgb(0, 255, 255)\">[foo</span></p> <p><span style=\"background-color:rgb(0, 255, 255)\">bar]</span></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<p>[foo</p> <p>bar]</p>", + [["stylewithcss","false"],["hilitecolor","#00FFFF"]], + "<p><span style=\"background-color:rgb(0, 255, 255)\">[foo</span></p> <p><span style=\"background-color:rgb(0, 255, 255)\">bar]</span></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<span>[foo</span> <span>bar]</span>", + [["stylewithcss","true"],["hilitecolor","#00FFFF"]], + "<span style=\"background-color:rgb(0, 255, 255)\"><span>[foo</span> <span>bar]</span></span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<span>[foo</span> <span>bar]</span>", + [["stylewithcss","false"],["hilitecolor","#00FFFF"]], + "<span style=\"background-color:rgb(0, 255, 255)\"><span>[foo</span> <span>bar]</span></span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<p>[foo</p><p> <span>bar</span> </p><p>baz]</p>", + [["stylewithcss","true"],["hilitecolor","#00FFFF"]], + "<p><span style=\"background-color:rgb(0, 255, 255)\">[foo</span></p><p> <span style=\"background-color:rgb(0, 255, 255)\"><span>bar</span></span> </p><p><span style=\"background-color:rgb(0, 255, 255)\">baz]</span></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<p>[foo</p><p> <span>bar</span> </p><p>baz]</p>", + [["stylewithcss","false"],["hilitecolor","#00FFFF"]], + "<p><span style=\"background-color:rgb(0, 255, 255)\">[foo</span></p><p> <span style=\"background-color:rgb(0, 255, 255)\"><span>bar</span></span> </p><p><span style=\"background-color:rgb(0, 255, 255)\">baz]</span></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<p>[foo<p><br><p>bar]", + [["stylewithcss","true"],["hilitecolor","#00FFFF"]], + "<p><span style=\"background-color:rgb(0, 255, 255)\">[foo</span></p><p><span style=\"background-color:rgb(0, 255, 255)\"><br></span></p><p><span style=\"background-color:rgb(0, 255, 255)\">bar]</span></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<p>[foo<p><br><p>bar]", + [["stylewithcss","false"],["hilitecolor","#00FFFF"]], + "<p><span style=\"background-color:rgb(0, 255, 255)\">[foo</span></p><p><span style=\"background-color:rgb(0, 255, 255)\"><br></span></p><p><span style=\"background-color:rgb(0, 255, 255)\">bar]</span></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<b>foo[]bar</b>", + [["hilitecolor","#00FFFF"]], + "<b>foo[]bar</b>", + [true], + {"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<i>foo[]bar</i>", + [["hilitecolor","#00FFFF"]], + "<i>foo[]bar</i>", + [true], + {"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<span>foo</span>{}<span>bar</span>", + [["hilitecolor","#00FFFF"]], + "<span>foo</span>{}<span>bar</span>", + [true], + {"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<span>foo[</span><span>]bar</span>", + [["hilitecolor","#00FFFF"]], + "<span>foo[</span><span>]bar</span>", + [true], + {"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["foo[bar]baz", + [["stylewithcss","true"],["hilitecolor","#00FFFF"]], + "foo<span style=\"background-color:rgb(0, 255, 255)\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["foo[bar]baz", + [["stylewithcss","false"],["hilitecolor","#00FFFF"]], + "foo<span style=\"background-color:rgb(0, 255, 255)\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["foo[bar<b>baz]qoz</b>quz", + [["stylewithcss","true"],["hilitecolor","#00FFFF"]], + "foo<span style=\"background-color:rgb(0, 255, 255)\">[bar</span><b><span style=\"background-color:rgb(0, 255, 255)\">baz]</span>qoz</b>quz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["foo[bar<b>baz]qoz</b>quz", + [["stylewithcss","false"],["hilitecolor","#00FFFF"]], + "foo<span style=\"background-color:rgb(0, 255, 255)\">[bar</span><b><span style=\"background-color:rgb(0, 255, 255)\">baz]</span>qoz</b>quz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["foo[bar<i>baz]qoz</i>quz", + [["stylewithcss","true"],["hilitecolor","#00FFFF"]], + "foo<span style=\"background-color:rgb(0, 255, 255)\">[bar</span><i><span style=\"background-color:rgb(0, 255, 255)\">baz]</span>qoz</i>quz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["foo[bar<i>baz]qoz</i>quz", + [["stylewithcss","false"],["hilitecolor","#00FFFF"]], + "foo<span style=\"background-color:rgb(0, 255, 255)\">[bar</span><i><span style=\"background-color:rgb(0, 255, 255)\">baz]</span>qoz</i>quz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["{<p><p> <p>foo</p>}", + [["stylewithcss","true"],["hilitecolor","#00FFFF"]], + "{<p></p><p> </p><p><span style=\"background-color:rgb(0, 255, 255)\">foo</span></p>}", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["{<p><p> <p>foo</p>}", + [["stylewithcss","false"],["hilitecolor","#00FFFF"]], + "{<p></p><p> </p><p><span style=\"background-color:rgb(0, 255, 255)\">foo</span></p>}", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>", + [["stylewithcss","true"],["hilitecolor","#00FFFF"]], + "<table><tbody><tr><td>foo</td><td>b<span style=\"background-color:rgb(0, 255, 255)\">[a]</span>r</td><td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>", + [["stylewithcss","false"],["hilitecolor","#00FFFF"]], + "<table><tbody><tr><td>foo</td><td>b<span style=\"background-color:rgb(0, 255, 255)\">[a]</span>r</td><td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table>", + [["stylewithcss","true"],["hilitecolor","#00FFFF"]], + "<table><tbody><tr><td>foo</td>{<td><span style=\"background-color:rgb(0, 255, 255)\">bar</span></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table>", + [["stylewithcss","false"],["hilitecolor","#00FFFF"]], + "<table><tbody><tr><td>foo</td>{<td><span style=\"background-color:rgb(0, 255, 255)\">bar</span></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table>", + [["stylewithcss","true"],["hilitecolor","#00FFFF"]], + "<table><tbody><tr>{<td><span style=\"background-color:rgb(0, 255, 255)\">foo</span></td><td><span style=\"background-color:rgb(0, 255, 255)\">bar</span></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table>", + [["stylewithcss","false"],["hilitecolor","#00FFFF"]], + "<table><tbody><tr>{<td><span style=\"background-color:rgb(0, 255, 255)\">foo</span></td><td><span style=\"background-color:rgb(0, 255, 255)\">bar</span></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>", + [["stylewithcss","true"],["hilitecolor","#00FFFF"]], + "<table><tbody>{<tr><td><span style=\"background-color:rgb(0, 255, 255)\">foo</span></td><td><span style=\"background-color:rgb(0, 255, 255)\">bar</span></td><td><span style=\"background-color:rgb(0, 255, 255)\">baz</span></td></tr>}</tbody></table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>", + [["stylewithcss","false"],["hilitecolor","#00FFFF"]], + "<table><tbody>{<tr><td><span style=\"background-color:rgb(0, 255, 255)\">foo</span></td><td><span style=\"background-color:rgb(0, 255, 255)\">bar</span></td><td><span style=\"background-color:rgb(0, 255, 255)\">baz</span></td></tr>}</tbody></table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>", + [["stylewithcss","true"],["hilitecolor","#00FFFF"]], + "<table>{<tbody><tr><td><span style=\"background-color:rgb(0, 255, 255)\">foo</span></td><td><span style=\"background-color:rgb(0, 255, 255)\">bar</span></td><td><span style=\"background-color:rgb(0, 255, 255)\">baz</span></td></tr></tbody>}</table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>", + [["stylewithcss","false"],["hilitecolor","#00FFFF"]], + "<table>{<tbody><tr><td><span style=\"background-color:rgb(0, 255, 255)\">foo</span></td><td><span style=\"background-color:rgb(0, 255, 255)\">bar</span></td><td><span style=\"background-color:rgb(0, 255, 255)\">baz</span></td></tr></tbody>}</table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["{<table><tr><td>foo<td>bar<td>baz</table>}", + [["stylewithcss","true"],["hilitecolor","#00FFFF"]], + "{<table><tbody><tr><td><span style=\"background-color:rgb(0, 255, 255)\">foo</span></td><td><span style=\"background-color:rgb(0, 255, 255)\">bar</span></td><td><span style=\"background-color:rgb(0, 255, 255)\">baz</span></td></tr></tbody></table>}", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["{<table><tr><td>foo<td>bar<td>baz</table>}", + [["stylewithcss","false"],["hilitecolor","#00FFFF"]], + "{<table><tbody><tr><td><span style=\"background-color:rgb(0, 255, 255)\">foo</span></td><td><span style=\"background-color:rgb(0, 255, 255)\">bar</span></td><td><span style=\"background-color:rgb(0, 255, 255)\">baz</span></td></tr></tbody></table>}", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<p style=\"background-color: rgb(0, 255, 255)\">foo[bar]baz</p>", + [["hilitecolor","#00FFFF"]], + "<p style=\"background-color:rgb(0, 255, 255)\">foo[bar]baz</p>", + [true], + {"hilitecolor":[false,false,"rgb(0, 255, 255)",false,false,"rgb(0, 255, 255)"]}], +["<p style=\"background-color: #00ffff\">foo[bar]baz</p>", + [["hilitecolor","#00FFFF"]], + "<p style=\"background-color:rgb(0, 255, 255)\">foo[bar]baz</p>", + [true], + {"hilitecolor":[false,false,"rgb(0, 255, 255)",false,false,"rgb(0, 255, 255)"]}], +["<p style=\"background-color: aqua\">foo[bar]baz</p>", + [["hilitecolor","#00FFFF"]], + "<p style=\"background-color:rgb(0, 255, 255)\">foo[bar]baz</p>", + [true], + {"hilitecolor":[false,false,"rgb(0, 255, 255)",false,false,"rgb(0, 255, 255)"]}], +["{<p style=\"background-color: aqua\">foo</p><p>bar</p>}", + [["stylewithcss","true"],["hilitecolor","#00FFFF"]], + "{<p style=\"background-color:rgb(0, 255, 255)\">foo</p><p><span style=\"background-color:rgb(0, 255, 255)\">bar</span></p>}", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"hilitecolor":[true,false,"rgb(0, 255, 255)",false,false,"rgb(0, 255, 255)"]}], +["{<p style=\"background-color: aqua\">foo</p><p>bar</p>}", + [["stylewithcss","false"],["hilitecolor","#00FFFF"]], + "{<p style=\"background-color:rgb(0, 255, 255)\">foo</p><p><span style=\"background-color:rgb(0, 255, 255)\">bar</span></p>}", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"hilitecolor":[true,false,"rgb(0, 255, 255)",false,false,"rgb(0, 255, 255)"]}], +["<span style=\"background-color: aqua\">foo<span style=\"background-color: tan\">[bar]</span>baz</span>", + [["stylewithcss","true"],["hilitecolor","#00FFFF"]], + "<span style=\"background-color:rgb(0, 255, 255)\">foo[bar]baz</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"hilitecolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["<span style=\"background-color: aqua\">foo<span style=\"background-color: tan\">[bar]</span>baz</span>", + [["stylewithcss","false"],["hilitecolor","#00FFFF"]], + "<span style=\"background-color:rgb(0, 255, 255)\">foo[bar]baz</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"hilitecolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["<span style=\"background-color: #00ffff\">foo<span style=\"background-color: tan\">[bar]</span>baz</span>", + [["stylewithcss","true"],["hilitecolor","#00FFFF"]], + "<span style=\"background-color:rgb(0, 255, 255)\">foo[bar]baz</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"hilitecolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["<span style=\"background-color: #00ffff\">foo<span style=\"background-color: tan\">[bar]</span>baz</span>", + [["stylewithcss","false"],["hilitecolor","#00FFFF"]], + "<span style=\"background-color:rgb(0, 255, 255)\">foo[bar]baz</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"hilitecolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["<span style=\"background-color: #0ff\">foo<span style=\"background-color: tan\">[bar]</span>baz</span>", + [["stylewithcss","true"],["hilitecolor","#00FFFF"]], + "<span style=\"background-color:rgb(0, 255, 255)\">foo[bar]baz</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"hilitecolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["<span style=\"background-color: #0ff\">foo<span style=\"background-color: tan\">[bar]</span>baz</span>", + [["stylewithcss","false"],["hilitecolor","#00FFFF"]], + "<span style=\"background-color:rgb(0, 255, 255)\">foo[bar]baz</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"hilitecolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["<span style=\"background-color: rgb(0, 255, 255)\">foo<span style=\"background-color: tan\">[bar]</span>baz</span>", + [["stylewithcss","true"],["hilitecolor","#00FFFF"]], + "<span style=\"background-color:rgb(0, 255, 255)\">foo[bar]baz</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"hilitecolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["<span style=\"background-color: rgb(0, 255, 255)\">foo<span style=\"background-color: tan\">[bar]</span>baz</span>", + [["stylewithcss","false"],["hilitecolor","#00FFFF"]], + "<span style=\"background-color:rgb(0, 255, 255)\">foo[bar]baz</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"hilitecolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["<span style=\"background-color: aqua\">foo<span style=\"background-color: tan\">b[ar]</span>baz</span>", + [["hilitecolor","#00FFFF"]], + "<span style=\"background-color:rgb(0, 255, 255)\">foo<span style=\"background-color:rgb(210, 180, 140)\">b</span>[ar]baz</span>", + [true], + {"hilitecolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["<p style=\"background-color: aqua\">foo<span style=\"background-color: tan\">b[ar]</span>baz</p>", + [["hilitecolor","#00FFFF"]], + "<p style=\"background-color:rgb(0, 255, 255)\">foo<span style=\"background-color:rgb(210, 180, 140)\">b</span>[ar]baz</p>", + [true], + {"hilitecolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["<div style=\"background-color: aqua\"><p style=\"background-color: tan\">b[ar]</p></div>", + [["stylewithcss","true"],["hilitecolor","#00FFFF"]], + "<div style=\"background-color:rgb(0, 255, 255)\"><p style=\"background-color:rgb(210, 180, 140)\">b<span style=\"background-color:rgb(0, 255, 255)\">[ar]</span></p></div>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"hilitecolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["<div style=\"background-color: aqua\"><p style=\"background-color: tan\">b[ar]</p></div>", + [["stylewithcss","false"],["hilitecolor","#00FFFF"]], + "<div style=\"background-color:rgb(0, 255, 255)\"><p style=\"background-color:rgb(210, 180, 140)\">b<span style=\"background-color:rgb(0, 255, 255)\">[ar]</span></p></div>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"hilitecolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["<span style=\"display: block; background-color: aqua\"><span style=\"display: block; background-color: tan\">b[ar]</span></span>", + [["stylewithcss","true"],["hilitecolor","#00FFFF"]], + "<span style=\"display:block; background-color:rgb(0, 255, 255)\"><span style=\"display:block; background-color:rgb(210, 180, 140)\">b<span style=\"background-color:rgb(0, 255, 255)\">[ar]</span></span></span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"hilitecolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["<span style=\"display: block; background-color: aqua\"><span style=\"display: block; background-color: tan\">b[ar]</span></span>", + [["stylewithcss","false"],["hilitecolor","#00FFFF"]], + "<span style=\"display:block; background-color:rgb(0, 255, 255)\"><span style=\"display:block; background-color:rgb(210, 180, 140)\">b<span style=\"background-color:rgb(0, 255, 255)\">[ar]</span></span></span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"hilitecolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["fo[o<span style=background-color:tan>b]ar</span>baz", + [["stylewithcss","true"],["hilitecolor","#00FFFF"]], + "fo<span style=\"background-color:rgb(0, 255, 255)\">[o</span><span style=\"background-color:rgb(210, 180, 140)\"><span style=\"background-color:rgb(0, 255, 255)\">b]</span>ar</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"hilitecolor":[true,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["fo[o<span style=background-color:tan>b]ar</span>baz", + [["stylewithcss","false"],["hilitecolor","#00FFFF"]], + "fo<span style=\"background-color:rgb(0, 255, 255)\">[o</span><span style=\"background-color:rgb(210, 180, 140)\"><span style=\"background-color:rgb(0, 255, 255)\">b]</span>ar</span>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"hilitecolor":[true,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["foo<span style=background-color:tan>ba[r</span>b]az", + [["stylewithcss","true"],["hilitecolor","#00FFFF"]], + "foo<span style=\"background-color:rgb(210, 180, 140)\">ba<span style=\"background-color:rgb(0, 255, 255)\">[r</span></span><span style=\"background-color:rgb(0, 255, 255)\">b]</span>az", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"hilitecolor":[true,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["foo<span style=background-color:tan>ba[r</span>b]az", + [["stylewithcss","false"],["hilitecolor","#00FFFF"]], + "foo<span style=\"background-color:rgb(210, 180, 140)\">ba<span style=\"background-color:rgb(0, 255, 255)\">[r</span></span><span style=\"background-color:rgb(0, 255, 255)\">b]</span>az", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"hilitecolor":[true,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["fo[o<span style=background-color:tan>bar</span>b]az", + [["hilitecolor","#00FFFF"]], + "fo<span style=\"background-color:rgb(0, 255, 255)\">[obarb]</span>az", + [true], + {"hilitecolor":[true,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["foo[<span style=background-color:tan>b]ar</span>baz", + [["stylewithcss","true"],["hilitecolor","#00FFFF"]], + "foo[<span style=\"background-color:rgb(210, 180, 140)\"><span style=\"background-color:rgb(0, 255, 255)\">b]</span>ar</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"hilitecolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["foo[<span style=background-color:tan>b]ar</span>baz", + [["stylewithcss","false"],["hilitecolor","#00FFFF"]], + "foo[<span style=\"background-color:rgb(210, 180, 140)\"><span style=\"background-color:rgb(0, 255, 255)\">b]</span>ar</span>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"hilitecolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["foo<span style=background-color:tan>ba[r</span>]baz", + [["stylewithcss","true"],["hilitecolor","#00FFFF"]], + "foo<span style=\"background-color:rgb(210, 180, 140)\">ba<span style=\"background-color:rgb(0, 255, 255)\">[r</span></span>]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"hilitecolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["foo<span style=background-color:tan>ba[r</span>]baz", + [["stylewithcss","false"],["hilitecolor","#00FFFF"]], + "foo<span style=\"background-color:rgb(210, 180, 140)\">ba<span style=\"background-color:rgb(0, 255, 255)\">[r</span></span>]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"hilitecolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["foo[<span style=background-color:tan>bar</span>]baz", + [["hilitecolor","#00FFFF"]], + "foo[<span style=\"background-color:rgb(0, 255, 255)\">bar</span>]baz", + [true], + {"hilitecolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["foo<span style=background-color:tan>[bar]</span>baz", + [["hilitecolor","#00FFFF"]], + "foo<span style=\"background-color:rgb(0, 255, 255)\">[bar]</span>baz", + [true], + {"hilitecolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["foo{<span style=background-color:tan>bar</span>}baz", + [["hilitecolor","#00FFFF"]], + "foo{<span style=\"background-color:rgb(0, 255, 255)\">bar}</span>baz", + [true], + {"hilitecolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["<span style=background-color:tan>fo[o</span><span style=background-color:yellow>b]ar</span>", + [["stylewithcss","true"],["hilitecolor","#00FFFF"]], + "<span style=\"background-color:rgb(210, 180, 140)\">fo<span style=\"background-color:rgb(0, 255, 255)\">[o</span></span><span style=\"background-color:rgb(255, 255, 0)\"><span style=\"background-color:rgb(0, 255, 255)\">b]</span>ar</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"hilitecolor":[true,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["<span style=background-color:tan>fo[o</span><span style=background-color:yellow>b]ar</span>", + [["stylewithcss","false"],["hilitecolor","#00FFFF"]], + "<span style=\"background-color:rgb(210, 180, 140)\">fo<span style=\"background-color:rgb(0, 255, 255)\">[o</span></span><span style=\"background-color:rgb(255, 255, 0)\"><span style=\"background-color:rgb(0, 255, 255)\">b]</span>ar</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"hilitecolor":[true,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["<span style=background-color:tan>fo[o</span><span style=background-color:tan>b]ar</span>", + [["stylewithcss","true"],["hilitecolor","#00FFFF"]], + "<span style=\"background-color:rgb(210, 180, 140)\">fo<span style=\"background-color:rgb(0, 255, 255)\">[o</span></span><span style=\"background-color:rgb(210, 180, 140)\"><span style=\"background-color:rgb(0, 255, 255)\">b]</span>ar</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"hilitecolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["<span style=background-color:tan>fo[o</span><span style=background-color:tan>b]ar</span>", + [["stylewithcss","false"],["hilitecolor","#00FFFF"]], + "<span style=\"background-color:rgb(210, 180, 140)\">fo<span style=\"background-color:rgb(0, 255, 255)\">[o</span></span><span style=\"background-color:rgb(210, 180, 140)\"><span style=\"background-color:rgb(0, 255, 255)\">b]</span>ar</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"hilitecolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["<span style=background-color:tan>fo[o<span style=background-color:transparent>b]ar</span></span>", + [["stylewithcss","true"],["hilitecolor","#00FFFF"]], + "<span style=\"background-color:rgb(210, 180, 140)\">fo<span style=\"background-color:rgb(0, 255, 255)\">[o</span><span style=\"background-color:rgba(0, 0, 0, 0)\"><span style=\"background-color:rgb(0, 255, 255)\">b]</span>ar</span></span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"hilitecolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["<span style=background-color:tan>fo[o<span style=background-color:transparent>b]ar</span></span>", + [["stylewithcss","false"],["hilitecolor","#00FFFF"]], + "<span style=\"background-color:rgb(210, 180, 140)\">fo<span style=\"background-color:rgb(0, 255, 255)\">[o</span><span style=\"background-color:rgba(0, 0, 0, 0)\"><span style=\"background-color:rgb(0, 255, 255)\">b]</span>ar</span></span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"hilitecolor":[false,false,"rgb(210, 180, 140)",false,false,"rgb(0, 255, 255)"]}], +["<font size=6>[foo]</font>", + [["stylewithcss","true"],["hilitecolor","#00FFFF"]], + ["<font size=\"6\" style=\"background-color:rgb(0, 255, 255)\">foo</font>", + "<font style=\"background-color:rgb(0, 255, 255)\" size=\"6\">foo</font>"], + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<font size=6>[foo]</font>", + [["stylewithcss","false"],["hilitecolor","#00FFFF"]], + ["<font size=\"6\" style=\"background-color:rgb(0, 255, 255)\">foo</font>", + "<font style=\"background-color:rgb(0, 255, 255)\" size=\"6\">foo</font>"], + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<span style=font-size:xx-large>[foo]</span>", + [["stylewithcss","true"],["hilitecolor","#00FFFF"]], + "<span style=\"font-size:xx-large; background-color:rgb(0, 255, 255)\">[foo]</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<span style=font-size:xx-large>[foo]</span>", + [["stylewithcss","false"],["hilitecolor","#00FFFF"]], + "<span style=\"font-size:xx-large; background-color:rgb(0, 255, 255)\">[foo]</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<font size=6>foo[bar]baz</font>", + [["stylewithcss","true"],["hilitecolor","#00FFFF"]], + "<font size=\"6\">foo<span style=\"background-color:rgb(0, 255, 255)\">[bar]</span>baz</font>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<font size=6>foo[bar]baz</font>", + [["stylewithcss","false"],["hilitecolor","#00FFFF"]], + "<font size=\"6\">foo<span style=\"background-color:rgb(0, 255, 255)\">[bar]</span>baz</font>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<span style=font-size:xx-large>foo[bar]baz</span>", + [["stylewithcss","true"],["hilitecolor","#00FFFF"]], + "<span style=\"font-size:xx-large\">foo<span style=\"background-color:rgb(0, 255, 255)\">[bar]</span>baz</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["<span style=font-size:xx-large>foo[bar]baz</span>", + [["stylewithcss","false"],["hilitecolor","#00FFFF"]], + "<span style=\"font-size:xx-large\">foo<span style=\"background-color:rgb(0, 255, 255)\">[bar]</span>baz</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["[foo<font size=6>bar</font>baz]", + [["stylewithcss","true"],["hilitecolor","#00FFFF"]], + "<span style=\"background-color:rgb(0, 255, 255)\">[foo<font size=\"6\">bar</font>baz]</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["[foo<font size=6>bar</font>baz]", + [["stylewithcss","false"],["hilitecolor","#00FFFF"]], + "<span style=\"background-color:rgb(0, 255, 255)\">[foo<font size=\"6\">bar</font>baz]</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["[foo<span style=font-size:xx-large>bar</span>baz]", + [["stylewithcss","true"],["hilitecolor","#00FFFF"]], + "<span style=\"background-color:rgb(0, 255, 255)\">[foo<span style=\"font-size:xx-large\">bar</span>baz]</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}], +["[foo<span style=font-size:xx-large>bar</span>baz]", + [["stylewithcss","false"],["hilitecolor","#00FFFF"]], + "<span style=\"background-color:rgb(0, 255, 255)\">[foo<span style=\"font-size:xx-large\">bar</span>baz]</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"]}] +] diff --git a/testing/web-platform/tests/editing/data/indent.js b/testing/web-platform/tests/editing/data/indent.js new file mode 100644 index 0000000000..4dd7d1feee --- /dev/null +++ b/testing/web-platform/tests/editing/data/indent.js @@ -0,0 +1,730 @@ +// For documentation of the format, see README in this directory. +var browserTests = [ +["foo[]bar<p>extra", + [["indent",""]], + "<blockquote>foo[]bar</blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<span>foo</span>{}<span>bar</span><p>extra", + [["indent",""]], + "<blockquote><span>foo</span>{}<span>bar</span></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<span>foo[</span><span>]bar</span><p>extra", + [["indent",""]], + "<blockquote><span>foo[</span><span>]bar</span></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["foo[bar]baz<p>extra", + [["indent",""]], + "<blockquote>foo[bar]baz</blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<p dir=rtl>פו[בר]בז<p dir=rtl>נוםף", + [["indent",""]], + "<blockquote><p dir=\"rtl\">פו[בר]בז</p></blockquote><p dir=\"rtl\">נוםף</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<p dir=rtl>פו[ברבז<p>Foobar]baz<p>Extra", + [["indent",""]], + "<blockquote><p dir=\"rtl\">פו[ברבז</p><p>Foobar]baz</p></blockquote><p>Extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<p>Foo[barbaz<p dir=rtl>פובר]בז<p>Extra", + [["indent",""]], + "<blockquote><p>Foo[barbaz</p><p dir=\"rtl\">פובר]בז</p></blockquote><p>Extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<div><p>Foo[barbaz<p dir=rtl>פובר]בז</div><p>Extra", + [["indent",""]], + "<blockquote><div><p>Foo[barbaz</p><p dir=\"rtl\">פובר]בז</p></div></blockquote><p>Extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["foo]bar[baz<p>extra", + [["indent",""]], + "<blockquote>foo[bar]baz</blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["{<p><p> <p>foo</p>}<p>extra", + [["indent",""]], + "<blockquote>{<p></p><p> </p><p>foo</p>}</blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["foo[bar<i>baz]qoz</i>quz<p>extra", + [["indent",""]], + "<blockquote>foo[bar<i>baz]qoz</i>quz</blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["[]foo<p>extra", + [["indent",""]], + "<blockquote>[]foo</blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["foo[]<p>extra", + [["indent",""]], + "<blockquote>foo[]</blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<p>[]foo<p>extra", + [["indent",""]], + "<blockquote><p>[]foo</p></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<p>foo[]<p>extra", + [["indent",""]], + "<blockquote><p>foo[]</p></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<p>{}<br>foo</p><p>extra", + [["indent",""]], + "<blockquote>{}<br></blockquote><p>foo</p><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<p>foo<br>{}</p><p>extra", + [["indent",""]], + "<blockquote><p>foo{}</p></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<span>{}<br>foo</span>bar<p>extra", + [["indent",""]], + "<blockquote>{}<br></blockquote><span>foo</span>bar<p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<span>foo<br>{}</span>bar<p>extra", + [["indent",""]], + "<span>foo{}</span><blockquote>bar</blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<p>foo</p>{}<p>bar</p>", + [["indent",""]], + "<p>foo</p>{}<p>bar</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<table><tbody><tr><td>foo<td>b[a]r<td>baz</table><p>extra", + [["indent",""]], + "<table><tbody><tr><td>foo</td><td><blockquote>b[a]r</blockquote></td><td>baz</td></tr></tbody></table><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["indent",""]], + "<table><tbody><tr><td>foo</td>{<td><blockquote>bar</blockquote></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["indent",""]], + "<table><tbody><tr>{<td><blockquote>foo</blockquote></td><td><blockquote>bar</blockquote></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra", + [["indent",""]], + "<blockquote><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table><p>extra", + [["indent",""]], + "<blockquote><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["{<table><tr><td>foo<td>bar<td>baz</table>}<p>extra", + [["indent",""]], + "<blockquote>{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<p>foo[bar]</p><p>baz</p><p>extra", + [["indent",""]], + "<blockquote><p>foo[bar]</p></blockquote><p>baz</p><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<p>[foobar</p><p>ba]z</p><p>extra", + [["indent",""]], + "<blockquote><p>[foobar</p><p>ba]z</p></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["foo[bar]<br>baz<p>extra", + [["indent",""]], + "<blockquote>foo[bar]</blockquote>baz<p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["foo[bar]<br><br><br><br>baz<p>extra", + [["indent",""]], + "<blockquote>foo[bar]</blockquote><br><br><br>baz<p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["foobar<br>[ba]z<p>extra", + [["indent",""]], + "foobar<blockquote>[ba]z</blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["foobar<br><br><br><br>[ba]z<p>extra", + [["indent",""]], + "foobar<br><br><br><br><blockquote>[ba]z</blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["foo[bar<br>ba]z<p>extra", + [["indent",""]], + "<blockquote>foo[bar<br>ba]z</blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<div>foo<p>[bar]</p>baz</div><p>extra", + [["indent",""]], + "<div>foo<blockquote><p>[bar]</p></blockquote>baz</div><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<blockquote><p>foo[bar]</p><p>baz</p></blockquote><p>extra", + [["indent",""]], + "<blockquote><blockquote><p>foo[bar]</p></blockquote><p>baz</p></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<blockquote><p>foo[bar</p><p>b]az</p></blockquote><p>extra", + [["indent",""]], + "<blockquote><blockquote><p>foo[bar</p><p>b]az</p></blockquote></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<blockquote><p>foo[bar]</p></blockquote><p>baz</p><p>extra", + [["indent",""]], + "<blockquote><blockquote><p>foo[bar]</p></blockquote></blockquote><p>baz</p><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<blockquote><p>foo[bar</p></blockquote><p>b]az</p><p>extra", + [["indent",""]], + "<blockquote><blockquote><p>foo[bar</p></blockquote><p>b]az</p></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<p>[foo]<blockquote><p>bar</blockquote><p>extra", + [["indent",""]], + "<blockquote><p>[foo]</p><p>bar</p></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<p>[foo<blockquote><p>b]ar</blockquote><p>extra", + [["indent",""]], + "<blockquote><p>[foo</p><blockquote><p>b]ar</p></blockquote></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<p>foo<blockquote><p>bar</blockquote><p>[baz]<p>extra", + [["indent",""]], + "<p>foo</p><blockquote><p>bar</p><p>[baz]</p></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<p>foo<blockquote><p>[bar</blockquote><p>baz]<p>extra", + [["indent",""]], + "<p>foo</p><blockquote><blockquote><p>[bar</p></blockquote><p>baz]</p></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<p>[foo<blockquote><p>bar</blockquote><p>baz]<p>extra", + [["indent",""]], + "<blockquote><p>[foo</p><blockquote><p>bar</p></blockquote><p>baz]</p></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<blockquote><p>foo</blockquote><p>[bar]<blockquote><p>baz</blockquote><p>extra", + [["indent",""]], + "<blockquote><p>foo</p><p>[bar]</p><p>baz</p></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<blockquote>foo[bar]<br>baz</blockquote><p>extra", + [["indent",""]], + "<blockquote><blockquote>foo[bar]</blockquote>baz</blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<blockquote>foo[bar<br>b]az</blockquote><p>extra", + [["indent",""]], + "<blockquote><blockquote>foo[bar<br>b]az</blockquote></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<blockquote>foo[bar]</blockquote>baz<p>extra", + [["indent",""]], + "<blockquote><blockquote>foo[bar]</blockquote></blockquote>baz<p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<blockquote>foo[bar</blockquote>b]az<p>extra", + [["indent",""]], + "<blockquote><blockquote>foo[bar</blockquote>b]az</blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["[foo]<blockquote>bar</blockquote><p>extra", + [["indent",""]], + "<blockquote>[foo]<br>bar</blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["[foo<blockquote>b]ar</blockquote><p>extra", + [["indent",""]], + "<blockquote>[foo<blockquote>b]ar</blockquote></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["foo<blockquote>bar</blockquote>[baz]<p>extra", + [["indent",""]], + "foo<blockquote>bar<br>[baz]</blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["[foo<blockquote>bar</blockquote>baz]<p>extra", + [["indent",""]], + "<blockquote>[foo<blockquote>bar</blockquote>baz]</blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<blockquote>foo</blockquote>[bar]<blockquote>baz</blockquote><p>extra", + [["indent",""]], + "<blockquote>foo<br>[bar]<br>baz</blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<blockquote style=\"margin-right: 0\" dir=\"ltr\"><p>foo[bar]</p><p>baz</p></blockquote><p>extra", + [["indent",""]], + "<blockquote style=\"margin-right:0\" dir=\"ltr\"><blockquote><p>foo[bar]</p></blockquote><p>baz</p></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<blockquote style=\"margin-right: 0\" dir=\"ltr\"><p>foo[bar</p><p>b]az</p></blockquote><p>extra", + [["indent",""]], + "<blockquote><blockquote style=\"margin-right:0\" dir=\"ltr\"><p>foo[bar</p><p>b]az</p></blockquote></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<blockquote style=\"margin-right: 0\" dir=\"ltr\"><p>foo[bar]</p></blockquote><p>baz</p><p>extra", + [["indent",""]], + "<blockquote><blockquote style=\"margin-right:0\" dir=\"ltr\"><p>foo[bar]</p></blockquote></blockquote><p>baz</p><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<blockquote style=\"margin-right: 0\" dir=\"ltr\"><p>foo[bar</p></blockquote><p>b]az</p><p>extra", + [["indent",""]], + "<blockquote><blockquote style=\"margin-right:0\" dir=\"ltr\"><p>foo[bar</p></blockquote><p>b]az</p></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<p>[foo]<blockquote style=\"margin-right: 0\" dir=\"ltr\"><p>bar</blockquote><p>extra", + [["indent",""]], + "<blockquote style=\"margin-right:0\" dir=\"ltr\"><p>[foo]</p><p>bar</p></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<p>[foo<blockquote style=\"margin-right: 0\" dir=\"ltr\"><p>b]ar</blockquote><p>extra", + [["indent",""]], + "<blockquote><p>[foo</p><blockquote style=\"margin-right:0\" dir=\"ltr\"><p>b]ar</p></blockquote></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<p>foo<blockquote style=\"margin-right: 0\" dir=\"ltr\"><p>bar</blockquote><p>[baz]<p>extra", + [["indent",""]], + "<p>foo</p><blockquote style=\"margin-right:0\" dir=\"ltr\"><p>bar</p><p>[baz]</p></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<p>foo<blockquote style=\"margin-right: 0\" dir=\"ltr\"><p>[bar</blockquote><p>baz]<p>extra", + [["indent",""]], + "<p>foo</p><blockquote><blockquote style=\"margin-right:0\" dir=\"ltr\"><p>[bar</p></blockquote><p>baz]</p></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<p>[foo<blockquote style=\"margin-right: 0\" dir=\"ltr\"><p>bar</blockquote><p>baz]<p>extra", + [["indent",""]], + "<blockquote><p>[foo</p><blockquote style=\"margin-right:0\" dir=\"ltr\"><p>bar</p></blockquote><p>baz]</p></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<blockquote style=\"margin-right: 0\" dir=\"ltr\"><p>foo</blockquote><p>[bar]<blockquote style=\"margin-right: 0\" dir=\"ltr\"><p>baz</blockquote><p>extra", + [["stylewithcss","true"],["indent",""]], + "<blockquote style=\"margin-right:0\" dir=\"ltr\"><p>foo</p><p>[bar]</p><p>baz</p></blockquote><p>extra</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"indent":[false,false,"",false,false,""]}], +["<blockquote style=\"margin-right: 0\" dir=\"ltr\"><p>foo</blockquote><p>[bar]<blockquote style=\"margin-right: 0\" dir=\"ltr\"><p>baz</blockquote><p>extra", + [["stylewithcss","false"],["indent",""]], + "<blockquote style=\"margin-right:0\" dir=\"ltr\"><p>foo</p><p>[bar]</p><p>baz</p></blockquote><p>extra</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"indent":[false,false,"",false,false,""]}], +["<p style=\"margin-left: 40px\">foo[bar]</p><p style=\"margin-left: 40px\">baz</p><p>extra", + [["indent",""]], + "<blockquote><p style=\"margin-left:40px\">foo[bar]</p></blockquote><p style=\"margin-left:40px\">baz</p><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<p style=\"margin-left: 40px\">foo[bar</p><p style=\"margin-left: 40px\">b]az</p><p>extra", + [["indent",""]], + "<blockquote><p style=\"margin-left:40px\">foo[bar</p><p style=\"margin-left:40px\">b]az</p></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<p style=\"margin-left: 40px\">foo[bar]</p><p>baz</p><p>extra", + [["indent",""]], + "<blockquote><p style=\"margin-left:40px\">foo[bar]</p></blockquote><p>baz</p><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<p style=\"margin-left: 40px\">foo[bar</p><p>b]az</p><p>extra", + [["indent",""]], + "<blockquote><p style=\"margin-left:40px\">foo[bar</p><p>b]az</p></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<p>[foo]<p style=\"margin-left: 40px\">bar<p>extra", + [["indent",""]], + "<blockquote><p>[foo]</p></blockquote><p style=\"margin-left:40px\">bar</p><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<p>[foo<p style=\"margin-left: 40px\">b]ar<p>extra", + [["indent",""]], + "<blockquote><p>[foo</p><p style=\"margin-left:40px\">b]ar</p></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<p>foo<p style=\"margin-left: 40px\">bar<p>[baz]<p>extra", + [["indent",""]], + "<p>foo</p><p style=\"margin-left:40px\">bar</p><blockquote><p>[baz]</p></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<p>foo<p style=\"margin-left: 40px\">[bar<p>baz]<p>extra", + [["indent",""]], + "<p>foo</p><blockquote><p style=\"margin-left:40px\">[bar</p><p>baz]</p></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<p>[foo<p style=\"margin-left: 40px\">bar<p>baz]<p>extra", + [["indent",""]], + "<blockquote><p>[foo</p><p style=\"margin-left:40px\">bar</p><p>baz]</p></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<p style=\"margin-left: 40px\">foo<p>[bar]<p style=\"margin-left: 40px\">baz<p>extra", + [["indent",""]], + "<p style=\"margin-left:40px\">foo</p><blockquote><p>[bar]</p></blockquote><p style=\"margin-left:40px\">baz</p><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<blockquote class=\"webkit-indent-blockquote\" style=\"margin: 0 0 0 40px; border: none; padding: 0px\"><p>foo[bar]</p><p>baz</p></blockquote><p>extra", + [["indent",""]], + "<blockquote class=\"webkit-indent-blockquote\" style=\"margin:0 0 0 40px; border:none; padding:0px\"><blockquote><p>foo[bar]</p></blockquote><p>baz</p></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<blockquote class=\"webkit-indent-blockquote\" style=\"margin: 0 0 0 40px; border: none; padding: 0px\"><p>foo[bar</p><p>b]az</p></blockquote><p>extra", + [["indent",""]], + "<blockquote><blockquote class=\"webkit-indent-blockquote\" style=\"margin:0 0 0 40px; border:none; padding:0px\"><p>foo[bar</p><p>b]az</p></blockquote></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<blockquote class=\"webkit-indent-blockquote\" style=\"margin: 0 0 0 40px; border: none; padding: 0px\"><p>foo[bar]</p></blockquote><p>baz</p><p>extra", + [["indent",""]], + "<blockquote><blockquote class=\"webkit-indent-blockquote\" style=\"margin:0 0 0 40px; border:none; padding:0px\"><p>foo[bar]</p></blockquote></blockquote><p>baz</p><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<blockquote class=\"webkit-indent-blockquote\" style=\"margin: 0 0 0 40px; border: none; padding: 0px\"><p>foo[bar</p></blockquote><p>b]az</p><p>extra", + [["indent",""]], + "<blockquote><blockquote class=\"webkit-indent-blockquote\" style=\"margin:0 0 0 40px; border:none; padding:0px\"><p>foo[bar</p></blockquote><p>b]az</p></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<p>[foo]<blockquote class=\"webkit-indent-blockquote\" style=\"margin: 0 0 0 40px; border: none; padding: 0px\"><p>bar</blockquote><p>extra", + [["indent",""]], + "<blockquote><p>[foo]</p></blockquote><blockquote class=\"webkit-indent-blockquote\" style=\"margin:0 0 0 40px; border:none; padding:0px\"><p>bar</p></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<p>[foo<blockquote class=\"webkit-indent-blockquote\" style=\"margin: 0 0 0 40px; border: none; padding: 0px\"><p>b]ar</blockquote><p>extra", + [["indent",""]], + "<blockquote><p>[foo</p><blockquote class=\"webkit-indent-blockquote\" style=\"margin:0 0 0 40px; border:none; padding:0px\"><p>b]ar</p></blockquote></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<p>foo<blockquote class=\"webkit-indent-blockquote\" style=\"margin: 0 0 0 40px; border: none; padding: 0px\"><p>bar</blockquote><p>[baz]<p>extra", + [["indent",""]], + "<p>foo</p><blockquote class=\"webkit-indent-blockquote\" style=\"margin:0 0 0 40px; border:none; padding:0px\"><p>bar</p></blockquote><blockquote><p>[baz]</p></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<p>foo<blockquote class=\"webkit-indent-blockquote\" style=\"margin: 0 0 0 40px; border: none; padding: 0px\"><p>[bar</blockquote><p>baz]<p>extra", + [["indent",""]], + "<p>foo</p><blockquote><blockquote class=\"webkit-indent-blockquote\" style=\"margin:0 0 0 40px; border:none; padding:0px\"><p>[bar</p></blockquote><p>baz]</p></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<p>[foo<blockquote class=\"webkit-indent-blockquote\" style=\"margin: 0 0 0 40px; border: none; padding: 0px\"><p>bar</blockquote><p>baz]<p>extra", + [["indent",""]], + "<blockquote><p>[foo</p><blockquote class=\"webkit-indent-blockquote\" style=\"margin:0 0 0 40px; border:none; padding:0px\"><p>bar</p></blockquote><p>baz]</p></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<blockquote class=\"webkit-indent-blockquote\" style=\"margin: 0 0 0 40px; border: none; padding: 0px\"><p>foo</blockquote><p>[bar]<blockquote class=\"webkit-indent-blockquote\" style=\"margin: 0 0 0 40px; border: none; padding: 0px\"><p>baz</blockquote><p>extra", + [["indent",""]], + "<blockquote class=\"webkit-indent-blockquote\" style=\"margin:0 0 0 40px; border:none; padding:0px\"><p>foo</p></blockquote><blockquote><p>[bar]</p></blockquote><blockquote class=\"webkit-indent-blockquote\" style=\"margin:0 0 0 40px; border:none; padding:0px\"><p>baz</p></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<blockquote>f[oo<blockquote>b]ar</blockquote></blockquote><p>extra", + [["indent",""]], + "<blockquote><blockquote>f[oo<blockquote>b]ar</blockquote></blockquote></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li>foo<li>[bar]<li>baz</ol>", + [["indent",""]], + "<ol><li>foo</li><ol><li>[bar]</li></ol><li>baz</li></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol data-start=1 data-end=2><li>foo<li>bar<li>baz</ol>", + [["indent",""]], + "<ol><li>foo</li><ol>{<li>bar</li>}</ol><li>baz</li></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li>foo</ol>[bar]", + [["indent",""]], + "<ol><li>foo</li></ol><blockquote>[bar]</blockquote>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li>[foo]<br>bar<li>baz</ol>", + [["indent",""]], + "<ol><ol><li>[foo]<br>bar</li></ol><li>baz</li></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li>foo<br>[bar]<li>baz</ol>", + [["indent",""]], + "<ol><ol><li>foo<br>[bar]</li></ol><li>baz</li></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li><div>[foo]</div>bar<li>baz</ol>", + [["indent",""]], + "<ol><ol><li><div>[foo]</div>bar</li></ol><li>baz</li></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li>foo<ol><li>[bar]<li>baz</ol><li>quz</ol>", + [["indent",""]], + "<ol><li>foo</li><ol><ol><li>[bar]</li></ol><li>baz</li></ol><li>quz</li></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li>foo<ol><li>bar<li>[baz]</ol><li>quz</ol>", + [["indent",""]], + "<ol><li>foo</li><ol><li>bar</li><ol><li>[baz]</li></ol></ol><li>quz</li></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li>foo</li><ol><li>[bar]<li>baz</ol><li>quz</ol>", + [["indent",""]], + "<ol><li>foo</li><ol><ol><li>[bar]</li></ol><li>baz</li></ol><li>quz</li></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li>foo</li><ol data-start=0 data-end=1><li>bar<li>baz</ol><li>quz</ol>", + [["indent",""]], + "<ol><li>foo</li><ol><ol>{<li>bar</li>}</ol><li>baz</li></ol><li>quz</li></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li>foo</li><ol><li>bar<li>[baz]</ol><li>quz</ol>", + [["indent",""]], + "<ol><li>foo</li><ol><li>bar</li><ol><li>[baz]</li></ol></ol><li>quz</li></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li>foo</li><ol data-start=1 data-end=2><li>bar<li>baz</ol><li>quz</ol>", + [["indent",""]], + "<ol><li>foo</li><ol><li>bar</li><ol>{<li>baz</li>}</ol></ol><li>quz</li></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li>foo<ol><li>b[a]r</ol><li>baz</ol>", + [["indent",""]], + "<ol><li>foo</li><ol><ol><li>b[a]r</li></ol></ol><li>baz</li></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li>foo</li><ol><li>b[a]r</ol><li>baz</ol>", + [["indent",""]], + "<ol><li>foo</li><ol><ol><li>b[a]r</li></ol></ol><li>baz</li></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li>foo{<ol><li>bar</ol>}<li>baz</ol>", + [["indent",""]], + "<ol><li>foo</li><ol>{<ol><li>bar</li></ol>}</ol><li>baz</li></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li>foo</li>{<ol><li>bar</ol>}<li>baz</ol>", + [["indent",""]], + "<ol><li>foo</li><ol>{<ol><li>bar</li></ol>}</ol><li>baz</li></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li>[foo]<ol><li>bar</ol><li>baz</ol>", + [["indent",""]], + "<ol><ol><li>[foo]</li><li>bar</li></ol><li>baz</li></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li>[foo]</li><ol><li>bar</ol><li>baz</ol>", + [["indent",""]], + "<ol><ol><li>[foo]</li><li>bar</li></ol><li>baz</li></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li>foo<li>[bar]<ol><li>baz</ol><li>quz</ol>", + [["indent",""]], + "<ol><li>foo</li><ol><li>[bar]</li><li>baz</li></ol><li>quz</li></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li>foo<li>[bar]</li><ol><li>baz</ol><li>quz</ol>", + [["indent",""]], + "<ol><li>foo</li><ol><li>[bar]</li><li>baz</li></ol><li>quz</li></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li>foo<ol><li>bar<li>baz</ol><li>[quz]</ol>", + [["indent",""]], + "<ol><li>foo</li><ol><li>bar</li><li>baz</li><li>[quz]</li></ol></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li>foo</li><ol><li>bar<li>baz</ol><li>[quz]</ol>", + [["indent",""]], + "<ol><li>foo</li><ol><li>bar</li><li>baz</li><li>[quz]</li></ol></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><ol id=u1><li id=i1>foo</ol><li id=i2>[bar]</li><ol id=u3><li id=i3>baz</ol></ol>", + [["indent",""]], + "<ol><ol id=\"u1\"><li id=\"i1\">foo</li><li id=\"i2\">[bar]</li><li id=\"i3\">baz</li></ol></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><ol><li id=i1>foo</ol><li id=i2>[bar]</li><ol id=u3><li id=i3>baz</ol></ol>", + [["indent",""]], + "<ol><ol><li id=\"i1\">foo</li><li id=\"i2\">[bar]</li><li id=\"i3\">baz</li></ol></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><ol id=u1><li id=i1>foo</ol><li id=i2>[bar]</li><ol><li id=i3>baz</ol></ol>", + [["indent",""]], + "<ol><ol id=\"u1\"><li id=\"i1\">foo</li><li id=\"i2\">[bar]</li><li id=\"i3\">baz</li></ol></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li id=i2>[bar]</li><ol id=u3><li id=i3>baz</ol></ol>", + [["indent",""]], + "<ol><ol id=\"u3\"><li id=\"i2\">[bar]</li><li id=\"i3\">baz</li></ol></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><ol id=u1><li id=i1>foo</ol><li id=i2>[bar]</ol>", + [["indent",""]], + "<ol><ol id=\"u1\"><li id=\"i1\">foo</li><li id=\"i2\">[bar]</li></ol></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li>foo<li>b[ar<li>baz]</ol>", + [["indent",""]], + "<ol><li>foo</li><ol><li>b[ar</li><li>baz]</li></ol></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li>[foo<ol><li>bar]</ol><li>baz</ol>", + [["indent",""]], + "<ol><ol><li>[foo</li><ol><li>bar]</li></ol></ol><li>baz</li></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li>[foo</li><ol><li>bar]</ol><li>baz</ol>", + [["indent",""]], + "<ol><ol><li>[foo</li><ol><li>bar]</li></ol></ol><li>baz</li></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li>foo<ol><li>b[ar</ol><li>b]az</ol>", + [["indent",""]], + "<ol><li>foo</li><ol><ol><li>b[ar</li></ol><li>b]az</li></ol></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li>foo</li><ol><li>b[ar</ol><li>b]az</ol>", + [["indent",""]], + "<ol><li>foo</li><ol><ol><li>b[ar</li></ol><li>b]az</li></ol></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li>[foo<ol><li>bar</ol><li>baz]</ol><p>extra", + [["indent",""]], + "<blockquote><ol><li>[foo</li><ol><li>bar</li></ol><li>baz]</li></ol></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li>[foo</li><ol><li>bar</ol><li>baz]</ol><p>extra", + [["indent",""]], + "<blockquote><ol><li>[foo</li><ol><li>bar</li></ol><li>baz]</li></ol></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li>[foo]<ol><li>bar</ol>baz</ol>", + [["indent",""]], + "<ol><ol><li>[foo]</li><li>bar</li></ol><li>baz</li></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li>foo<ol><li>[bar]</ol>baz</ol>", + [["indent",""]], + "<ol><li>foo</li><ol><ol><li>[bar]</li></ol></ol><li>baz</li></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li>foo<ol><li>bar</ol>[baz]</ol>", + [["indent",""]], + "<ol><li>foo</li><ol><li>bar</li><li>[baz]</li></ol></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li>[foo<ol><li>bar]</ol>baz</ol>", + [["indent",""]], + "<ol><ol><li>[foo</li><ol><li>bar]</li></ol></ol><li>baz</li></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["foo<!--bar-->[baz]<p>extra", + [["indent",""]], + "<blockquote>foo<!--bar-->[baz]</blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["[foo]<!--bar-->baz<p>extra", + [["indent",""]], + "<blockquote>[foo]<!--bar-->baz</blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<p>foo<!--bar-->{}<p>extra", + [["indent",""]], + "<blockquote><p>foo<!--bar-->{}</p></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<p>{}<!--foo-->bar<p>extra", + [["indent",""]], + "<blockquote><p>{}<!--foo-->bar</p></blockquote><p>extra</p>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<blockquote><p>foo</blockquote> <p>[bar]", + [["indent",""]], + "<blockquote><p>foo</p> <p>[bar]</p></blockquote>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<p>[foo]</p> <blockquote><p>bar</blockquote>", + [["indent",""]], + "<blockquote><p>[foo]</p> <p>bar</p></blockquote>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<blockquote><p>foo</blockquote> <p>[bar]</p> <blockquote><p>baz</blockquote>", + [["indent",""]], + "<blockquote><p>foo</p> <p>[bar]</p> <p>baz</p></blockquote>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li>foo</li><ol><li>bar</li> </ol><li>[baz]</ol>", + [["indent",""]], + "<ol><li>foo</li><ol><li>bar</li> <li>[baz]</li></ol></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li>foo</li><ol><li>bar</li></ol> <li>[baz]</ol>", + [["indent",""]], + "<ol><li>foo</li><ol><li>bar</li> <li>[baz]</li></ol></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li>foo</li><ol><li>bar</li> </ol> <li>[baz]</ol>", + [["indent",""]], + "<ol><li>foo</li><ol><li>bar</li> <li>[baz]</li></ol></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li>foo<ol><li>bar</li> </ol></li><li>[baz]</ol>", + [["indent",""]], + "<ol><li>foo</li><ol><li>bar</li> <li>[baz]</li></ol></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li>foo<ol><li>bar</li></ol></li> <li>[baz]</ol>", + [["indent",""]], + "<ol><li>foo</li><ol><li>bar</li> <li>[baz]</li></ol></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li>foo<ol><li>bar</li> </ol></li> <li>[baz]</ol>", + [["indent",""]], + "<ol><li>foo</li><ol><li>bar</li> <li>[baz]</li></ol></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li>foo<li>[bar]</li> <ol><li>baz</ol></ol>", + [["indent",""]], + "<ol><li>foo</li><ol><li>[bar]</li> <li>baz</li></ol></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li>foo<li>[bar]</li><ol> <li>baz</ol></ol>", + [["indent",""]], + "<ol><li>foo</li><ol><li>[bar]</li> <li>baz</li></ol></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li>foo<li>[bar]</li> <ol> <li>baz</ol></ol>", + [["indent",""]], + "<ol><li>foo</li><ol><li>[bar]</li> <li>baz</li></ol></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li>foo<li>[bar] <ol><li>baz</ol></ol>", + [["indent",""]], + "<ol><li>foo</li><ol><li>[bar] </li><li>baz</li></ol></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li>foo<li>[bar]<ol> <li>baz</ol></ol>", + [["indent",""]], + "<ol><li>foo</li><ol><li>[bar]</li> <li>baz</li></ol></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ol><li>foo<li>[bar] <ol> <li>baz</ol></ol>", + [["indent",""]], + "<ol><li>foo</li><ol><li>[bar] </li> <li>baz</li></ol></ol>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<ul><li>a<br>{<br>}</li><li>b</li></ul>", + [["indent",""]], + "<ul><ul><li>a<br>{<br>}</li></ul><li>b</li></ul>", + [true], + {"indent":[false,false,"",false,false,""]}], +["<p>[abc]</p>", + [["stylewithcss","true"],["indent",""]], + ["<p style=\"margin-left:40px\">abc</p>", + "<blockquote style=\"margin:0 0 0 40px; border:none; padding:0px\"><p>abc</p></blockquote>"], + [true,true], + {"indent":[false,false,"",false,false,""]}], +["<div contenteditable=false><div contenteditable>[abc]</div></div>", + [["stylewithcss","true"],["indent",""]], + ["<div contenteditable=\"false\"><div contenteditable=\"\"><div style=\"margin-left:40px\">abc</div></div></div>", + "<div contenteditable=\"false\"><div contenteditable=\"\"><blockquote style=\"margin:0 0 0 40px; border:none; padding:0px\">abc</blockquote></div></div>"], + [true,true], + {"indent":[false,false,"",false,false,""]}], +] diff --git a/testing/web-platform/tests/editing/data/insert-list-items-in-table-cells.js b/testing/web-platform/tests/editing/data/insert-list-items-in-table-cells.js new file mode 100644 index 0000000000..9324d5b55a --- /dev/null +++ b/testing/web-platform/tests/editing/data/insert-list-items-in-table-cells.js @@ -0,0 +1,63 @@ +// For documentation of the format, see README in this directory. +var browserTests = [ +['<div contenteditable="true"><table><tr><td>[fsdf]</td><td>fsdf</td></tr><tr><td>gghfg</td><td>fsfg</td></tr></table></div>', + [["insertOrderedList",""]], + '<div contenteditable="true"><table><tbody><tr><td><ol><li>fsdf</li></ol></td><td>fsdf</td></tr><tr><td>gghfg</td><td>fsfg</td></tr></tbody></table></div>', + [true], + {"insertOrderedList":[false,false,"false",false,true,"true"]}], +['<div contenteditable="true"><table><tr><td>[fs<br>df]</td><td>fsdf</td></tr><tr><td>gghfg</td><td>fsfg</td></tr></table></div>', + [["insertOrderedList",""]], + '<div contenteditable="true"><table><tbody><tr><td><ol><li>fs</li><li>df</li></ol></td><td>fsdf</td></tr><tr><td>gghfg</td><td>fsfg</td></tr></tbody></table></div>', + [true], + {"insertOrderedList":[false,false,"false",false,true,"true"]}], +['<div contenteditable="true"><table><tr><td>[f<b>s<br>d</b>f]</td><td>fsdf</td></tr><tr><td>gghfg</td><td>fsfg</td></tr></table></div>', + [["insertOrderedList",""]], + '<div contenteditable="true"><table><tbody><tr><td><ol><li>f<b>s</b></li><li><b>d</b>f</li></ol></td><td>fsdf</td></tr><tr><td>gghfg</td><td>fsfg</td></tr></tbody></table></div>', + [true], + {"insertOrderedList":[false,false,"false",false,true,"true"]}], +['<div contenteditable="true"><table><tr><td>[fs]<br>df</td><td>fsdf</td></tr><tr><td>gghfg</td><td>fsfg</td></tr></table></div>', + [["insertOrderedList",""]], + '<div contenteditable="true"><table><tbody><tr><td><ol><li>fs</li></ol>df</td><td>fsdf</td></tr><tr><td>gghfg</td><td>fsfg</td></tr></tbody></table></div>', + [true], + {"insertOrderedList":[false,false,"false",false,true,"true"]}], +['<div contenteditable="true"><table><tr><td>[f<b>s]<br>d</b>f</td><td>fsdf</td></tr><tr><td>gghfg</td><td>fsfg</td></tr></table></div>', + [["insertOrderedList",""]], + '<div contenteditable="true"><table><tbody><tr><td><ol><li>f<b>s</b></li></ol><b>d</b>f</td><td>fsdf</td></tr><tr><td>gghfg</td><td>fsfg</td></tr></tbody></table></div>', + [true], + {"insertOrderedList":[false,false,"false",false,true,"true"]}], +['<div contenteditable="true"><table><tr data-start=0 data-end=2><td>fsdf</td><td>fsdf</td></tr><tr><td>gghfg</td><td>fsfg</td></tr></table></div>', + [["insertOrderedList",""]], + '<div contenteditable="true"><table><tbody><tr><td><ol><li>fsdf</li></ol></td><td><ol><li>fsdf</li></ol></td></tr><tr><td>gghfg</td><td>fsfg</td></tr></tbody></table></div>', + [true], + {"insertOrderedList":[false,false,"false",false,false,"false"]}], +['<div contenteditable="true"><table><tr data-start=0><td>fsdf</td><td>fsdf</td></tr><tr data-end=2><td>gghfg</td><td>fsfg</td></tr></table></div>', + [["insertOrderedList",""]], + '<div contenteditable="true"><table><tbody><tr><td><ol><li>fsdf</li></ol></td><td><ol><li>fsdf</li></ol></td></tr><tr><td><ol><li>gghfg</li></ol></td><td><ol><li>fsfg</li></ol></td></tr></tbody></table></div>', + [true], + {"insertOrderedList":[false,false,"false",false,false,"false"]}], +['<div contenteditable="true"><table data-start=0 data-end=1><tr><td>fsdf</td><td>fsdf</td></tr><tr><td>gghfg</td><td>fsfg</td></tr></table></div>', + [["insertOrderedList",""]], + '<div contenteditable="true"><ol><li><table><tbody><tr><td>fsdf</td><td>fsdf</td></tr><tr><td>gghfg</td><td>fsfg</td></tr></tbody></table></li></ol></div>', + [true], + {"insertOrderedList":[false,false,"false",false,true,"true"]}], +['<div contenteditable="true"><table><tr><td>[fsdf]</td><td>fsdf</td></tr><tr><td>gghfg</td><td>fsfg</td></tr></table></div>', + [["insertOrderedList",""], ["insertOrderedList","1"]], + '<div contenteditable="true"><table><tbody><tr><td>fsdf<br></td><td>fsdf</td></tr><tr><td>gghfg</td><td>fsfg</td></tr></tbody></table></div>', + [true, true], + {"insertOrderedList":[false,false,"false",false,true,"true"], "insertOrderedList":[false,false,"false",false,false,"false"]}], +['<div contenteditable="true"><table><tr data-start=0 data-end=2><td>fsdf</td><td>fsdf</td></tr><tr><td>gghfg</td><td>fsfg</td></tr></table></div>', + [["insertOrderedList",""], ["insertOrderedList","1"]], + '<div contenteditable="true"><table><tbody><tr><td>fsdf<br></td><td>fsdf<br></td></tr><tr><td>gghfg</td><td>fsfg</td></tr></tbody></table></div>', + [true, true], + {"insertOrderedList":[false,false,"false",false,true,"true"], "insertOrderedList":[false,false,"false",false,false,"false"]}], +['<div contenteditable="true"><table><tr data-start=0><td>fsdf</td><td>fsdf</td></tr><tr data-end=2><td>gghfg</td><td>fsfg</td></tr></table></div>', + [["insertOrderedList",""], ["insertOrderedList","1"]], + '<div contenteditable="true"><table><tbody><tr><td>fsdf<br></td><td>fsdf<br></td></tr><tr><td>gghfg<br></td><td>fsfg<br></td></tr></tbody></table></div>', + [true, true], + {"insertOrderedList":[false,false,"false",false,true,"true"], "insertOrderedList":[false,false,"false",false,false,"false"]}], +['<div contenteditable="true"><table data-start=0 data-end=1><tr><td>fsdf</td><td>fsdf</td></tr><tr><td>gghfg</td><td>fsfg</td></tr></table></div>', + [["insertOrderedList",""], ["insertOrderedList","1"]], + '<div contenteditable="true"><table><tbody><tr><td>fsdf</td><td>fsdf</td></tr><tr><td>gghfg</td><td>fsfg</td></tr></tbody></table></div>', + [true, true], + {"insertOrderedList":[false,false,"false",false,true,"true"], "insertOrderedList":[false,false,"false",false,false,"false"]}] +] diff --git a/testing/web-platform/tests/editing/data/inserthorizontalrule.js b/testing/web-platform/tests/editing/data/inserthorizontalrule.js new file mode 100644 index 0000000000..998822789f --- /dev/null +++ b/testing/web-platform/tests/editing/data/inserthorizontalrule.js @@ -0,0 +1,573 @@ +// For documentation of the format, see README in this directory. +var browserTests = [ +["foo[]bar", + [["inserthorizontalrule",""]], + "foo<hr>{}bar", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<span>foo</span>{}<span>bar</span>", + [["inserthorizontalrule",""]], + "<span>foo</span><hr>{}<span>bar</span>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<span>foo[</span><span>]bar</span>", + [["inserthorizontalrule",""]], + "<span>foo</span><hr>{}<span>bar</span>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<p>foo[bar<p>baz]quz", + [["inserthorizontalrule",""]], + "<p>foo</p><hr>{}<p>quz</p>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<div><b>foo</b>{}<b>bar</b></div>", + [["inserthorizontalrule",""]], + "<div><b>foo</b><hr>{}<b>bar</b></div>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<div><b>foo[</b><b>]bar</b></div>", + [["inserthorizontalrule",""]], + "<div><b>foo</b><hr>{}<b>bar</b></div>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<div><b>foo</b>{<b>bar</b>}<b>baz</b></div>", + [["stylewithcss","true"],["inserthorizontalrule",""]], + "<div><b>foo</b><hr>{}<b>baz</b></div>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserthorizontalrule":[false,false,"",false,false,""]}], +["<div><b>foo</b>{<b>bar</b>}<b>baz</b></div>", + [["stylewithcss","false"],["inserthorizontalrule",""]], + "<div><b>foo</b><hr>{}<b>baz</b></div>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserthorizontalrule":[false,false,"",false,false,""]}], +["<b>foo[]bar</b>", + [["stylewithcss","true"],["inserthorizontalrule",""]], + "<b>foo</b><hr>{}<b>bar</b>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserthorizontalrule":[false,false,"",false,false,""]}], +["<b>foo[]bar</b>", + [["stylewithcss","false"],["inserthorizontalrule",""]], + "<b>foo</b><hr>{}<b>bar</b>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserthorizontalrule":[false,false,"",false,false,""]}], +["<b id=abc>foo[]bar</b>", + [["stylewithcss","true"],["inserthorizontalrule",""]], + "<b id=\"abc\">foo</b><hr>{}<b>bar</b>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserthorizontalrule":[false,false,"",false,false,""]}], +["<b id=abc>foo[]bar</b>", + [["stylewithcss","false"],["inserthorizontalrule",""]], + "<b id=\"abc\">foo</b><hr>{}<b>bar</b>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserthorizontalrule":[false,false,"",false,false,""]}], +["foo[bar]baz", + [["inserthorizontalrule","abc"]], + "foo<hr>{}baz", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["foo[bar]baz", + [["inserthorizontalrule",""]], + "foo<hr>{}baz", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["foo<b>[bar]</b>baz", + [["stylewithcss","true"],["inserthorizontalrule",""]], + "foo<hr>{}baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserthorizontalrule":[false,false,"",false,false,""]}], +["foo<b>[bar]</b>baz", + [["stylewithcss","false"],["inserthorizontalrule",""]], + "foo<hr>{}baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserthorizontalrule":[false,false,"",false,false,""]}], +["foo<b>{bar}</b>baz", + [["stylewithcss","true"],["inserthorizontalrule",""]], + "foo<hr>{}baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserthorizontalrule":[false,false,"",false,false,""]}], +["foo<b>{bar}</b>baz", + [["stylewithcss","false"],["inserthorizontalrule",""]], + "foo<hr>{}baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserthorizontalrule":[false,false,"",false,false,""]}], +["foo{<b>bar</b>}baz", + [["stylewithcss","true"],["inserthorizontalrule",""]], + "foo<hr>{}baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserthorizontalrule":[false,false,"",false,false,""]}], +["foo{<b>bar</b>}baz", + [["stylewithcss","false"],["inserthorizontalrule",""]], + "foo<hr>{}baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserthorizontalrule":[false,false,"",false,false,""]}], +["<p>foo<p>[bar]<p>baz", + [["defaultparagraphseparator","div"],["inserthorizontalrule",""]], + "<p>foo</p><hr>{}<p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"div"],"inserthorizontalrule":[false,false,"",false,false,""]}], +["<p>foo<p>[bar]<p>baz", + [["defaultparagraphseparator","p"],["inserthorizontalrule",""]], + "<p>foo</p><hr>{}<p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"inserthorizontalrule":[false,false,"",false,false,""]}], +["<p>foo<p>{bar}<p>baz", + [["defaultparagraphseparator","div"],["inserthorizontalrule",""]], + "<p>foo</p><hr>{}<p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"inserthorizontalrule":[false,false,"",false,false,""]}], +["<p>foo<p>{bar}<p>baz", + [["defaultparagraphseparator","p"],["inserthorizontalrule",""]], + "<p>foo</p><hr>{}<p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"inserthorizontalrule":[false,false,"",false,false,""]}], +["<p>foo{<p>bar</p>}<p>baz", + [["defaultparagraphseparator","div"],["inserthorizontalrule",""]], + "<p>foo</p><hr>{}<p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"inserthorizontalrule":[false,false,"",false,false,""]}], +["<p>foo{<p>bar</p>}<p>baz", + [["defaultparagraphseparator","p"],["inserthorizontalrule",""]], + "<p>foo</p><hr>{}<p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"inserthorizontalrule":[false,false,"",false,false,""]}], +["<p>foo[bar]baz</p>", + [["defaultparagraphseparator","div"],["inserthorizontalrule",""]], + "<p>foo</p><hr>{}<p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"inserthorizontalrule":[false,false,"",false,false,""]}], +["<p>foo[bar]baz</p>", + [["defaultparagraphseparator","p"],["inserthorizontalrule",""]], + "<p>foo</p><hr>{}<p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"inserthorizontalrule":[false,false,"",false,false,""]}], +["<p id=abc>foo[bar]baz</p>", + [["defaultparagraphseparator","div"],["inserthorizontalrule",""]], + "<p id=\"abc\">foo</p><hr>{}<p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"inserthorizontalrule":[false,false,"",false,false,""]}], +["<p id=abc>foo[bar]baz</p>", + [["defaultparagraphseparator","p"],["inserthorizontalrule",""]], + "<p id=\"abc\">foo</p><hr>{}<p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"inserthorizontalrule":[false,false,"",false,false,""]}], +["<p>foo<b>b[a]r</b>baz</p>", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["inserthorizontalrule",""]], + "<p>foo<b>b</b></p><hr>{}<p><b>r</b>baz</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"inserthorizontalrule":[false,false,"",false,false,""]}], +["<p>foo<b>b[a]r</b>baz</p>", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["inserthorizontalrule",""]], + "<p>foo<b>b</b></p><hr>{}<p><b>r</b>baz</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"inserthorizontalrule":[false,false,"",false,false,""]}], +["<p>foo<b>b[a]r</b>baz</p>", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["inserthorizontalrule",""]], + "<p>foo<b>b</b></p><hr>{}<p><b>r</b>baz</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"inserthorizontalrule":[false,false,"",false,false,""]}], +["<p>foo<b>b[a]r</b>baz</p>", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["inserthorizontalrule",""]], + "<p>foo<b>b</b></p><hr>{}<p><b>r</b>baz</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"inserthorizontalrule":[false,false,"",false,false,""]}], +["<a>foo[bar]baz</a>", + [["inserthorizontalrule",""]], + "<a>foo</a><hr>{}<a>baz</a>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<a href=/>foo[bar]baz</a>", + [["inserthorizontalrule",""]], + "<a href=\"/\">foo</a><hr>{}<a href=\"/\">baz</a>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<abbr>foo[bar]baz</abbr>", + [["inserthorizontalrule",""]], + "<abbr>foo</abbr><hr>{}<abbr>baz</abbr>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<address>foo[bar]baz</address>", + [["inserthorizontalrule",""]], + "<address>foo<hr>{}baz</address>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<article>foo[bar]baz</article>", + [["inserthorizontalrule",""]], + "<article>foo<hr>{}baz</article>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<aside>foo[bar]baz</aside>", + [["inserthorizontalrule",""]], + "<aside>foo<hr>{}baz</aside>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<b>foo[bar]baz</b>", + [["stylewithcss","true"],["inserthorizontalrule",""]], + "<b>foo</b><hr>{}<b>baz</b>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserthorizontalrule":[false,false,"",false,false,""]}], +["<b>foo[bar]baz</b>", + [["stylewithcss","false"],["inserthorizontalrule",""]], + "<b>foo</b><hr>{}<b>baz</b>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserthorizontalrule":[false,false,"",false,false,""]}], +["<bdi>foo[bar]baz</bdi>", + [["inserthorizontalrule",""]], + "<bdi>foo</bdi><hr>{}<bdi>baz</bdi>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<bdo dir=rtl>foo[bar]baz</bdo>", + [["inserthorizontalrule",""]], + "<bdo dir=\"rtl\">foo</bdo><hr>{}<bdo dir=\"rtl\">baz</bdo>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<blockquote>foo[bar]baz</blockquote>", + [["inserthorizontalrule",""]], + "<blockquote>foo<hr>{}baz</blockquote>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<table><caption>foo[bar]baz</caption><tr><td>quz</table>", + [["inserthorizontalrule",""]], + "<table><caption>foo<hr>{}baz</caption><tbody><tr><td>quz</td></tr></tbody></table>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<cite>foo[bar]baz</cite>", + [["inserthorizontalrule",""]], + "<cite>foo</cite><hr>{}<cite>baz</cite>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<code>foo[bar]baz</code>", + [["inserthorizontalrule",""]], + "<code>foo</code><hr>{}<code>baz</code>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<dl><dd>foo[bar]baz</dd></dl>", + [["inserthorizontalrule",""]], + "<dl><dd>foo<hr>{}baz</dd></dl>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<del>foo[bar]baz</del>", + [["inserthorizontalrule",""]], + "<del>foo<hr>{}baz</del>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<details>foo[bar]baz</details>", + [["inserthorizontalrule",""]], + "<details>foo<hr>{}baz</details>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<dfn>foo[bar]baz</dfn>", + [["inserthorizontalrule",""]], + "<dfn>foo</dfn><hr>{}<dfn>baz</dfn>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<div>foo[bar]baz</div>", + [["inserthorizontalrule",""]], + "<div>foo<hr>{}baz</div>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<dl><dt>foo[bar]baz</dt></dl>", + [["inserthorizontalrule",""]], + "<dl><dt>foo<hr>{}baz</dt></dl>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<em>foo[bar]baz</em>", + [["inserthorizontalrule",""]], + "<em>foo</em><hr>{}<em>baz</em>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<figure><figcaption>foo[bar]baz</figcaption>quz</figure>", + [["inserthorizontalrule",""]], + "<figure><figcaption>foo<hr>{}baz</figcaption>quz</figure>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<figure>foo[bar]baz</figure>", + [["inserthorizontalrule",""]], + "<figure>foo<hr>{}baz</figure>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<footer>foo[bar]baz</footer>", + [["inserthorizontalrule",""]], + "<footer>foo<hr>{}baz</footer>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<h1>foo[bar]baz</h1>", + [["inserthorizontalrule",""]], + "<h1>foo</h1><hr>{}<h1>baz</h1>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<h2>foo[bar]baz</h2>", + [["inserthorizontalrule",""]], + "<h2>foo</h2><hr>{}<h2>baz</h2>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<h3>foo[bar]baz</h3>", + [["inserthorizontalrule",""]], + "<h3>foo</h3><hr>{}<h3>baz</h3>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<h4>foo[bar]baz</h4>", + [["inserthorizontalrule",""]], + "<h4>foo</h4><hr>{}<h4>baz</h4>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<h5>foo[bar]baz</h5>", + [["inserthorizontalrule",""]], + "<h5>foo</h5><hr>{}<h5>baz</h5>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<h6>foo[bar]baz</h6>", + [["inserthorizontalrule",""]], + "<h6>foo</h6><hr>{}<h6>baz</h6>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<header>foo[bar]baz</header>", + [["inserthorizontalrule",""]], + "<header>foo<hr>{}baz</header>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<hgroup>foo[bar]baz</hgroup>", + [["inserthorizontalrule",""]], + "<hgroup>foo</hgroup><hr>{}<hgroup>baz</hgroup>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<hgroup><h1>foo[bar]baz</h1></hgroup>", + [["inserthorizontalrule",""]], + "<hgroup><h1>foo</h1></hgroup><hr>{}<hgroup><h1>baz</h1></hgroup>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<i>foo[bar]baz</i>", + [["stylewithcss","true"],["inserthorizontalrule",""]], + "<i>foo</i><hr>{}<i>baz</i>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserthorizontalrule":[false,false,"",false,false,""]}], +["<i>foo[bar]baz</i>", + [["stylewithcss","false"],["inserthorizontalrule",""]], + "<i>foo</i><hr>{}<i>baz</i>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserthorizontalrule":[false,false,"",false,false,""]}], +["<ins>foo[bar]baz</ins>", + [["inserthorizontalrule",""]], + "<ins>foo<hr>{}baz</ins>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<kbd>foo[bar]baz</kbd>", + [["inserthorizontalrule",""]], + "<kbd>foo</kbd><hr>{}<kbd>baz</kbd>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<mark>foo[bar]baz</mark>", + [["inserthorizontalrule",""]], + "<mark>foo</mark><hr>{}<mark>baz</mark>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<nav>foo[bar]baz</nav>", + [["inserthorizontalrule",""]], + "<nav>foo<hr>{}baz</nav>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<ol><li>foo[bar]baz</li></ol>", + [["inserthorizontalrule",""]], + "<ol><li>foo<hr>{}baz</li></ol>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<pre>foo[bar]baz</pre>", + [["inserthorizontalrule",""]], + "<pre>foo</pre><hr>{}<pre>baz</pre>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<q>foo[bar]baz</q>", + [["inserthorizontalrule",""]], + "<q>foo</q><hr>{}<q>baz</q>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<ruby>foo[bar]baz<rt>quz</rt></ruby>", + [["inserthorizontalrule",""]], + "<ruby>foo</ruby><hr>{}<ruby>baz<rt>quz</rt></ruby>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<ruby>foo<rt>bar[baz]quz</rt></ruby>", + [["inserthorizontalrule",""]], + "<ruby>foo<rt>bar</rt></ruby><hr>{}<ruby><rt>quz</rt></ruby>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<ruby>foo<rp>bar[baz]quz</rp><rt>qoz</rt><rp>qiz</rp></ruby>", + [["inserthorizontalrule",""]], + "<ruby>foo<rp>bar</rp></ruby><hr>{}<ruby><rp>quz</rp><rt>qoz</rt><rp>qiz</rp></ruby>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<s>foo[bar]baz</s>", + [["stylewithcss","true"],["inserthorizontalrule",""]], + "<s>foo</s><hr>{}<s>baz</s>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserthorizontalrule":[false,false,"",false,false,""]}], +["<s>foo[bar]baz</s>", + [["stylewithcss","false"],["inserthorizontalrule",""]], + "<s>foo</s><hr>{}<s>baz</s>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserthorizontalrule":[false,false,"",false,false,""]}], +["<samp>foo[bar]baz</samp>", + [["inserthorizontalrule",""]], + "<samp>foo</samp><hr>{}<samp>baz</samp>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<section>foo[bar]baz</section>", + [["inserthorizontalrule",""]], + "<section>foo<hr>{}baz</section>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<small>foo[bar]baz</small>", + [["inserthorizontalrule",""]], + "<small>foo</small><hr>{}<small>baz</small>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<span>foo[bar]baz</span>", + [["inserthorizontalrule",""]], + "<span>foo</span><hr>{}<span>baz</span>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<strong>foo[bar]baz</strong>", + [["inserthorizontalrule",""]], + "<strong>foo</strong><hr>{}<strong>baz</strong>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<sub>foo[bar]baz</sub>", + [["stylewithcss","true"],["inserthorizontalrule",""]], + "<sub>foo</sub><hr>{}<sub>baz</sub>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserthorizontalrule":[false,false,"",false,false,""]}], +["<sub>foo[bar]baz</sub>", + [["stylewithcss","false"],["inserthorizontalrule",""]], + "<sub>foo</sub><hr>{}<sub>baz</sub>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserthorizontalrule":[false,false,"",false,false,""]}], +["<sup>foo[bar]baz</sup>", + [["stylewithcss","true"],["inserthorizontalrule",""]], + "<sup>foo</sup><hr>{}<sup>baz</sup>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserthorizontalrule":[false,false,"",false,false,""]}], +["<sup>foo[bar]baz</sup>", + [["stylewithcss","false"],["inserthorizontalrule",""]], + "<sup>foo</sup><hr>{}<sup>baz</sup>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserthorizontalrule":[false,false,"",false,false,""]}], +["<table><tr><td>foo[bar]baz</td></table>", + [["inserthorizontalrule",""]], + "<table><tbody><tr><td>foo<hr>{}baz</td></tr></tbody></table>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<table><tr><th>foo[bar]baz</th></table>", + [["inserthorizontalrule",""]], + "<table><tbody><tr><th>foo<hr>{}baz</th></tr></tbody></table>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<u>foo[bar]baz</u>", + [["stylewithcss","true"],["inserthorizontalrule",""]], + "<u>foo</u><hr>{}<u>baz</u>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserthorizontalrule":[false,false,"",false,false,""]}], +["<u>foo[bar]baz</u>", + [["stylewithcss","false"],["inserthorizontalrule",""]], + "<u>foo</u><hr>{}<u>baz</u>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserthorizontalrule":[false,false,"",false,false,""]}], +["<ul><li>foo[bar]baz</li></ul>", + [["inserthorizontalrule",""]], + "<ul><li>foo<hr>{}baz</li></ul>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<var>foo[bar]baz</var>", + [["inserthorizontalrule",""]], + "<var>foo</var><hr>{}<var>baz</var>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<acronym>foo[bar]baz</acronym>", + [["inserthorizontalrule",""]], + "<acronym>foo</acronym><hr>{}<acronym>baz</acronym>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<big>foo[bar]baz</big>", + [["inserthorizontalrule",""]], + "<big>foo</big><hr>{}<big>baz</big>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<blink>foo[bar]baz</blink>", + [["inserthorizontalrule",""]], + "<blink>foo</blink><hr>{}<blink>baz</blink>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<center>foo[bar]baz</center>", + [["inserthorizontalrule",""]], + "<center>foo<hr>{}baz</center>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<dir>foo[bar]baz</dir>", + [["inserthorizontalrule",""]], + "<dir>foo</dir><hr>{}<dir>baz</dir>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<dir><li>foo[bar]baz</li></dir>", + [["inserthorizontalrule",""]], + "<dir><li>foo<hr>{}baz</li></dir>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<font>foo[bar]baz</font>", + [["stylewithcss","true"],["inserthorizontalrule",""]], + "<font>foo</font><hr>{}<font>baz</font>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserthorizontalrule":[false,false,"",false,false,""]}], +["<font>foo[bar]baz</font>", + [["stylewithcss","false"],["inserthorizontalrule",""]], + "<font>foo</font><hr>{}<font>baz</font>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserthorizontalrule":[false,false,"",false,false,""]}], +["<listing>foo[bar]baz</listing>", + [["inserthorizontalrule",""]], + "<listing>foo</listing><hr>{}<listing>baz</listing>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<marquee>foo[bar]baz</marquee>", + [["inserthorizontalrule",""]], + "<marquee>foo</marquee><hr>{}<marquee>baz</marquee>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<nobr>foo[bar]baz</nobr>", + [["inserthorizontalrule",""]], + "<nobr>foo</nobr><hr>{}<nobr>baz</nobr>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<strike>foo[bar]baz</strike>", + [["stylewithcss","true"],["inserthorizontalrule",""]], + "<strike>foo</strike><hr>{}<strike>baz</strike>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserthorizontalrule":[false,false,"",false,false,""]}], +["<strike>foo[bar]baz</strike>", + [["stylewithcss","false"],["inserthorizontalrule",""]], + "<strike>foo</strike><hr>{}<strike>baz</strike>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserthorizontalrule":[false,false,"",false,false,""]}], +["<tt>foo[bar]baz</tt>", + [["inserthorizontalrule",""]], + "<tt>foo</tt><hr>{}<tt>baz</tt>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<xmp>foo[bar]baz</xmp>", + [["inserthorizontalrule",""]], + "<xmp>foo</xmp><hr>{}<xmp>baz</xmp>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<quasit>foo[bar]baz</quasit>", + [["inserthorizontalrule",""]], + "<quasit>foo<hr>{}baz</quasit>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["<table><tr><td>fo[o<td>b]ar</table>", + [["inserthorizontalrule",""]], + "<table><tbody><tr><td>fo<hr>{}</td><td>ar</td></tr></tbody></table>", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}], +["fo[o<span contenteditable=false>bar</span>b]az", + [["inserthorizontalrule",""]], + "fo<hr>{}<span contenteditable=\"false\">bar</span>az", + [true], + {"inserthorizontalrule":[false,false,"",false,false,""]}] +] diff --git a/testing/web-platform/tests/editing/data/inserthtml.js b/testing/web-platform/tests/editing/data/inserthtml.js new file mode 100644 index 0000000000..350f0a1556 --- /dev/null +++ b/testing/web-platform/tests/editing/data/inserthtml.js @@ -0,0 +1,606 @@ +// For documentation of the format, see README in this directory. +var browserTests = [ +["foo[]bar", + [["stylewithcss","true"],["inserthtml","ab<b>c</b>d"]], + "fooab<b>c</b>d{}bar", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserthtml":[false,false,"",false,false,""]}], +["foo[]bar", + [["stylewithcss","false"],["inserthtml","ab<b>c</b>d"]], + "fooab<b>c</b>d{}bar", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserthtml":[false,false,"",false,false,""]}], +["foo[bar]baz", + [["stylewithcss","true"],["inserthtml","ab<b>c</b>d"]], + "fooab<b>c</b>d{}baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserthtml":[false,false,"",false,false,""]}], +["foo[bar]baz", + [["stylewithcss","false"],["inserthtml","ab<b>c</b>d"]], + "fooab<b>c</b>d{}baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserthtml":[false,false,"",false,false,""]}], +["foo<span style=color:#aBcDeF>[bar]</span>baz", + [["stylewithcss","true"],["inserthtml","ab<b>c</b>d"]], + "fooab<b>c</b>d{}baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserthtml":[false,false,"",false,false,""]}], +["foo<span style=color:#aBcDeF>[bar]</span>baz", + [["stylewithcss","false"],["inserthtml","ab<b>c</b>d"]], + "fooab<b>c</b>d{}baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserthtml":[false,false,"",false,false,""]}], +["foo<span style=color:#aBcDeF>{bar}</span>baz", + [["stylewithcss","true"],["inserthtml","ab<b>c</b>d"]], + "fooab<b>c</b>d{}baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserthtml":[false,false,"",false,false,""]}], +["foo<span style=color:#aBcDeF>{bar}</span>baz", + [["stylewithcss","false"],["inserthtml","ab<b>c</b>d"]], + "fooab<b>c</b>d{}baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserthtml":[false,false,"",false,false,""]}], +["foo{<span style=color:#aBcDeF>bar</span>}baz", + [["stylewithcss","true"],["inserthtml","ab<b>c</b>d"]], + "fooab<b>c</b>d{}baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserthtml":[false,false,"",false,false,""]}], +["foo{<span style=color:#aBcDeF>bar</span>}baz", + [["stylewithcss","false"],["inserthtml","ab<b>c</b>d"]], + "fooab<b>c</b>d{}baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserthtml":[false,false,"",false,false,""]}], +["[foo<span style=color:#aBcDeF>bar]</span>baz", + [["stylewithcss","true"],["inserthtml","ab<b>c</b>d"]], + "ab<b>c</b>d{}baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserthtml":[false,false,"",false,false,""]}], +["[foo<span style=color:#aBcDeF>bar]</span>baz", + [["stylewithcss","false"],["inserthtml","ab<b>c</b>d"]], + "ab<b>c</b>d{}baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserthtml":[false,false,"",false,false,""]}], +["{foo<span style=color:#aBcDeF>bar}</span>baz", + [["stylewithcss","true"],["inserthtml","ab<b>c</b>d"]], + "ab<b>c</b>d{}baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserthtml":[false,false,"",false,false,""]}], +["{foo<span style=color:#aBcDeF>bar}</span>baz", + [["stylewithcss","false"],["inserthtml","ab<b>c</b>d"]], + "ab<b>c</b>d{}baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserthtml":[false,false,"",false,false,""]}], +["foo<span style=color:#aBcDeF>[bar</span>baz]", + [["stylewithcss","true"],["inserthtml","ab<b>c</b>d"]], + "fooab<b>c</b>d{}", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserthtml":[false,false,"",false,false,""]}], +["foo<span style=color:#aBcDeF>[bar</span>baz]", + [["stylewithcss","false"],["inserthtml","ab<b>c</b>d"]], + "fooab<b>c</b>d{}", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserthtml":[false,false,"",false,false,""]}], +["foo<span style=color:#aBcDeF>{bar</span>baz}", + [["stylewithcss","true"],["inserthtml","ab<b>c</b>d"]], + "fooab<b>c</b>d{}", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserthtml":[false,false,"",false,false,""]}], +["foo<span style=color:#aBcDeF>{bar</span>baz}", + [["stylewithcss","false"],["inserthtml","ab<b>c</b>d"]], + "fooab<b>c</b>d{}", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserthtml":[false,false,"",false,false,""]}], +["foo<span style=color:#aBcDeF>[bar</span><span style=color:#fEdCbA>baz]</span>quz", + [["stylewithcss","true"],["inserthtml","ab<b>c</b>d"]], + "fooab<b>c</b>d{}quz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserthtml":[false,false,"",false,false,""]}], +["foo<span style=color:#aBcDeF>[bar</span><span style=color:#fEdCbA>baz]</span>quz", + [["stylewithcss","false"],["inserthtml","ab<b>c</b>d"]], + "fooab<b>c</b>d{}quz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserthtml":[false,false,"",false,false,""]}], +["foo[bar]baz", + [["inserthtml",""]], + "foo[]baz", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["foo[bar]baz", + [["inserthtml","\u0000"]], + "foo[]baz", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["foo[bar]baz", + [["inserthtml","\u0007"]], + "foo\u0007{}baz", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["foo[bar]baz", + [["stylewithcss","true"],["inserthtml","<b>"]], + "foo<b></b>{}baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserthtml":[false,false,"",false,false,""]}], +["foo[bar]baz", + [["stylewithcss","false"],["inserthtml","<b>"]], + "foo<b></b>{}baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserthtml":[false,false,"",false,false,""]}], +["foo[bar]baz", + [["stylewithcss","true"],["inserthtml","<b>abc"]], + "foo<b>abc</b>{}baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserthtml":[false,false,"",false,false,""]}], +["foo[bar]baz", + [["stylewithcss","false"],["inserthtml","<b>abc"]], + "foo<b>abc</b>{}baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserthtml":[false,false,"",false,false,""]}], +["<p>foo[bar]baz", + [["defaultparagraphseparator","div"],["inserthtml","<p>abc"]], + "<p>foo</p><p>abc</p>{}<p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"div"],"inserthtml":[false,false,"",false,false,""]}], +["<p>foo[bar]baz", + [["defaultparagraphseparator","p"],["inserthtml","<p>abc"]], + "<p>foo</p><p>abc</p>{}<p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"inserthtml":[false,false,"",false,false,""]}], +["<p>foo[bar]baz", + [["defaultparagraphseparator","div"],["inserthtml","<li>abc"]], + "<p>foo</p><div>abc</div>{}<p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"inserthtml":[false,false,"",false,false,""]}], +["<p>foo[bar]baz", + [["defaultparagraphseparator","p"],["inserthtml","<li>abc"]], + "<p>foo</p><p>abc</p>{}<p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"inserthtml":[false,false,"",false,false,""]}], +["<ol>{<li>foo</li>}<li>bar</ol>", + [["defaultparagraphseparator","div"],["inserthtml","<p>abc"]], + "<p>abc</p>{}<ol><li>bar</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"inserthtml":[false,false,"",false,false,""]}], +["<ol>{<li>foo</li>}<li>bar</ol>", + [["defaultparagraphseparator","p"],["inserthtml","<p>abc"]], + "<p>abc</p>{}<ol><li>bar</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"inserthtml":[false,false,"",false,false,""]}], +["<ol><li>foo</li>{<li>bar</li>}<li>baz</ol>", + [["defaultparagraphseparator","div"],["inserthtml","<p>abc"]], + "<ol><li>foo</li></ol><p>abc</p>{}<ol><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"inserthtml":[false,false,"",false,false,""]}], +["<ol><li>foo</li>{<li>bar</li>}<li>baz</ol>", + [["defaultparagraphseparator","p"],["inserthtml","<p>abc"]], + "<ol><li>foo</li></ol><p>abc</p>{}<ol><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"inserthtml":[false,false,"",false,false,""]}], +["<ol><li>[foo]</li><li>bar</ol>", + [["defaultparagraphseparator","div"],["inserthtml","<p>abc"]], + "<ol><li><p>abc</p>{}</li><li>bar</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"inserthtml":[false,false,"",false,false,""]}], +["<ol><li>[foo]</li><li>bar</ol>", + [["defaultparagraphseparator","p"],["inserthtml","<p>abc"]], + "<ol><li><p>abc</p>{}</li><li>bar</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"inserthtml":[false,false,"",false,false,""]}], +["<xmp>f[o]o</xmp>", + [["inserthtml","abc"]], + "<xmp>fabc{}o</xmp>", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["<xmp>f[o]o</xmp>", + [["stylewithcss","true"],["inserthtml","<b>abc</b>"]], + "<xmp>f<b>abc</b>{}o</xmp>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserthtml":[false,false,"",false,false,""]}], +["<xmp>f[o]o</xmp>", + [["stylewithcss","false"],["inserthtml","<b>abc</b>"]], + "<xmp>f<b>abc</b>{}o</xmp>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserthtml":[false,false,"",false,false,""]}], +["<script>f[o]o</script>bar", + [["inserthtml","abc"]], + "<script>fabc{}o</script>bar", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["<script>f[o]o</script>bar", + [["stylewithcss","true"],["inserthtml","<b>abc</b>"]], + "<script>f<b>abc</b>{}o</script>bar", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserthtml":[false,false,"",false,false,""]}], +["<script>f[o]o</script>bar", + [["stylewithcss","false"],["inserthtml","<b>abc</b>"]], + "<script>f<b>abc</b>{}o</script>bar", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserthtml":[false,false,"",false,false,""]}], +["<a>f[o]o</a>", + [["inserthtml","<a>abc</a>"]], + "<a>f</a><a>abc</a>{}<a>o</a>", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["<a href=.>f[o]o</a>", + [["inserthtml","<a href=/>abc</a>"]], + "<a href=\".\">f</a><a href=\"/\">abc</a>{}<a href=\".\">o</a>", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["<p>f[o]o", + [["defaultparagraphseparator","div"],["inserthtml","<hr>"]], + "<p>f</p><hr>{}<p>o</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"inserthtml":[false,false,"",false,false,""]}], +["<p>f[o]o", + [["defaultparagraphseparator","p"],["inserthtml","<hr>"]], + "<p>f</p><hr>{}<p>o</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"inserthtml":[false,false,"",false,false,""]}], +["<b>f[o]o</b>", + [["stylewithcss","true"],["inserthtml","<hr>"]], + "<b>f</b><hr>{}<b>o</b>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserthtml":[false,false,"",false,false,""]}], +["<b>f[o]o</b>", + [["stylewithcss","false"],["inserthtml","<hr>"]], + "<b>f</b><hr>{}<b>o</b>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserthtml":[false,false,"",false,false,""]}], +["<h1>f[o]o</h1>", + [["inserthtml","<h2>abc</h2>"]], + "<h1>f</h1><h2>abc</h2>{}<h1>o</h1>", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["<table><tr><td>f[o]o</table>", + [["inserthtml","<td>abc</td>"]], + "<table><tbody><tr><td>fabc{}o</td></tr></tbody></table>", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["f[o]o", + [["inserthtml","<td>abc</td>"]], + "fabc{}o", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["<dl><dt>f[o]o<dd>bar</dl>", + [["inserthtml","<dt>abc</dt>"]], + "<dl><dt>f</dt><dt>abc</dt>{}<dt>o</dt><dd>bar</dd></dl>", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["<dl><dt>foo<dd>b[a]r</dl>", + [["inserthtml","<dt>abc</dt>"]], + "<dl><dt>foo</dt><dd>b</dd><dt>abc</dt>{}<dd>r</dd></dl>", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["<dl><dt>f[o]o<dd>bar</dl>", + [["inserthtml","<dd>abc</dd>"]], + "<dl><dt>f</dt><dd>abc</dd>{}<dt>o</dt><dd>bar</dd></dl>", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["<dl><dt>foo<dd>b[a]r</dl>", + [["inserthtml","<dd>abc</dd>"]], + "<dl><dt>foo</dt><dd>b</dd><dd>abc</dd>{}<dd>r</dd></dl>", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["f[o]o", + [["inserthtml","<dt>abc</dt>"]], + "f<dl><dt>abc</dt>{}</dl>o", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["<ol><li>f[o]o</ol>", + [["inserthtml","<dt>abc</dt>"]], + "<ol><li>f<dl><dt>abc</dt>{}</dl>o</li></ol>", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["f[o]o", + [["inserthtml","<dd>abc</dd>"]], + "f<dl><dd>abc</dd>{}</dl>o", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["<ol><li>f[o]o</ol>", + [["inserthtml","<dd>abc</dd>"]], + "<ol><li>f<dl><dd>abc</dd>{}</dl>o</li></ol>", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["<dir><li>f[o]o</dir>", + [["inserthtml","<li>abc</li>"]], + "<dir><li>f</li><li>abc</li>{}<li>o</li></dir>", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["<ol><li>f[o]o</ol>", + [["inserthtml","<li>abc</li>"]], + "<ol><li>f</li><li>abc</li>{}<li>o</li></ol>", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["<ul><li>f[o]o</ul>", + [["inserthtml","<li>abc</li>"]], + "<ul><li>f</li><li>abc</li>{}<li>o</li></ul>", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["<dir><li>f[o]o</dir>", + [["inserthtml","<dir><li>abc</dir>"]], + "<dir><li>f<dir><li>abc</li></dir>{}o</li></dir>", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["<ol><li>f[o]o</ol>", + [["inserthtml","<dir><li>abc</dir>"]], + "<ol><li>f<dir><li>abc</li></dir>{}o</li></ol>", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["<ul><li>f[o]o</ul>", + [["inserthtml","<dir><li>abc</dir>"]], + "<ul><li>f<dir><li>abc</li></dir>{}o</li></ul>", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["<dir><li>f[o]o</dir>", + [["inserthtml","<ol><li>abc</ol>"]], + "<dir><li>f<ol><li>abc</li></ol>{}o</li></dir>", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["<ol><li>f[o]o</ol>", + [["inserthtml","<ol><li>abc</ol>"]], + "<ol><li>f<ol><li>abc</li></ol>{}o</li></ol>", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["<ul><li>f[o]o</ul>", + [["inserthtml","<ol><li>abc</ol>"]], + "<ul><li>f<ol><li>abc</li></ol>{}o</li></ul>", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["<dir><li>f[o]o</dir>", + [["inserthtml","<ul><li>abc</ul>"]], + "<dir><li>f<ul><li>abc</li></ul>{}o</li></dir>", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["<ol><li>f[o]o</ol>", + [["inserthtml","<ul><li>abc</ul>"]], + "<ol><li>f<ul><li>abc</li></ul>{}o</li></ol>", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["<ul><li>f[o]o</ul>", + [["inserthtml","<ul><li>abc</ul>"]], + "<ul><li>f<ul><li>abc</li></ul>{}o</li></ul>", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["<ul id=\"old\"><li id=\"li0\">{}<br></ul>", + [["inserthtml","<ul id=\"new\"><li id=\"li1\">abc</li><li id=\"li2\">def</li></ul>"]], + "<ul id=\"old\"><li id=\"li1\">abc</li><li id=\"li2\">def</li></ul>", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["<ol id=\"old\"><li id=\"li0\">{}<br></ol>", + [["inserthtml","<ol id=\"new\"><li id=\"li1\">abc</li><li id=\"li2\">def</li></ol>"]], + "<ol id=\"old\"><li id=\"li1\">abc</li><li id=\"li2\">def</li></ol>", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["<ul id=\"old\"><li id=\"li0\">{}<br></ul>", + [["inserthtml","<ol id=\"new\"><li id=\"li1\">abc</li><li id=\"li2\">def</li></ol>"]], + "<ul id=\"old\"><li id=\"li1\">abc</li><li id=\"li2\">def</li></ul>", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["<ol id=\"old\"><li id=\"li0\">{}<br></ol>", + [["inserthtml","<ul id=\"new\"><li id=\"li1\">abc</li><li id=\"li2\">def</li></ul>"]], + "<ol id=\"old\"><li id=\"li1\">abc</li><li id=\"li2\">def</li></ol>", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["f[o]o", + [["defaultparagraphseparator","div"],["inserthtml","<li>abc</li>"]], + "f<div>abc</div>{}o", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"inserthtml":[false,false,"",false,false,""]}], +["f[o]o", + [["defaultparagraphseparator","p"],["inserthtml","<li>abc</li>"]], + "f<p>abc</p>{}o", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"inserthtml":[false,false,"",false,false,""]}], +["<nobr>f[o]o</nobr>", + [["inserthtml","<nobr>abc</nobr>"]], + "<nobr>f</nobr><nobr>abc</nobr>{}<nobr>o</nobr>", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["f[o]o", + [["inserthtml","<nobr>abc</nobr>"]], + "f<nobr>abc</nobr>{}o", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["<font color=blue>foo[]bar</font>", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["inserthtml","<p>abc"]], + "<font color=\"blue\">foo</font><p><span style=\"color:rgb(0, 0, 255)\">abc</span></p>{}<font color=\"blue\">bar</font>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"inserthtml":[false,false,"",false,false,""]}], +["<font color=blue>foo[]bar</font>", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["inserthtml","<p>abc"]], + "<font color=\"blue\">foo</font><p><font color=\"#0000ff\">abc</font></p>{}<font color=\"blue\">bar</font>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"inserthtml":[false,false,"",false,false,""]}], +["<font color=blue>foo[]bar</font>", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["inserthtml","<p>abc"]], + "<font color=\"blue\">foo</font><p><span style=\"color:rgb(0, 0, 255)\">abc</span></p>{}<font color=\"blue\">bar</font>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"inserthtml":[false,false,"",false,false,""]}], +["<font color=blue>foo[]bar</font>", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["inserthtml","<p>abc"]], + "<font color=\"blue\">foo</font><p><font color=\"#0000ff\">abc</font></p>{}<font color=\"blue\">bar</font>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"inserthtml":[false,false,"",false,false,""]}], +["<span style=color:blue>foo[]bar</span>", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["inserthtml","<p>abc"]], + "<span style=\"color:rgb(0, 0, 255)\">foo</span><p><span style=\"color:rgb(0, 0, 255)\">abc</span></p>{}<span style=\"color:rgb(0, 0, 255)\">bar</span>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"inserthtml":[false,false,"",false,false,""]}], +["<span style=color:blue>foo[]bar</span>", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["inserthtml","<p>abc"]], + "<span style=\"color:rgb(0, 0, 255)\">foo</span><p><font color=\"#0000ff\">abc</font></p>{}<span style=\"color:rgb(0, 0, 255)\">bar</span>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"inserthtml":[false,false,"",false,false,""]}], +["<span style=color:blue>foo[]bar</span>", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["inserthtml","<p>abc"]], + "<span style=\"color:rgb(0, 0, 255)\">foo</span><p><span style=\"color:rgb(0, 0, 255)\">abc</span></p>{}<span style=\"color:rgb(0, 0, 255)\">bar</span>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"inserthtml":[false,false,"",false,false,""]}], +["<span style=color:blue>foo[]bar</span>", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["inserthtml","<p>abc"]], + "<span style=\"color:rgb(0, 0, 255)\">foo</span><p><font color=\"#0000ff\">abc</font></p>{}<span style=\"color:rgb(0, 0, 255)\">bar</span>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"inserthtml":[false,false,"",false,false,""]}], +["<span style=font-variant:small-caps>foo[]bar</span>", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["inserthtml","<p>abc"]], + "<span style=\"font-variant:small-caps\">foo</span><p>abc</p>{}<span style=\"font-variant:small-caps\">bar</span>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"inserthtml":[false,false,"",false,false,""]}], +["<span style=font-variant:small-caps>foo[]bar</span>", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["inserthtml","<p>abc"]], + "<span style=\"font-variant:small-caps\">foo</span><p>abc</p>{}<span style=\"font-variant:small-caps\">bar</span>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"inserthtml":[false,false,"",false,false,""]}], +["<span style=font-variant:small-caps>foo[]bar</span>", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["inserthtml","<p>abc"]], + "<span style=\"font-variant:small-caps\">foo</span><p>abc</p>{}<span style=\"font-variant:small-caps\">bar</span>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"inserthtml":[false,false,"",false,false,""]}], +["<span style=font-variant:small-caps>foo[]bar</span>", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["inserthtml","<p>abc"]], + "<span style=\"font-variant:small-caps\">foo</span><p>abc</p>{}<span style=\"font-variant:small-caps\">bar</span>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"inserthtml":[false,false,"",false,false,""]}], +["<p>[foo]</p>", + [["inserthtml"," "]], + "<p> {}<br></p>", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["<p>[foo]</p>", + [["stylewithcss","true"],["inserthtml","<span style=display:none></span>"]], + "<p><span style=\"display:none\"></span>{}<br></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserthtml":[false,false,"",false,false,""]}], +["<p>[foo]</p>", + [["stylewithcss","false"],["inserthtml","<span style=display:none></span>"]], + "<p><span style=\"display:none\"></span>{}<br></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserthtml":[false,false,"",false,false,""]}], +["<p>[foo]</p>", + [["inserthtml","<!--abc-->"]], + "<p><!--abc-->{}<br></p>", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["<p>{}<br></p>", + [["inserthtml","abc"]], + "<p>abc{}</p>", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["<p>{}<br></p>", + [["inserthtml","<!--abc-->"]], + "<p><!--abc-->{}<br></p>", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["<p><!--foo-->{}<span><br></span><!--bar--></p>", + [["inserthtml","abc"]], + "<p><!--foo-->abc{}<!--bar--></p>", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["<p><!--foo-->{}<span><br></span><!--bar--></p>", + [["inserthtml","<!--abc-->"]], + "<p><!--foo--><!--abc-->{}<!--bar--><br></p>", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["<p>{}<span><!--foo--><br><!--bar--></span></p>", + [["inserthtml","abc"]], + "<p>abc{}</p>", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["<p>{}<span><!--foo--><br><!--bar--></span></p>", + [["inserthtml","<!--abc-->"]], + "<p><!--abc-->{}<br></p>", + [true], + {"inserthtml":[false,false,"",false,false,""]}], + +// When selection is collapsed after an invisible <br> element, content should +// be inserted before it because inserting something after the <br> element +// makes the element visible. +["<p><br>{}</p>", + [["inserthtml","abc"]], + ["<p>abc</p>", + "<p>abc<br></p>"], + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["<p><br>{}</p>", + [["inserthtml","<!--abc-->"]], + "<p><!--abc--><br></p>", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["<p><!--foo--><span><br></span>{}<!--bar--></p>", + [["inserthtml","abc"]], + ["<p><!--foo--><span>abc</span><!--bar--></p>", + "<p><!--foo-->abc<span><br></span><!--bar--></p>"], + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["<p><!--foo--><span><br></span>{}<!--bar--></p>", + [["inserthtml","<!--abc-->"]], + "<p><!--foo--><span><!--abc-->{}<br></span><!--bar--></p>", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["<p><span><!--foo--><br><!--bar--></span>{}</p>", + [["inserthtml","abc"]], + "<p>abc<span><!--foo--><br><!--bar--></span></p>", + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["<p><span><!--foo--><br><!--bar--></span>{}</p>", + [["inserthtml","<!--abc-->"]], + "<p><!--abc--><span><!--foo--><br><!--bar--></span></p>", + [true], + {"inserthtml":[false,false,"",false,false,""]}], + +["<pre>12[]34</pre>", + [["inserthtml","<pre>abc</pre>"]], + ["<pre>12abc34</pre>", + "<pre>12abc34<br></pre>"], + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["<pre>1[23]4</pre>", + [["inserthtml","<pre>abc</pre>"]], + ["<pre>1abc4</pre>", + "<pre>1abc4<br></pre>"], + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["<pre>[1234]</pre>", + [["inserthtml","<pre>abc</pre>"]], + ["<pre>abc</pre>", + "<pre>abc<br></pre>"], + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["<pre contenteditable=\"false\"><span contenteditable>[1234]</span></pre>", + [["inserthtml","<pre>abc</pre>"]], + ["<pre contenteditable=\"false\"><span contenteditable=\"\">abc</span></pre>", + "<pre contenteditable=\"false\"><span contenteditable=\"\">abc<br></span></pre>"], + [true], + {"inserthtml":[false,false,"",false,false,""]}], + +// Empty inline elements shouldn't be deleted if they are inserted intentionally +["<div>a[]b</div>", + [["inserthtml","<span></span>"]], + ["<div>a<span></span>b</div>", + "<div>a<span></span>b<br></div>"], + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["<div>a[]c</div>", + [["inserthtml","<span class=\"s1\"></span>b<span class=\"s2\"></span>"]], + ["<div>a<span class=\"s1\"></span>b<span class=\"s2\"></span>c</div>", + "<div>a<span class=\"s1\"></span>b<span class=\"s2\"></span>c<br></div>"], + [true], + {"inserthtml":[false,false,"",false,false,""]}], +["{}", + [["inserthtml","<div class=\"d1\"></div><div class=\"d2\"><span class=\"s1\">some text</span><a href=\"foo.html\"></a></div>"]], + "<div class=\"d1\"></div><div class=\"d2\"><span class=\"s1\">some text</span><a href=\"foo.html\"></a></div>", + [true], + {"inserthtml":[false,false,"",false,false,""]}], + +// Do not delete non-editable when clearing the original style +["<p><b>[X]<span contenteditable=false>abc</span></b><i>def</i></p>", + [["inserthtml","<i>Z</i>"]], + "<p><i>Z</i><b><span contenteditable=\"false\">abc</span></b><i>def</i></p>", + [true], + {}], +["<p><b><span contenteditable=false>abc</span>[Y]</b><i>def</i></p>", + [["inserthtml","<i>Z</i>"]], + ["<p><b><span contenteditable=\"false\">abc</span></b><i>Z</i><i>def</i></p>", + "<p><b><span contenteditable=\"false\">abc</span></b><i>Zdef</i></p>"], + [true], + {}], +] diff --git a/testing/web-platform/tests/editing/data/insertimage.js b/testing/web-platform/tests/editing/data/insertimage.js new file mode 100644 index 0000000000..b18388a797 --- /dev/null +++ b/testing/web-platform/tests/editing/data/insertimage.js @@ -0,0 +1,358 @@ +// For documentation of the format, see README in this directory. +var browserTests = [ +["foo[]bar", + [["insertimage","/img/lion.svg"]], + "foo<img src=\"/img/lion.svg\">{}bar", + [true], + {"insertimage":[false,false,"",false,false,""]}], +["<span>foo</span>{}<span>bar</span>", + [["insertimage","/img/lion.svg"]], + "<span>foo</span><img src=\"/img/lion.svg\">{}<span>bar</span>", + [true], + {"insertimage":[false,false,"",false,false,""]}], +["<span>foo[</span><span>]bar</span>", + [["insertimage","/img/lion.svg"]], + "<span>foo<img src=\"/img/lion.svg\">{}</span><span>bar</span>", + [true], + {"insertimage":[false,false,"",false,false,""]}], +["foo[bar]baz", + [["insertimage",""]], + "foo[bar]baz", + [false], + {"insertimage":[false,false,"",false,false,""]}], +["foo[bar]baz", + [["insertimage","/img/lion.svg"]], + "foo<img src=\"/img/lion.svg\">{}baz", + [true], + {"insertimage":[false,false,"",false,false,""]}], +["foo<span style=color:#aBcDeF>[bar]</span>baz", + [["insertimage","/img/lion.svg"]], + "foo<span style=\"color:rgb(171, 205, 239)\"><img src=\"/img/lion.svg\">{}</span>baz", + [true], + {"insertimage":[false,false,"",false,false,""]}], +["foo<span style=color:#aBcDeF>{bar}</span>baz", + [["insertimage","/img/lion.svg"]], + "foo<span style=\"color:rgb(171, 205, 239)\"><img src=\"/img/lion.svg\">{}</span>baz", + [true], + {"insertimage":[false,false,"",false,false,""]}], +["foo{<span style=color:#aBcDeF>bar</span>}baz", + [["insertimage","/img/lion.svg"]], + "foo<span style=\"color:rgb(171, 205, 239)\"><img src=\"/img/lion.svg\">{}</span>baz", + [true], + {"insertimage":[false,false,"",false,false,""]}], +["[foo<span style=color:#aBcDeF>bar]</span>baz", + [["stylewithcss","true"],["insertimage","/img/lion.svg"]], + "<img src=\"/img/lion.svg\">{}baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"insertimage":[false,false,"",false,false,""]}], +["[foo<span style=color:#aBcDeF>bar]</span>baz", + [["stylewithcss","false"],["insertimage","/img/lion.svg"]], + "<img src=\"/img/lion.svg\">{}baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"insertimage":[false,false,"",false,false,""]}], +["{foo<span style=color:#aBcDeF>bar}</span>baz", + [["stylewithcss","true"],["insertimage","/img/lion.svg"]], + "<img src=\"/img/lion.svg\">{}baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"insertimage":[false,false,"",false,false,""]}], +["{foo<span style=color:#aBcDeF>bar}</span>baz", + [["stylewithcss","false"],["insertimage","/img/lion.svg"]], + "<img src=\"/img/lion.svg\">{}baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"insertimage":[false,false,"",false,false,""]}], +["foo<span style=color:#aBcDeF>[bar</span>baz]", + [["insertimage","/img/lion.svg"]], + "foo<span style=\"color:rgb(171, 205, 239)\"><img src=\"/img/lion.svg\">{}</span>", + [true], + {"insertimage":[false,false,"",false,false,""]}], +["foo<span style=color:#aBcDeF>{bar</span>baz}", + [["insertimage","/img/lion.svg"]], + "foo<span style=\"color:rgb(171, 205, 239)\"><img src=\"/img/lion.svg\">{}</span>", + [true], + {"insertimage":[false,false,"",false,false,""]}], +["foo<span style=color:#aBcDeF>[bar</span><span style=color:#fEdCbA>baz]</span>quz", + [["stylewithcss","true"],["insertimage","/img/lion.svg"]], + "foo<span style=\"color:rgb(171, 205, 239)\"><img src=\"/img/lion.svg\">{}</span>quz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"insertimage":[false,false,"",false,false,""]}], +["foo<span style=color:#aBcDeF>[bar</span><span style=color:#fEdCbA>baz]</span>quz", + [["stylewithcss","false"],["insertimage","/img/lion.svg"]], + "foo<span style=\"color:rgb(171, 205, 239)\"><img src=\"/img/lion.svg\">{}</span>quz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"insertimage":[false,false,"",false,false,""]}], +["foo<b>[bar]</b>baz", + [["insertimage","/img/lion.svg"]], + "foo<b><img src=\"/img/lion.svg\">{}</b>baz", + [true], + {"insertimage":[false,false,"",false,false,""]}], +["foo<b>{bar}</b>baz", + [["insertimage","/img/lion.svg"]], + "foo<b><img src=\"/img/lion.svg\">{}</b>baz", + [true], + {"insertimage":[false,false,"",false,false,""]}], +["foo{<b>bar</b>}baz", + [["insertimage","/img/lion.svg"]], + "foo<b><img src=\"/img/lion.svg\">{}</b>baz", + [true], + {"insertimage":[false,false,"",false,false,""]}], +["foo<span>[bar]</span>baz", + [["insertimage","/img/lion.svg"]], + "foo<span><img src=\"/img/lion.svg\">{}</span>baz", + [true], + {"insertimage":[false,false,"",false,false,""]}], +["foo<span>{bar}</span>baz", + [["insertimage","/img/lion.svg"]], + "foo<span><img src=\"/img/lion.svg\">{}</span>baz", + [true], + {"insertimage":[false,false,"",false,false,""]}], +["foo{<span>bar</span>}baz", + [["insertimage","/img/lion.svg"]], + "foo<span><img src=\"/img/lion.svg\">{}</span>baz", + [true], + {"insertimage":[false,false,"",false,false,""]}], +["<b>foo[bar</b><i>baz]quz</i>", + [["insertimage","/img/lion.svg"]], + "<b>foo<img src=\"/img/lion.svg\">{}</b><i>quz</i>", + [true], + {"insertimage":[false,false,"",false,false,""]}], +["<p>foo</p><p>[bar]</p><p>baz</p>", + [["insertimage","/img/lion.svg"]], + "<p>foo</p><p><img src=\"/img/lion.svg\">{}</p><p>baz</p>", + [true], + {"insertimage":[false,false,"",false,false,""]}], +["<p>foo</p><p>{bar}</p><p>baz</p>", + [["insertimage","/img/lion.svg"]], + "<p>foo</p><p><img src=\"/img/lion.svg\">{}</p><p>baz</p>", + [true], + {"insertimage":[false,false,"",false,false,""]}], +["<p>foo</p>{<p>bar</p>}<p>baz</p>", + [["defaultparagraphseparator","div"],["insertimage","/img/lion.svg"]], + "<p>foo</p><img src=\"/img/lion.svg\">{}<p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"div"],"insertimage":[false,false,"",false,false,""]}], +["<p>foo</p>{<p>bar</p>}<p>baz</p>", + [["defaultparagraphseparator","p"],["insertimage","/img/lion.svg"]], + "<p>foo</p><img src=\"/img/lion.svg\">{}<p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertimage":[false,false,"",false,false,""]}], +["<p>foo[bar<p>baz]quz", + [["defaultparagraphseparator","div"],["insertimage","/img/lion.svg"]], + "<p>foo<img src=\"/img/lion.svg\">{}quz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertimage":[false,false,"",false,false,""]}], +["<p>foo[bar<p>baz]quz", + [["defaultparagraphseparator","p"],["insertimage","/img/lion.svg"]], + "<p>foo<img src=\"/img/lion.svg\">{}quz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertimage":[false,false,"",false,false,""]}], +["<p>foo[bar<div>baz]quz</div>", + [["defaultparagraphseparator","div"],["insertimage","/img/lion.svg"]], + "<p>foo<img src=\"/img/lion.svg\">{}quz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertimage":[false,false,"",false,false,""]}], +["<p>foo[bar<div>baz]quz</div>", + [["defaultparagraphseparator","p"],["insertimage","/img/lion.svg"]], + "<p>foo<img src=\"/img/lion.svg\">{}quz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertimage":[false,false,"",false,false,""]}], +["<p>foo[bar<h1>baz]quz</h1>", + [["insertimage","/img/lion.svg"]], + "<p>foo<img src=\"/img/lion.svg\">{}quz</p>", + [true], + {"insertimage":[false,false,"",false,false,""]}], +["<div>foo[bar</div><p>baz]quz", + [["defaultparagraphseparator","div"],["insertimage","/img/lion.svg"]], + "<div>foo<img src=\"/img/lion.svg\">{}quz</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertimage":[false,false,"",false,false,""]}], +["<div>foo[bar</div><p>baz]quz", + [["defaultparagraphseparator","p"],["insertimage","/img/lion.svg"]], + "<div>foo<img src=\"/img/lion.svg\">{}quz</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertimage":[false,false,"",false,false,""]}], +["<blockquote>foo[bar</blockquote><pre>baz]quz</pre>", + [["insertimage","/img/lion.svg"]], + "<blockquote>foo<img src=\"/img/lion.svg\">{}quz</blockquote>", + [true], + {"insertimage":[false,false,"",false,false,""]}], +["<p><b>foo[bar</b><p>baz]quz", + [["defaultparagraphseparator","div"],["insertimage","/img/lion.svg"]], + "<p><b>foo</b><img src=\"/img/lion.svg\">{}quz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertimage":[false,false,"",false,false,""]}], +["<p><b>foo[bar</b><p>baz]quz", + [["defaultparagraphseparator","p"],["insertimage","/img/lion.svg"]], + "<p><b>foo</b><img src=\"/img/lion.svg\">{}quz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertimage":[false,false,"",false,false,""]}], +["<div><p>foo[bar</div><p>baz]quz", + [["defaultparagraphseparator","div"],["insertimage","/img/lion.svg"]], + "<div><p>foo<img src=\"/img/lion.svg\">{}quz</p></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertimage":[false,false,"",false,false,""]}], +["<div><p>foo[bar</div><p>baz]quz", + [["defaultparagraphseparator","p"],["insertimage","/img/lion.svg"]], + "<div><p>foo<img src=\"/img/lion.svg\">{}quz</p></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertimage":[false,false,"",false,false,""]}], +["<p>foo[bar<blockquote><p>baz]quz<p>qoz</blockquote", + [["defaultparagraphseparator","div"],["insertimage","/img/lion.svg"]], + "<p>foo<img src=\"/img/lion.svg\">{}quz</p><blockquote><p>qoz</p></blockquote>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertimage":[false,false,"",false,false,""]}], +["<p>foo[bar<blockquote><p>baz]quz<p>qoz</blockquote", + [["defaultparagraphseparator","p"],["insertimage","/img/lion.svg"]], + "<p>foo<img src=\"/img/lion.svg\">{}quz</p><blockquote><p>qoz</p></blockquote>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertimage":[false,false,"",false,false,""]}], +["<p>foo[bar<p style=color:blue>baz]quz", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["insertimage","/img/lion.svg"]], + "<p>foo<img src=\"/img/lion.svg\">{}<span style=\"color:rgb(0, 0, 255)\">quz</span></p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertimage":[false,false,"",false,false,""]}], +["<p>foo[bar<p style=color:blue>baz]quz", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["insertimage","/img/lion.svg"]], + "<p>foo<img src=\"/img/lion.svg\">{}<font color=\"#0000ff\">quz</font></p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"insertimage":[false,false,"",false,false,""]}], +["<p>foo[bar<p style=color:blue>baz]quz", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["insertimage","/img/lion.svg"]], + "<p>foo<img src=\"/img/lion.svg\">{}<span style=\"color:rgb(0, 0, 255)\">quz</span></p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertimage":[false,false,"",false,false,""]}], +["<p>foo[bar<p style=color:blue>baz]quz", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["insertimage","/img/lion.svg"]], + "<p>foo<img src=\"/img/lion.svg\">{}<font color=\"#0000ff\">quz</font></p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"insertimage":[false,false,"",false,false,""]}], +["<p>foo[bar<p><b>baz]quz</b>", + [["defaultparagraphseparator","div"],["insertimage","/img/lion.svg"]], + "<p>foo<img src=\"/img/lion.svg\">{}<b>quz</b></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertimage":[false,false,"",false,false,""]}], +["<p>foo[bar<p><b>baz]quz</b>", + [["defaultparagraphseparator","p"],["insertimage","/img/lion.svg"]], + "<p>foo<img src=\"/img/lion.svg\">{}<b>quz</b></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertimage":[false,false,"",false,false,""]}], +["<div><p>foo<p>[bar<p>baz]</div>", + [["defaultparagraphseparator","div"],["insertimage","/img/lion.svg"]], + "<div><p>foo</p><p><img src=\"/img/lion.svg\">{}</p></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertimage":[false,false,"",false,false,""]}], +["<div><p>foo<p>[bar<p>baz]</div>", + [["defaultparagraphseparator","p"],["insertimage","/img/lion.svg"]], + "<div><p>foo</p><p><img src=\"/img/lion.svg\">{}</p></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertimage":[false,false,"",false,false,""]}], +["foo[<br>]bar", + [["insertimage","/img/lion.svg"]], + "foo<img src=\"/img/lion.svg\">{}bar", + [true], + {"insertimage":[false,false,"",false,false,""]}], +["<p>foo[</p><p>]bar</p>", + [["defaultparagraphseparator","div"],["insertimage","/img/lion.svg"]], + "<p>foo<img src=\"/img/lion.svg\">{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertimage":[false,false,"",false,false,""]}], +["<p>foo[</p><p>]bar</p>", + [["defaultparagraphseparator","p"],["insertimage","/img/lion.svg"]], + "<p>foo<img src=\"/img/lion.svg\">{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertimage":[false,false,"",false,false,""]}], +["<p>foo[</p><p>]bar<br>baz</p>", + [["defaultparagraphseparator","div"],["insertimage","/img/lion.svg"]], + "<p>foo<img src=\"/img/lion.svg\">{}bar<br>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertimage":[false,false,"",false,false,""]}], +["<p>foo[</p><p>]bar<br>baz</p>", + [["defaultparagraphseparator","p"],["insertimage","/img/lion.svg"]], + "<p>foo<img src=\"/img/lion.svg\">{}bar<br>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertimage":[false,false,"",false,false,""]}], +["foo[<p>]bar</p>", + [["defaultparagraphseparator","div"],["insertimage","/img/lion.svg"]], + "foo<img src=\"/img/lion.svg\">{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertimage":[false,false,"",false,false,""]}], +["foo[<p>]bar</p>", + [["defaultparagraphseparator","p"],["insertimage","/img/lion.svg"]], + "foo<img src=\"/img/lion.svg\">{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertimage":[false,false,"",false,false,""]}], +["foo[<p>]bar<br>baz</p>", + [["insertimage","/img/lion.svg"]], + "foo<img src=\"/img/lion.svg\">{}bar<p>baz</p>", + [true], + {"insertimage":[false,false,"",false,false,""]}], +["foo[<p>]bar</p>baz", + [["defaultparagraphseparator","div"],["insertimage","/img/lion.svg"]], + "foo<img src=\"/img/lion.svg\">{}bar<br>baz", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertimage":[false,false,"",false,false,""]}], +["foo[<p>]bar</p>baz", + [["defaultparagraphseparator","p"],["insertimage","/img/lion.svg"]], + "foo<img src=\"/img/lion.svg\">{}bar<br>baz", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertimage":[false,false,"",false,false,""]}], +["<p>foo[</p>]bar", + [["insertimage","/img/lion.svg"]], + "<p>foo<img src=\"/img/lion.svg\">{}bar</p>", + [true], + {"insertimage":[false,false,"",false,false,""]}], +["<p>foo[</p>]bar<br>baz", + [["insertimage","/img/lion.svg"]], + "<p>foo<img src=\"/img/lion.svg\">{}bar</p>baz", + [true], + {"insertimage":[false,false,"",false,false,""]}], +["<p>foo[</p>]bar<p>baz</p>", + [["insertimage","/img/lion.svg"]], + "<p>foo<img src=\"/img/lion.svg\">{}bar</p><p>baz</p>", + [true], + {"insertimage":[false,false,"",false,false,""]}], +["foo[<div><p>]bar</div>", + [["defaultparagraphseparator","div"],["insertimage","/img/lion.svg"]], + "foo<img src=\"/img/lion.svg\">{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertimage":[false,false,"",false,false,""]}], +["foo[<div><p>]bar</div>", + [["defaultparagraphseparator","p"],["insertimage","/img/lion.svg"]], + "foo<img src=\"/img/lion.svg\">{}bar", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertimage":[false,false,"",false,false,""]}], +["<div><p>foo[</p></div>]bar", + [["insertimage","/img/lion.svg"]], + "<div><p>foo<img src=\"/img/lion.svg\">{}bar</p></div>", + [true], + {"insertimage":[false,false,"",false,false,""]}], +["foo[<div><p>]bar</p>baz</div>", + [["defaultparagraphseparator","div"],["insertimage","/img/lion.svg"]], + "foo<img src=\"/img/lion.svg\">{}bar<div>baz</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertimage":[false,false,"",false,false,""]}], +["foo[<div><p>]bar</p>baz</div>", + [["defaultparagraphseparator","p"],["insertimage","/img/lion.svg"]], + "foo<img src=\"/img/lion.svg\">{}bar<div>baz</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertimage":[false,false,"",false,false,""]}], +["foo[<div>]bar<p>baz</p></div>", + [["insertimage","/img/lion.svg"]], + "foo<img src=\"/img/lion.svg\">{}bar<div><p>baz</p></div>", + [true], + {"insertimage":[false,false,"",false,false,""]}], +["<div><p>foo</p>bar[</div>]baz", + [["insertimage","/img/lion.svg"]], + "<div><p>foo</p>bar<img src=\"/img/lion.svg\">{}baz</div>", + [true], + {"insertimage":[false,false,"",false,false,""]}], +["<div>foo<p>bar[</p></div>]baz", + [["insertimage","/img/lion.svg"]], + "<div>foo<p>bar<img src=\"/img/lion.svg\">{}baz</p></div>", + [true], + {"insertimage":[false,false,"",false,false,""]}], +["foo[]bar", + [["insertimage","/\u65E5\u672C\u8A9E\u30D1\u30B9/lion.svg"]], + "foo<img src=\"/\u65E5\u672C\u8A9E\u30D1\u30B9/lion.svg\">{}bar", + [true], + {"insertimage":[false,false,"",false,false,""]}], +] diff --git a/testing/web-platform/tests/editing/data/insertlinebreak.js b/testing/web-platform/tests/editing/data/insertlinebreak.js new file mode 100644 index 0000000000..a29862ffd3 --- /dev/null +++ b/testing/web-platform/tests/editing/data/insertlinebreak.js @@ -0,0 +1,873 @@ +// For documentation of the format, see README in this directory. +var browserTests = [ +["foo[bar]baz", + [["insertlinebreak",""]], + "foo<br>{}baz", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["fo[o<table><tr><td>b]ar</table>", + [["insertlinebreak",""]], + "fo<br>{}<br><table><tbody><tr><td>ar</td></tr></tbody></table>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<table><tr><td>[foo<td>bar]<tr><td>baz<td>quz</table>", + [["insertlinebreak",""]], + "<table><tbody><tr><td><br>{}<br></td><td><br></td></tr><tr><td>baz</td><td>quz</td></tr></tbody></table>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<tr><td>baz<td>quz</table>", + [["insertlinebreak",""]], + "<table><tbody>{}<tr><td><br></td><td><br></td></tr><tr><td>baz</td><td>quz</td></tr></tbody></table>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<table><tr><td>fo[o</table>b]ar", + [["insertlinebreak",""]], + "<table><tbody><tr><td>fo<br>{}<br></td></tr></tbody></table>ar", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<table><tr><td>fo[o<td>b]ar<td>baz</table>", + [["insertlinebreak",""]], + "<table><tbody><tr><td>fo<br>{}<br></td><td>ar</td><td>baz</td></tr></tbody></table>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["{<table><tr><td>foo</table>}", + [["insertlinebreak",""]], + "<br>{}<br>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<table><tr><td>[foo]</table>", + [["insertlinebreak",""]], + "<table><tbody><tr><td><br>{}<br></td></tr></tbody></table>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<ol><li>[foo]<li>bar</ol>", + [["insertlinebreak",""]], + "<ol><li><br>{}<br></li><li>bar</li></ol>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<ol><li>f[o]o<li>bar</ol>", + [["insertlinebreak",""]], + "<ol><li>f<br>{}o</li><li>bar</li></ol>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["[]foo", + [["insertlinebreak",""]], + "<br>{}foo", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["foo[]", + [["insertlinebreak",""]], + "foo<br>{}<br>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<span>foo[]</span>", + [["insertlinebreak",""]], + "<span>foo<br>{}<br></span>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["foo[]<br>", + [["insertlinebreak",""]], + "foo<br>{}<br>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["foo[]bar", + [["insertlinebreak",""]], + "foo<br>{}bar", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<address>[]foo</address>", + [["insertlinebreak",""]], + "<address><br>{}foo</address>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<address>foo[]</address>", + [["insertlinebreak",""]], + "<address>foo<br>{}<br></address>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<address>foo[]<br></address>", + [["insertlinebreak",""]], + "<address>foo<br>{}<br></address>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<address>foo[]bar</address>", + [["insertlinebreak",""]], + "<address>foo<br>{}bar</address>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<div>[]foo</div>", + [["insertlinebreak",""]], + "<div><br>{}foo</div>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<div>foo[]</div>", + [["insertlinebreak",""]], + "<div>foo<br>{}<br></div>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<div>foo[]<br></div>", + [["insertlinebreak",""]], + "<div>foo<br>{}<br></div>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<div>foo[]bar</div>", + [["insertlinebreak",""]], + "<div>foo<br>{}bar</div>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<dl><dt>[]foo<dd>bar</dl>", + [["insertlinebreak",""]], + "<dl><dt><br>{}foo</dt><dd>bar</dd></dl>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<dl><dt>foo[]<dd>bar</dl>", + [["insertlinebreak",""]], + "<dl><dt>foo<br>{}<br></dt><dd>bar</dd></dl>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<dl><dt>foo[]<br><dd>bar</dl>", + [["insertlinebreak",""]], + "<dl><dt>foo<br>{}<br></dt><dd>bar</dd></dl>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<dl><dt>foo[]bar<dd>baz</dl>", + [["insertlinebreak",""]], + "<dl><dt>foo<br>{}bar</dt><dd>baz</dd></dl>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<dl><dt>foo<dd>[]bar</dl>", + [["insertlinebreak",""]], + "<dl><dt>foo</dt><dd><br>{}bar</dd></dl>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<dl><dt>foo<dd>bar[]</dl>", + [["insertlinebreak",""]], + "<dl><dt>foo</dt><dd>bar<br>{}<br></dd></dl>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<dl><dt>foo<dd>bar[]<br></dl>", + [["insertlinebreak",""]], + "<dl><dt>foo</dt><dd>bar<br>{}<br></dd></dl>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<dl><dt>foo<dd>bar[]baz</dl>", + [["insertlinebreak",""]], + "<dl><dt>foo</dt><dd>bar<br>{}baz</dd></dl>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<h1>[]foo</h1>", + [["insertlinebreak",""]], + "<h1><br>{}foo</h1>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<h1>foo[]</h1>", + [["insertlinebreak",""]], + "<h1>foo<br>{}<br></h1>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<h1>foo[]<br></h1>", + [["insertlinebreak",""]], + "<h1>foo<br>{}<br></h1>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<h1>foo[]bar</h1>", + [["insertlinebreak",""]], + "<h1>foo<br>{}bar</h1>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<ol><li>[]foo</ol>", + [["insertlinebreak",""]], + "<ol><li><br>{}foo</li></ol>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<ol><li>foo[]</ol>", + [["insertlinebreak",""]], + "<ol><li>foo<br>{}<br></li></ol>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<ol><li>foo[]<br></ol>", + [["insertlinebreak",""]], + "<ol><li>foo<br>{}<br></li></ol>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<ol><li>foo[]bar</ol>", + [["insertlinebreak",""]], + "<ol><li>foo<br>{}bar</li></ol>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<p>[]foo</p>", + [["insertlinebreak",""]], + "<p><br>{}foo</p>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<p>foo[]</p>", + [["insertlinebreak",""]], + "<p>foo<br>{}<br></p>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<p>foo[]<br></p>", + [["insertlinebreak",""]], + "<p>foo<br>{}<br></p>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<p>foo[]bar</p>", + [["insertlinebreak",""]], + "<p>foo<br>{}bar</p>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<pre>[]foo</pre>", + [["insertlinebreak",""]], + "<pre><br>{}foo</pre>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<pre>foo[]</pre>", + [["insertlinebreak",""]], + "<pre>foo<br>{}<br></pre>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<pre>foo[]<br></pre>", + [["insertlinebreak",""]], + "<pre>foo<br>{}<br></pre>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<pre>foo[]bar</pre>", + [["insertlinebreak",""]], + "<pre>foo<br>{}bar</pre>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<pre>foo[]<br><br></pre>", + [["insertlinebreak",""]], + "<pre>foo<br>{}<br><br></pre>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<pre>foo<br>{}<br></pre>", + [["insertlinebreak",""]], + "<pre>foo<br><br>{}<br></pre>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<pre>foo []</pre>", + [["insertlinebreak",""]], + "<pre>foo\n<br>{}<br></pre>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<pre>foo[] </pre>", + [["insertlinebreak",""]], + "<pre>foo<br>{}\n</pre>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<pre>foo [] </pre>", + [["insertlinebreak",""]], + "<pre>foo\n<br>{}\n</pre>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<xmp>foo[]bar</xmp>", + [["insertlinebreak",""]], + "<xmp>foo[]bar</xmp>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<script>foo[]bar</script>baz", + [["insertlinebreak",""]], + "<script>foo[]bar</script>baz", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<listing>foo[]bar</listing>", + [["insertlinebreak",""]], + "<listing>foo<br>{}bar</listing>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<ol><li>{}<br></li></ol>", + [["insertlinebreak",""]], + "<ol><li><br>{}<br></li></ol>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["foo<ol><li>{}<br></li></ol>", + [["insertlinebreak",""]], + "foo<ol><li><br>{}<br></li></ol>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<ol><li>{}<br></li></ol>foo", + [["insertlinebreak",""]], + "<ol><li><br>{}<br></li></ol>foo", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<ol><li>foo<li>{}<br></ol>", + [["insertlinebreak",""]], + "<ol><li>foo</li><li><br>{}<br></li></ol>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<ol><li>{}<br><li>bar</ol>", + [["insertlinebreak",""]], + "<ol><li><br>{}<br></li><li>bar</li></ol>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<ol><li>foo</li><ul><li>{}<br></ul></ol>", + [["insertlinebreak",""]], + "<ol><li>foo</li><ul><li><br>{}<br></li></ul></ol>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<dl><dt>{}<br></dt></dl>", + [["insertlinebreak",""]], + "<dl><dt><br>{}<br></dt></dl>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<dl><dt>foo<dd>{}<br></dl>", + [["insertlinebreak",""]], + "<dl><dt>foo</dt><dd><br>{}<br></dd></dl>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<dl><dt>{}<br><dd>bar</dl>", + [["insertlinebreak",""]], + "<dl><dt><br>{}<br></dt><dd>bar</dd></dl>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<dl><dt>foo<dd>bar<dl><dt>{}<br><dd>baz</dl></dl>", + [["insertlinebreak",""]], + "<dl><dt>foo</dt><dd>bar<dl><dt><br>{}<br></dt><dd>baz</dd></dl></dd></dl>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<dl><dt>foo<dd>bar<dl><dt>baz<dd>{}<br></dl></dl>", + [["insertlinebreak",""]], + "<dl><dt>foo</dt><dd>bar<dl><dt>baz</dt><dd><br>{}<br></dd></dl></dd></dl>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<h1>foo[bar</h1><p>baz]quz</p>", + [["defaultparagraphseparator","div"],["insertlinebreak",""]], + "<h1>foo<br>{}quz</h1>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"div"],"insertlinebreak":[false,false,"",false,false,""]}], +["<h1>foo[bar</h1><p>baz]quz</p>", + [["defaultparagraphseparator","p"],["insertlinebreak",""]], + "<h1>foo<br>{}quz</h1>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertlinebreak":[false,false,"",false,false,""]}], +["<p>foo[bar</p><h1>baz]quz</h1>", + [["insertlinebreak",""]], + "<p>foo<br>{}quz</p>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<p>foo</p>{}<br>", + [["insertlinebreak",""]], + "<p>foo</p><br>{}<br>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["{}<br><p>foo</p>", + [["insertlinebreak",""]], + "<br>{}<br><p>foo</p>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<p>foo</p>{}<br><h1>bar</h1>", + [["insertlinebreak",""]], + "<p>foo</p><br>{}<br><h1>bar</h1>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<h1>foo</h1>{}<br><p>bar</p>", + [["insertlinebreak",""]], + "<h1>foo</h1><br>{}<br><p>bar</p>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<h1>foo</h1>{}<br><h2>bar</h2>", + [["insertlinebreak",""]], + "<h1>foo</h1><br>{}<br><h2>bar</h2>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<p>foo</p><h1>[bar]</h1><p>baz</p>", + [["insertlinebreak",""]], + "<p>foo</p><h1><br>{}<br></h1><p>baz</p>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<p>foo</p>{<h1>bar</h1>}<p>baz</p>", + [["insertlinebreak",""]], + "<p>foo</p><br>{}<br><p>baz</p>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<table><tr><td>foo[]bar</table>", + [["insertlinebreak",""]], + "<table><tbody><tr><td>foo<br>{}bar</td></tr></tbody></table>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<table><tr><td><p>foo[]bar</table>", + [["insertlinebreak",""]], + "<table><tbody><tr><td><p>foo<br>{}bar</p></td></tr></tbody></table>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<blockquote>[]foo</blockquote>", + [["insertlinebreak",""]], + "<blockquote><br>{}foo</blockquote>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<blockquote>foo[]</blockquote>", + [["insertlinebreak",""]], + "<blockquote>foo<br>{}<br></blockquote>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<blockquote>foo[]<br></blockquote>", + [["insertlinebreak",""]], + "<blockquote>foo<br>{}<br></blockquote>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<blockquote>foo[]bar</blockquote>", + [["insertlinebreak",""]], + "<blockquote>foo<br>{}bar</blockquote>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<blockquote><p>[]foo</blockquote>", + [["insertlinebreak",""]], + "<blockquote><p><br>{}foo</p></blockquote>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<blockquote><p>foo[]</blockquote>", + [["insertlinebreak",""]], + "<blockquote><p>foo<br>{}<br></p></blockquote>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<blockquote><p>foo[]bar</blockquote>", + [["insertlinebreak",""]], + "<blockquote><p>foo<br>{}bar</p></blockquote>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<blockquote><p>foo[]<p>bar</blockquote>", + [["insertlinebreak",""]], + "<blockquote><p>foo<br>{}<br></p><p>bar</p></blockquote>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<blockquote><p>foo[]bar<p>baz</blockquote>", + [["insertlinebreak",""]], + "<blockquote><p>foo<br>{}bar</p><p>baz</p></blockquote>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<span>foo[]bar</span>", + [["insertlinebreak",""]], + "<span>foo<br>{}bar</span>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<span>foo[]bar</span>baz", + [["insertlinebreak",""]], + "<span>foo<br>{}bar</span>baz", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<b>foo[]bar</b>", + [["insertlinebreak",""]], + "<b>foo<br>{}bar</b>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<b>foo[]bar</b>baz", + [["insertlinebreak",""]], + "<b>foo<br>{}bar</b>baz", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<b>foo[]</b>bar", + [["insertlinebreak",""]], + "<b>foo<br>{}</b>bar", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["foo<b>[]bar</b>", + [["insertlinebreak",""]], + "foo<b><br>{}bar</b>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<b>foo[]</b><i>bar</i>", + [["insertlinebreak",""]], + "<b>foo<br>{}</b><i>bar</i>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<b>foo</b>{}<i>bar</i>", + [["insertlinebreak",""]], + "<b>foo</b><br>{}<i>bar</i>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<b id=x class=y>foo[]bar</b>", + [["insertlinebreak",""]], + "<b id=\"x\" class=\"y\">foo<br>{}bar</b>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<i><b>foo[]bar</b>baz</i>", + [["insertlinebreak",""]], + "<i><b>foo<br>{}bar</b>baz</i>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<p><b>foo[]bar</b></p>", + [["insertlinebreak",""]], + "<p><b>foo<br>{}bar</b></p>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<p><b>[]foo</b></p>", + [["insertlinebreak",""]], + "<p><b><br>{}foo</b></p>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<p><b id=x class=y>foo[]bar</b></p>", + [["insertlinebreak",""]], + "<p><b id=\"x\" class=\"y\">foo<br>{}bar</b></p>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<div><b>foo[]bar</b></div>", + [["insertlinebreak",""]], + "<div><b>foo<br>{}bar</b></div>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<a href=foo>foo[]bar</a>", + [["insertlinebreak",""]], + "<a href=\"foo\">foo<br>{}bar</a>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<a href=foo>foo[]bar</a>baz", + [["insertlinebreak",""]], + "<a href=\"foo\">foo<br>{}bar</a>baz", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<a href=foo>foo[]</a>bar", + [["insertlinebreak",""]], + "<a href=\"foo\">foo<br>{}</a>bar", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["foo<a href=foo>[]bar</a>", + [["insertlinebreak",""]], + "foo<a href=\"foo\"><br>{}bar</a>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<p>foo[]<!--bar-->", + [["insertlinebreak",""]], + "<p>foo<br>{}<br><!--bar--></p>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<p><!--foo-->[]bar", + [["insertlinebreak",""]], + "<p><!--foo--><br>{}bar</p>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>[bar]</span>baz", + [["insertlinebreak",""]], + "<p>foo<span style=\"color:rgb(171, 205, 239)\"><br>{}</span>baz</p>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>{bar}</span>baz", + [["insertlinebreak",""]], + "<p>foo<span style=\"color:rgb(171, 205, 239)\"><br>{}</span>baz</p>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<p>foo{<span style=color:#aBcDeF>bar</span>}baz", + [["insertlinebreak",""]], + "<p>foo<span style=\"color:rgb(171, 205, 239)\"><br>{}</span>baz</p>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<p>[foo<span style=color:#aBcDeF>bar]</span>baz", + [["stylewithcss","true"],["insertlinebreak",""]], + "<p><br>{}baz</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"insertlinebreak":[false,false,"",false,false,""]}], +["<p>[foo<span style=color:#aBcDeF>bar]</span>baz", + [["stylewithcss","false"],["insertlinebreak",""]], + "<p><br>{}baz</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"insertlinebreak":[false,false,"",false,false,""]}], +["<p>{foo<span style=color:#aBcDeF>bar}</span>baz", + [["stylewithcss","true"],["insertlinebreak",""]], + "<p><br>{}baz</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"insertlinebreak":[false,false,"",false,false,""]}], +["<p>{foo<span style=color:#aBcDeF>bar}</span>baz", + [["stylewithcss","false"],["insertlinebreak",""]], + "<p><br>{}baz</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"insertlinebreak":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>[bar</span>baz]", + [["insertlinebreak",""]], + "<p>foo<span style=\"color:rgb(171, 205, 239)\"><br>{}<br></span></p>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>{bar</span>baz}", + [["insertlinebreak",""]], + "<p>foo<span style=\"color:rgb(171, 205, 239)\"><br>{}<br></span></p>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>[bar</span><span style=color:#fEdCbA>baz]</span>quz", + [["stylewithcss","true"],["insertlinebreak",""]], + "<p>foo<span style=\"color:rgb(171, 205, 239)\"><br>{}</span>quz</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"insertlinebreak":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>[bar</span><span style=color:#fEdCbA>baz]</span>quz", + [["stylewithcss","false"],["insertlinebreak",""]], + "<p>foo<span style=\"color:rgb(171, 205, 239)\"><br>{}</span>quz</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"insertlinebreak":[false,false,"",false,false,""]}], +["<ul contenteditable><li>{}<br></ul>", + [["insertlinebreak",""]], + "<ul contenteditable=\"\"><li><br>{}<br></li></ul>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<ul contenteditable><li>foo[]</ul>", + [["insertlinebreak",""]], + "<ul contenteditable=\"\"><li>foo<br>{}<br></li></ul>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<div contenteditable=false><ul contenteditable><li>{}<br></ul></div>", + [["insertlinebreak",""]], + "<div contenteditable=\"false\"><ul contenteditable=\"\"><li><br>{}<br></li></ul></div>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<div contenteditable=false><ul contenteditable><li>foo[]</ul></div>", + [["insertlinebreak",""]], + "<div contenteditable=\"false\"><ul contenteditable=\"\"><li>foo<br>{}<br></li></ul></div>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<address><p>foo[]</address>", + [["insertlinebreak",""]], + "<address><p>foo<br>{}<br></p></address>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<dl><dt><p>foo[]</dl>", + [["insertlinebreak",""]], + "<dl><dt><p>foo<br>{}<br></p></dt></dl>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<dl><dd><p>foo[]</dl>", + [["insertlinebreak",""]], + "<dl><dd><p>foo<br>{}<br></p></dd></dl>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<ol><li><p>foo[]</ol>", + [["insertlinebreak",""]], + "<ol><li><p>foo<br>{}<br></p></li></ol>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<ul><li><p>foo[]</ul>", + [["insertlinebreak",""]], + "<ul><li><p>foo<br>{}<br></p></li></ul>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<address><div>foo[]</address>", + [["insertlinebreak",""]], + "<address><div>foo<br>{}<br></div></address>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<dl><dt><div>foo[]</dl>", + [["insertlinebreak",""]], + "<dl><dt><div>foo<br>{}<br></div></dt></dl>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<dl><dd><div>foo[]</dl>", + [["insertlinebreak",""]], + "<dl><dd><div>foo<br>{}<br></div></dd></dl>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<ol><li><div>foo[]</ol>", + [["insertlinebreak",""]], + "<ol><li><div>foo<br>{}<br></div></li></ol>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<ul><li><div>foo[]</ul>", + [["insertlinebreak",""]], + "<ul><li><div>foo<br>{}<br></div></li></ul>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<div><p>foo[]</div>", + [["insertlinebreak",""]], + "<div><p>foo<br>{}<br></p></div>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<div><div>foo[]</div>", + [["insertlinebreak",""]], + "<div><div>foo<br>{}<br></div></div>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<address><p>[]foo</address>", + [["insertlinebreak",""]], + "<address><p><br>{}foo</p></address>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<dl><dt><p>[]foo</dl>", + [["insertlinebreak",""]], + "<dl><dt><p><br>{}foo</p></dt></dl>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<dl><dd><p>[]foo</dl>", + [["insertlinebreak",""]], + "<dl><dd><p><br>{}foo</p></dd></dl>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<ol><li><p>[]foo</ol>", + [["insertlinebreak",""]], + "<ol><li><p><br>{}foo</p></li></ol>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<ul><li><p>[]foo</ul>", + [["insertlinebreak",""]], + "<ul><li><p><br>{}foo</p></li></ul>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<address><div>[]foo</address>", + [["insertlinebreak",""]], + "<address><div><br>{}foo</div></address>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<dl><dt><div>[]foo</dl>", + [["insertlinebreak",""]], + "<dl><dt><div><br>{}foo</div></dt></dl>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<dl><dd><div>[]foo</dl>", + [["insertlinebreak",""]], + "<dl><dd><div><br>{}foo</div></dd></dl>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<ol><li><div>[]foo</ol>", + [["insertlinebreak",""]], + "<ol><li><div><br>{}foo</div></li></ol>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<ul><li><div>[]foo</ul>", + [["insertlinebreak",""]], + "<ul><li><div><br>{}foo</div></li></ul>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<div><p>[]foo</div>", + [["insertlinebreak",""]], + "<div><p><br>{}foo</p></div>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<div><div>[]foo</div>", + [["insertlinebreak",""]], + "<div><div><br>{}foo</div></div>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<address><p>foo[]bar</address>", + [["insertlinebreak",""]], + "<address><p>foo<br>{}bar</p></address>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<dl><dt><p>foo[]bar</dl>", + [["insertlinebreak",""]], + "<dl><dt><p>foo<br>{}bar</p></dt></dl>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<dl><dd><p>foo[]bar</dl>", + [["insertlinebreak",""]], + "<dl><dd><p>foo<br>{}bar</p></dd></dl>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<ol><li><p>foo[]bar</ol>", + [["insertlinebreak",""]], + "<ol><li><p>foo<br>{}bar</p></li></ol>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<ul><li><p>foo[]bar</ul>", + [["insertlinebreak",""]], + "<ul><li><p>foo<br>{}bar</p></li></ul>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<address><div>foo[]bar</address>", + [["insertlinebreak",""]], + "<address><div>foo<br>{}bar</div></address>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<dl><dt><div>foo[]bar</dl>", + [["insertlinebreak",""]], + "<dl><dt><div>foo<br>{}bar</div></dt></dl>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<dl><dd><div>foo[]bar</dl>", + [["insertlinebreak",""]], + "<dl><dd><div>foo<br>{}bar</div></dd></dl>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<ol><li><div>foo[]bar</ol>", + [["insertlinebreak",""]], + "<ol><li><div>foo<br>{}bar</div></li></ol>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<ul><li><div>foo[]bar</ul>", + [["insertlinebreak",""]], + "<ul><li><div>foo<br>{}bar</div></li></ul>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<div><p>foo[]bar</div>", + [["insertlinebreak",""]], + "<div><p>foo<br>{}bar</p></div>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<div><div>foo[]bar</div>", + [["insertlinebreak",""]], + "<div><div>foo<br>{}bar</div></div>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<ol><li class=a id=x><p class=b id=y>foo[]</ol>", + [["insertlinebreak",""]], + "<ol><li class=\"a\" id=\"x\"><p class=\"b\" id=\"y\">foo<br>{}<br></p></li></ol>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<div class=a id=x><div class=b id=y>foo[]</div></div>", + [["insertlinebreak",""]], + "<div class=\"a\" id=\"x\"><div class=\"b\" id=\"y\">foo<br>{}<br></div></div>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<div class=a id=x><p class=b id=y>foo[]</div>", + [["insertlinebreak",""]], + "<div class=\"a\" id=\"x\"><p class=\"b\" id=\"y\">foo<br>{}<br></p></div>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<ol><li class=a id=x><p class=b id=y>[]foo</ol>", + [["insertlinebreak",""]], + "<ol><li class=\"a\" id=\"x\"><p class=\"b\" id=\"y\"><br>{}foo</p></li></ol>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<div class=a id=x><div class=b id=y>[]foo</div></div>", + [["insertlinebreak",""]], + "<div class=\"a\" id=\"x\"><div class=\"b\" id=\"y\"><br>{}foo</div></div>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<div class=a id=x><p class=b id=y>[]foo</div>", + [["insertlinebreak",""]], + "<div class=\"a\" id=\"x\"><p class=\"b\" id=\"y\"><br>{}foo</p></div>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<ol><li class=a id=x><p class=b id=y>foo[]bar</ol>", + [["insertlinebreak",""]], + "<ol><li class=\"a\" id=\"x\"><p class=\"b\" id=\"y\">foo<br>{}bar</p></li></ol>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<div class=a id=x><div class=b id=y>foo[]bar</div></div>", + [["insertlinebreak",""]], + "<div class=\"a\" id=\"x\"><div class=\"b\" id=\"y\">foo<br>{}bar</div></div>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<div class=a id=x><p class=b id=y>foo[]bar</div>", + [["insertlinebreak",""]], + "<div class=\"a\" id=\"x\"><p class=\"b\" id=\"y\">foo<br>{}bar</p></div>", + [true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<div>abc [] </div>", + [["insertlinebreak",""]], + "<div>abc<br><br></div>", + [true,true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<div>abc[] </div>", + [["insertlinebreak",""]], + "<div>abc<br><br></div>", + [true,true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<div>[] abc</div>", + [["insertlinebreak",""]], + ["<div><br>abc</div>", + "<div><br> abc</div>"], + [true,true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<div>[] abc</div>", + [["insertlinebreak",""]], + ["<div><br>abc</div>", + "<div><br> abc</div>"], + [true,true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<div> [] abc</div>", + [["insertlinebreak",""]], + ["<div><br>abc</div>", + "<div><br> abc</div>", + "<div><br> abc</div>"], + [true,true], + {"insertlinebreak":[false,false,"",false,false,""]}], +["<div> []abc</div>", + [["insertlinebreak",""]], + ["<div><br>abc</div>", + "<div><br> abc</div>"], + [true,true], + {"insertlinebreak":[false,false,"",false,false,""]}], +] diff --git a/testing/web-platform/tests/editing/data/insertorderedlist.js b/testing/web-platform/tests/editing/data/insertorderedlist.js new file mode 100644 index 0000000000..71aacdd9c2 --- /dev/null +++ b/testing/web-platform/tests/editing/data/insertorderedlist.js @@ -0,0 +1,767 @@ +// For documentation of the format, see README in this directory. +var browserTests = [ +["foo[]bar", + [["insertorderedlist",""]], + "<ol><li>foo[]bar</li></ol>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["foo[bar]baz", + [["insertorderedlist",""]], + "<ol><li>foo[bar]baz</li></ol>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["foo<br>[bar]", + [["insertorderedlist",""]], + "foo<ol><li>[bar]</li></ol>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["f[oo<br>b]ar<br>baz", + [["insertorderedlist",""]], + "<ol><li>f[oo</li><li>b]ar</li></ol>baz", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["<p>[foo]<br>bar</p>", + [["insertorderedlist",""]], + "<ol><li>[foo]</li></ol><p>bar</p>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["[foo<ol><li>bar]</ol>baz", + [["insertorderedlist",""]], + "<ol><li>[foo</li><li>bar]</li></ol>baz", + [true], + {"insertorderedlist":[true,false,"",false,true,""]}], +["foo<ol><li>[bar</ol>baz]", + [["insertorderedlist",""]], + "foo<ol><li>[bar</li><li>baz]</li></ol>", + [true], + {"insertorderedlist":[true,false,"",false,true,""]}], +["[foo<ul><li>bar]</ul>baz", + [["insertorderedlist",""]], + "<ol><li>[foo</li><li>bar]</li></ol>baz", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["foo<ul><li>[bar</ul>baz]", + [["insertorderedlist",""]], + "foo<ol><li>[bar</li><li>baz]</li></ol>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["foo<ul><li>[bar</ul><ol><li>baz]</ol>quz", + [["insertorderedlist",""]], + "foo<ol><li>[bar</li><li>baz]</li></ol>quz", + [true], + {"insertorderedlist":[true,false,"",false,true,""]}], +["foo<ol><li>[bar</ol><ul><li>baz]</ul>quz", + [["insertorderedlist",""]], + "foo<ol><li>[bar</li><li>baz]</li></ol>quz", + [true], + {"insertorderedlist":[true,false,"",false,true,""]}], +["<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>", + [["insertorderedlist",""]], + "<table><tbody><tr><td>foo</td><td><ol><li>b[a]r</li></ol></td><td>baz</td></tr></tbody></table>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["<table><tbody><tr><td>fo[o<td>b]ar<td>baz</table>", + [["insertorderedlist",""]], + "<table><tbody><tr><td><ol><li>fo[o</li></ol></td><td><ol><li>b]ar</li></ol></td><td>baz</td></tr></tbody></table>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["{<table><tr><td>foo<td>bar<td>baz</table>}", + [["insertorderedlist",""]], + "<ol><li>{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</li></ol>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["<p>foo<p>[bar]<p>baz", + [["defaultparagraphseparator","div"],["insertorderedlist",""]], + "<p>foo</p><ol><li>[bar]</li></ol><p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"div"],"insertorderedlist":[false,false,"",false,true,""]}], +["<p>foo<p>[bar]<p>baz", + [["defaultparagraphseparator","p"],["insertorderedlist",""]], + "<p>foo</p><ol><li>[bar]</li></ol><p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertorderedlist":[false,false,"",false,true,""]}], +["<p>foo<blockquote>[bar]</blockquote><p>baz", + [["insertorderedlist",""]], + "<p>foo</p><blockquote><ol><li>[bar]</li></ol></blockquote><p>baz</p>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["<dl><dt>foo<dd>[bar]<dt>baz<dd>quz</dl>", + [["insertorderedlist",""]], + "<dl><dt>foo</dt><dd><ol><li>[bar]</li></ol></dd><dt>baz</dt><dd>quz</dd></dl>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["<dl><dt>foo<dd>bar<dt>[baz]<dd>quz</dl>", + [["insertorderedlist",""]], + "<dl><dt>foo</dt><dd>bar</dd><dt><ol><li>[baz]</li></ol></dt><dd>quz</dd></dl>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["<p>[foo<p>bar]<p>baz", + [["defaultparagraphseparator","div"],["insertorderedlist",""]], + "<ol><li>[foo</li><li>bar]</li></ol><p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertorderedlist":[false,false,"",false,true,""]}], +["<p>[foo<p>bar]<p>baz", + [["defaultparagraphseparator","p"],["insertorderedlist",""]], + "<ol><li>[foo</li><li>bar]</li></ol><p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertorderedlist":[false,false,"",false,true,""]}], +["<p>[foo<blockquote>bar]</blockquote><p>baz", + [["defaultparagraphseparator","div"],["insertorderedlist",""]], + "<ol><li>[foo</li><ol><li>bar]</li></ol></ol><p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertorderedlist":[false,false,"",false,true,""]}], +["<p>[foo<blockquote>bar]</blockquote><p>baz", + [["defaultparagraphseparator","p"],["insertorderedlist",""]], + "<ol><li>[foo</li><ol><li>bar]</li></ol></ol><p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertorderedlist":[false,false,"",false,true,""]}], +["<dl><dt>[foo<dd>bar]<dt>baz<dd>quz</dl>", + [["insertorderedlist",""]], + "<dl><dt><ol><li>[foo</li></ol></dt><dd><ol><li>bar]</li></ol></dd><dt>baz</dt><dd>quz</dd></dl>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["<dl><dt>foo<dd>[bar<dt>baz]<dd>quz</dl>", + [["insertorderedlist",""]], + "<dl><dt>foo</dt><dd><ol><li>[bar</li></ol></dd><dt><ol><li>baz]</li></ol></dt><dd>quz</dd></dl>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["<p>[foo<blockquote><p>bar]<p>baz</blockquote>", + [["defaultparagraphseparator","div"],["insertorderedlist",""]], + "<ol><li>[foo</li><ol><li>bar]</li></ol></ol><blockquote><p>baz</p></blockquote>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertorderedlist":[false,false,"",false,true,""]}], +["<p>[foo<blockquote><p>bar]<p>baz</blockquote>", + [["defaultparagraphseparator","p"],["insertorderedlist",""]], + "<ol><li>[foo</li><ol><li>bar]</li></ol></ol><blockquote><p>baz</p></blockquote>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertorderedlist":[false,false,"",false,true,""]}], +["<ol><li>foo<li>[bar]<li>baz</ol>", + [["defaultparagraphseparator","div"],["insertorderedlist",""]], + "<ol><li>foo</li></ol><div>[bar]</div><ol><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertorderedlist":[false,true,"",false,false,""]}], +["<ol><li>foo<li>[bar]<li>baz</ol>", + [["defaultparagraphseparator","p"],["insertorderedlist",""]], + "<ol><li>foo</li></ol><p>[bar]</p><ol><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertorderedlist":[false,true,"",false,false,""]}], +["<ol><li>foo</ol>[bar]", + [["insertorderedlist",""]], + "<ol><li>foo</li><li>[bar]</li></ol>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["[foo]<ol><li>bar</ol>", + [["insertorderedlist",""]], + "<ol><li>[foo]</li><li>bar</li></ol>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["<ol><li>foo</ol>[bar]<ol><li>baz</ol>", + [["insertorderedlist",""]], + "<ol><li>foo</li><li>[bar]</li><li>baz</li></ol>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["<ol><ol><li>[foo]</ol></ol>", + [["insertorderedlist",""]], + "<ol><li>[foo]</li></ol>", + [true], + {"insertorderedlist":[false,true,"",false,true,""]}], +["<ol><li>[foo]<br>bar<li>baz</ol>", + [["defaultparagraphseparator","div"],["insertorderedlist",""]], + "<div>[foo]<br>bar</div><ol><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertorderedlist":[false,true,"",false,false,""]}], +["<ol><li>[foo]<br>bar<li>baz</ol>", + [["defaultparagraphseparator","p"],["insertorderedlist",""]], + "<p>[foo]<br>bar</p><ol><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertorderedlist":[false,true,"",false,false,""]}], +["<ol><li>foo<br>[bar]<li>baz</ol>", + [["defaultparagraphseparator","div"],["insertorderedlist",""]], + "<div>foo<br>[bar]</div><ol><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertorderedlist":[false,true,"",false,false,""]}], +["<ol><li>foo<br>[bar]<li>baz</ol>", + [["defaultparagraphseparator","p"],["insertorderedlist",""]], + "<p>foo<br>[bar]</p><ol><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertorderedlist":[false,true,"",false,false,""]}], +["<ol><li><div>[foo]</div>bar<li>baz</ol>", + [["defaultparagraphseparator","div"],["insertorderedlist",""]], + "<div>[foo]</div><div>bar</div><ol><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertorderedlist":[false,true,"",false,false,""]}], +["<ol><li><div>[foo]</div>bar<li>baz</ol>", + [["defaultparagraphseparator","p"],["insertorderedlist",""]], + "<div>[foo]</div><p>bar</p><ol><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertorderedlist":[false,true,"",false,false,""]}], +["<ol><li>foo<ol><li>[bar]<li>baz</ol><li>quz</ol>", + [["insertorderedlist",""]], + "<ol><li>foo</li><li>[bar]</li><ol><li>baz</li></ol><li>quz</li></ol>", + [true], + {"insertorderedlist":[false,true,"",false,true,""]}], +["<ol><li>foo<ol><li>bar<li>[baz]</ol><li>quz</ol>", + [["insertorderedlist",""]], + "<ol><li>foo</li><ol><li>bar</li></ol><li>[baz]</li><li>quz</li></ol>", + [true], + {"insertorderedlist":[false,true,"",false,true,""]}], +["<ol><li>foo</li><ol><li>[bar]<li>baz</ol><li>quz</ol>", + [["insertorderedlist",""]], + "<ol><li>foo</li><li>[bar]</li><ol><li>baz</li></ol><li>quz</li></ol>", + [true], + {"insertorderedlist":[false,true,"",false,true,""]}], +["<ol><li>foo</li><ol><li>bar<li>[baz]</ol><li>quz</ol>", + [["insertorderedlist",""]], + "<ol><li>foo</li><ol><li>bar</li></ol><li>[baz]</li><li>quz</li></ol>", + [true], + {"insertorderedlist":[false,true,"",false,true,""]}], +["<ol><li>[foo]<ol><li>bar</ol><li>baz</ol>", + [["defaultparagraphseparator","div"],["insertorderedlist",""]], + "<div>[foo]</div><ol><ol><li>bar</li></ol><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertorderedlist":[false,true,"",false,false,""]}], +["<ol><li>[foo]<ol><li>bar</ol><li>baz</ol>", + [["defaultparagraphseparator","p"],["insertorderedlist",""]], + "<p>[foo]</p><ol><ol><li>bar</li></ol><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertorderedlist":[false,true,"",false,false,""]}], +["<ol><li>[foo]</li><ol><li>bar</ol><li>baz</ol>", + [["defaultparagraphseparator","div"],["insertorderedlist",""]], + "<div>[foo]</div><ol><ol><li>bar</li></ol><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertorderedlist":[false,true,"",false,false,""]}], +["<ol><li>[foo]</li><ol><li>bar</ol><li>baz</ol>", + [["defaultparagraphseparator","p"],["insertorderedlist",""]], + "<p>[foo]</p><ol><ol><li>bar</li></ol><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertorderedlist":[false,true,"",false,false,""]}], +["<ol><li>foo<li>[bar]<ol><li>baz</ol><li>quz</ol>", + [["defaultparagraphseparator","div"],["insertorderedlist",""]], + "<ol><li>foo</li></ol><div>[bar]</div><ol><ol><li>baz</li></ol><li>quz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertorderedlist":[false,true,"",false,false,""]}], +["<ol><li>foo<li>[bar]<ol><li>baz</ol><li>quz</ol>", + [["defaultparagraphseparator","p"],["insertorderedlist",""]], + "<ol><li>foo</li></ol><p>[bar]</p><ol><ol><li>baz</li></ol><li>quz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertorderedlist":[false,true,"",false,false,""]}], +["<ol><li>foo<li>[bar]</li><ol><li>baz</ol><li>quz</ol>", + [["defaultparagraphseparator","div"],["insertorderedlist",""]], + "<ol><li>foo</li></ol><div>[bar]</div><ol><ol><li>baz</li></ol><li>quz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertorderedlist":[false,true,"",false,false,""]}], +["<ol><li>foo<li>[bar]</li><ol><li>baz</ol><li>quz</ol>", + [["defaultparagraphseparator","p"],["insertorderedlist",""]], + "<ol><li>foo</li></ol><p>[bar]</p><ol><ol><li>baz</li></ol><li>quz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertorderedlist":[false,true,"",false,false,""]}], +["<ol><li>foo<ol><li>bar<li>baz</ol><li>[quz]</ol>", + [["defaultparagraphseparator","div"],["insertorderedlist",""]], + "<ol><li>foo<ol><li>bar</li><li>baz</li></ol></li></ol><div>[quz]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertorderedlist":[false,true,"",false,false,""]}], +["<ol><li>foo<ol><li>bar<li>baz</ol><li>[quz]</ol>", + [["defaultparagraphseparator","p"],["insertorderedlist",""]], + "<ol><li>foo<ol><li>bar</li><li>baz</li></ol></li></ol><p>[quz]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertorderedlist":[false,true,"",false,false,""]}], +["<ol><li>foo</li><ol><li>bar<li>baz</ol><li>[quz]</ol>", + [["defaultparagraphseparator","div"],["insertorderedlist",""]], + "<ol><li>foo</li><ol><li>bar</li><li>baz</li></ol></ol><div>[quz]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertorderedlist":[false,true,"",false,false,""]}], +["<ol><li>foo</li><ol><li>bar<li>baz</ol><li>[quz]</ol>", + [["defaultparagraphseparator","p"],["insertorderedlist",""]], + "<ol><li>foo</li><ol><li>bar</li><li>baz</li></ol></ol><p>[quz]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertorderedlist":[false,true,"",false,false,""]}], +["<ol><li>foo<li>[bar<li>baz]</ol>", + [["defaultparagraphseparator","div"],["insertorderedlist",""]], + "<ol><li>foo</li></ol><div>[bar</div><div>baz]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertorderedlist":[false,true,"",false,false,""]}], +["<ol><li>foo<li>[bar<li>baz]</ol>", + [["defaultparagraphseparator","p"],["insertorderedlist",""]], + "<ol><li>foo</li></ol><p>[bar</p><p>baz]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertorderedlist":[false,true,"",false,false,""]}], +["<ol><li>[foo<ol><li>bar]</ol><li>baz</ol>", + [["defaultparagraphseparator","div"],["insertorderedlist",""]], + "<div>[foo</div><ol><li>bar]</li><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertorderedlist":[false,true,"",true,false,""]}], +["<ol><li>[foo<ol><li>bar]</ol><li>baz</ol>", + [["defaultparagraphseparator","p"],["insertorderedlist",""]], + "<p>[foo</p><ol><li>bar]</li><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertorderedlist":[false,true,"",true,false,""]}], +["<ol><li>foo<ol><li>b[ar</ol><li>b]az</ol>", + [["defaultparagraphseparator","div"],["insertorderedlist",""]], + "<ol><li>foo</li><li>b[ar</li></ol><div>b]az</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertorderedlist":[false,true,"",true,false,""]}], +["<ol><li>foo<ol><li>b[ar</ol><li>b]az</ol>", + [["defaultparagraphseparator","p"],["insertorderedlist",""]], + "<ol><li>foo</li><li>b[ar</li></ol><p>b]az</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertorderedlist":[false,true,"",true,false,""]}], +["<ol><li>[foo<ol><li>bar</ol><li>baz]</ol><p>extra", + [["defaultparagraphseparator","div"],["insertorderedlist",""]], + "<div>[foo</div><ol><li>bar</li></ol><div>baz]</div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertorderedlist":[false,true,"",true,false,""]}], +["<ol><li>[foo<ol><li>bar</ol><li>baz]</ol><p>extra", + [["defaultparagraphseparator","p"],["insertorderedlist",""]], + "<p>[foo</p><ol><li>bar</li></ol><p>baz]</p><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertorderedlist":[false,true,"",true,false,""]}], +["<ol><li>[foo]<ol><li>bar</ol>baz</ol>", + [["defaultparagraphseparator","div"],["insertorderedlist",""]], + "<div>[foo]</div><ol><ol><li>bar</li></ol><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertorderedlist":[false,true,"",false,false,""]}], +["<ol><li>[foo]<ol><li>bar</ol>baz</ol>", + [["defaultparagraphseparator","p"],["insertorderedlist",""]], + "<p>[foo]</p><ol><ol><li>bar</li></ol><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertorderedlist":[false,true,"",false,false,""]}], +["<ol><li>foo<ol><li>[bar]</ol>baz</ol>", + [["insertorderedlist",""]], + "<ol><li>foo</li><li>[bar]</li><li>baz</li></ol>", + [true], + {"insertorderedlist":[false,true,"",false,true,""]}], +["<ol><li>foo<ol><li>bar</ol>[baz]</ol>", + [["defaultparagraphseparator","div"],["insertorderedlist",""]], + "<ol><li>foo</li><ol><li>bar</li></ol></ol><div>[baz]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertorderedlist":[false,true,"",false,false,""]}], +["<ol><li>foo<ol><li>bar</ol>[baz]</ol>", + [["defaultparagraphseparator","p"],["insertorderedlist",""]], + "<ol><li>foo</li><ol><li>bar</li></ol></ol><p>[baz]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertorderedlist":[false,true,"",false,false,""]}], +["<ol><li>[foo<ol><li>bar]</ol>baz</ol>", + [["defaultparagraphseparator","div"],["insertorderedlist",""]], + "<div>[foo</div><ol><li>bar]</li><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertorderedlist":[false,true,"",true,false,""]}], +["<ol><li>[foo<ol><li>bar]</ol>baz</ol>", + [["defaultparagraphseparator","p"],["insertorderedlist",""]], + "<p>[foo</p><ol><li>bar]</li><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertorderedlist":[false,true,"",true,false,""]}], +["<ul><li>foo<li>[bar]<li>baz</ul>", + [["insertorderedlist",""]], + "<ul><li>foo</li></ul><ol><li>[bar]</li></ol><ul><li>baz</li></ul>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["<ul><li>foo</ul>[bar]", + [["insertorderedlist",""]], + "<ul><li>foo</li></ul><ol><li>[bar]</li></ol>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["[foo]<ul><li>bar</ul>", + [["insertorderedlist",""]], + "<ol><li>[foo]</li></ol><ul><li>bar</li></ul>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["<ul><li>foo</ul>[bar]<ul><li>baz</ul>", + [["insertorderedlist",""]], + "<ul><li>foo</li></ul><ol><li>[bar]</li></ol><ul><li>baz</li></ul>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["<ul><ul><li>[foo]</ul></ul>", + [["insertorderedlist",""]], + "<ol><ol><li>[foo]</li></ol></ol>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["<ul><li>[foo]<br>bar<li>baz</ul>", + [["insertorderedlist",""]], + "<ol><li>[foo]<br>bar</li></ol><ul><li>baz</li></ul>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["<ul><li>foo<br>[bar]<li>baz</ul>", + [["insertorderedlist",""]], + "<ol><li>foo<br>[bar]</li></ol><ul><li>baz</li></ul>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["<ul><li><div>[foo]</div>bar<li>baz</ul>", + [["insertorderedlist",""]], + "<ol><li><div>[foo]</div>bar</li></ol><ul><li>baz</li></ul>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["<ul><li>foo<ul><li>[bar]<li>baz</ul><li>quz</ul>", + [["insertorderedlist",""]], + "<ul><li>foo</li><ol><li>[bar]</li></ol><ul><li>baz</li></ul><li>quz</li></ul>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["<ul><li>foo<ul><li>bar<li>[baz]</ul><li>quz</ul>", + [["insertorderedlist",""]], + "<ul><li>foo</li><ul><li>bar</li></ul><ol><li>[baz]</li></ol><li>quz</li></ul>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["<ul><li>foo</li><ul><li>[bar]<li>baz</ul><li>quz</ul>", + [["insertorderedlist",""]], + "<ul><li>foo</li><ol><li>[bar]</li></ol><ul><li>baz</li></ul><li>quz</li></ul>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["<ul><li>foo</li><ul><li>bar<li>[baz]</ul><li>quz</ul>", + [["insertorderedlist",""]], + "<ul><li>foo</li><ul><li>bar</li></ul><ol><li>[baz]</li></ol><li>quz</li></ul>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["<ul><li>[foo]<ul><li>bar</ul><li>baz</ul>", + [["insertorderedlist",""]], + "<ol><li>[foo]</li></ol><ul><ul><li>bar</li></ul><li>baz</li></ul>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["<ul><li>[foo]</li><ul><li>bar</ul><li>baz</ul>", + [["insertorderedlist",""]], + "<ol><li>[foo]</li></ol><ul><ul><li>bar</li></ul><li>baz</li></ul>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["<ul><li>foo<li>[bar]<ul><li>baz</ul><li>quz</ul>", + [["insertorderedlist",""]], + "<ul><li>foo</li></ul><ol><li>[bar]</li></ol><ul><ul><li>baz</li></ul><li>quz</li></ul>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["<ul><li>foo<li>[bar]</li><ul><li>baz</ul><li>quz</ul>", + [["insertorderedlist",""]], + "<ul><li>foo</li></ul><ol><li>[bar]</li></ol><ul><ul><li>baz</li></ul><li>quz</li></ul>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["<ul><li>foo<ul><li>bar<li>baz</ul><li>[quz]</ul>", + [["insertorderedlist",""]], + "<ul><li>foo<ul><li>bar</li><li>baz</li></ul></li></ul><ol><li>[quz]</li></ol>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["<ul><li>foo</li><ul><li>bar<li>baz</ul><li>[quz]</ul>", + [["insertorderedlist",""]], + "<ul><li>foo</li><ul><li>bar</li><li>baz</li></ul></ul><ol><li>[quz]</li></ol>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["<ul><li>foo<li>[bar<li>baz]</ul>", + [["insertorderedlist",""]], + "<ul><li>foo</li></ul><ol><li>[bar</li><li>baz]</li></ol>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["<ul><li>[foo<ul><li>bar]</ul><li>baz</ul>", + [["insertorderedlist",""]], + "<ol><li>[foo</li><ol><li>bar]</li></ol></ol><ul><li>baz</li></ul>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["<ul><li>foo<ul><li>b[ar</ul><li>b]az</ul>", + [["insertorderedlist",""]], + "<ul><li>foo</li></ul><ol><ol><li>b[ar</li></ol><li>b]az</li></ol>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["<ul><li>[foo<ul><li>bar</ul><li>baz]</ul><p>extra", + [["insertorderedlist",""]], + "<ol><li>[foo</li><ol><li>bar</li></ol><li>baz]</li></ol><p>extra</p>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["<ul><li>[foo]<ul><li>bar</ul>baz</ul>", + [["insertorderedlist",""]], + "<ol><li>[foo]</li></ol><ul><ul><li>bar</li></ul><li>baz</li></ul>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["<ul><li>foo<ul><li>[bar]</ul>baz</ul>", + [["insertorderedlist",""]], + "<ul><li>foo</li><ol><li>[bar]</li></ol><li>baz</li></ul>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["<ul><li>foo<ul><li>bar</ul>[baz]</ul>", + [["insertorderedlist",""]], + "<ul><li>foo</li><ul><li>bar</li></ul></ul><ol><li>[baz]</li></ol>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["<ul><li>[foo<ul><li>bar]</ul>baz</ul>", + [["insertorderedlist",""]], + "<ol><li>[foo</li><ol><li>bar]</li></ol></ol><ul><li>baz</li></ul>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["foo<ol><li>bar</ol><ul><li>[baz]</ul>quz", + [["insertorderedlist",""]], + "foo<ol><li>bar</li><li>[baz]</li></ol>quz", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["foo<ol><li>bar</ol><ul><li>[baz</ul>quz]", + [["insertorderedlist",""]], + "foo<ol><li>bar</li><li>[baz</li><li>quz]</li></ol>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["foo<ul><li>[bar]</ul><ol><li>baz</ol>quz", + [["insertorderedlist",""]], + "foo<ol><li>[bar]</li><li>baz</li></ol>quz", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["[foo<ul><li>bar]</ul><ol><li>baz</ol>quz", + [["insertorderedlist",""]], + "<ol><li>[foo</li><li>bar]</li><li>baz</li></ol>quz", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["[foo]<blockquote>bar</blockquote>baz", + [["insertorderedlist",""]], + "<ol><li>[foo]</li></ol><blockquote>bar</blockquote>baz", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["foo<blockquote>[bar]</blockquote>baz", + [["insertorderedlist",""]], + "foo<blockquote><ol><li>[bar]</li></ol></blockquote>baz", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["[foo<blockquote>bar]</blockquote>baz", + [["insertorderedlist",""]], + "<ol><li>[foo</li><ol><li>bar]</li></ol></ol>baz", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["<ol><li>foo</ol><blockquote>[bar]</blockquote>baz", + [["insertorderedlist",""]], + "<ol><li>foo</li><ol><li>[bar]</li></ol></ol>baz", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["[foo]<blockquote><ol><li>bar</ol></blockquote>baz", + [["insertorderedlist",""]], + "<ol><li>[foo]</li></ol><blockquote><ol><li>bar</li></ol></blockquote>baz", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["foo<blockquote>[bar]<br>baz</blockquote>", + [["insertorderedlist",""]], + "foo<blockquote><ol><li>[bar]</li></ol>baz</blockquote>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["[foo<blockquote>bar]<br>baz</blockquote>", + [["insertorderedlist",""]], + "<ol><li>[foo</li><ol><li>bar]</li></ol></ol><blockquote>baz</blockquote>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["<ol><li>foo</ol><blockquote>[bar]<br>baz</blockquote>", + [["insertorderedlist",""]], + "<ol><li>foo</li><ol><li>[bar]</li></ol></ol><blockquote>baz</blockquote>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["<p>[foo]<blockquote><p>bar</blockquote><p>baz", + [["defaultparagraphseparator","div"],["insertorderedlist",""]], + "<ol><li>[foo]</li></ol><blockquote><p>bar</p></blockquote><p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertorderedlist":[false,false,"",false,true,""]}], +["<p>[foo]<blockquote><p>bar</blockquote><p>baz", + [["defaultparagraphseparator","p"],["insertorderedlist",""]], + "<ol><li>[foo]</li></ol><blockquote><p>bar</p></blockquote><p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertorderedlist":[false,false,"",false,true,""]}], +["<p>foo<blockquote><p>[bar]</blockquote><p>baz", + [["defaultparagraphseparator","div"],["insertorderedlist",""]], + "<p>foo</p><blockquote><ol><li>[bar]</li></ol></blockquote><p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertorderedlist":[false,false,"",false,true,""]}], +["<p>foo<blockquote><p>[bar]</blockquote><p>baz", + [["defaultparagraphseparator","p"],["insertorderedlist",""]], + "<p>foo</p><blockquote><ol><li>[bar]</li></ol></blockquote><p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertorderedlist":[false,false,"",false,true,""]}], +["<p>[foo<blockquote><p>bar]</blockquote><p>baz", + [["defaultparagraphseparator","div"],["insertorderedlist",""]], + "<ol><li>[foo</li><ol><li>bar]</li></ol></ol><p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertorderedlist":[false,false,"",false,true,""]}], +["<p>[foo<blockquote><p>bar]</blockquote><p>baz", + [["defaultparagraphseparator","p"],["insertorderedlist",""]], + "<ol><li>[foo</li><ol><li>bar]</li></ol></ol><p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertorderedlist":[false,false,"",false,true,""]}], +["<ol><li>foo</ol><blockquote><p>[bar]</blockquote><p>baz", + [["defaultparagraphseparator","div"],["insertorderedlist",""]], + "<ol><li>foo</li><ol><li>[bar]</li></ol></ol><p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertorderedlist":[false,false,"",false,true,""]}], +["<ol><li>foo</ol><blockquote><p>[bar]</blockquote><p>baz", + [["defaultparagraphseparator","p"],["insertorderedlist",""]], + "<ol><li>foo</li><ol><li>[bar]</li></ol></ol><p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertorderedlist":[false,false,"",false,true,""]}], +["<ul id=abc><li>foo<li>[bar]<li>baz</ul>", + [["insertorderedlist",""]], + "<ul id=\"abc\"><li>foo</li></ul><ol><li>[bar]</li></ol><ul><li>baz</li></ul>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["<ul style=color:blue><li>foo<li>[bar]<li>baz</ul>", + [["stylewithcss","true"],["insertorderedlist",""]], + "<ul style=\"color:rgb(0, 0, 255)\"><li>foo</li></ul><ol><li><span style=\"color:rgb(0, 0, 255)\">[bar]</span></li></ol><ul style=\"color:rgb(0, 0, 255)\"><li>baz</li></ul>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"insertorderedlist":[false,false,"",false,true,""]}], +["<ul style=color:blue><li>foo<li>[bar]<li>baz</ul>", + [["stylewithcss","false"],["insertorderedlist",""]], + "<ul style=\"color:rgb(0, 0, 255)\"><li>foo</li></ul><ol><li><font color=\"#0000ff\">[bar]</font></li></ol><ul style=\"color:rgb(0, 0, 255)\"><li>baz</li></ul>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"insertorderedlist":[false,false,"",false,true,""]}], +["<ul style=text-indent:1em><li>foo<li>[bar]<li>baz</ul>", + [["stylewithcss","true"],["insertorderedlist",""]], + "<ul style=\"text-indent:1em\"><li>foo</li></ul><ol><li>[bar]</li></ol><ul style=\"text-indent:1em\"><li>baz</li></ul>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"insertorderedlist":[false,false,"",false,true,""]}], +["<ul style=text-indent:1em><li>foo<li>[bar]<li>baz</ul>", + [["stylewithcss","false"],["insertorderedlist",""]], + "<ul style=\"text-indent:1em\"><li>foo</li></ul><ol><li>[bar]</li></ol><ul style=\"text-indent:1em\"><li>baz</li></ul>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"insertorderedlist":[false,false,"",false,true,""]}], +["<ul id=abc><li>[foo]<li>bar<li>baz</ul>", + [["insertorderedlist",""]], + "<ol><li>[foo]</li></ol><ul id=\"abc\"><li>bar</li><li>baz</li></ul>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["<ul style=color:blue><li>[foo]<li>bar<li>baz</ul>", + [["stylewithcss","true"],["insertorderedlist",""]], + "<ol><li><span style=\"color:rgb(0, 0, 255)\">[foo]</span></li></ol><ul style=\"color:rgb(0, 0, 255)\"><li>bar</li><li>baz</li></ul>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"insertorderedlist":[false,false,"",false,true,""]}], +["<ul style=color:blue><li>[foo]<li>bar<li>baz</ul>", + [["stylewithcss","false"],["insertorderedlist",""]], + "<ol><li><font color=\"#0000ff\">[foo]</font></li></ol><ul style=\"color:rgb(0, 0, 255)\"><li>bar</li><li>baz</li></ul>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"insertorderedlist":[false,false,"",false,true,""]}], +["<ul style=text-indent:1em><li>[foo]<li>bar<li>baz</ul>", + [["insertorderedlist",""]], + "<ol><li>[foo]</li></ol><ul style=\"text-indent:1em\"><li>bar</li><li>baz</li></ul>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["<ul id=abc><li>foo<li>bar<li>[baz]</ul>", + [["insertorderedlist",""]], + "<ul id=\"abc\"><li>foo</li><li>bar</li></ul><ol><li>[baz]</li></ol>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["<ul style=color:blue><li>foo<li>bar<li>[baz]</ul>", + [["stylewithcss","true"],["insertorderedlist",""]], + "<ul style=\"color:rgb(0, 0, 255)\"><li>foo</li><li>bar</li></ul><ol><li><span style=\"color:rgb(0, 0, 255)\">[baz]</span></li></ol>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"insertorderedlist":[false,false,"",false,true,""]}], +["<ul style=color:blue><li>foo<li>bar<li>[baz]</ul>", + [["stylewithcss","false"],["insertorderedlist",""]], + "<ul style=\"color:rgb(0, 0, 255)\"><li>foo</li><li>bar</li></ul><ol><li><font color=\"#0000ff\">[baz]</font></li></ol>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"insertorderedlist":[false,false,"",false,true,""]}], +["<ul style=text-indent:1em><li>foo<li>bar<li>[baz]</ul>", + [["insertorderedlist",""]], + "<ul style=\"text-indent:1em\"><li>foo</li><li>bar</li></ul><ol><li>[baz]</li></ol>", + [true], + {"insertorderedlist":[false,false,"",false,true,""]}], +["<ol><li>foo</ol> <p>[bar]", + [["defaultparagraphseparator","div"],["insertorderedlist",""]], + "<ol><li>foo</li> <li>[bar]</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertorderedlist":[false,false,"",false,true,""]}], +["<ol><li>foo</ol> <p>[bar]", + [["defaultparagraphseparator","p"],["insertorderedlist",""]], + "<ol><li>foo</li> <li>[bar]</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertorderedlist":[false,false,"",false,true,""]}], +["<p>[foo]</p> <ol><li>bar</ol>", + [["defaultparagraphseparator","div"],["insertorderedlist",""]], + "<ol><li>[foo]</li> <li>bar</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertorderedlist":[false,false,"",false,true,""]}], +["<p>[foo]</p> <ol><li>bar</ol>", + [["defaultparagraphseparator","p"],["insertorderedlist",""]], + "<ol><li>[foo]</li> <li>bar</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertorderedlist":[false,false,"",false,true,""]}], +["<ol><li>foo</ol> <p>[bar]</p> <ol><li>baz</ol>", + [["defaultparagraphseparator","div"],["insertorderedlist",""]], + "<ol><li>foo</li> <li>[bar]</li> <li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertorderedlist":[false,false,"",false,true,""]}], +["<ol><li>foo</ol> <p>[bar]</p> <ol><li>baz</ol>", + [["defaultparagraphseparator","p"],["insertorderedlist",""]], + "<ol><li>foo</li> <li>[bar]</li> <li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertorderedlist":[false,false,"",false,true,""]}], +["<div><span style='font-family: times; color: blue'>[bar]</span></div>", + [["insertorderedlist",""]], + "<ol><li><span style=\"font-family:times; color:rgb(0, 0, 255)\">[bar]</span></li></ol>", + [true], + {"insertorderedlist":[false,false,"false",false,true,"true"]}], +["<div><span style='font-family: times; color: blue'>bar</span></div><span style='font-family: italic; color: green'>[baz]</span>", + [["insertorderedlist",""]], + "<div><span style=\"font-family:times; color:rgb(0, 0, 255)\">bar</span></div><ol><li><span style=\"font-family:italic; color:rgb(0, 128, 0)\">[baz]</span></li></ol>", + [true], + {"insertorderedlist":[false,false,"false",false,true,"true"]}], +["<div><ol style='font-family: times; color: blue'><li>bar</li></ol><span style='font-family: italic; color: green'>[baz]</span></div>", + [["insertorderedlist",""]], + "<ol style=\"font-family:times; color:rgb(0, 0, 255)\"><li>bar</li><li><span style=\"font-family:italic; color:rgb(0, 128, 0)\">[baz]</span></li></ol>", + [true], + {"insertorderedlist":[false,false,"false",false,true,"true"]}], +["{}", + [["insertorderedlist",""],["inserttext","abc"]], + ["<ol><li>abc</li></ol>", + "<ol><li>abc<br></li></ol>"], + [true,true], + {"insertorderedlist":[false,false,"false",false,true,"true"]}], +["<div>{}</div>", + [["insertorderedlist",""],["inserttext","abc"]], + ["<div><ol><li>abc</li></ol></div>", + "<div><ol><li>abc<br></li></ol></div>"], + [true,true], + {"insertorderedlist":[false,false,"false",false,true,"true"]}], +["<div>{}<br></div>", + [["insertorderedlist",""],["inserttext","abc"]], + ["<div><ol><li>abc</li></ol></div>", + "<div><ol><li>abc<br></li></ol></div>"], + [true,true], + {"insertorderedlist":[false,false,"false",false,true,"true"]}], +["<p>{}</p>", + [["insertorderedlist",""],["inserttext","abc"]], + ["<ol><li>abc</li></ol>", + "<ol><li>abc<br></li></ol>"], + [true,true], + {"insertorderedlist":[false,false,"false",false,true,"true"]}], +["<p>{}<br></p>", + [["insertorderedlist",""],["inserttext","abc"]], + ["<ol><li>abc</li></ol>", + "<ol><li>abc<br></li></ol>"], + [true,true], + {"insertorderedlist":[false,false,"false",false,true,"true"]}], + +// "dir" attribute should be preserved for the list element to make the +// bullets aligned correctly. +["<div dir=\"rtl\">a[]bc</div><div dir=\"rtl\">def</div>", + [["insertorderedlist",""]], + ["<div dir=\"rtl\"><ol><li>abc</li></ol></div><div dir=\"rtl\">def</div>", + "<ol dir=\"rtl\"><li>abc</li></ol><div dir=\"rtl\">def</div>"], + [true], + {}], +["<div dir=\"rtl\">a[bc</div><div dir=\"rtl\">de]f</div>", + [["insertorderedlist",""]], + ["<div dir=\"rtl\"><ol><li>abc</li><li>def</li></ol></div>", + "<ol dir=\"rtl\"><li>abc</li><li>def</li></ol>"], + [true], + {}], +// but do not copy `dir` attributes to corresponding <li>s because different +// one from the value of the parent list element causes odd looks and anyway +// the `dir` attribute does not affect the text direction. +["<div dir=\"rtl\">a[bc</div><div dir=\"ltr\">de]f</div>", + [["insertorderedlist",""]], + ["<div dir=\"rtl\"><ol><li>abc</li><li>def</li></ol></div>", + "<ol dir=\"rtl\"><li>abc</li><li>def</li></ol>"], + [true], + {}], + +// The other attributes should be clonsed to each list item. +["<div id=\"a\">a[bc</div><div id=\"b\">de]f</div>", + [["insertorderedlist",""]], + ["<div><ol><li id=\"a\">abc</li><li id=\"b\">def</li></ol></div>", + "<ol><li id=\"a\">abc</li><li id=\"b\">def</li></ol>"], + [true], + {}], +["<div class=\"a\">a[bc</div><div class=\"b\">de]f</div>", + [["insertorderedlist",""]], + ["<div><ol><li class=\"a\">abc</li><li class=\"b\">def</li></ol></div>", + "<ol><li class=\"a\">abc</li><li class=\"b\">def</li></ol>"], + [true], + {}], +["<div title=\"a\">a[bc</div><div title=\"b\">de]f</div>", + [["insertorderedlist",""]], + ["<div><ol><li title=\"a\">abc</li><li title=\"b\">def</li></ol></div>", + "<ol><li title=\"a\">abc</li><li title=\"b\">def</li></ol>"], + [true], + {}], +] diff --git a/testing/web-platform/tests/editing/data/insertparagraph.js b/testing/web-platform/tests/editing/data/insertparagraph.js new file mode 100644 index 0000000000..0dace0105c --- /dev/null +++ b/testing/web-platform/tests/editing/data/insertparagraph.js @@ -0,0 +1,2576 @@ +// For documentation of the format, see README in this directory. +var browserTests = [ +["foo[bar]baz", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div>foo</div><div>{}baz</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["foo[bar]baz", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p>foo</p><p>{}baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["fo[o<table><tr><td>b]ar</table>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div>fo</div><div>{}<br></div><table><tbody><tr><td>ar</td></tr></tbody></table>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["fo[o<table><tr><td>b]ar</table>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p>fo</p><p>{}<br></p><table><tbody><tr><td>ar</td></tr></tbody></table>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<table><tr><td>[foo<td>bar]<tr><td>baz<td>quz</table>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<table><tbody><tr><td><div><br></div><div>{}<br></div></td><td><br></td></tr><tr><td>baz</td><td>quz</td></tr></tbody></table>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<table><tr><td>[foo<td>bar]<tr><td>baz<td>quz</table>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<table><tbody><tr><td><p><br></p><p>{}<br></p></td><td><br></td></tr><tr><td>baz</td><td>quz</td></tr></tbody></table>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<tr><td>baz<td>quz</table>", + [["insertparagraph",""]], + "<table><tbody>{}<tr><td><br></td><td><br></td></tr><tr><td>baz</td><td>quz</td></tr></tbody></table>", + [true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<table><tr><td>fo[o</table>b]ar", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<table><tbody><tr><td><div>fo</div><div>{}<br></div></td></tr></tbody></table>ar", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<table><tr><td>fo[o</table>b]ar", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<table><tbody><tr><td><p>fo</p><p>{}<br></p></td></tr></tbody></table>ar", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<table><tr><td>fo[o<td>b]ar<td>baz</table>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<table><tbody><tr><td><div>fo</div><div>{}<br></div></td><td>ar</td><td>baz</td></tr></tbody></table>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<table><tr><td>fo[o<td>b]ar<td>baz</table>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<table><tbody><tr><td><p>fo</p><p>{}<br></p></td><td>ar</td><td>baz</td></tr></tbody></table>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["{<table><tr><td>foo</table>}", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div><br></div><div>{}<br></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["{<table><tr><td>foo</table>}", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p><br></p><p>{}<br></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<table><tr><td>[foo]</table>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<table><tbody><tr><td><div><br></div><div>{}<br></div></td></tr></tbody></table>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<table><tr><td>[foo]</table>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<table><tbody><tr><td><p><br></p><p>{}<br></p></td></tr></tbody></table>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<ol><li>[foo]<li>bar</ol>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div>{}<br></div><ol><li>bar</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<ol><li>[foo]<li>bar</ol>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p>{}<br></p><ol><li>bar</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<ol><li>f[o]o<li>bar</ol>", + [["insertparagraph",""]], + "<ol><li>f</li><li>{}o</li><li>bar</li></ol>", + [true], + {"insertparagraph":[false,false,"",false,false,""]}], +["[]foo", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div><br></div><div>{}foo</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["[]foo", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p><br></p><p>{}foo</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["foo[]", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div>foo</div><div>{}<br></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["foo[]", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p>foo</p><p>{}<br></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<span>foo[]</span>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div><span>foo</span></div><div>{}<br></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<span>foo[]</span>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p><span>foo</span></p><p>{}<br></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["foo[]<br>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div>foo</div><div>{}<br></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["foo[]<br>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p>foo</p><p>{}<br></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["foo[]bar", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div>foo</div><div>{}bar</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["foo[]bar", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p>foo</p><p>{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<address>[]foo</address>", + [["insertparagraph",""]], + "<address><br>{}foo</address>", + [true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<address>foo[]</address>", + [["insertparagraph",""]], + "<address>foo<br>{}<br></address>", + [true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<address>foo[]<br></address>", + [["insertparagraph",""]], + "<address>foo<br>{}<br></address>", + [true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<address>foo[]bar</address>", + [["insertparagraph",""]], + "<address>foo<br>{}bar</address>", + [true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<div>[]foo</div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div><br></div><div>{}foo</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div>[]foo</div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div><br></div><div>{}foo</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<div>foo[]</div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div>foo</div><div>{}<br></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div>foo[]</div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div>foo</div><div>{}<br></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<div>foo[]<br></div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div>foo</div><div>{}<br></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div>foo[]<br></div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div>foo</div><div>{}<br></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<div>foo[]bar</div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div>foo</div><div>{}bar</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div>foo[]bar</div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div>foo</div><div>{}bar</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<dl><dt>[]foo<dd>bar</dl>", + [["insertparagraph",""]], + "<dl><dt><br></dt><dt>{}foo</dt><dd>bar</dd></dl>", + [true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<dl><dt>foo[]<dd>bar</dl>", + [["insertparagraph",""]], + "<dl><dt>foo</dt><dd>{}<br></dd><dd>bar</dd></dl>", + [true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<dl><dt>foo[]<br><dd>bar</dl>", + [["insertparagraph",""]], + "<dl><dt>foo</dt><dd>{}<br></dd><dd>bar</dd></dl>", + [true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<dl><dt>foo[]bar<dd>baz</dl>", + [["insertparagraph",""]], + "<dl><dt>foo</dt><dt>{}bar</dt><dd>baz</dd></dl>", + [true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<dl><dt>foo<dd>[]bar</dl>", + [["insertparagraph",""]], + "<dl><dt>foo</dt><dd><br></dd><dd>{}bar</dd></dl>", + [true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<dl><dt>foo<dd>bar[]</dl>", + [["insertparagraph",""]], + "<dl><dt>foo</dt><dd>bar</dd><dt>{}<br></dt></dl>", + [true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<dl><dt>foo<dd>bar[]<br></dl>", + [["insertparagraph",""]], + "<dl><dt>foo</dt><dd>bar</dd><dt>{}<br></dt></dl>", + [true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<dl><dt>foo<dd>bar[]baz</dl>", + [["insertparagraph",""]], + "<dl><dt>foo</dt><dd>bar</dd><dd>{}baz</dd></dl>", + [true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<h1>[]foo</h1>", + [["insertparagraph",""]], + "<h1><br></h1><h1>{}foo</h1>", + [true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<h1>foo[]</h1>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<h1>foo</h1><div>{}<br></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<h1>foo[]</h1>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<h1>foo</h1><p>{}<br></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<h1>foo[]<br></h1>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<h1>foo</h1><div>{}<br></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<h1>foo[]<br></h1>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<h1>foo</h1><p>{}<br></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<h1>foo[]bar</h1>", + [["insertparagraph",""]], + "<h1>foo</h1><h1>{}bar</h1>", + [true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<ol><li>[]foo</ol>", + [["insertparagraph",""]], + "<ol><li><br></li><li>{}foo</li></ol>", + [true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<ol><li>foo[]</ol>", + [["insertparagraph",""]], + "<ol><li>foo</li><li>{}<br></li></ol>", + [true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<ol><li>foo[]<br></ol>", + [["insertparagraph",""]], + "<ol><li>foo</li><li>{}<br></li></ol>", + [true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<ol><li>foo[]bar</ol>", + [["insertparagraph",""]], + "<ol><li>foo</li><li>{}bar</li></ol>", + [true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<p>[]foo</p>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p><br></p><p>{}foo</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>[]foo</p>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p><br></p><p>{}foo</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>foo[]</p>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p>foo</p><p>{}<br></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>foo[]</p>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p>foo</p><p>{}<br></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>foo[]<br></p>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p>foo</p><p>{}<br></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>foo[]<br></p>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p>foo</p><p>{}<br></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>foo[]bar</p>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p>foo</p><p>{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>foo[]bar</p>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p>foo</p><p>{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<pre>[]foo</pre>", + [["insertparagraph",""]], + "<pre><br>{}foo</pre>", + [true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<pre>foo[]</pre>", + [["insertparagraph",""]], + "<pre>foo<br>{}<br></pre>", + [true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<pre>foo[]<br></pre>", + [["insertparagraph",""]], + "<pre>foo<br>{}<br></pre>", + [true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<pre>foo[]bar</pre>", + [["insertparagraph",""]], + "<pre>foo<br>{}bar</pre>", + [true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<pre>foo[]<br><br></pre>", + [["insertparagraph",""]], + "<pre>foo<br>{}<br><br></pre>", + [true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<pre>foo<br>{}<br></pre>", + [["insertparagraph",""]], + "<pre>foo<br><br>{}<br></pre>", + [true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<pre>foo []</pre>", + [["insertparagraph",""]], + "<pre>foo\n<br>{}<br></pre>", + [true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<pre>foo[] </pre>", + [["insertparagraph",""]], + "<pre>foo<br>{}\n</pre>", + [true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<pre>foo [] </pre>", + [["insertparagraph",""]], + "<pre>foo\n<br>{}\n</pre>", + [true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<xmp>foo[]bar</xmp>", + [["insertparagraph",""]], + "<xmp>foo</xmp><xmp>{}bar</xmp>", + [true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<script>foo[]bar</script>baz", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div><script>foo</script><br></div><div>{}<script>bar</script>baz</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<script>foo[]bar</script>baz", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p><script>foo</script><br></p><p>{}<script>bar</script>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<div style=display:none>foo[]bar</div>baz", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div style=\"display:none\">foo<br></div><div style=\"display:none\">{}bar<br></div>baz", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div style=display:none>foo[]bar</div>baz", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div style=\"display:none\">foo<br></div><div style=\"display:none\">{}bar<br></div>baz", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div style=display:none>foo[]bar</div>baz", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div style=\"display:none\">foo<br></div><div style=\"display:none\">{}bar<br></div>baz", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<div style=display:none>foo[]bar</div>baz", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div style=\"display:none\">foo<br></div><div style=\"display:none\">{}bar<br></div>baz", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<listing>foo[]bar</listing>", + [["insertparagraph",""]], + "<listing>foo<br>{}bar</listing>", + [true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<ol><li>{}<br></li></ol>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div>{}<br></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<ol><li>{}<br></li></ol>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p>{}<br></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["foo<ol><li>{}<br></li></ol>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "foo<div>{}<br></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["foo<ol><li>{}<br></li></ol>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "foo<p>{}<br></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<ol><li>{}<br></li></ol>foo", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div>{}<br></div>foo", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<ol><li>{}<br></li></ol>foo", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p>{}<br></p>foo", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<ol><li>foo<li>{}<br></ol>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<ol><li>foo</li></ol><div>{}<br></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<ol><li>foo<li>{}<br></ol>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<ol><li>foo</li></ol><p>{}<br></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<ol><li>{}<br><li>bar</ol>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div>{}<br></div><ol><li>bar</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<ol><li>{}<br><li>bar</ol>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p>{}<br></p><ol><li>bar</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<ol><li>foo</li><ul><li>{}<br></ul></ol>", + [["insertparagraph",""]], + "<ol><li>foo</li><li>{}<br></li></ol>", + [true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<dl><dt>{}<br></dt></dl>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div>{}<br></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<dl><dt>{}<br></dt></dl>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p>{}<br></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<dl><dt>foo<dd>{}<br></dl>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<dl><dt>foo</dt></dl><div>{}<br></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<dl><dt>foo<dd>{}<br></dl>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<dl><dt>foo</dt></dl><p>{}<br></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<dl><dt>{}<br><dd>bar</dl>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div>{}<br></div><dl><dd>bar</dd></dl>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<dl><dt>{}<br><dd>bar</dl>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p>{}<br></p><dl><dd>bar</dd></dl>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<dl><dt>foo<dd>bar<dl><dt>{}<br><dd>baz</dl></dl>", + [["insertparagraph",""]], + "<dl><dt>foo</dt><dd>bar</dd><dt>{}<br></dt><dd><dl><dd>baz</dd></dl></dd></dl>", + [true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<dl><dt>foo<dd>bar<dl><dt>baz<dd>{}<br></dl></dl>", + [["insertparagraph",""]], + "<dl><dt>foo</dt><dd>bar<dl><dt>baz</dt></dl></dd><dd>{}<br></dd></dl>", + [true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<h1>foo[bar</h1><p>baz]quz</p>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<h1>foo</h1><h1>{}quz</h1>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<h1>foo[bar</h1><p>baz]quz</p>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<h1>foo</h1><h1>{}quz</h1>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>foo[bar</p><h1>baz]quz</h1>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p>foo</p><p>{}quz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>foo[bar</p><h1>baz]quz</h1>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p>foo</p><p>{}quz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>foo</p>{}<br>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p>foo</p><div><br></div><div>{}<br></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>foo</p>{}<br>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p>foo</p><p><br></p><p>{}<br></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["{}<br><p>foo</p>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div><br></div><div>{}<br></div><p>foo</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["{}<br><p>foo</p>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p><br></p><p>{}<br></p><p>foo</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>foo</p>{}<br><h1>bar</h1>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p>foo</p><div><br></div><div>{}<br></div><h1>bar</h1>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>foo</p>{}<br><h1>bar</h1>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p>foo</p><p><br></p><p>{}<br></p><h1>bar</h1>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<h1>foo</h1>{}<br><p>bar</p>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<h1>foo</h1><div><br></div><div>{}<br></div><p>bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<h1>foo</h1>{}<br><p>bar</p>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<h1>foo</h1><p><br></p><p>{}<br></p><p>bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<h1>foo</h1>{}<br><h2>bar</h2>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<h1>foo</h1><div><br></div><div>{}<br></div><h2>bar</h2>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<h1>foo</h1>{}<br><h2>bar</h2>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<h1>foo</h1><p><br></p><p>{}<br></p><h2>bar</h2>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>foo</p><h1>[bar]</h1><p>baz</p>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p>foo</p><h1><br></h1><div>{}<br></div><p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>foo</p><h1>[bar]</h1><p>baz</p>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p>foo</p><h1><br></h1><p>{}<br></p><p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>foo</p>{<h1>bar</h1>}<p>baz</p>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p>foo</p><div>{}<br></div><p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>foo</p>{<h1>bar</h1>}<p>baz</p>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p>foo</p><p>{}<br></p><p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<table><tr><td>foo[]bar</table>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<table><tbody><tr><td><div>foo</div><div>{}bar</div></td></tr></tbody></table>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<table><tr><td>foo[]bar</table>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<table><tbody><tr><td><p>foo</p><p>{}bar</p></td></tr></tbody></table>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<table><tr><td><p>foo[]bar</table>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<table><tbody><tr><td><p>foo</p><p>{}bar</p></td></tr></tbody></table>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<table><tr><td><p>foo[]bar</table>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<table><tbody><tr><td><p>foo</p><p>{}bar</p></td></tr></tbody></table>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<blockquote>[]foo</blockquote>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<blockquote><div><br></div><div>{}foo</div></blockquote>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<blockquote>[]foo</blockquote>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<blockquote><p><br></p><p>{}foo</p></blockquote>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<blockquote>foo[]</blockquote>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<blockquote><div>foo</div><div>{}<br></div></blockquote>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<blockquote>foo[]</blockquote>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<blockquote><p>foo</p><p>{}<br></p></blockquote>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<blockquote>foo[]<br></blockquote>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<blockquote><div>foo</div><div>{}<br></div></blockquote>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<blockquote>foo[]<br></blockquote>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<blockquote><p>foo</p><p>{}<br></p></blockquote>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<blockquote>foo[]bar</blockquote>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<blockquote><div>foo</div><div>{}bar</div></blockquote>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<blockquote>foo[]bar</blockquote>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<blockquote><p>foo</p><p>{}bar</p></blockquote>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<blockquote><p>[]foo</blockquote>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<blockquote><p><br></p><p>{}foo</p></blockquote>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<blockquote><p>[]foo</blockquote>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<blockquote><p><br></p><p>{}foo</p></blockquote>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<blockquote><p>foo[]</blockquote>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<blockquote><p>foo</p><p>{}<br></p></blockquote>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<blockquote><p>foo[]</blockquote>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<blockquote><p>foo</p><p>{}<br></p></blockquote>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<blockquote><p>foo[]bar</blockquote>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<blockquote><p>foo</p><p>{}bar</p></blockquote>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<blockquote><p>foo[]bar</blockquote>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<blockquote><p>foo</p><p>{}bar</p></blockquote>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<blockquote><p>foo[]<p>bar</blockquote>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<blockquote><p>foo</p><p>{}<br></p><p>bar</p></blockquote>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<blockquote><p>foo[]<p>bar</blockquote>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<blockquote><p>foo</p><p>{}<br></p><p>bar</p></blockquote>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<blockquote><p>foo[]bar<p>baz</blockquote>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<blockquote><p>foo</p><p>{}bar</p><p>baz</p></blockquote>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<blockquote><p>foo[]bar<p>baz</blockquote>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<blockquote><p>foo</p><p>{}bar</p><p>baz</p></blockquote>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<span>foo[]bar</span>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div><span>foo</span></div><div>{}<span>bar</span></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<span>foo[]bar</span>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p><span>foo</span></p><p>{}<span>bar</span></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<span>foo[]bar</span>baz", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div><span>foo</span></div><div>{}<span>bar</span>baz</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<span>foo[]bar</span>baz", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p><span>foo</span></p><p>{}<span>bar</span>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<b>foo[]bar</b>", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div><b>foo</b></div><div>{}<b>bar</b></div>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<b>foo[]bar</b>", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div><b>foo</b></div><div>{}<b>bar</b></div>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<b>foo[]bar</b>", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p><b>foo</b></p><p>{}<b>bar</b></p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<b>foo[]bar</b>", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p><b>foo</b></p><p>{}<b>bar</b></p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<b>foo[]bar</b>baz", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div><b>foo</b></div><div>{}<b>bar</b>baz</div>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<b>foo[]bar</b>baz", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div><b>foo</b></div><div>{}<b>bar</b>baz</div>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<b>foo[]bar</b>baz", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p><b>foo</b></p><p>{}<b>bar</b>baz</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<b>foo[]bar</b>baz", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p><b>foo</b></p><p>{}<b>bar</b>baz</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<b>foo[]</b>bar", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div><b>foo</b></div><div>{}bar</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<b>foo[]</b>bar", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p><b>foo</b></p><p>{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p><b>foo[]</b></p>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p><b>foo</b></p><p><b>{}<br></b></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div><b>foo[]</b></div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div><b>foo</b></div><div><b>{}<br></b></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p><b><i>foo[]</i></b></p>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p><b><i>foo</i></b></p><p><b><i>{}<br></i></b></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div><b><i>foo[]</i></b></div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div><b><i>foo</i></b></div><div><b><i>{}<br></i></b></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p><i><b>foo[]</b></i></p>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p><i><b>foo</b></i></p><p><i><b>{}<br></b></i></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div><i><b>foo[]</b></i></div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div><i><b>foo</b></i></div><div><i><b>{}<br></b></i></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["foo<b>[]bar</b>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div>foo</div><div>{}<b>bar</b></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["foo<b>[]bar</b>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p>foo</p><p>{}<b>bar</b></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p><b>[]foo</b></p>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p><b><br></b></p><p><b>{}foo</b></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div><b>[]foo</b></div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div><b><br></b></div><div><b>{}foo</b></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p><b><i>[]foo</i></b></p>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p><b><i><br></i></b></p><p><b><i>{}foo</i></b></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div><b><i>[]foo</i></b></div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div><b><i><br></i></b></div><div><b><i>{}foo</i></b></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p><i><b>[]foo</b></i></p>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p><i><b><br></b></i></p><p><i><b>{}foo</b></i></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div><i><b>[]foo</b></i></div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div><i><b><br></b></i></div><div><i><b>{}foo</b></i></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<b>foo[]</b><i>bar</i>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div><b>foo</b></div><div>{}<i>bar</i></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<b>foo[]</b><i>bar</i>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p><b>foo</b></p><p>{}<i>bar</i></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<b id=x class=y>foo[]bar</b>", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div><b id=\"x\" class=\"y\">foo</b></div><div>{}<b class=\"y\">bar</b></div>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<b id=x class=y>foo[]bar</b>", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div><b id=\"x\" class=\"y\">foo</b></div><div>{}<b class=\"y\">bar</b></div>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<b id=x class=y>foo[]bar</b>", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p><b id=\"x\" class=\"y\">foo</b></p><p>{}<b class=\"y\">bar</b></p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<b id=x class=y>foo[]bar</b>", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p><b id=\"x\" class=\"y\">foo</b></p><p>{}<b class=\"y\">bar</b></p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<i><b>foo[]bar</b>baz</i>", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div><i><b>foo</b></i></div><div>{}<i><b>bar</b>baz</i></div>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<i><b>foo[]bar</b>baz</i>", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div><i><b>foo</b></i></div><div>{}<i><b>bar</b>baz</i></div>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<i><b>foo[]bar</b>baz</i>", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p><i><b>foo</b></i></p><p>{}<i><b>bar</b>baz</i></p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<i><b>foo[]bar</b>baz</i>", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p><i><b>foo</b></i></p><p>{}<i><b>bar</b>baz</i></p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p><b>foo[]bar</b></p>", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p><b>foo</b></p><p>{}<b>bar</b></p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<p><b>foo[]bar</b></p>", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p><b>foo</b></p><p>{}<b>bar</b></p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<p><b>foo[]bar</b></p>", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p><b>foo</b></p><p>{}<b>bar</b></p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p><b>foo[]bar</b></p>", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p><b>foo</b></p><p>{}<b>bar</b></p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p><b id=x class=y>foo[]bar</b></p>", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p><b id=\"x\" class=\"y\">foo</b></p><p>{}<b class=\"y\">bar</b></p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<p><b id=x class=y>foo[]bar</b></p>", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p><b id=\"x\" class=\"y\">foo</b></p><p>{}<b class=\"y\">bar</b></p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<p><b id=x class=y>foo[]bar</b></p>", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p><b id=\"x\" class=\"y\">foo</b></p><p>{}<b class=\"y\">bar</b></p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p><b id=x class=y>foo[]bar</b></p>", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p><b id=\"x\" class=\"y\">foo</b></p><p>{}<b class=\"y\">bar</b></p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<div><b>foo[]bar</b></div>", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div><b>foo</b></div><div>{}<b>bar</b></div>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div><b>foo[]bar</b></div>", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div><b>foo</b></div><div>{}<b>bar</b></div>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div><b>foo[]bar</b></div>", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div><b>foo</b></div><div>{}<b>bar</b></div>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<div><b>foo[]bar</b></div>", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div><b>foo</b></div><div>{}<b>bar</b></div>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<a href=foo>foo[]bar</a>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div><a href=\"foo\">foo</a></div><div>{}<a href=\"foo\">bar</a></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<a href=foo>foo[]bar</a>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p><a href=\"foo\">foo</a></p><p>{}<a href=\"foo\">bar</a></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<a href=foo>foo[]bar</a>baz", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div><a href=\"foo\">foo</a></div><div>{}<a href=\"foo\">bar</a>baz</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<a href=foo>foo[]bar</a>baz", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p><a href=\"foo\">foo</a></p><p>{}<a href=\"foo\">bar</a>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p><a href=foo>foo[]bar</a></p>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p><a href=\"foo\">foo</a></p><p><a href=\"foo\">{}bar</a></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div><a href=foo>foo[]bar</a></div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div><a href=\"foo\">foo</a></div><div><a href=\"foo\">{}bar</a></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p><a href=foo><b>foo[]bar</b></a></p>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p><a href=\"foo\"><b>foo</b></a></p><p><a href=\"foo\"><b>{}bar</b></a></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div><a href=foo><b>foo[]bar</b></a></div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div><a href=\"foo\"><b>foo</b></a></div><div><a href=\"foo\"><b>{}bar</b></a></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p><b><a href=foo>foo[]bar</a></b></p>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p><b><a href=\"foo\">foo</a></b></p><p><b><a href=\"foo\">{}bar</a></b></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div><b><a href=foo>foo[]bar</a></b></div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div><b><a href=\"foo\">foo</a></b></div><div><b><a href=\"foo\">{}bar</a></b></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +// <a href="foo"> shouldn't be duplicated in new paragraph when it's split at +// start or end of it. +["<a href=foo>foo[]</a>bar", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div><a href=\"foo\">foo</a></div><div>{}bar</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<a href=foo>foo[]</a>bar", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p><a href=\"foo\">foo</a></p><p>{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["foo<a href=foo>[]bar</a>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div>foo</div><div>{}<a href=\"foo\">bar</a></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["foo<a href=foo>[]bar</a>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p>foo</p><p>{}<a href=\"foo\">bar</a></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p><a href=foo>foo[]</a></p>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p><a href=\"foo\">foo</a></p><p>{}<br></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div><a href=foo>foo[]</a></div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div><a href=\"foo\">foo</a></div><div>{}<br></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p><a href=foo>[]foo</a></p>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p><br></p><p><a href=\"foo\">{}foo</a></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div><a href=foo>[]foo</a></div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div><br></div><div><a href=\"foo\">{}foo</a></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p><a href=foo><b>foo[]</b></a></p>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p><a href=\"foo\"><b>foo</b></a></p><p>{}<br></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div><a href=foo><b>foo[]</b></a></div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div><a href=\"foo\"><b>foo</b></a></div><div>{}<br></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p><a href=foo><b>[]foo</b></a></p>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p><br></p><p><a href=\"foo\"><b>{}foo</b></a></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div><a href=foo><b>[]foo</b></a></div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div><br></div><div><a href=\"foo\"><b>{}foo</b></a></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p><b><a href=foo>foo[]</a></b></p>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p><b><a href=\"foo\">foo</a></b></p><p><b>{}<br></b></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div><b><a href=foo>foo[]</a></b></div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div><b><a href=\"foo\">foo</a></b></div><div><b>{}<br></b></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p><b><a href=foo>[]foo</a></b></p>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p><b><br></b></p><p><b><a href=\"foo\">{}foo</a></b></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div><b><a href=foo>[]foo</a></b></div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div><b><br></b></div><div><b><a href=\"foo\">{}foo</a></b></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +// <br> is usually inserted after an <a href="foo"> element is split next to +// an ASCII whitespace. So, <br> element should be ignored if it's invisible. +["<p><a href=foo>foo []<br></a></p>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p><a href=\"foo\">foo <br></a></p><p>{}<br></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div><a href=foo>foo []<br></a></div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div><a href=\"foo\">foo <br></a></div><div>{}<br></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p><a href=foo><b>foo []<br></b></a></p>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p><a href=\"foo\"><b>foo <br></b></a></p><p>{}<br></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div><a href=foo><b>foo []<br></b></a></div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div><a href=\"foo\"><b>foo <br></b></a></div><div>{}<br></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p><b><a href=foo>foo []<br></a></b></p>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p><b><a href=\"foo\">foo <br></a></b></p><p><b>{}<br></b></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div><b><a href=foo>foo []<br></a></b></div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div><b><a href=\"foo\">foo <br></a></b></div><div><b>{}<br></b></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p><a href=foo>foo {}<br></a></p>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p><a href=\"foo\">foo <br></a></p><p>{}<br></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div><a href=foo>foo {}<br></a></div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div><a href=\"foo\">foo <br></a></div><div>{}<br></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p><a href=foo><b>foo {}<br></b></a></p>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p><a href=\"foo\"><b>foo <br></b></a></p><p>{}<br></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div><a href=foo><b>foo {}<br></b></a></div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div><a href=\"foo\"><b>foo <br></b></a></div><div>{}<br></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p><b><a href=foo>foo {}<br></a></b></p>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p><b><a href=\"foo\">foo <br></a></b></p><p><b>{}<br></b></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div><b><a href=foo>foo {}<br></a></b></div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div><b><a href=\"foo\">foo <br></a></b></div><div><b>{}<br></b></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +// So, if <br> is visible, its any inline containers should be split. +["<p><a href=foo>foo []<br><br></a></p>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p><a href=\"foo\">foo <br></a></p><p><a href=\"foo\">{}<br><br></a></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div><a href=foo>foo []<br><br></a></div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div><a href=\"foo\">foo <br></a></div><div><a href=\"foo\">{}<br><br></a></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p><a href=foo><b>foo []<br><br></b></a></p>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p><a href=\"foo\"><b>foo <br></b></a></p><p><a href=\"foo\"><b>{}<br><br></b></a></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div><a href=foo><b>foo []<br><br></b></a></div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div><a href=\"foo\"><b>foo <br></b><br></a></div><div><a href=\"foo\"><b>{}<br><br></b></a></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p><a href=foo><b>foo []<br></b><br></a></p>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p><a href=\"foo\"><b>foo <br></b></a></p><p><a href=\"foo\"><b>{}<br></b><br></a></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div><a href=foo><b>foo []<br></b><br></a></div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div><a href=\"foo\"><b>foo <br></b></a></div><div><a href=\"foo\"><b>{}<br></b><br></a></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p><a href=foo>foo {}<br><br></a></p>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p><a href=\"foo\">foo <br><br></a></p><p><a href=\"foo\">{}<br></a></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div><a href=foo>foo {}<br><br></a></div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div><a href=\"foo\">foo <br></a></div><div><a href=\"foo\">{}<br></a></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p><a href=foo><b>foo {}<br><br></b></a></p>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p><a href=\"foo\"><b>foo <br></b><br></a></p><p><a href=\"foo\"><b>{}<br><br></b></a></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div><a href=foo><b>foo {}<br><br></b></a></div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div><a href=\"foo\"><b>foo <br></b><br></a></div><div><a href=\"foo\"><b>{}<br><br></b></a></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p><a href=foo><b>foo {}<br></b><br></a></p>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p><a href=\"foo\"><b>foo <br></b></a></p><p><a href=\"foo\"><b>{}<br></b><br></a></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div><a href=foo><b>foo {}<br></b><br></a></div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div><a href=\"foo\"><b>foo <br></b></a></div><div><a href=\"foo\"><b>{}<br></b><br></a></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], + +["<p>foo[]<!--bar-->", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p>foo</p><p>{}<!--bar--><br></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>foo[]<!--bar-->", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p>foo</p><p>{}<!--bar--><br></p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p><!--foo-->[]bar", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p><!--foo--><br></p><p>{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<p><!--foo-->[]bar", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p><!--foo--><br></p><p>{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>[bar]</span>baz", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p>foo</p><p>{}baz</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>[bar]</span>baz", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p>foo</p><p>{}baz</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>[bar]</span>baz", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p>foo</p><p>{}baz</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>[bar]</span>baz", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p>foo</p><p>{}baz</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>{bar}</span>baz", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p>foo</p><p>{}baz</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>{bar}</span>baz", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p>foo</p><p>{}baz</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>{bar}</span>baz", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p>foo</p><p>{}baz</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>{bar}</span>baz", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p>foo</p><p>{}baz</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>foo{<span style=color:#aBcDeF>bar</span>}baz", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p>foo</p><p>{}baz</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>foo{<span style=color:#aBcDeF>bar</span>}baz", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p>foo</p><p>{}baz</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>foo{<span style=color:#aBcDeF>bar</span>}baz", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p>foo</p><p>{}baz</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>foo{<span style=color:#aBcDeF>bar</span>}baz", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p>foo</p><p>{}baz</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>[foo<span style=color:#aBcDeF>bar]</span>baz", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p><br></p><p>{}baz</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>[foo<span style=color:#aBcDeF>bar]</span>baz", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p><br></p><p>{}baz</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>[foo<span style=color:#aBcDeF>bar]</span>baz", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p><br></p><p>{}baz</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>[foo<span style=color:#aBcDeF>bar]</span>baz", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p><br></p><p>{}baz</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>{foo<span style=color:#aBcDeF>bar}</span>baz", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p><br></p><p>{}baz</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>{foo<span style=color:#aBcDeF>bar}</span>baz", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p><br></p><p>{}baz</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>{foo<span style=color:#aBcDeF>bar}</span>baz", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p><br></p><p>{}baz</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>{foo<span style=color:#aBcDeF>bar}</span>baz", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p><br></p><p>{}baz</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>[bar</span>baz]", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p>foo</p><p>{}<br></p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>[bar</span>baz]", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p>foo</p><p>{}<br></p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>[bar</span>baz]", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p>foo</p><p>{}<br></p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>[bar</span>baz]", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p>foo</p><p>{}<br></p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>{bar</span>baz}", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p>foo</p><p>{}<br></p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>{bar</span>baz}", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p>foo</p><p>{}<br></p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>{bar</span>baz}", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p>foo</p><p>{}<br></p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>{bar</span>baz}", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p>foo</p><p>{}<br></p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>[bar</span><span style=color:#fEdCbA>baz]</span>quz", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p>foo</p><p>{}quz</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>[bar</span><span style=color:#fEdCbA>baz]</span>quz", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p>foo</p><p>{}quz</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>[bar</span><span style=color:#fEdCbA>baz]</span>quz", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p>foo</p><p>{}quz</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>[bar</span><span style=color:#fEdCbA>baz]</span>quz", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p>foo</p><p>{}quz</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<ul contenteditable><li>{}<br></ul>", + [["insertparagraph",""]], + "<ul contenteditable=\"\"><li>{}<br></li></ul>", + [true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<ul contenteditable><li>foo[]</ul>", + [["insertparagraph",""]], + "<ul contenteditable=\"\"><li>foo</li><li>{}<br></li></ul>", + [true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<div contenteditable=false><ul contenteditable><li>{}<br></ul></div>", + [["insertparagraph",""]], + "<div contenteditable=\"false\"><ul contenteditable=\"\"><li>{}<br></li></ul></div>", + [true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<div contenteditable=false><ul contenteditable><li>foo[]</ul></div>", + [["insertparagraph",""]], + "<div contenteditable=\"false\"><ul contenteditable=\"\"><li>foo</li><li>{}<br></li></ul></div>", + [true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<address><p>foo[]</address>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<address><p>foo</p><p>{}<br></p></address>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<address><p>foo[]</address>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<address><p>foo</p><p>{}<br></p></address>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<dl><dt><p>foo[]</dl>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<dl><dt><p>foo</p></dt><dd><p>{}<br></p></dd></dl>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<dl><dt><p>foo[]</dl>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<dl><dt><p>foo</p></dt><dd><p>{}<br></p></dd></dl>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<dl><dd><p>foo[]</dl>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<dl><dd><p>foo</p></dd><dt><p>{}<br></p></dt></dl>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<dl><dd><p>foo[]</dl>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<dl><dd><p>foo</p></dd><dt><p>{}<br></p></dt></dl>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<ol><li><p>foo[]</ol>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<ol><li><p>foo</p></li><li><p>{}<br></p></li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<ol><li><p>foo[]</ol>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<ol><li><p>foo</p></li><li><p>{}<br></p></li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<ul><li><p>foo[]</ul>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<ul><li><p>foo</p></li><li><p>{}<br></p></li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<ul><li><p>foo[]</ul>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<ul><li><p>foo</p></li><li><p>{}<br></p></li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<address><div>foo[]</address>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<address><div>foo</div><div>{}<br></div></address>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<address><div>foo[]</address>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<address><div>foo</div><div>{}<br></div></address>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<dl><dt><div>foo[]</dl>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<dl><dt><div>foo</div></dt><dd><div>{}<br></div></dd></dl>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<dl><dt><div>foo[]</dl>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<dl><dt><div>foo</div></dt><dd><div>{}<br></div></dd></dl>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<dl><dd><div>foo[]</dl>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<dl><dd><div>foo</div></dd><dt><div>{}<br></div></dt></dl>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<dl><dd><div>foo[]</dl>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<dl><dd><div>foo</div></dd><dt><div>{}<br></div></dt></dl>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<ol><li><div>foo[]</ol>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<ol><li><div>foo</div></li><li><div>{}<br></div></li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<ol><li><div>foo[]</ol>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<ol><li><div>foo</div></li><li><div>{}<br></div></li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<ul><li><div>foo[]</ul>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<ul><li><div>foo</div></li><li><div>{}<br></div></li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<ul><li><div>foo[]</ul>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<ul><li><div>foo</div></li><li><div>{}<br></div></li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<div><p>foo[]</div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div><p>foo</p><p>{}<br></p></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div><p>foo[]</div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div><p>foo</p><p>{}<br></p></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<div><div>foo[]</div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div><div>foo</div><div>{}<br></div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div><div>foo[]</div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div><div>foo</div><div>{}<br></div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<address><p>[]foo</address>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<address><p><br></p><p>{}foo</p></address>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<address><p>[]foo</address>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<address><p><br></p><p>{}foo</p></address>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<dl><dt><p>[]foo</dl>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<dl><dt><p><br></p></dt><dt><p>{}foo</p></dt></dl>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<dl><dt><p>[]foo</dl>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<dl><dt><p><br></p></dt><dt><p>{}foo</p></dt></dl>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<dl><dd><p>[]foo</dl>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<dl><dd><p><br></p></dd><dd><p>{}foo</p></dd></dl>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<dl><dd><p>[]foo</dl>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<dl><dd><p><br></p></dd><dd><p>{}foo</p></dd></dl>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<ol><li><p>[]foo</ol>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<ol><li><p><br></p></li><li><p>{}foo</p></li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<ol><li><p>[]foo</ol>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<ol><li><p><br></p></li><li><p>{}foo</p></li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<ul><li><p>[]foo</ul>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<ul><li><p><br></p></li><li><p>{}foo</p></li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<ul><li><p>[]foo</ul>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<ul><li><p><br></p></li><li><p>{}foo</p></li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<address><div>[]foo</address>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<address><div><br></div><div>{}foo</div></address>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<address><div>[]foo</address>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<address><div><br></div><div>{}foo</div></address>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<dl><dt><div>[]foo</dl>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<dl><dt><div><br></div></dt><dt><div>{}foo</div></dt></dl>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<dl><dt><div>[]foo</dl>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<dl><dt><div><br></div></dt><dt><div>{}foo</div></dt></dl>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<dl><dd><div>[]foo</dl>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<dl><dd><div><br></div></dd><dd><div>{}foo</div></dd></dl>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<dl><dd><div>[]foo</dl>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<dl><dd><div><br></div></dd><dd><div>{}foo</div></dd></dl>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<ol><li><div>[]foo</ol>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<ol><li><div><br></div></li><li><div>{}foo</div></li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<ol><li><div>[]foo</ol>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<ol><li><div><br></div></li><li><div>{}foo</div></li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<ul><li><div>[]foo</ul>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<ul><li><div><br></div></li><li><div>{}foo</div></li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<ul><li><div>[]foo</ul>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<ul><li><div><br></div></li><li><div>{}foo</div></li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<div><p>[]foo</div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div><p><br></p><p>{}foo</p></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div><p>[]foo</div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div><p><br></p><p>{}foo</p></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<div><div>[]foo</div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div><div><br></div><div>{}foo</div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div><div>[]foo</div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div><div><br></div><div>{}foo</div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<address><p>foo[]bar</address>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<address><p>foo</p><p>{}bar</p></address>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<address><p>foo[]bar</address>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<address><p>foo</p><p>{}bar</p></address>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<dl><dt><p>foo[]bar</dl>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<dl><dt><p>foo</p></dt><dt><p>{}bar</p></dt></dl>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<dl><dt><p>foo[]bar</dl>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<dl><dt><p>foo</p></dt><dt><p>{}bar</p></dt></dl>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<dl><dd><p>foo[]bar</dl>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<dl><dd><p>foo</p></dd><dd><p>{}bar</p></dd></dl>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<dl><dd><p>foo[]bar</dl>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<dl><dd><p>foo</p></dd><dd><p>{}bar</p></dd></dl>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<ol><li><p>foo[]bar</ol>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<ol><li><p>foo</p></li><li><p>{}bar</p></li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<ol><li><p>foo[]bar</ol>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<ol><li><p>foo</p></li><li><p>{}bar</p></li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<ul><li><p>foo[]bar</ul>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<ul><li><p>foo</p></li><li><p>{}bar</p></li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<ul><li><p>foo[]bar</ul>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<ul><li><p>foo</p></li><li><p>{}bar</p></li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<address><div>foo[]bar</address>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<address><div>foo</div><div>{}bar</div></address>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<address><div>foo[]bar</address>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<address><div>foo</div><div>{}bar</div></address>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<dl><dt><div>foo[]bar</dl>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<dl><dt><div>foo</div></dt><dt><div>{}bar</div></dt></dl>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<dl><dt><div>foo[]bar</dl>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<dl><dt><div>foo</div></dt><dt><div>{}bar</div></dt></dl>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<dl><dd><div>foo[]bar</dl>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<dl><dd><div>foo</div></dd><dd><div>{}bar</div></dd></dl>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<dl><dd><div>foo[]bar</dl>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<dl><dd><div>foo</div></dd><dd><div>{}bar</div></dd></dl>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<ol><li><div>foo[]bar</ol>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<ol><li><div>foo</div></li><li><div>{}bar</div></li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<ol><li><div>foo[]bar</ol>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<ol><li><div>foo</div></li><li><div>{}bar</div></li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<ul><li><div>foo[]bar</ul>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<ul><li><div>foo</div></li><li><div>{}bar</div></li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<ul><li><div>foo[]bar</ul>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<ul><li><div>foo</div></li><li><div>{}bar</div></li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<div><p>foo[]bar</div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div><p>foo</p><p>{}bar</p></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div><p>foo[]bar</div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div><p>foo</p><p>{}bar</p></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<div><div>foo[]bar</div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div><div>foo</div><div>{}bar</div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div><div>foo[]bar</div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div><div>foo</div><div>{}bar</div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<ol><li class=a id=x><p class=b id=y>foo[]</ol>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<ol><li class=\"a\" id=\"x\"><p class=\"b\" id=\"y\">foo</p></li><li class=\"a\"><p class=\"b\">{}<br></p></li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<ol><li class=a id=x><p class=b id=y>foo[]</ol>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<ol><li class=\"a\" id=\"x\"><p class=\"b\" id=\"y\">foo</p></li><li class=\"a\"><p class=\"b\">{}<br></p></li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<div class=a id=x><div class=b id=y>foo[]</div></div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div class=\"a\" id=\"x\"><div class=\"b\" id=\"y\">foo</div><div class=\"b\">{}<br></div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div class=a id=x><div class=b id=y>foo[]</div></div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div class=\"a\" id=\"x\"><div class=\"b\" id=\"y\">foo</div><div class=\"b\">{}<br></div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<div class=a id=x><p class=b id=y>foo[]</div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div class=\"a\" id=\"x\"><p class=\"b\" id=\"y\">foo</p><p class=\"b\">{}<br></p></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div class=a id=x><p class=b id=y>foo[]</div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div class=\"a\" id=\"x\"><p class=\"b\" id=\"y\">foo</p><p class=\"b\">{}<br></p></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<ol><li class=a id=x><p class=b id=y>[]foo</ol>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<ol><li class=\"a\" id=\"x\"><p class=\"b\" id=\"y\"><br></p></li><li class=\"a\"><p class=\"b\">{}foo</p></li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<ol><li class=a id=x><p class=b id=y>[]foo</ol>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<ol><li class=\"a\" id=\"x\"><p class=\"b\" id=\"y\"><br></p></li><li class=\"a\"><p class=\"b\">{}foo</p></li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<div class=a id=x><div class=b id=y>[]foo</div></div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div class=\"a\" id=\"x\"><div class=\"b\" id=\"y\"><br></div><div class=\"b\">{}foo</div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div class=a id=x><div class=b id=y>[]foo</div></div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div class=\"a\" id=\"x\"><div class=\"b\" id=\"y\"><br></div><div class=\"b\">{}foo</div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<div class=a id=x><p class=b id=y>[]foo</div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div class=\"a\" id=\"x\"><p class=\"b\" id=\"y\"><br></p><p class=\"b\">{}foo</p></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div class=a id=x><p class=b id=y>[]foo</div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div class=\"a\" id=\"x\"><p class=\"b\" id=\"y\"><br></p><p class=\"b\">{}foo</p></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<ol><li class=a id=x><p class=b id=y>foo[]bar</ol>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<ol><li class=\"a\" id=\"x\"><p class=\"b\" id=\"y\">foo</p></li><li class=\"a\"><p class=\"b\">{}bar</p></li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<ol><li class=a id=x><p class=b id=y>foo[]bar</ol>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<ol><li class=\"a\" id=\"x\"><p class=\"b\" id=\"y\">foo</p></li><li class=\"a\"><p class=\"b\">{}bar</p></li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<div class=a id=x><div class=b id=y>foo[]bar</div></div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div class=\"a\" id=\"x\"><div class=\"b\" id=\"y\">foo</div><div class=\"b\">{}bar</div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div class=a id=x><div class=b id=y>foo[]bar</div></div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div class=\"a\" id=\"x\"><div class=\"b\" id=\"y\">foo</div><div class=\"b\">{}bar</div></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<div class=a id=x><p class=b id=y>foo[]bar</div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div class=\"a\" id=\"x\"><p class=\"b\" id=\"y\">foo</p><p class=\"b\">{}bar</p></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div class=a id=x><p class=b id=y>foo[]bar</div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div class=\"a\" id=\"x\"><p class=\"b\" id=\"y\">foo</p><p class=\"b\">{}bar</p></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<div contenteditable=false><foo-bar contenteditable><p>foo[]bar</p></foo-bar></div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div contenteditable=\"false\"><foo-bar contenteditable=\"\"><p>foo</p><p>bar</p></foo-bar></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div contenteditable=false><foo-bar contenteditable><p>foo[]bar</p></foo-bar></div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div contenteditable=\"false\"><foo-bar contenteditable=\"\"><p>foo</p><p>bar</p></foo-bar></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<div contenteditable=false><foo-bar contenteditable><div>foo[]bar</div></foo-bar></div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div contenteditable=\"false\"><foo-bar contenteditable=\"\"><div>foo</div><div>bar</div></foo-bar></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertparagraph":[false,false,"",false,false,""]}], +["<div contenteditable=false><foo-bar contenteditable><div>foo[]bar</div></foo-bar></div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div contenteditable=\"false\"><foo-bar contenteditable=\"\"><div>foo</div><div>bar</div></foo-bar></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertparagraph":[false,false,"",false,false,""]}], +["<div>abc[] </div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["<div>abc</div><div><br></div>", + "<div>abc </div><div><br></div>"], + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<div>abc[] </div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["<div>abc</div><div><br></div>", + "<div>abc </div><div><br></div>"], + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<div>abc [] </div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["<div>abc</div><div><br></div>", + "<div>abc </div><div><br></div>", + "<div>abc </div><div><br></div>"], + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<div>[] abc</div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["<div><br></div><div>abc</div>", + "<div><br></div><div> abc</div>"], + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<div>[] abc</div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["<div><br></div><div>abc</div>", + "<div><br></div><div> abc</div>"], + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<div> [] abc</div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["<div><br></div><div>abc</div>", + "<div><br></div><div> abc</div>", + "<div><br></div><div> abc</div>"], + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<div> []abc</div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["<div><br></div><div>abc</div>", + "<div><br></div><div> abc</div>"], + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], + +// TODO: Move the following tests into insertparagraph-or-insertlinebreak-in-inline-editing-host.tentative.html +["<h1 contenteditable=false><span contenteditable>ab[]cd</span></h1>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["<h1 contenteditable=\"false\"><span contenteditable=\"\">ab<br>cd</span></h1>", + "<h1 contenteditable=\"false\"><span contenteditable=\"\">ab<br>cd<br></span></h1>"], + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<ol contenteditable=false><li><span contenteditable>ab[]cd</span></li></ol>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["<ol contenteditable=\"false\"><li><span contenteditable=\"\">ab<br>cd</span></li></ol>", + "<ol contenteditable=\"false\"><li><span contenteditable=\"\">ab<br>cd<br></span></li></ol>"], + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<dl contenteditable=false><dt><span contenteditable>ab[]cd</span></dt></dl>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["<dl contenteditable=\"false\"><dt><span contenteditable=\"\">ab<br>cd</span></dt></dl>", + "<dl contenteditable=\"false\"><dt><span contenteditable=\"\">ab<br>cd<br></span></dt></dl>"], + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<dl contenteditable=false><dd><span contenteditable>ab[]cd</span></dd></dl>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["<dl contenteditable=\"false\"><dd><span contenteditable=\"\">ab<br>cd</span></dd></dl>", + "<dl contenteditable=\"false\"><dd><span contenteditable=\"\">ab<br>cd<br></span></dd></dl>"], + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<div contenteditable=false><h1 contenteditable>ab[]cd</h1></div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["<div contenteditable=\"false\"><h1 contenteditable=\"\">ab<br>cd</h1></div>", + "<div contenteditable=\"false\"><h1 contenteditable=\"\">ab<br>cd<br></h1></div>"], + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<ol contenteditable=false><li contenteditable>ab[]cd</li></ol>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["<ol contenteditable=\"false\"><li contenteditable=\"\"><div>ab</div><div>cd</div></li></ol>", + "<ol contenteditable=\"false\"><li contenteditable=\"\"><div>ab</div><div>cd<br></div></li></ol>"], + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<dl contenteditable=false><dt contenteditable>ab[]cd</dt></dl>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["<dl contenteditable=\"false\"><dt contenteditable=\"\">ab<br>cd</dt></dl>", + "<dl contenteditable=\"false\"><dt contenteditable=\"\">ab<br>cd<br></dt></dl>"], + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<dl contenteditable=false><dd contenteditable>ab[]cd</dd></dl>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["<dl contenteditable=\"false\"><dd contenteditable=\"\"><div>ab</div><div>cd</div></dd></dl>", + "<dl contenteditable=\"false\"><dd contenteditable=\"\"><div>ab</div><div>cd<br></div>/dd></dl>"], + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], + +// The first white-space of the second paragraph must be for making it +// visible, but the other things do not matter for the following tests. +["<div>a[] b</div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div>a</div><div> b</div>", + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +// And if the first paragraph ends with white-space, the text node should be +// followed by <br> element. +["<div>a []b</div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["<div>a <br></div><div>b</div>", + "<div>a </div><div>b</div>"], + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<div>a [] b</div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["<div>a <br></div><div> b</div>", + "<div>a </div><div> b</div>"], + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<div>a [] b</div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["<div>a <br></div><div> b</div>", + "<div>a </div><div> b</div>"], + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +// These tests do not mind about the white-space sequence because it's not +// important here. That's tested by +// editing/other/white-spaces-after-execCommand-*.tentative.html +["<div>a [] b</div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["<div>a <br></div><div> b</div>", + "<div>a </div><div> b</div>", + "<div>a <br></div><div> b</div>", + "<div>a </div><div> b</div>"], + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<div>a [] b</div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["<div>a <br></div><div> b</div>", + "<div>a </div><div> b</div>", + "<div>a <br></div><div> b</div>", + "<div>a </div><div> b</div>"], + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<div>a [] b</div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["<div>a <br></div><div> b</div>", + "<div>a </div><div> b</div>", + "<div>a <br></div><div> b</div>", + "<div>a </div><div> b</div>"], + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<div>a [] b</div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["<div>a <br></div><div> b</div>", + "<div>a </div><div> b</div>", + "<div>a </div><div> b</div>", + "<div>a <br></div><div> b</div>", + "<div>a </div><div> b</div>", + "<div>a </div><div> b</div>"], + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<div>a [] b</div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["<div>a <br></div><div> b</div>", + "<div>a </div><div> b</div>", + "<div>a </div><div> b</div>", + "<div>a <br></div><div> b</div>", + "<div>a </div><div> b</div>", + "<div>a </div><div> b</div>"], + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<div>a [] b</div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["<div>a <br></div><div> b</div>", + "<div>a </div><div> b</div>", + "<div>a </div><div> b</div>", + "<div>a <br></div><div> b</div>", + "<div>a </div><div> b</div>", + "<div>a </div><div> b</div>"], + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<div>a [] b</div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["<div>a <br></div><div> b</div>", + "<div>a </div><div> b</div>", + "<div>a </div><div> b</div>", + "<div>a <br></div><div> b</div>", + "<div>a </div><div> b</div>", + "<div>a </div><div> b</div>"], + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<div>a [] b</div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["<div>a <br></div><div> b</div>", + "<div>a </div><div> b</div>", + "<div>a </div><div> b</div>", + "<div>a <br></div><div> b</div>", + "<div>a </div><div> b</div>", + "<div>a </div><div> b</div>"], + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], + +// insertparagraph with selecting all text in a <div> which is the only +// block in the editing host. +// In this case, the <div> should be unwrapped and a <br> element should be +// put there, then, new paragraph should be created after it. +["<div>[abc]</div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<br><div><br></div>", + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<div>[abc]</div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<br><p><br></p>", + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], + +// insertparagraph with selecting all text in a <p> which is the only block in +// the editing host. +// In this case, the <p> element should become empty but stay here, and new <p> +// element should be created. +["<p>[abc]</p>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<p><br></p><p><br></p>", + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<p>[abc]</p>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p><br></p><p><br></p>", + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], + +// insertparagraph with selecting all text in a paragraph which is not only +// block in the editing host. +// In this case, new same element should be created rather than respecting the +// default paragraph separator, and caret should be moved to the new paragraph. +["<div>abc</div><div>[def]</div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div>abc</div><div><br></div><div><br></div>", + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<div>abc</div><p>[def]</p>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div>abc</div><p><br></p><p><br></p>", + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<div>abc</div><div>[def]</div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div>abc</div><div><br></div><div><br></div>", + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<div>abc</div><p>[def]</p>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<div>abc</div><p><br></p><p><br></p>", + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<div>abc</div><div>[def]</div>", + [["defaultparagraphseparator","div"],["insertparagraph",""],["inserttext","d"]], + ["<div>abc</div><div><br></div><div>d</div>", + "<div>abc</div><div><br></div><div>d<br></div>"], + [true,true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<div>abc</div><p>[def]</p>", + [["defaultparagraphseparator","div"],["insertparagraph",""],["inserttext","d"]], + ["<div>abc</div><p><br></p><p>d</p>", + "<div>abc</div><p><br></p><p>d<br></p>"], + [true,true,true], + {"insertparagraph":[false,false,"",false,false,""]}], + +// insertparagraph with selecting all text in a list-item which is only one of +// the list. +// In this case, the list and list-item elements should be unwrapped and create +// a new paragraph whose type conforms to the default paragraph separator. +["<ol><li>[abc]</li></ol>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div><br></div>", + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<ol><li>[abc]</li></ol>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p><br></p>", + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<ol><li>[abc]</li></ol>", + [["defaultparagraphseparator","div"],["insertparagraph",""],["inserttext","d"]], + ["<div>d</div>", + "<div>d<br></div>"], + [true,true,true], + {"insertparagraph":[false,false,"",false,false,""]}], + +// insertparagraph with selecting all text in a list-item which is the last +// list item in the list. +// In this case, the last list item should be deleted and new paragraph should +// be created after the list element. +["<ol><li>abc</li><li>[def]</li></ol>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<ol><li>abc</li></ol><div><br></div>", + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<ol><li>abc</li><li>[def]</li></ol>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<ol><li>abc</li></ol><p><br></p>", + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<ol><li>abc</li><li>[def]</li></ol>", + [["defaultparagraphseparator","div"],["insertparagraph",""],["inserttext","d"]], + ["<ol><li>abc</li></ol><div>d</div>", + "<ol><li>abc</li></ol><div>d<br></div>"], + [true,true,true], + {"insertparagraph":[false,false,"",false,false,""]}], + +// insertparagraph with selecting all text in a list-item which is not a middle +// list item in the list. +// In this case, the list should be split at the list item, and new paragraph +// should be created between the list elements. +["<ol><li>abc</li><li>[def]</li><li>ghi</li></ol>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<ol><li>abc</li></ol><div><br></div><ol><li>ghi</li></ol>", + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<ol><li>abc</li><li>[def]</li><li>ghi</li></ol>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<ol><li>abc</li></ol><p><br></p><ol><li>ghi</li></ol>", + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<ol><li>abc</li><li>[def]</li><li>ghi</li></ol>", + [["defaultparagraphseparator","div"],["insertparagraph",""],["inserttext","d"]], + ["<ol><li>abc</li></ol><div>d</div><ol><li>ghi</li></ol>", + "<ol><li>abc</li></ol><div>d<br></div><ol><li>ghi</li></ol>"], + [true,true,true], + {"insertparagraph":[false,false,"",false,false,""]}], + +// insertparagraph with selecting all text in a list-item which is the first +// list item in the list. +// In this case, the first list item should be deleted and new paragraph should +// be created before the list element. +["<ol><li>[abc]</li><li>def</li></ol>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div><br></div><ol><li>def</li></ol>", + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<ol><li>[abc]</li><li>def</li></ol>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<p><br></p><ol><li>def</li></ol>", + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<ol><li>[abc]</li><li>def</li></ol>", + [["defaultparagraphseparator","div"],["insertparagraph",""],["inserttext","a"]], + ["<div>a</div><ol><li>def</li></ol>", + "<div>a<br></div><ol><li>def</li></ol>"], + [true,true,true], + {"insertparagraph":[false,false,"",false,false,""]}], + +// insertparagraph with selecting all text in a heading element. +// In this case, the heading element should become empty, but stay there, and +// a new paragraph should be created after it. +["<h3>[abc]</h3>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<h3><br></h3><div><br></div>", + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<h3>[abc]</h3>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<h3><br></h3><p><br></p>", + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<h3>[abc]</h3>", + [["defaultparagraphseparator","div"],["insertparagraph",""],["inserttext","a"]], + ["<h3><br></h3><div>a</div>", + "<h3><br></h3><div>a<br></div>"], + [true,true,true], + {"insertparagraph":[false,false,"",false,false,""]}], + +// insertparagraph with selecting all text in a heading element which is +// followed by a paragraph. +// In this case, the heading element should become empty, but stay there, and +// insert a new paragraph immediately after the heading element. +["<h3>[abc]</h3><div>def</div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<h3><br></h3><div><br></div><div>def</div>", + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<h3>[abc]</h3><div>def</div>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<h3><br></h3><p><br></p><div>def</div>", + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<h3>[abc]</h3><p>def</p>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<h3><br></h3><div><br></div><p>def</p>", + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<h3>[abc]</h3><p>def</p>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + "<h3><br></h3><p><br></p><p>def</p>", + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], + +// Preserve inline elements at splitting the elements at end. It's out of scope +// of these tests that how to treat the <br> element in the left paragraph. +["<div><span style=\"color:rgb(0, 0, 255)\">foo[]</span></div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div><span style=\"color:rgb(0, 0, 255)\">foo</span></div><div><span style=\"color:rgb(0, 0, 255)\"><br></span></div>", + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<div><span style=\"background-color:rgb(0, 0, 255)\">foo[]</span></div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div><span style=\"background-color:rgb(0, 0, 255)\">foo</span></div><div><span style=\"background-color:rgb(0, 0, 255)\"><br></span></div>", + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<div><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\">foo[]</span></span></div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<div><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\">foo</span></span></div><div><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\"><br></span></span></div>", + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<div><span style=\"color:rgb(0, 0, 255)\">foo[]<br></span></div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["<div><span style=\"color:rgb(0, 0, 255)\">foo</span></div><div><span style=\"color:rgb(0, 0, 255)\"><br></span></div>", + "<div><span style=\"color:rgb(0, 0, 255)\">foo<br></span></div><div><span style=\"color:rgb(0, 0, 255)\"><br></span></div>", + "<div><span style=\"color:rgb(0, 0, 255)\">foo</span><br></div><div><span style=\"color:rgb(0, 0, 255)\"><br></span></div>"], + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<div><span style=\"background-color:rgb(0, 0, 255)\">foo[]<br></span></div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["<div><span style=\"background-color:rgb(0, 0, 255)\">foo</span></div><div><span style=\"background-color:rgb(0, 0, 255)\"><br></span></div>", + "<div><span style=\"background-color:rgb(0, 0, 255)\">foo<br></span></div><div><span style=\"background-color:rgb(0, 0, 255)\"><br></span></div>", + "<div><span style=\"background-color:rgb(0, 0, 255)\">foo</span><br></div><div><span style=\"background-color:rgb(0, 0, 255)\"><br></span></div>"], + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<div><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\">foo[]<br></span></span></div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["<div><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\">foo</span></span></div><div><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\"><br></span></span></div>", + "<div><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\">foo<br></span></span></div><div><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\"><br></span></span></div>", + "<div><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\">foo</span></span><br></div><div><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\"><br></span></span></div>"], + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<div><span style=\"color:rgb(0, 0, 255)\">foo[]</span><br></div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["<div><span style=\"color:rgb(0, 0, 255)\">foo</span></div><div><span style=\"color:rgb(0, 0, 255)\"><br></span></div>", + "<div><span style=\"color:rgb(0, 0, 255)\">foo</span><br></div><div><span style=\"color:rgb(0, 0, 255)\"><br></span></div>"], + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<div><span style=\"background-color:rgb(0, 0, 255)\">foo[]</span><br></div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["<div><span style=\"background-color:rgb(0, 0, 255)\">foo</span></div><div><span style=\"background-color:rgb(0, 0, 255)\"><br></span></div>", + "<div><span style=\"background-color:rgb(0, 0, 255)\">foo</span><br></div><div><span style=\"background-color:rgb(0, 0, 255)\"><br></span></div>"], + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<div><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\">foo[]</span></span><br></div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["<div><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\">foo</span></span></div><div><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\"><br></span></span></div>", + "<div><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\">foo</span></span><br></div><div><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\"><br></span></span></div>"], + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<div><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\">foo[]</span><br></span></div>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["<div><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\">foo</span></span></div><div><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\"><br></span></span></div>", + "<div><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\">foo</span><br></span></div><div><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\"><br></span></span></div>", + "<div><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\">foo<br></span></span></div><div><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\"><br></span></span></div>", + "<div><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\">foo</span></span><br></div><div><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\"><br></span></span></div>"], + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], + +// Same things for list-item +["<ul><li><span style=\"color:rgb(0, 0, 255)\">foo[]</span></li></ul>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<ul><li><span style=\"color:rgb(0, 0, 255)\">foo</span></li><li><span style=\"color:rgb(0, 0, 255)\"><br></span></li></ul>", + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<ul><li><span style=\"background-color:rgb(0, 0, 255)\">foo[]</span></li></ul>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<ul><li><span style=\"background-color:rgb(0, 0, 255)\">foo</span></li><li><span style=\"background-color:rgb(0, 0, 255)\"><br></span></li></ul>", + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<ul><li><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\">foo[]</span></span></li></ul>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + "<ul><li><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\">foo</span></span></li><li><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\"><br></span></span></li></ul>", + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<ul><li><span style=\"color:rgb(0, 0, 255)\">foo[]<br></span></li></ul>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["<ul><li><span style=\"color:rgb(0, 0, 255)\">foo</span></li><li><span style=\"color:rgb(0, 0, 255)\"><br></span></li></ul>", + "<ul><li><span style=\"color:rgb(0, 0, 255)\">foo<br></span></li><li><span style=\"color:rgb(0, 0, 255)\"><br></span></li></ul>", + "<ul><li><span style=\"color:rgb(0, 0, 255)\">foo</span><br></li><li><span style=\"color:rgb(0, 0, 255)\"><br></span></li></ul>"], + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<ul><li><span style=\"background-color:rgb(0, 0, 255)\">foo[]<br></span></li></ul>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["<ul><li><span style=\"background-color:rgb(0, 0, 255)\">foo</span></li><li><span style=\"background-color:rgb(0, 0, 255)\"><br></span></li></ul>", + "<ul><li><span style=\"background-color:rgb(0, 0, 255)\">foo<br></span></li><li><span style=\"background-color:rgb(0, 0, 255)\"><br></span></li></ul>", + "<ul><li><span style=\"background-color:rgb(0, 0, 255)\">foo</span><br></li><li><span style=\"background-color:rgb(0, 0, 255)\"><br></span></li></ul>"], + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<ul><li><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\">foo[]<br></span></span></li></ul>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["<ul><li><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\">foo</span></span></li><li><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\"><br></span></span></li></ul>", + "<ul><li><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\">foo<br></span></span></li><li><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\"><br></span></span></li></ul>", + "<ul><li><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\">foo</span></span><br></li><li><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\"><br></span></span></li></ul>"], + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<ul><li><span style=\"color:rgb(0, 0, 255)\">foo[]</span><br></li></ul>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["<ul><li><span style=\"color:rgb(0, 0, 255)\">foo</span></li><li><span style=\"color:rgb(0, 0, 255)\"><br></span></li></ul>", + "<ul><li><span style=\"color:rgb(0, 0, 255)\">foo</span><br></li><li><span style=\"color:rgb(0, 0, 255)\"><br></span></li></ul>"], + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<ul><li><span style=\"background-color:rgb(0, 0, 255)\">foo[]</span><br></li></ul>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["<ul><li><span style=\"background-color:rgb(0, 0, 255)\">foo</span></li><li><span style=\"background-color:rgb(0, 0, 255)\"><br></span></li></ul>", + "<ul><li><span style=\"background-color:rgb(0, 0, 255)\">foo</span><br></li><li><span style=\"background-color:rgb(0, 0, 255)\"><br></span></li></ul>"], + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<ul><li><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\">foo[]</span></span><br></li></ul>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["<ul><li><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\">foo</span></span></li><li><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\"><br></span></span></li></ul>", + "<ul><li><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\">foo</span></span><br></li><li><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\"><br></span></span></li></ul>"], + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], +["<ul><li><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\">foo[]</span><br></span></li></ul>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["<ul><li><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\">foo</span></span></li><li><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\"><br></span></span></li></ul>", + "<ul><li><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\">foo</span><br></span></li><li><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\"><br></span></span></li></ul>", + "<ul><li><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\">foo<br></span></span></li><li><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\"><br></span></span></li></ul>", + "<ul><li><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\">foo</span></span><br></li><li><span style=\"color:rgb(0, 0, 255)\"><span style=\"background-color:rgb(0, 0, 255)\"><br></span></span></li></ul>"], + [true,true], + {"insertparagraph":[false,false,"",false,false,""]}], + +["<p>[X]<span contenteditable=false>abc</span></p>", + [["insertparagraph",""]], + "<p><br></p><p><span contenteditable=\"false\">abc</span></p>", + [true], + {}], +["<p><span contenteditable=false>abc</span>[X]</p>", + [["insertparagraph",""]], + "<p><span contenteditable=\"false\">abc</span></p><p><br></p>", + [true], + {}], + +// When inserting paragraph under the editing host, new paragraph should be +// created and unwrapped lines after the insertion point should be wrapped +// into it at least. +["foo<br>bar[]<br><span contenteditable=\"false\">baz</span>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["foo<br>bar<div><br><span contenteditable=\"false\">baz</span></div>", + "foo<br><div>bar</div><div><br><span contenteditable=\"false\">baz</span></div>"], + [true,true], + {}], +["foo<br>bar[]<br><span>baz</span>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["foo<br>bar<div><br><span>baz</span></div>", + "foo<br><div>bar</div><div><br><span>baz</span></div>"], + [true,true], + {}], +["foo<br>bar[]<br><span contenteditable=\"false\">baz</span>qux", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["foo<br>bar<div><br><span contenteditable=\"false\">baz</span>qux</div>", + "foo<br><div>bar</div><div><br><span contenteditable=\"false\">baz</span>qux</div>"], + [true,true], + {}], +["foo<br>ba[]r<br><span contenteditable=\"false\">baz</span>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["foo<br>ba<div>r<br><span contenteditable=\"false\">baz</span></div>", + "foo<br><div>ba</div><div>r<br><span contenteditable=\"false\">baz</span></div>"], + [true,true], + {}], +["foo<br>ba[]r<br><span>baz</span>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["foo<br>ba<div>r<br><span>baz</span></div>", + "foo<br><div>ba</div><div>r<br><span>baz</span></div>"], + [true,true], + {}], +["foo<br>ba[]r<br><span contenteditable=\"false\">baz</span>qux", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["foo<br>ba<div>r<br><span contenteditable=\"false\">baz</span>qux</div>", + "foo<br><div>ba</div><div>r<br><span contenteditable=\"false\">baz</span>qux</div>"], + [true,true], + {}], +["foo<br>[]bar<br><span contenteditable=\"false\">baz</span>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["foo<br><br><div>bar<br><span contenteditable=\"false\">baz</span></div>", + "foo<br><div><br></div><div>bar<br><span contenteditable=\"false\">baz</span></div>"], + [true,true], + {}], +["foo<br>[]bar<br><span>baz</span>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["foo<br><br><div>bar<br><span>baz</span></div>", + "foo<br><div><br></div><div>bar<br><span>baz</span></div>"], + [true,true], + {}], +["foo<br>[]bar<span contenteditable=\"false\">baz</span>qux", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["foo<br><br><div>bar<span contenteditable=\"false\">baz</span>qux</div>", + "foo<br><div><br></div><div>bar<span contenteditable=\"false\">baz</span>qux</div>"], + [true,true], + {}], +["foo<br>[]bar<span contenteditable=\"false\">baz</span><br>qux", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["foo<br><br><div>bar<span contenteditable=\"false\">baz</span><br>qux</div>", + "foo<br><div><br></div><div>bar<span contenteditable=\"false\">baz</span><br>qux</div>"], + [true,true], + {}], +["foo<br>[]bar<span>baz</span><br>qux", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["foo<br><br><div>bar<span>baz</span><br>qux</div>", + "foo<br><div><br></div><div>bar<span>baz</span><br>qux</div>"], + [true,true], + {}], +// And the new paragraph should be the default paragraph. +["foo<br>bar[]<br><span contenteditable=\"false\">baz</span>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + ["foo<br>bar<p><br><span contenteditable=\"false\">baz</span></p>", + "foo<br><p>bar</p><p><br><span contenteditable=\"false\">baz</span></p>"], + [true,true], + {}], +["foo<br>bar[]<br><span>baz</span>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + ["foo<br>bar<p><br><span>baz</span></p>", + "foo<br><p>bar</p><p><br><span>baz</span></p>"], + [true,true], + {}], +["foo<br>bar[]<br><span contenteditable=\"false\">baz</span>qux", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + ["foo<br>bar<p><br><span contenteditable=\"false\">baz</span>qux</p>", + "foo<br><p>bar</p><p><br><span contenteditable=\"false\">baz</span>qux</p>"], + [true,true], + {}], +["foo<br>ba[]r<br><span contenteditable=\"false\">baz</span>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + ["foo<br>ba<p>r<br><span contenteditable=\"false\">baz</span></p>", + "foo<br><p>ba</p><p>r<br><span contenteditable=\"false\">baz</span></p>"], + [true,true], + {}], +["foo<br>ba[]r<br><span>baz</span>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + ["foo<br>ba<p>r<br><span>baz</span></p>", + "foo<br><p>ba</p><p>r<br><span>baz</span></p>"], + [true,true], + {}], +["foo<br>ba[]r<br><span contenteditable=\"false\">baz</span>qux", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + ["foo<br>ba<p>r<br><span contenteditable=\"false\">baz</span>qux</p>", + "foo<br><p>ba</p><p>r<br><span contenteditable=\"false\">baz</span>qux</p>"], + [true,true], + {}], +["foo<br>[]bar<br><span contenteditable=\"false\">baz</span>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + ["foo<br><br><p>bar<br><span contenteditable=\"false\">baz</span></p>", + "foo<br><p><br></p><p>bar<br><span contenteditable=\"false\">baz</span></p>"], + [true,true], + {}], +["foo<br>[]bar<br><span>baz</span>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + ["foo<br><br><p>bar<br><span>baz</span></p>", + "foo<br><p><br></p><p>bar<br><span>baz</span></p>"], + [true,true], + {}], +["foo<br>[]bar<span contenteditable=\"false\">baz</span>qux", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + ["foo<br><br><p>bar<span contenteditable=\"false\">baz</span>qux</p>", + "foo<br><p><br></p><p>bar<span contenteditable=\"false\">baz</span>qux</p>"], + [true,true], + {}], +["foo<br>[]bar<span contenteditable=\"false\">baz</span><br>qux", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + ["foo<br><br><p>bar<span contenteditable=\"false\">baz</span><br>qux</p>", + "foo<br><p><br></p><p>bar<span contenteditable=\"false\">baz</span><br>qux</p>"], + [true,true], + {}], +["foo<br>[]bar<span>baz</span><br>qux", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + ["foo<br><br><p>bar<span>baz</span><br>qux</p>", + "foo<br><p><br></p><p>bar<span>baz</span><br>qux</p>"], + [true,true], + {}], + +// Inserting paragraph before <br> followed by a blocked <span> should cause +// inserting an empty paragraph to start of the editing host at least. +["{}<br><span style=display:block>abc<br>def<br></span>", + [["defaultparagraphseparator","div"],["insertparagraph",""]], + ["<div><br></div><br><span style=\"display:block\">abc<br>def<br></span>", + "<div><br></div><div><br></div><span style=\"display:block\">abc<br>def<br></span>"], + [true,true], + {}], +["{}<br><span style=display:block>abc<br>def<br></span>", + [["defaultparagraphseparator","p"],["insertparagraph",""]], + ["<p><br></p><br><span style=\"display:block\">abc<br>def<br></span>", + "<p><br></p><p><br></p><span style=\"display:block\">abc<br>def<br></span>"], + [true,true], + {}], +] diff --git a/testing/web-platform/tests/editing/data/inserttext.js b/testing/web-platform/tests/editing/data/inserttext.js new file mode 100644 index 0000000000..8fa8127f2d --- /dev/null +++ b/testing/web-platform/tests/editing/data/inserttext.js @@ -0,0 +1,1548 @@ +// For documentation of the format, see README in this directory. +var browserTests = [ +["foo[bar]baz", + [["inserttext","a"]], + "fooa[]baz", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo[bar]baz", + [["inserttext",""]], + "foo[]baz", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["inserttext","\t"]], + "foo\t[]bar", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["inserttext","&"]], + "foo&[]bar", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["defaultparagraphseparator","div"],["inserttext","\n"]], + "<div>foo</div><div>{}bar</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"div"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["defaultparagraphseparator","p"],["inserttext","\n"]], + "<p>foo</p><p>{}bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["defaultparagraphseparator","div"],["inserttext","abc\ndef"]], + "<div>fooabc</div><div>def[]bar</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["defaultparagraphseparator","p"],["inserttext","abc\ndef"]], + "<p>fooabc</p><p>def[]bar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["inserttext","\u0007"]], + "foo\u0007[]bar", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["inserttext","<b>hi</b>"]], + "foo<b>hi</b>[]bar", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["inserttext","<"]], + "foo<[]bar", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["inserttext","&"]], + "foo&amp;[]bar", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["inserttext"," "]], + "foo []bar", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo []bar", + [["inserttext"," "]], + "foo []bar", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo[] bar", + [["inserttext"," "]], + "foo [] bar", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo []bar", + [["inserttext"," "]], + "foo []bar", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo [] bar", + [["inserttext"," "]], + "foo [] bar", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo[] bar", + [["inserttext"," "]], + "foo [] bar", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo []bar", + [["inserttext"," "]], + "foo []bar", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo [] bar", + [["inserttext"," "]], + "foo [] bar", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo[] bar", + [["inserttext"," "]], + "foo [] bar", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo []bar", + [["inserttext"," "]], + "foo []bar", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo [] bar", + [["inserttext"," "]], + "foo [] bar", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo[] bar", + [["inserttext"," "]], + "foo [] bar", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo [] bar", + [["inserttext"," "]], + "foo [] bar", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo []bar", + [["inserttext"," "]], + "foo []bar", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo [] bar", + [["inserttext"," "]], + "foo [] bar", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["[]foo", + [["inserttext"," "]], + " []foo", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["{}foo", + [["inserttext"," "]], + " []foo", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo[]", + [["inserttext"," "]], + "foo []", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo{}", + [["inserttext"," "]], + "foo []", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo []", + [["inserttext"," "]], + "foo []", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo {}", + [["inserttext"," "]], + "foo []", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo []", + [["inserttext"," "]], + "foo []", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo {}", + [["inserttext"," "]], + "foo []", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<b>foo[]</b>bar", + [["inserttext"," "]], + "<b>foo []</b>bar", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo[]<b>bar</b>", + [["inserttext"," "]], + "foo []<b>bar</b>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo[] ", + [["inserttext"," "]], + "foo []", + [true], + {"inserttext":[false,false,"",false,false,""]}], +[" foo [] ", + [["inserttext"," "]], + " foo []", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo[]<span> </span>", + [["inserttext"," "]], + "foo []<span> </span>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo[]<span> </span> ", + [["inserttext"," "]], + "foo []<span> </span> ", + [true], + {"inserttext":[false,false,"",false,false,""]}], +[" []foo", + [["inserttext"," "]], + " []foo", + [true], + {"inserttext":[false,false,"",false,false,""]}], +[" [] foo ", + [["inserttext"," "]], + " []foo ", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<span> </span>[]foo", + [["inserttext"," "]], + "<span> </span> []foo", + [true], + {"inserttext":[false,false,"",false,false,""]}], +[" <span> </span>[]foo", + [["inserttext"," "]], + " <span> </span> []foo", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["{}<br>", + [["inserttext"," "]], + " []", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<p>{}<br>", + [["inserttext"," "]], + "<p> []</p>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<p>foo[]<p>bar", + [["inserttext"," "]], + "<p>foo []</p><p>bar</p>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<p>foo []<p>bar", + [["inserttext"," "]], + "<p>foo []</p><p>bar</p>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<p>foo[]<p> bar", + [["inserttext"," "]], + "<p>foo []</p><p> bar</p>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<pre>foo[]bar</pre>", + [["inserttext"," "]], + "<pre>foo []bar</pre>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<pre>foo []bar</pre>", + [["inserttext"," "]], + "<pre>foo []bar</pre>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<pre>foo[] bar</pre>", + [["inserttext"," "]], + "<pre>foo [] bar</pre>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<pre>foo []bar</pre>", + [["inserttext"," "]], + "<pre>foo []bar</pre>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<pre>[]foo</pre>", + [["inserttext"," "]], + "<pre> []foo</pre>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<pre>foo[]</pre>", + [["inserttext"," "]], + "<pre>foo []</pre>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<pre>foo []</pre>", + [["inserttext"," "]], + "<pre>foo []</pre>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<pre> foo [] </pre>", + [["inserttext"," "]], + "<pre> foo [] </pre>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div style=white-space:pre>foo[]bar</div>", + [["inserttext"," "]], + "<div style=\"white-space:pre\">foo []bar</div>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div style=white-space:pre>foo []bar</div>", + [["inserttext"," "]], + "<div style=\"white-space:pre\">foo []bar</div>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div style=white-space:pre>foo[] bar</div>", + [["inserttext"," "]], + "<div style=\"white-space:pre\">foo [] bar</div>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div style=white-space:pre>foo []bar</div>", + [["inserttext"," "]], + "<div style=\"white-space:pre\">foo []bar</div>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div style=white-space:pre>[]foo</div>", + [["inserttext"," "]], + "<div style=\"white-space:pre\"> []foo</div>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div style=white-space:pre>foo[]</div>", + [["inserttext"," "]], + "<div style=\"white-space:pre\">foo []</div>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div style=white-space:pre>foo []</div>", + [["inserttext"," "]], + "<div style=\"white-space:pre\">foo []</div>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div style=white-space:pre> foo [] </div>", + [["inserttext"," "]], + "<div style=\"white-space:pre\"> foo [] </div>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div style=white-space:pre-wrap>foo[]bar</div>", + [["inserttext"," "]], + "<div style=\"white-space:pre-wrap\">foo []bar</div>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div style=white-space:pre-wrap>foo []bar</div>", + [["inserttext"," "]], + "<div style=\"white-space:pre-wrap\">foo []bar</div>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div style=white-space:pre-wrap>foo[] bar</div>", + [["inserttext"," "]], + "<div style=\"white-space:pre-wrap\">foo [] bar</div>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div style=white-space:pre-wrap>foo []bar</div>", + [["inserttext"," "]], + "<div style=\"white-space:pre-wrap\">foo []bar</div>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div style=white-space:pre-wrap>[]foo</div>", + [["inserttext"," "]], + "<div style=\"white-space:pre-wrap\"> []foo</div>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div style=white-space:pre-wrap>foo[]</div>", + [["inserttext"," "]], + "<div style=\"white-space:pre-wrap\">foo []</div>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div style=white-space:pre-wrap>foo []</div>", + [["inserttext"," "]], + "<div style=\"white-space:pre-wrap\">foo []</div>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div style=white-space:pre-wrap> foo [] </div>", + [["inserttext"," "]], + "<div style=\"white-space:pre-wrap\"> foo [] </div>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div style=white-space:pre-line>foo[]bar</div>", + [["inserttext"," "]], + "<div style=\"white-space:pre-line\">foo []bar</div>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div style=white-space:pre-line>foo []bar</div>", + [["inserttext"," "]], + "<div style=\"white-space:pre-line\">foo []bar</div>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div style=white-space:pre-line>foo[] bar</div>", + [["inserttext"," "]], + "<div style=\"white-space:pre-line\">foo [] bar</div>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div style=white-space:pre-line>foo []bar</div>", + [["inserttext"," "]], + "<div style=\"white-space:pre-line\">foo []bar</div>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div style=white-space:pre-line>[]foo</div>", + [["inserttext"," "]], + "<div style=\"white-space:pre-line\"> []foo</div>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div style=white-space:pre-line>foo[]</div>", + [["inserttext"," "]], + "<div style=\"white-space:pre-line\">foo []</div>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div style=white-space:pre-line>foo []</div>", + [["inserttext"," "]], + "<div style=\"white-space:pre-line\">foo []</div>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div style=white-space:pre-line> foo [] </div>", + [["inserttext"," "]], + "<div style=\"white-space:pre-line\"> foo []</div>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div style=white-space:nowrap>foo[]bar</div>", + [["inserttext"," "]], + "<div style=\"white-space:nowrap\">foo []bar</div>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div style=white-space:nowrap>foo []bar</div>", + [["inserttext"," "]], + "<div style=\"white-space:nowrap\">foo []bar</div>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div style=white-space:nowrap>foo[] bar</div>", + [["inserttext"," "]], + "<div style=\"white-space:nowrap\">foo [] bar</div>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div style=white-space:nowrap>foo []bar</div>", + [["inserttext"," "]], + "<div style=\"white-space:nowrap\">foo []bar</div>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div style=white-space:nowrap>[]foo</div>", + [["inserttext"," "]], + "<div style=\"white-space:nowrap\"> []foo</div>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div style=white-space:nowrap>foo[]</div>", + [["inserttext"," "]], + "<div style=\"white-space:nowrap\">foo []</div>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div style=white-space:nowrap>foo []</div>", + [["inserttext"," "]], + "<div style=\"white-space:nowrap\">foo []</div>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div style=white-space:nowrap> foo [] </div>", + [["inserttext"," "]], + "<div style=\"white-space:nowrap\"> foo []</div>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["http://a[]", + [["inserttext"," "]], + "<a href=\"http://a\">http://a</a> []", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["ftp://a[]", + [["inserttext"," "]], + "<a href=\"ftp://a\">ftp://a</a> []", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["quasit://a[]", + [["inserttext"," "]], + "<a href=\"quasit://a\">quasit://a</a> []", + [true], + {"inserttext":[false,false,"",false,false,""]}], +[".x-++-.://a[]", + [["inserttext"," "]], + ".<a href=\"x-++-.://a\">x-++-.://a</a> []", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["(http://a)[]", + [["inserttext"," "]], + "(<a href=\"http://a\">http://a</a>) []", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<http://a>[]", + [["inserttext"," "]], + "<<a href=\"http://a\">http://a</a>> []", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["http://a![]", + [["inserttext"," "]], + "<a href=\"http://a\">http://a</a>! []", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["!\"#$%&'()*+,-./:;<=>?^_`|~http://a!\"#$%&'()*+,-./:;<=>?^_`|~[]", + [["inserttext"," "]], + "!\"#$%&'()*+,-./:;<=>?^_`|~<a href=\"http://a!"#$%&'()*+,-./:;<=>?^_`|~\">http://a!\"#$%&'()*+,-./:;<=>?^_`|~</a> []", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["http://a!\"'(),-.:;<>`[]", + [["inserttext"," "]], + "<a href=\"http://a\">http://a</a>!\"'(),-.:;<>` []", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["http://a#$%&*+/=?^_|~[]", + [["inserttext"," "]], + "<a href=\"http://a#$%&*+/=?^_|~\">http://a#$%&*+/=?^_|~</a> []", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["mailto:a[]", + [["inserttext"," "]], + "<a href=\"mailto:a\">mailto:a</a> []", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["a@b[]", + [["inserttext"," "]], + "<a href=\"mailto:a@b\">a@b</a> []", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["a@[]", + [["inserttext"," "]], + "a@ []", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["@b[]", + [["inserttext"," "]], + "@b []", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["#@x[]", + [["inserttext"," "]], + "<a href=\"mailto:#@x\">#@x</a> []", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["a@.[]", + [["inserttext"," "]], + "a@. []", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["!\"#$%&'()*+,-./:;<=>?^_`|~a@b!\"#$%&'()*+,-./:;<=>?^_`|~[]", + [["inserttext"," "]], + "!\"#$%&'()*+,-./:;<=><a href=\"mailto:?^_`|~a@b\">?^_`|~a@b</a>!\"#$%&'()*+,-./:;<=>?^_`|~ []", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<b>a@b</b>{}", + [["inserttext"," "]], + "<a href=\"mailto:a@b\"><b>a@b</b></a> []", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<b>a</b><i>@</i><u>b</u>{}", + [["inserttext"," "]], + "<b>a</b><i>@</i><u>b</u> []", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["a@b<b>[]c</b>", + [["inserttext"," "]], + "<a href=\"mailto:a@b\">a@b</a><b> []c</b>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<p>a@b</p><p>[]c</p>", + [["inserttext"," "]], + "<p>a@b</p><p> []c</p>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["http://a[]", + [["inserttext","a"]], + "http://aa[]", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["http://a[]", + [["inserttext","\t"]], + "<a href=\"http://a\">http://a</a>\t[]", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["http://a[]", + [["inserttext","\f"]], + "<a href=\"http://a\">http://a</a>\f[]", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["http://a[]", + [["inserttext"," "]], + "http://a []", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo[]", + [["inserttext"," "]], + "foo []", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["inserttext","a"]], + "fooa[]bar", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo []", + [["inserttext","a"]], + "foo a[]", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo []", + [["inserttext","a"]], + "foo a[]", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<p>foo[]", + [["inserttext","a"]], + "<p>fooa[]</p>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<p>foo</p>{}", + [["inserttext","a"]], + "<p>foo</p>a[]", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<p>[]foo", + [["inserttext","a"]], + "<p>a[]foo</p>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<p>{}foo", + [["inserttext","a"]], + "<p>a[]foo</p>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["{}<p>foo", + [["inserttext","a"]], + "a[]<p>foo</p>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<p>foo</p>{}<p>bar</p>", + [["inserttext","a"]], + "<p>foo</p>a[]<p>bar</p>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<b>foo[]</b>bar", + [["inserttext","a"]], + "<b>fooa[]</b>bar", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<b>foo</b>[]bar", + [["inserttext","a"]], + "<b>foo</b>a[]bar", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo<b>{}</b>bar", + [["inserttext","a"]], + "foo<b>a[]</b>bar", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<a>foo[]</a>bar", + [["inserttext","a"]], + "<a>fooa[]</a>bar", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<a>foo</a>[]bar", + [["inserttext","a"]], + "<a>foo</a>a[]bar", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<a href=/>foo[]</a>bar", + [["inserttext","a"]], + "<a href=\"/\">fooa[]</a>bar", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<a href=/>foo</a>[]bar", + [["inserttext","a"]], + "<a href=\"/\">foo</a>a[]bar", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<p>fo[o<p>b]ar", + [["defaultparagraphseparator","div"],["inserttext","a"]], + "<p>foa[]ar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"inserttext":[false,false,"",false,false,""]}], +["<p>fo[o<p>b]ar", + [["defaultparagraphseparator","p"],["inserttext","a"]], + "<p>foa[]ar</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"inserttext":[false,false,"",false,false,""]}], +["<p>fo[o<p>bar<p>b]az", + [["defaultparagraphseparator","div"],["inserttext","a"]], + "<p>foa[]az</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"inserttext":[false,false,"",false,false,""]}], +["<p>fo[o<p>bar<p>b]az", + [["defaultparagraphseparator","p"],["inserttext","a"]], + "<p>foa[]az</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"inserttext":[false,false,"",false,false,""]}], +["{}<br>", + [["inserttext","a"]], + "a[]", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<p>{}<br>", + [["inserttext","a"]], + "<p>a[]</p>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<p><span>{}<br></span>", + [["inserttext","a"]], + "<p><span>a[]</span></p>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>[bar]</span>baz", + [["inserttext","a"]], + "<p>foo<span style=\"color:rgb(171, 205, 239)\">a[]</span>baz</p>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>{bar}</span>baz", + [["inserttext","a"]], + "<p>foo<span style=\"color:rgb(171, 205, 239)\">a[]</span>baz</p>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<p>foo{<span style=color:#aBcDeF>bar</span>}baz", + [["inserttext","a"]], + "<p>foo<span style=\"color:rgb(171, 205, 239)\">a[]</span>baz</p>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<p>[foo<span style=color:#aBcDeF>bar]</span>baz", + [["stylewithcss","true"],["inserttext","a"]], + "<p>a[]baz</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["<p>[foo<span style=color:#aBcDeF>bar]</span>baz", + [["stylewithcss","false"],["inserttext","a"]], + "<p>a[]baz</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["<p>{foo<span style=color:#aBcDeF>bar}</span>baz", + [["stylewithcss","true"],["inserttext","a"]], + "<p>a[]baz</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["<p>{foo<span style=color:#aBcDeF>bar}</span>baz", + [["stylewithcss","false"],["inserttext","a"]], + "<p>a[]baz</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>[bar</span>baz]", + [["inserttext","a"]], + "<p>foo<span style=\"color:rgb(171, 205, 239)\">a[]</span></p>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>{bar</span>baz}", + [["inserttext","a"]], + "<p>foo<span style=\"color:rgb(171, 205, 239)\">a[]</span></p>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>[bar</span><span style=color:#fEdCbA>baz]</span>quz", + [["stylewithcss","true"],["inserttext","a"]], + "<p>foo<span style=\"color:rgb(171, 205, 239)\">a[]</span>quz</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["<p>foo<span style=color:#aBcDeF>[bar</span><span style=color:#fEdCbA>baz]</span>quz", + [["stylewithcss","false"],["inserttext","a"]], + "<p>foo<span style=\"color:rgb(171, 205, 239)\">a[]</span>quz</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<b>[bar]</b>baz", + [["inserttext","a"]], + "foo<b>a[]</b>baz", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo<i>[bar]</i>baz", + [["inserttext","a"]], + "foo<i>a[]</i>baz", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo<s>[bar]</s>baz", + [["inserttext","a"]], + "foo<s>a[]</s>baz", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo<sub>[bar]</sub>baz", + [["inserttext","a"]], + "foo<sub>a[]</sub>baz", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo<sup>[bar]</sup>baz", + [["inserttext","a"]], + "foo<sup>a[]</sup>baz", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo<u>[bar]</u>baz", + [["inserttext","a"]], + "foo<u>a[]</u>baz", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo<a href=http://www.google.com>[bar]</a>baz", + [["inserttext","a"]], + "foo<a href=\"http://www.google.com\">a[]</a>baz", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo<font face=sans-serif>[bar]</font>baz", + [["inserttext","a"]], + "foo<font face=\"sans-serif\">a[]</font>baz", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo<font size=4>[bar]</font>baz", + [["inserttext","a"]], + "foo<font size=\"4\">a[]</font>baz", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo<font color=#0000FF>[bar]</font>baz", + [["inserttext","a"]], + "foo<font color=\"#0000FF\">a[]</font>baz", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo<span style=background-color:#00FFFF>[bar]</span>baz", + [["inserttext","a"]], + "foo<span style=\"background-color:rgb(0, 255, 255)\">a[]</span>baz", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo<a href=http://www.google.com><font color=blue>[bar]</font></a>baz", + [["inserttext","a"]], + "foo<a href=\"http://www.google.com\"><font color=\"blue\">a[]</font></a>baz", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo<font color=blue><a href=http://www.google.com>[bar]</a></font>baz", + [["inserttext","a"]], + "foo<font color=\"blue\"><a href=\"http://www.google.com\">a[]</a></font>baz", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo<a href=http://www.google.com><font color=brown>[bar]</font></a>baz", + [["inserttext","a"]], + "foo<a href=\"http://www.google.com\"><font color=\"brown\">a[]</font></a>baz", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo<font color=brown><a href=http://www.google.com>[bar]</a></font>baz", + [["inserttext","a"]], + "foo<font color=\"brown\"><a href=\"http://www.google.com\">a[]</a></font>baz", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo<a href=http://www.google.com><font color=black>[bar]</font></a>baz", + [["inserttext","a"]], + "foo<a href=\"http://www.google.com\"><font color=\"black\">a[]</font></a>baz", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo<a href=http://www.google.com><u>[bar]</u></a>baz", + [["inserttext","a"]], + "foo<a href=\"http://www.google.com\"><u>a[]</u></a>baz", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo<u><a href=http://www.google.com>[bar]</a></u>baz", + [["inserttext","a"]], + "foo<u><a href=\"http://www.google.com\">a[]</a></u>baz", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo<sub><font size=2>[bar]</font></sub>baz", + [["inserttext","a"]], + "foo<sub><font size=\"2\">a[]</font></sub>baz", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo<font size=2><sub>[bar]</sub></font>baz", + [["inserttext","a"]], + "foo<font size=\"2\"><sub>a[]</sub></font>baz", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo<sub><font size=3>[bar]</font></sub>baz", + [["inserttext","a"]], + "foo<sub><font size=\"3\">a[]</font></sub>baz", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo<font size=3><sub>[bar]</sub></font>baz", + [["inserttext","a"]], + "foo<font size=\"3\"><sub>a[]</sub></font>baz", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["[foo<b>bar]</b>baz", + [["stylewithcss","true"],["inserttext","a"]], + "a[]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<b>bar]</b>baz", + [["stylewithcss","false"],["inserttext","a"]], + "a[]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<i>bar]</i>baz", + [["stylewithcss","true"],["inserttext","a"]], + "a[]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<i>bar]</i>baz", + [["stylewithcss","false"],["inserttext","a"]], + "a[]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<s>bar]</s>baz", + [["stylewithcss","true"],["inserttext","a"]], + "a[]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<s>bar]</s>baz", + [["stylewithcss","false"],["inserttext","a"]], + "a[]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<sub>bar]</sub>baz", + [["stylewithcss","true"],["inserttext","a"]], + "a[]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<sub>bar]</sub>baz", + [["stylewithcss","false"],["inserttext","a"]], + "a[]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<sup>bar]</sup>baz", + [["stylewithcss","true"],["inserttext","a"]], + "a[]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<sup>bar]</sup>baz", + [["stylewithcss","false"],["inserttext","a"]], + "a[]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<u>bar]</u>baz", + [["stylewithcss","true"],["inserttext","a"]], + "a[]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<u>bar]</u>baz", + [["stylewithcss","false"],["inserttext","a"]], + "a[]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<a href=http://www.google.com>bar]</a>baz", + [["inserttext","a"]], + "a[]baz", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["[foo<font face=sans-serif>bar]</font>baz", + [["stylewithcss","true"],["inserttext","a"]], + "a[]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<font face=sans-serif>bar]</font>baz", + [["stylewithcss","false"],["inserttext","a"]], + "a[]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<font size=4>bar]</font>baz", + [["stylewithcss","true"],["inserttext","a"]], + "a[]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<font size=4>bar]</font>baz", + [["stylewithcss","false"],["inserttext","a"]], + "a[]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<font color=#0000FF>bar]</font>baz", + [["stylewithcss","true"],["inserttext","a"]], + "a[]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<font color=#0000FF>bar]</font>baz", + [["stylewithcss","false"],["inserttext","a"]], + "a[]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<span style=background-color:#00FFFF>bar]</span>baz", + [["stylewithcss","true"],["inserttext","a"]], + "a[]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<span style=background-color:#00FFFF>bar]</span>baz", + [["stylewithcss","false"],["inserttext","a"]], + "a[]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<a href=http://www.google.com><font color=blue>bar]</font></a>baz", + [["stylewithcss","true"],["inserttext","a"]], + "a[]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<a href=http://www.google.com><font color=blue>bar]</font></a>baz", + [["stylewithcss","false"],["inserttext","a"]], + "a[]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<font color=blue><a href=http://www.google.com>bar]</a></font>baz", + [["stylewithcss","true"],["inserttext","a"]], + "a[]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<font color=blue><a href=http://www.google.com>bar]</a></font>baz", + [["stylewithcss","false"],["inserttext","a"]], + "a[]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<a href=http://www.google.com><font color=brown>bar]</font></a>baz", + [["stylewithcss","true"],["inserttext","a"]], + "a[]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<a href=http://www.google.com><font color=brown>bar]</font></a>baz", + [["stylewithcss","false"],["inserttext","a"]], + "a[]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<font color=brown><a href=http://www.google.com>bar]</a></font>baz", + [["stylewithcss","true"],["inserttext","a"]], + "a[]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<font color=brown><a href=http://www.google.com>bar]</a></font>baz", + [["stylewithcss","false"],["inserttext","a"]], + "a[]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<a href=http://www.google.com><font color=black>bar]</font></a>baz", + [["stylewithcss","true"],["inserttext","a"]], + "a[]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<a href=http://www.google.com><font color=black>bar]</font></a>baz", + [["stylewithcss","false"],["inserttext","a"]], + "a[]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<a href=http://www.google.com><u>bar]</u></a>baz", + [["stylewithcss","true"],["inserttext","a"]], + "a[]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<a href=http://www.google.com><u>bar]</u></a>baz", + [["stylewithcss","false"],["inserttext","a"]], + "a[]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<u><a href=http://www.google.com>bar]</a></u>baz", + [["stylewithcss","true"],["inserttext","a"]], + "a[]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<u><a href=http://www.google.com>bar]</a></u>baz", + [["stylewithcss","false"],["inserttext","a"]], + "a[]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<sub><font size=2>bar]</font></sub>baz", + [["stylewithcss","true"],["inserttext","a"]], + "a[]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<sub><font size=2>bar]</font></sub>baz", + [["stylewithcss","false"],["inserttext","a"]], + "a[]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<font size=2><sub>bar]</sub></font>baz", + [["stylewithcss","true"],["inserttext","a"]], + "a[]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<font size=2><sub>bar]</sub></font>baz", + [["stylewithcss","false"],["inserttext","a"]], + "a[]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<sub><font size=3>bar]</font></sub>baz", + [["stylewithcss","true"],["inserttext","a"]], + "a[]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<sub><font size=3>bar]</font></sub>baz", + [["stylewithcss","false"],["inserttext","a"]], + "a[]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<font size=3><sub>bar]</sub></font>baz", + [["stylewithcss","true"],["inserttext","a"]], + "a[]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<font size=3><sub>bar]</sub></font>baz", + [["stylewithcss","false"],["inserttext","a"]], + "a[]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<b>[bar</b>baz]", + [["inserttext","a"]], + "foo<b>a[]</b>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo<i>[bar</i>baz]", + [["inserttext","a"]], + "foo<i>a[]</i>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo<s>[bar</s>baz]", + [["inserttext","a"]], + "foo<s>a[]</s>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo<sub>[bar</sub>baz]", + [["inserttext","a"]], + "foo<sub>a[]</sub>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo<sup>[bar</sup>baz]", + [["inserttext","a"]], + "foo<sup>a[]</sup>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo<u>[bar</u>baz]", + [["inserttext","a"]], + "foo<u>a[]</u>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo<a href=http://www.google.com>[bar</a>baz]", + [["inserttext","a"]], + "fooa[]", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo<font face=sans-serif>[bar</font>baz]", + [["inserttext","a"]], + "foo<font face=\"sans-serif\">a[]</font>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo<font size=4>[bar</font>baz]", + [["inserttext","a"]], + "foo<font size=\"4\">a[]</font>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo<font color=#0000FF>[bar</font>baz]", + [["inserttext","a"]], + "foo<font color=\"#0000FF\">a[]</font>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo<span style=background-color:#00FFFF>[bar</span>baz]", + [["inserttext","a"]], + "foo<span style=\"background-color:rgb(0, 255, 255)\">a[]</span>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +// <a href> should always be removed if entirely replaced. +["foo<a href=http://www.google.com><font color=blue>[bar</font></a>baz]", + [["inserttext","a"]], + "foo<font color=\"blue\">a[]</font>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo<font color=blue><a href=http://www.google.com>[bar</a></font>baz]", + [["inserttext","a"]], + "foo<font color=\"blue\">a[]</font>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo<a href=http://www.google.com><font color=brown>[bar</font></a>baz]", + [["inserttext","a"]], + "foo<font color=\"brown\">a[]</font>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo<font color=brown><a href=http://www.google.com>[bar</a></font>baz]", + [["inserttext","a"]], + "foo<font color=\"brown\">a[]</font>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo<a href=http://www.google.com><font color=black>[bar</font></a>baz]", + [["inserttext","a"]], + "foo<font color=\"black\">a[]</font>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo<a href=http://www.google.com><u>[bar</u></a>baz]", + [["inserttext","a"]], + "foo<u>a[]</u>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo<u><a href=http://www.google.com>[bar</a></u>baz]", + [["inserttext","a"]], + "foo<u>a[]</u>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo<sub><font size=2>[bar</font></sub>baz]", + [["inserttext","a"]], + "foo<sub><font size=\"2\">a[]</font></sub>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo<font size=2><sub>[bar</sub></font>baz]", + [["inserttext","a"]], + "foo<font size=\"2\"><sub>a[]</sub></font>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo<sub><font size=3>[bar</font></sub>baz]", + [["inserttext","a"]], + "foo<sub><font size=\"3\">a[]</font></sub>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["foo<font size=3><sub>[bar</sub></font>baz]", + [["inserttext","a"]], + "foo<font size=\"3\"><sub>a[]</sub></font>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<blockquote><font color=blue>[foo]</font></blockquote>", + [["inserttext","a"]], + "<blockquote><font color=\"blue\">a[]</font></blockquote>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div>[] abc</div>", + [["inserttext"," "]], + "<div> abc</div>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div> []abc</div>", + [["inserttext"," "]], + "<div> abc</div>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div>[] abc</div>", + [["inserttext"," "]], + "<div> abc</div>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div> [] abc</div>", + [["inserttext"," "]], + "<div> abc</div>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div> []abc</div>", + [["inserttext"," "]], + "<div> abc</div>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div>abc[] </div>", + [["inserttext"," "]], + ["<div>abc </div>", + "<div>abc <br></div>"], + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div>abc []</div>", + [["inserttext"," "]], + ["<div>abc </div>", + "<div>abc <br></div>"], + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div>abc[] </div>", + [["inserttext"," "]], + ["<div>abc </div>", + "<div>abc <br></div>"], + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div>abc [] </div>", + [["inserttext"," "]], + ["<div>abc </div>", + "<div>abc <br></div>"], + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div>abc []</div>", + [["inserttext"," "]], + ["<div>abc </div>", + "<div>abc <br></div>"], + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<br>{}", + [["inserttext","a"]], + ["a", "a<br>"], + [true], + {"inserttext":[false,false,"",false,false,""]}], +["abc<br>{}", + [["inserttext","d"]], + ["abcd", "abcd<br>"], + [true], + {"inserttext":[false,false,"",false,false,""]}], +["abc<br>{}<br>", + [["inserttext","d"]], + ["abc<br>d", + "abc<br>d<br>"], + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<span contenteditable=false>abc</span><br>{}", + [["inserttext","d"]], + ["<span contenteditable=\"false\">abc</span>d", + "<span contenteditable=\"false\">abc</span>d<br>"], + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div contenteditable=false><span contenteditable><br>{}</span></div>", + [["inserttext","a"]], + ["<div contenteditable=\"false\"><span contenteditable=\"\">a</span></div>", + "<div contenteditable=\"false\"><span contenteditable=\"\">a<br></span></div>"], + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div contenteditable=false><span contenteditable>abc<br>{}</span></div>", + [["inserttext","d"]], + ["<div contenteditable=\"false\"><span contenteditable=\"\">abcd</span></div>", + "<div contenteditable=\"false\"><span contenteditable=\"\">abcd<br></span></div>"], + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div style=white-space:pre>foo[]bar</div>", + [["inserttext"," "]], + "<div style=\"white-space:pre\">foo bar</div>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div style=white-space:pre>foo[]</div>", + [["inserttext"," "]], + "<div style=\"white-space:pre\">foo </div>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div style=white-space:pre-wrap>foo[]bar</div>", + [["inserttext"," "]], + "<div style=\"white-space:pre-wrap\">foo bar</div>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div style=white-space:pre-wrap>foo[]</div>", + [["inserttext"," "]], + "<div style=\"white-space:pre-wrap\">foo </div>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +// FYI: The white-space sequence different does not matter here. It's tested +// in white-spaces-after-execCommand-inserttext.tentative.html. +["<div style=white-space:pre-line>foo[]bar</div>", + [["inserttext"," "]], + [ + "<div style=\"white-space:pre-line\">foo bar</div>", + "<div style=\"white-space:pre-line\">foo bar</div>", + "<div style=\"white-space:pre-line\">foo bar</div>", + ], + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div style=white-space:pre-line>foo[]</div>", + [["inserttext"," "]], + [ + "<div style=\"white-space:pre-line\">foo </div>", + "<div style=\"white-space:pre-line\">foo </div>", + "<div style=\"white-space:pre-line\">foo \n</div>", + "<div style=\"white-space:pre-line\">foo \n</div>", + "<div style=\"white-space:pre-line\">foo <br></div>", + "<div style=\"white-space:pre-line\">foo <br></div>", + ], + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div style=white-space:nowrap>foo[]bar</div>", + [["inserttext"," "]], + [ + "<div style=\"white-space:nowrap\">foo bar</div>", + "<div style=\"white-space:nowrap\">foo bar</div>", + "<div style=\"white-space:nowrap\">foo bar</div>", + ], + [true], + {"inserttext":[false,false,"",false,false,""]}], +["<div style=white-space:nowrap>foo[]</div>", + [["inserttext"," "]], + [ + "<div style=\"white-space:nowrap\">foo </div>", + "<div style=\"white-space:nowrap\">foo </div>", + "<div style=\"white-space:nowrap\">foo \n</div>", + "<div style=\"white-space:nowrap\">foo \n</div>", + "<div style=\"white-space:nowrap\">foo <br></div>", + "<div style=\"white-space:nowrap\">foo <br></div>", + ], + [true], + {"inserttext":[false,false,"",false,false,""]}], +// If selection is after a <br> element in a block and the <br> element follows +// last visible thing in the block, content should be inserted before the <br> +// element. +["<p>a<br>{}<span></span></p>", + [["inserttext","b"]], + "<p>ab<br><span></span></p>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +// In this case, the <span> element after <br> element is visible and is put in +// the second line, but for backward compatibility, typing text should be +// inserted before the <br> element. +["<p style=\"white-space:pre-wrap\">a<br>{}<span style=\"padding:1px\"></span></p>", + [["inserttext","b"]], + "<p style=\"white-space:pre-wrap\">ab<br><span style=\"padding:1px\"></span></p>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +// Similar case if <br> follows last visible thing and is followed by invisible +// inline element and a block. In this case, Chrome inserts text into the +// following block so that the expectation follows it. +["<div>a<br>{}<span></span><p>c</p></div>", + [["inserttext","b"]], + "<div>a<br><span></span><p>bc</p></div>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +// And even if the <br> element is followed by visible but empty inline element, +// should be same as previous test. +["<div style=\"white-space:pre-wrap\">a<br>{}<span style=\"padding:1px\"></span><p>c</p></div>", + [["inserttext","b"]], + "<div style=\"white-space:pre-wrap\">a<br><span style=\"padding:1px\"></span><p>bc</p></div>", + [true], + {"inserttext":[false,false,"",false,false,""]}], +// https://bugzilla.mozilla.org/show_bug.cgi?id=1785801 +["<div>abc{</div><div>}efg</div>", + [["inserttext", "d"]], + "<div>abcdefg</div>", + [true], + {"inserttext":[false,false,"",false,false,""]}], + +// Tests preserving inline style of the last visible thing in the selection +// for replacing text. +["<div>abc{<b><i>def</i></b>}ghi</div>", + [["inserttext","d"],["inserttext","e"],["inserttext","f"]], + "<div>abc<b><i>def</i></b>ghi</div>", + [true,true,true], + {}], +["<div>abc<b><i>[def]</i></b>ghi</div>", + [["inserttext","d"],["inserttext","e"],["inserttext","f"]], + "<div>abc<b><i>def</i></b>ghi</div>", + [true,true,true], + {}], +["<div>abc[<b><i>def]</i></b>ghi</div>", + [["inserttext","d"],["inserttext","e"],["inserttext","f"]], + "<div>abc<b><i>def</i></b>ghi</div>", + [true,true,true], + {}], +["<div>abc<b><i>[def</i></b>]ghi</div>", + [["inserttext","d"],["inserttext","e"],["inserttext","f"]], + "<div>abc<b><i>def</i></b>ghi</div>", + [true,true,true], + {}], +["<div>abc<b><i>[def</i></b>g]hi</div>", + [["inserttext","d"],["inserttext","e"],["inserttext","f"],["inserttext","g"]], + "<div>abc<b><i>defg</i></b>hi</div>", + [true,true,true,true], + {}], +["<div>abc[<b><i>def</i></b>g]hi</div>", + [["inserttext","d"],["inserttext","e"],["inserttext","f"],["inserttext","g"]], + "<div>abc<b><i>defg</i></b>hi</div>", + [true,true,true,true], + {}], +["<div>abc{<b><i>def</i></b>g]hi</div>", + [["inserttext","d"],["inserttext","e"],["inserttext","f"],["inserttext","g"]], + "<div>abc<b><i>defg</i></b>hi</div>", + [true,true,true,true], + {}], +// Don't preserve inline styles if first content is <img> and it's replaced. +["<div>abc[<b><i><img src=\"/img/lion.svg\">de]f</i></b>ghi</div>", + [["inserttext","d"],["inserttext","e"]], + "<div>abcde<b><i>f</i></b>ghi</div>", + [true,true], + {}], +["<div>abc[<b><i><img src=\"/img/lion.svg\">def]</i></b>ghi</div>", + [["inserttext","d"],["inserttext","e"],["inserttext","f"]], + "<div>abcdefghi</div>", + [true,true,true], + {}], +["<div>abc[<b><i><img src=\"/img/lion.svg\">def</i></b>]ghi</div>", + [["inserttext","d"],["inserttext","e"],["inserttext","f"]], + "<div>abcdefghi</div>", + [true,true,true], + {}], +["<div>abc{<b><i><img src=\"/img/lion.svg\">def</i></b>]ghi</div>", + [["inserttext","d"],["inserttext","e"],["inserttext","f"]], + "<div>abcdefghi</div>", + [true,true,true], + {}], +// Don't preserve inline styles even if end boundary is styled. +["<div>ab[c<b><i>de]f</i></b>ghi</div>", + [["inserttext","c"],["inserttext","d"],["inserttext","e"]], + "<div>abcde<b><i>f</i></b>ghi</div>", + [true,true,true], + {}], +// But preserve inline styles if first content is styled. +["<div>abc[<b><i>de]f</i></b>ghi</div>", + [["inserttext","d"],["inserttext","e"]], + "<div>abc<b><i>def</i></b>ghi</div>", + [true,true], + {}], +["<div>abc{<b><i>de]f</i></b>ghi</div>", + [["inserttext","d"],["inserttext","e"]], + "<div>abc<b><i>def</i></b>ghi</div>", + [true,true], + {}], +// Don't preserve empty inline style, but preserve the following text style if first content is text +["<div>abc[<s></s><b><i>de]f</i></b>ghi</div>", + [["inserttext","d"],["inserttext","e"]], + ["<div>abc<b><i>def</i></b>ghi</div>", + "<div>abc<s></s><b><i>def</i></b>ghi</div>"], + [true,true], + {}], +["<div>abc{<s></s><b><i>de]f</i></b>ghi</div>", + [["inserttext","d"],["inserttext","e"]], + ["<div>abc<b><i>def</i></b>ghi</div>", + "<div>abc<s></s><b><i>def</i></b>ghi</div>"], + [true,true], + {}], +// Don't remove parent blocks of selection start to insert new text into the +// selection start container. +["<div>{abc</div><div>def</div>}", + [["inserttext","g"],["inserttext","h"]], + ["<div>gh</div>", + "<div>gh<br></div>"], + [true,true], + {}], +["<div>abc</div><div>{def</div>}", + [["inserttext","g"],["inserttext","h"]], + ["<div>abc</div><div>gh</div>", + "<div>abc</div><div>gh<br></div>"], + [true,true], + {}], +["<div style=display:flex><span>{abc</span><span>def</span>}</div>", + [["inserttext","g"],["inserttext","h"]], + ["<div style=\"display:flex\"><span>gh</span></div>", + "<div style=\"display:flex\"><span>gh<br></span></div>"], + [true,true], + {}], +["<div style=display:flex><span>abc</span><span>{def</span>}</div>", + [["inserttext","g"],["inserttext","h"]], + ["<div style=\"display:flex\"><span>abc</span><span>gh</span></div>", + "<div style=\"display:flex\"><span>abc</span><span>gh<br></span></div>"], + [true,true], + {}], +["<div style=display:grid><span>{abc</span><span>def</span>}</div>", + [["inserttext","g"],["inserttext","h"]], + ["<div style=\"display:grid\"><span>gh</span></div>", + "<div style=\"display:grid\"><span>gh<br></span></div>"], + [true,true], + {}], +["<div style=display:grid><span>abc</span><span>{def</span>}</div>", + [["inserttext","g"],["inserttext","h"]], + ["<div style=\"display:grid\"><span>abc</span><span>gh</span></div>", + "<div style=\"display:grid\"><span>abc</span><span>gh<br></span></div>"], + [true,true], + {}], +// The inline style at selection start should be preserved for typed text. +["<div><b>{abc</b></div><div>def</div>}", + [["inserttext","g"],["inserttext","h"]], + ["<div><b>gh</b></div>", + "<div><b>gh<br></b></div>"], + [true,true], + {}], +["<div>abc</div><div><b>{def</b></div>}", + [["inserttext","g"],["inserttext","h"]], + ["<div>abc</div><div><b>gh</b></div>", + "<div>abc</div><div><b>gh<br></b></div>"], + [true,true], + {}], +["<div style=display:flex><span><b>{abc</b></span><span>def</span>}</div>", + [["inserttext","g"],["inserttext","h"]], + ["<div style=\"display:flex\"><span><b>gh</b></span></div>", + "<div style=\"display:flex\"><span><b>gh<br></b></span></div>"], + [true,true], + {}], +["<div style=display:flex><span>abc</span><span><b>{def</b></span>}</div>", + [["inserttext","g"],["inserttext","h"]], + ["<div style=\"display:flex\"><span>abc</span><span><b>gh</b></span></div>", + "<div style=\"display:flex\"><span>abc</span><span><b>gh<br></b></span></div>"], + [true,true], + {}], +["<div style=display:grid><span><b>{abc</b></span><span>def</span>}</div>", + [["inserttext","g"],["inserttext","h"]], + ["<div style=\"display:grid\"><span><b>gh</b></span></div>", + "<div style=\"display:grid\"><span><b>gh<br></b></span></div>"], + [true,true], + {}], +["<div style=display:grid><span>abc</span><span><b>{def</b></span>}</div>", + [["inserttext","g"],["inserttext","h"]], + ["<div style=\"display:grid\"><span>abc</span><span><b>gh</b></span></div>", + "<div style=\"display:grid\"><span>abc</span><span><b>gh<br></b></span></div>"], + [true,true], + {}], +] diff --git a/testing/web-platform/tests/editing/data/insertunorderedlist.js b/testing/web-platform/tests/editing/data/insertunorderedlist.js new file mode 100644 index 0000000000..6401e8d967 --- /dev/null +++ b/testing/web-platform/tests/editing/data/insertunorderedlist.js @@ -0,0 +1,859 @@ +// For documentation of the format, see README in this directory. +var browserTests = [ +["foo[]bar", + [["insertunorderedlist",""]], + "<ul><li>foo[]bar</li></ul>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["foo[bar]baz", + [["insertunorderedlist",""]], + "<ul><li>foo[bar]baz</li></ul>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["foo<br>[bar]", + [["insertunorderedlist",""]], + "foo<ul><li>[bar]</li></ul>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["f[oo<br>b]ar<br>baz", + [["insertunorderedlist",""]], + "<ul><li>f[oo</li><li>b]ar</li></ul>baz", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["<p>[foo]<br>bar</p>", + [["insertunorderedlist",""]], + "<ul><li>[foo]</li></ul><p>bar</p>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["[foo<ol><li>bar]</ol>baz", + [["insertunorderedlist",""]], + "<ul><li>[foo</li><li>bar]</li></ul>baz", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["foo<ol><li>[bar</ol>baz]", + [["insertunorderedlist",""]], + "foo<ul><li>[bar</li><li>baz]</li></ul>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["[foo<ul><li>bar]</ul>baz", + [["insertunorderedlist",""]], + "<ul><li>[foo</li><li>bar]</li></ul>baz", + [true], + {"insertunorderedlist":[true,false,"",false,true,""]}], +["foo<ul><li>[bar</ul>baz]", + [["insertunorderedlist",""]], + "foo<ul><li>[bar</li><li>baz]</li></ul>", + [true], + {"insertunorderedlist":[true,false,"",false,true,""]}], +["foo<ul><li>[bar</ul><ol><li>baz]</ol>quz", + [["insertunorderedlist",""]], + "foo<ul><li>[bar</li><li>baz]</li></ul>quz", + [true], + {"insertunorderedlist":[true,false,"",false,true,""]}], +["foo<ol><li>[bar</ol><ul><li>baz]</ul>quz", + [["insertunorderedlist",""]], + "foo<ul><li>[bar</li><li>baz]</li></ul>quz", + [true], + {"insertunorderedlist":[true,false,"",false,true,""]}], +["<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>", + [["insertunorderedlist",""]], + "<table><tbody><tr><td>foo</td><td><ul><li>b[a]r</li></ul></td><td>baz</td></tr></tbody></table>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["<table><tbody><tr><td>fo[o<td>b]ar<td>baz</table>", + [["insertunorderedlist",""]], + "<table><tbody><tr><td><ul><li>fo[o</li></ul></td><td><ul><li>b]ar</li></ul></td><td>baz</td></tr></tbody></table>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["{<table><tr><td>foo<td>bar<td>baz</table>}", + [["insertunorderedlist",""]], + "<ul><li>{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</li></ul>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["<p>foo<p>[bar]<p>baz", + [["defaultparagraphseparator","div"],["insertunorderedlist",""]], + "<p>foo</p><ul><li>[bar]</li></ul><p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"div"],"insertunorderedlist":[false,false,"",false,true,""]}], +["<p>foo<p>[bar]<p>baz", + [["defaultparagraphseparator","p"],["insertunorderedlist",""]], + "<p>foo</p><ul><li>[bar]</li></ul><p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertunorderedlist":[false,false,"",false,true,""]}], +["<p>foo<blockquote>[bar]</blockquote><p>baz", + [["insertunorderedlist",""]], + "<p>foo</p><blockquote><ul><li>[bar]</li></ul></blockquote><p>baz</p>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["<dl><dt>foo<dd>[bar]<dt>baz<dd>quz</dl>", + [["insertunorderedlist",""]], + "<dl><dt>foo</dt><dd><ul><li>[bar]</li></ul></dd><dt>baz</dt><dd>quz</dd></dl>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["<dl><dt>foo<dd>bar<dt>[baz]<dd>quz</dl>", + [["insertunorderedlist",""]], + "<dl><dt>foo</dt><dd>bar</dd><dt><ul><li>[baz]</li></ul></dt><dd>quz</dd></dl>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["<p>[foo<p>bar]<p>baz", + [["defaultparagraphseparator","div"],["insertunorderedlist",""]], + "<ul><li>[foo</li><li>bar]</li></ul><p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertunorderedlist":[false,false,"",false,true,""]}], +["<p>[foo<p>bar]<p>baz", + [["defaultparagraphseparator","p"],["insertunorderedlist",""]], + "<ul><li>[foo</li><li>bar]</li></ul><p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertunorderedlist":[false,false,"",false,true,""]}], +["<p>[foo<blockquote>bar]</blockquote><p>baz", + [["defaultparagraphseparator","div"],["insertunorderedlist",""]], + "<ul><li>[foo</li><ul><li>bar]</li></ul></ul><p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertunorderedlist":[false,false,"",false,true,""]}], +["<p>[foo<blockquote>bar]</blockquote><p>baz", + [["defaultparagraphseparator","p"],["insertunorderedlist",""]], + "<ul><li>[foo</li><ul><li>bar]</li></ul></ul><p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertunorderedlist":[false,false,"",false,true,""]}], +["<dl><dt>[foo<dd>bar]<dt>baz<dd>quz</dl>", + [["insertunorderedlist",""]], + "<dl><dt><ul><li>[foo</li></ul></dt><dd><ul><li>bar]</li></ul></dd><dt>baz</dt><dd>quz</dd></dl>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["<dl><dt>foo<dd>[bar<dt>baz]<dd>quz</dl>", + [["insertunorderedlist",""]], + "<dl><dt>foo</dt><dd><ul><li>[bar</li></ul></dd><dt><ul><li>baz]</li></ul></dt><dd>quz</dd></dl>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["<p>[foo<blockquote><p>bar]<p>baz</blockquote>", + [["defaultparagraphseparator","div"],["insertunorderedlist",""]], + "<ul><li>[foo</li><ul><li>bar]</li></ul></ul><blockquote><p>baz</p></blockquote>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertunorderedlist":[false,false,"",false,true,""]}], +["<p>[foo<blockquote><p>bar]<p>baz</blockquote>", + [["defaultparagraphseparator","p"],["insertunorderedlist",""]], + "<ul><li>[foo</li><ul><li>bar]</li></ul></ul><blockquote><p>baz</p></blockquote>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertunorderedlist":[false,false,"",false,true,""]}], +["<ol><li>foo<li>[bar]<li>baz</ol>", + [["insertunorderedlist",""]], + "<ol><li>foo</li></ol><ul><li>[bar]</li></ul><ol><li>baz</li></ol>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["<ol><li>foo</ol>[bar]", + [["insertunorderedlist",""]], + "<ol><li>foo</li></ol><ul><li>[bar]</li></ul>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["[foo]<ol><li>bar</ol>", + [["insertunorderedlist",""]], + "<ul><li>[foo]</li></ul><ol><li>bar</li></ol>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["<ol><li>foo</ol>[bar]<ol><li>baz</ol>", + [["insertunorderedlist",""]], + "<ol><li>foo</li></ol><ul><li>[bar]</li></ul><ol><li>baz</li></ol>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["<ol><ol><li>[foo]</ol></ol>", + [["insertunorderedlist",""]], + "<ul><ul><li>[foo]</li></ul></ul>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["<ol><li>[foo]<br>bar<li>baz</ol>", + [["insertunorderedlist",""]], + "<ul><li>[foo]<br>bar</li></ul><ol><li>baz</li></ol>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["<ol><li>foo<br>[bar]<li>baz</ol>", + [["insertunorderedlist",""]], + "<ul><li>foo<br>[bar]</li></ul><ol><li>baz</li></ol>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["<ol><li><div>[foo]</div>bar<li>baz</ol>", + [["insertunorderedlist",""]], + "<ul><li><div>[foo]</div>bar</li></ul><ol><li>baz</li></ol>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["<ol><li>foo<ol><li>[bar]<li>baz</ol><li>quz</ol>", + [["insertunorderedlist",""]], + "<ol><li>foo</li><ul><li>[bar]</li></ul><ol><li>baz</li></ol><li>quz</li></ol>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["<ol><li>foo<ol><li>bar<li>[baz]</ol><li>quz</ol>", + [["insertunorderedlist",""]], + "<ol><li>foo</li><ol><li>bar</li></ol><ul><li>[baz]</li></ul><li>quz</li></ol>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["<ol><li>foo</li><ol><li>[bar]<li>baz</ol><li>quz</ol>", + [["insertunorderedlist",""]], + "<ol><li>foo</li><ul><li>[bar]</li></ul><ol><li>baz</li></ol><li>quz</li></ol>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["<ol><li>foo</li><ol><li>bar<li>[baz]</ol><li>quz</ol>", + [["insertunorderedlist",""]], + "<ol><li>foo</li><ol><li>bar</li></ol><ul><li>[baz]</li></ul><li>quz</li></ol>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["<ol><li>[foo]<ol><li>bar</ol><li>baz</ol>", + [["insertunorderedlist",""]], + "<ul><li>[foo]</li></ul><ol><ol><li>bar</li></ol><li>baz</li></ol>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["<ol><li>[foo]</li><ol><li>bar</ol><li>baz</ol>", + [["insertunorderedlist",""]], + "<ul><li>[foo]</li></ul><ol><ol><li>bar</li></ol><li>baz</li></ol>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["<ol><li>foo<li>[bar]<ol><li>baz</ol><li>quz</ol>", + [["insertunorderedlist",""]], + "<ol><li>foo</li></ol><ul><li>[bar]</li></ul><ol><ol><li>baz</li></ol><li>quz</li></ol>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["<ol><li>foo<li>[bar]</li><ol><li>baz</ol><li>quz</ol>", + [["insertunorderedlist",""]], + "<ol><li>foo</li></ol><ul><li>[bar]</li></ul><ol><ol><li>baz</li></ol><li>quz</li></ol>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["<ol><li>foo<ol><li>bar<li>baz</ol><li>[quz]</ol>", + [["insertunorderedlist",""]], + "<ol><li>foo<ol><li>bar</li><li>baz</li></ol></li></ol><ul><li>[quz]</li></ul>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["<ol><li>foo</li><ol><li>bar<li>baz</ol><li>[quz]</ol>", + [["insertunorderedlist",""]], + "<ol><li>foo</li><ol><li>bar</li><li>baz</li></ol></ol><ul><li>[quz]</li></ul>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["<ol><li>foo<li>[bar<li>baz]</ol>", + [["insertunorderedlist",""]], + "<ol><li>foo</li></ol><ul><li>[bar</li><li>baz]</li></ul>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["<ol><li>[foo<ol><li>bar]</ol><li>baz</ol>", + [["insertunorderedlist",""]], + "<ul><li>[foo</li><ul><li>bar]</li></ul></ul><ol><li>baz</li></ol>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["<ol><li>foo<ol><li>b[ar</ol><li>b]az</ol>", + [["insertunorderedlist",""]], + "<ol><li>foo</li></ol><ul><ul><li>b[ar</li></ul><li>b]az</li></ul>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["<ol><li>[foo<ol><li>bar</ol><li>baz]</ol><p>extra", + [["insertunorderedlist",""]], + "<ul><li>[foo</li><ul><li>bar</li></ul><li>baz]</li></ul><p>extra</p>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["<ol><li>[foo]<ol><li>bar</ol>baz</ol>", + [["insertunorderedlist",""]], + "<ul><li>[foo]</li></ul><ol><ol><li>bar</li></ol><li>baz</li></ol>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["<ol><li>foo<ol><li>[bar]</ol>baz</ol>", + [["insertunorderedlist",""]], + "<ol><li>foo</li><ul><li>[bar]</li></ul><li>baz</li></ol>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["<ol><li>foo<ol><li>bar</ol>[baz]</ol>", + [["insertunorderedlist",""]], + "<ol><li>foo</li><ol><li>bar</li></ol></ol><ul><li>[baz]</li></ul>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["<ol><li>[foo<ol><li>bar]</ol>baz</ol>", + [["insertunorderedlist",""]], + "<ul><li>[foo</li><ul><li>bar]</li></ul></ul><ol><li>baz</li></ol>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["<ul><li>foo<li>[bar]<li>baz</ul>", + [["defaultparagraphseparator","div"],["insertunorderedlist",""]], + "<ul><li>foo</li></ul><div>[bar]</div><ul><li>baz</li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul><li>foo<li>[bar]<li>baz</ul>", + [["defaultparagraphseparator","p"],["insertunorderedlist",""]], + "<ul><li>foo</li></ul><p>[bar]</p><ul><li>baz</li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul><li>foo</ul>[bar]", + [["insertunorderedlist",""]], + "<ul><li>foo</li><li>[bar]</li></ul>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["[foo]<ul><li>bar</ul>", + [["insertunorderedlist",""]], + "<ul><li>[foo]</li><li>bar</li></ul>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["<ul><li>foo</ul>[bar]<ul><li>baz</ul>", + [["insertunorderedlist",""]], + "<ul><li>foo</li><li>[bar]</li><li>baz</li></ul>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["<ul><ul><li>[foo]</ul></ul>", + [["insertunorderedlist",""]], + "<ul><li>[foo]</li></ul>", + [true], + {"insertunorderedlist":[false,true,"",false,true,""]}], +["<ul><li>[foo]<br>bar<li>baz</ul>", + [["defaultparagraphseparator","div"],["insertunorderedlist",""]], + "<div>[foo]<br>bar</div><ul><li>baz</li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul><li>[foo]<br>bar<li>baz</ul>", + [["defaultparagraphseparator","p"],["insertunorderedlist",""]], + "<p>[foo]<br>bar</p><ul><li>baz</li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul><li>foo<br>[bar]<li>baz</ul>", + [["defaultparagraphseparator","div"],["insertunorderedlist",""]], + "<div>foo<br>[bar]</div><ul><li>baz</li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul><li>foo<br>[bar]<li>baz</ul>", + [["defaultparagraphseparator","p"],["insertunorderedlist",""]], + "<p>foo<br>[bar]</p><ul><li>baz</li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul><li><div>[foo]</div>bar<li>baz</ul>", + [["defaultparagraphseparator","div"],["insertunorderedlist",""]], + "<div>[foo]</div><div>bar</div><ul><li>baz</li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul><li><div>[foo]</div>bar<li>baz</ul>", + [["defaultparagraphseparator","p"],["insertunorderedlist",""]], + "<div>[foo]</div><p>bar</p><ul><li>baz</li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul><li>foo<ul><li>[bar]<li>baz</ul><li>quz</ul>", + [["insertunorderedlist",""]], + "<ul><li>foo</li><li>[bar]</li><ul><li>baz</li></ul><li>quz</li></ul>", + [true], + {"insertunorderedlist":[false,true,"",false,true,""]}], +["<ul><li>foo<ul><li>bar<li>[baz]</ul><li>quz</ul>", + [["insertunorderedlist",""]], + "<ul><li>foo</li><ul><li>bar</li></ul><li>[baz]</li><li>quz</li></ul>", + [true], + {"insertunorderedlist":[false,true,"",false,true,""]}], +["<ul><li>foo</li><ul><li>[bar]<li>baz</ul><li>quz</ul>", + [["insertunorderedlist",""]], + "<ul><li>foo</li><li>[bar]</li><ul><li>baz</li></ul><li>quz</li></ul>", + [true], + {"insertunorderedlist":[false,true,"",false,true,""]}], +["<ul><li>foo</li><ul><li>bar<li>[baz]</ul><li>quz</ul>", + [["insertunorderedlist",""]], + "<ul><li>foo</li><ul><li>bar</li></ul><li>[baz]</li><li>quz</li></ul>", + [true], + {"insertunorderedlist":[false,true,"",false,true,""]}], +["<ul><li>[foo]<ul><li>bar</ul><li>baz</ul>", + [["defaultparagraphseparator","div"],["insertunorderedlist",""]], + "<div>[foo]</div><ul><ul><li>bar</li></ul><li>baz</li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul><li>[foo]<ul><li>bar</ul><li>baz</ul>", + [["defaultparagraphseparator","p"],["insertunorderedlist",""]], + "<p>[foo]</p><ul><ul><li>bar</li></ul><li>baz</li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul><li>[foo]</li><ul><li>bar</ul><li>baz</ul>", + [["defaultparagraphseparator","div"],["insertunorderedlist",""]], + "<div>[foo]</div><ul><ul><li>bar</li></ul><li>baz</li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul><li>[foo]</li><ul><li>bar</ul><li>baz</ul>", + [["defaultparagraphseparator","p"],["insertunorderedlist",""]], + "<p>[foo]</p><ul><ul><li>bar</li></ul><li>baz</li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul><li>foo<li>[bar]<ul><li>baz</ul><li>quz</ul>", + [["defaultparagraphseparator","div"],["insertunorderedlist",""]], + "<ul><li>foo</li></ul><div>[bar]</div><ul><ul><li>baz</li></ul><li>quz</li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul><li>foo<li>[bar]<ul><li>baz</ul><li>quz</ul>", + [["defaultparagraphseparator","p"],["insertunorderedlist",""]], + "<ul><li>foo</li></ul><p>[bar]</p><ul><ul><li>baz</li></ul><li>quz</li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul><li>foo<li>[bar]</li><ul><li>baz</ul><li>quz</ul>", + [["defaultparagraphseparator","div"],["insertunorderedlist",""]], + "<ul><li>foo</li></ul><div>[bar]</div><ul><ul><li>baz</li></ul><li>quz</li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul><li>foo<li>[bar]</li><ul><li>baz</ul><li>quz</ul>", + [["defaultparagraphseparator","p"],["insertunorderedlist",""]], + "<ul><li>foo</li></ul><p>[bar]</p><ul><ul><li>baz</li></ul><li>quz</li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul><li>foo<ul><li>bar<li>baz</ul><li>[quz]</ul>", + [["defaultparagraphseparator","div"],["insertunorderedlist",""]], + "<ul><li>foo<ul><li>bar</li><li>baz</li></ul></li></ul><div>[quz]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul><li>foo<ul><li>bar<li>baz</ul><li>[quz]</ul>", + [["defaultparagraphseparator","p"],["insertunorderedlist",""]], + "<ul><li>foo<ul><li>bar</li><li>baz</li></ul></li></ul><p>[quz]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul><li>foo</li><ul><li>bar<li>baz</ul><li>[quz]</ul>", + [["defaultparagraphseparator","div"],["insertunorderedlist",""]], + "<ul><li>foo</li><ul><li>bar</li><li>baz</li></ul></ul><div>[quz]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul><li>foo</li><ul><li>bar<li>baz</ul><li>[quz]</ul>", + [["defaultparagraphseparator","p"],["insertunorderedlist",""]], + "<ul><li>foo</li><ul><li>bar</li><li>baz</li></ul></ul><p>[quz]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul><li>foo<li>[bar<li>baz]</ul>", + [["defaultparagraphseparator","div"],["insertunorderedlist",""]], + "<ul><li>foo</li></ul><div>[bar</div><div>baz]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul><li>foo<li>[bar<li>baz]</ul>", + [["defaultparagraphseparator","p"],["insertunorderedlist",""]], + "<ul><li>foo</li></ul><p>[bar</p><p>baz]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul><li>[foo<ul><li>bar]</ul><li>baz</ul>", + [["defaultparagraphseparator","div"],["insertunorderedlist",""]], + "<div>[foo</div><ul><li>bar]</li><li>baz</li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertunorderedlist":[false,true,"",true,false,""]}], +["<ul><li>[foo<ul><li>bar]</ul><li>baz</ul>", + [["defaultparagraphseparator","p"],["insertunorderedlist",""]], + "<p>[foo</p><ul><li>bar]</li><li>baz</li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertunorderedlist":[false,true,"",true,false,""]}], +["<ul><li>foo<ul><li>b[ar</ul><li>b]az</ul>", + [["defaultparagraphseparator","div"],["insertunorderedlist",""]], + "<ul><li>foo</li><li>b[ar</li></ul><div>b]az</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertunorderedlist":[false,true,"",true,false,""]}], +["<ul><li>foo<ul><li>b[ar</ul><li>b]az</ul>", + [["defaultparagraphseparator","p"],["insertunorderedlist",""]], + "<ul><li>foo</li><li>b[ar</li></ul><p>b]az</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertunorderedlist":[false,true,"",true,false,""]}], +["<ul><li>[foo<ul><li>bar</ul><li>baz]</ul><p>extra", + [["defaultparagraphseparator","div"],["insertunorderedlist",""]], + "<div>[foo</div><ul><li>bar</li></ul><div>baz]</div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertunorderedlist":[false,true,"",true,false,""]}], +["<ul><li>[foo<ul><li>bar</ul><li>baz]</ul><p>extra", + [["defaultparagraphseparator","p"],["insertunorderedlist",""]], + "<p>[foo</p><ul><li>bar</li></ul><p>baz]</p><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertunorderedlist":[false,true,"",true,false,""]}], +["<ul><li>[foo]<ul><li>bar</ul>baz</ul>", + [["defaultparagraphseparator","div"],["insertunorderedlist",""]], + "<div>[foo]</div><ul><ul><li>bar</li></ul><li>baz</li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul><li>[foo]<ul><li>bar</ul>baz</ul>", + [["defaultparagraphseparator","p"],["insertunorderedlist",""]], + "<p>[foo]</p><ul><ul><li>bar</li></ul><li>baz</li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul><li>foo<ul><li>[bar]</ul>baz</ul>", + [["insertunorderedlist",""]], + "<ul><li>foo</li><li>[bar]</li><li>baz</li></ul>", + [true], + {"insertunorderedlist":[false,true,"",false,true,""]}], +["<ul><li>foo<ul><li>bar</ul>[baz]</ul>", + [["defaultparagraphseparator","div"],["insertunorderedlist",""]], + "<ul><li>foo</li><ul><li>bar</li></ul></ul><div>[baz]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul><li>foo<ul><li>bar</ul>[baz]</ul>", + [["defaultparagraphseparator","p"],["insertunorderedlist",""]], + "<ul><li>foo</li><ul><li>bar</li></ul></ul><p>[baz]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul><li>[foo<ul><li>bar]</ul>baz</ul>", + [["defaultparagraphseparator","div"],["insertunorderedlist",""]], + "<div>[foo</div><ul><li>bar]</li><li>baz</li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertunorderedlist":[false,true,"",true,false,""]}], +["<ul><li>[foo<ul><li>bar]</ul>baz</ul>", + [["defaultparagraphseparator","p"],["insertunorderedlist",""]], + "<p>[foo</p><ul><li>bar]</li><li>baz</li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertunorderedlist":[false,true,"",true,false,""]}], +["foo<ol><li>bar</ol><ul><li>[baz]</ul>quz", + [["defaultparagraphseparator","div"],["insertunorderedlist",""]], + "foo<ol><li>bar</li></ol><div>[baz]</div>quz", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertunorderedlist":[false,true,"",false,false,""]}], +["foo<ol><li>bar</ol><ul><li>[baz]</ul>quz", + [["defaultparagraphseparator","p"],["insertunorderedlist",""]], + "foo<ol><li>bar</li></ol><p>[baz]</p>quz", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertunorderedlist":[false,true,"",false,false,""]}], +["foo<ol><li>bar</ol><ul><li>[baz</ul>quz]", + [["insertunorderedlist",""]], + "foo<ol><li>bar</li></ol><ul><li>[baz</li><li>quz]</li></ul>", + [true], + {"insertunorderedlist":[true,false,"",false,true,""]}], +["foo<ul><li>[bar]</ul><ol><li>baz</ol>quz", + [["defaultparagraphseparator","div"],["insertunorderedlist",""]], + "foo<div>[bar]</div><ol><li>baz</li></ol>quz", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertunorderedlist":[false,true,"",false,false,""]}], +["foo<ul><li>[bar]</ul><ol><li>baz</ol>quz", + [["defaultparagraphseparator","p"],["insertunorderedlist",""]], + "foo<p>[bar]</p><ol><li>baz</li></ol>quz", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertunorderedlist":[false,true,"",false,false,""]}], +["[foo<ul><li>bar]</ul><ol><li>baz</ol>quz", + [["insertunorderedlist",""]], + "<ul><li>[foo</li><li>bar]</li></ul><ol><li>baz</li></ol>quz", + [true], + {"insertunorderedlist":[true,false,"",false,true,""]}], +["[foo]<blockquote>bar</blockquote>baz", + [["insertunorderedlist",""]], + "<ul><li>[foo]</li></ul><blockquote>bar</blockquote>baz", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["foo<blockquote>[bar]</blockquote>baz", + [["insertunorderedlist",""]], + "foo<blockquote><ul><li>[bar]</li></ul></blockquote>baz", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["[foo<blockquote>bar]</blockquote>baz", + [["insertunorderedlist",""]], + "<ul><li>[foo</li><ul><li>bar]</li></ul></ul>baz", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["<ol><li>foo</ol><blockquote>[bar]</blockquote>baz", + [["insertunorderedlist",""]], + "<ol><li>foo</li></ol><blockquote><ul><li>[bar]</li></ul></blockquote>baz", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["[foo]<blockquote><ol><li>bar</ol></blockquote>baz", + [["insertunorderedlist",""]], + "<ul><li>[foo]</li></ul><blockquote><ol><li>bar</li></ol></blockquote>baz", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["foo<blockquote>[bar]<br>baz</blockquote>", + [["insertunorderedlist",""]], + "foo<blockquote><ul><li>[bar]</li></ul>baz</blockquote>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["[foo<blockquote>bar]<br>baz</blockquote>", + [["insertunorderedlist",""]], + "<ul><li>[foo</li><ul><li>bar]</li></ul></ul><blockquote>baz</blockquote>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["<ol><li>foo</ol><blockquote>[bar]<br>baz</blockquote>", + [["insertunorderedlist",""]], + "<ol><li>foo</li></ol><blockquote><ul><li>[bar]</li></ul>baz</blockquote>", + [true], + {"insertunorderedlist":[false,false,"",false,true,""]}], +["<p>[foo]<blockquote><p>bar</blockquote><p>baz", + [["defaultparagraphseparator","div"],["insertunorderedlist",""]], + "<ul><li>[foo]</li></ul><blockquote><p>bar</p></blockquote><p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertunorderedlist":[false,false,"",false,true,""]}], +["<p>[foo]<blockquote><p>bar</blockquote><p>baz", + [["defaultparagraphseparator","p"],["insertunorderedlist",""]], + "<ul><li>[foo]</li></ul><blockquote><p>bar</p></blockquote><p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertunorderedlist":[false,false,"",false,true,""]}], +["<p>foo<blockquote><p>[bar]</blockquote><p>baz", + [["defaultparagraphseparator","div"],["insertunorderedlist",""]], + "<p>foo</p><blockquote><ul><li>[bar]</li></ul></blockquote><p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertunorderedlist":[false,false,"",false,true,""]}], +["<p>foo<blockquote><p>[bar]</blockquote><p>baz", + [["defaultparagraphseparator","p"],["insertunorderedlist",""]], + "<p>foo</p><blockquote><ul><li>[bar]</li></ul></blockquote><p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertunorderedlist":[false,false,"",false,true,""]}], +["<p>[foo<blockquote><p>bar]</blockquote><p>baz", + [["defaultparagraphseparator","div"],["insertunorderedlist",""]], + "<ul><li>[foo</li><ul><li>bar]</li></ul></ul><p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertunorderedlist":[false,false,"",false,true,""]}], +["<p>[foo<blockquote><p>bar]</blockquote><p>baz", + [["defaultparagraphseparator","p"],["insertunorderedlist",""]], + "<ul><li>[foo</li><ul><li>bar]</li></ul></ul><p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertunorderedlist":[false,false,"",false,true,""]}], +["<ol><li>foo</ol><blockquote><p>[bar]</blockquote><p>baz", + [["defaultparagraphseparator","div"],["insertunorderedlist",""]], + "<ol><li>foo</li></ol><blockquote><ul><li>[bar]</li></ul></blockquote><p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertunorderedlist":[false,false,"",false,true,""]}], +["<ol><li>foo</ol><blockquote><p>[bar]</blockquote><p>baz", + [["defaultparagraphseparator","p"],["insertunorderedlist",""]], + "<ol><li>foo</li></ol><blockquote><ul><li>[bar]</li></ul></blockquote><p>baz</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertunorderedlist":[false,false,"",false,true,""]}], +["<ul id=abc><li>foo<li>[bar]<li>baz</ul>", + [["defaultparagraphseparator","div"],["insertunorderedlist",""]], + "<ul id=\"abc\"><li>foo</li></ul><div>[bar]</div><ul><li>baz</li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul id=abc><li>foo<li>[bar]<li>baz</ul>", + [["defaultparagraphseparator","p"],["insertunorderedlist",""]], + "<ul id=\"abc\"><li>foo</li></ul><p>[bar]</p><ul><li>baz</li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul style=color:blue><li>foo<li>[bar]<li>baz</ul>", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["insertunorderedlist",""]], + "<ul style=\"color:rgb(0, 0, 255)\"><li>foo</li></ul><div>[bar]</div><ul style=\"color:rgb(0, 0, 255)\"><li>baz</li></ul>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul style=color:blue><li>foo<li>[bar]<li>baz</ul>", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["insertunorderedlist",""]], + "<ul style=\"color:rgb(0, 0, 255)\"><li>foo</li></ul><div>[bar]</div><ul style=\"color:rgb(0, 0, 255)\"><li>baz</li></ul>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul style=color:blue><li>foo<li>[bar]<li>baz</ul>", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["insertunorderedlist",""]], + "<ul style=\"color:rgb(0, 0, 255)\"><li>foo</li></ul><p>[bar]</p><ul style=\"color:rgb(0, 0, 255)\"><li>baz</li></ul>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul style=color:blue><li>foo<li>[bar]<li>baz</ul>", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["insertunorderedlist",""]], + "<ul style=\"color:rgb(0, 0, 255)\"><li>foo</li></ul><p>[bar]</p><ul style=\"color:rgb(0, 0, 255)\"><li>baz</li></ul>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul style=text-indent:1em><li>foo<li>[bar]<li>baz</ul>", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["insertunorderedlist",""]], + "<ul style=\"text-indent:1em\"><li>foo</li></ul><div>[bar]</div><ul style=\"text-indent:1em\"><li>baz</li></ul>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul style=text-indent:1em><li>foo<li>[bar]<li>baz</ul>", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["insertunorderedlist",""]], + "<ul style=\"text-indent:1em\"><li>foo</li></ul><div>[bar]</div><ul style=\"text-indent:1em\"><li>baz</li></ul>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul style=text-indent:1em><li>foo<li>[bar]<li>baz</ul>", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["insertunorderedlist",""]], + "<ul style=\"text-indent:1em\"><li>foo</li></ul><p>[bar]</p><ul style=\"text-indent:1em\"><li>baz</li></ul>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul style=text-indent:1em><li>foo<li>[bar]<li>baz</ul>", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["insertunorderedlist",""]], + "<ul style=\"text-indent:1em\"><li>foo</li></ul><p>[bar]</p><ul style=\"text-indent:1em\"><li>baz</li></ul>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul id=abc><li>[foo]<li>bar<li>baz</ul>", + [["defaultparagraphseparator","div"],["insertunorderedlist",""]], + "<div>[foo]</div><ul id=\"abc\"><li>bar</li><li>baz</li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul id=abc><li>[foo]<li>bar<li>baz</ul>", + [["defaultparagraphseparator","p"],["insertunorderedlist",""]], + "<p>[foo]</p><ul id=\"abc\"><li>bar</li><li>baz</li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul style=color:blue><li>[foo]<li>bar<li>baz</ul>", + [["defaultparagraphseparator","div"],["insertunorderedlist",""]], + "<div>[foo]</div><ul style=\"color:rgb(0, 0, 255)\"><li>bar</li><li>baz</li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul style=color:blue><li>[foo]<li>bar<li>baz</ul>", + [["defaultparagraphseparator","p"],["insertunorderedlist",""]], + "<p>[foo]</p><ul style=\"color:rgb(0, 0, 255)\"><li>bar</li><li>baz</li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul style=text-indent:1em><li>[foo]<li>bar<li>baz</ul>", + [["defaultparagraphseparator","div"],["insertunorderedlist",""]], + "<div>[foo]</div><ul style=\"text-indent:1em\"><li>bar</li><li>baz</li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul style=text-indent:1em><li>[foo]<li>bar<li>baz</ul>", + [["defaultparagraphseparator","p"],["insertunorderedlist",""]], + "<p>[foo]</p><ul style=\"text-indent:1em\"><li>bar</li><li>baz</li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul id=abc><li>foo<li>bar<li>[baz]</ul>", + [["defaultparagraphseparator","div"],["insertunorderedlist",""]], + "<ul id=\"abc\"><li>foo</li><li>bar</li></ul><div>[baz]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul id=abc><li>foo<li>bar<li>[baz]</ul>", + [["defaultparagraphseparator","p"],["insertunorderedlist",""]], + "<ul id=\"abc\"><li>foo</li><li>bar</li></ul><p>[baz]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul style=color:blue><li>foo<li>bar<li>[baz]</ul>", + [["defaultparagraphseparator","div"],["insertunorderedlist",""]], + "<ul style=\"color:rgb(0, 0, 255)\"><li>foo</li><li>bar</li></ul><div>[baz]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul style=color:blue><li>foo<li>bar<li>[baz]</ul>", + [["defaultparagraphseparator","p"],["insertunorderedlist",""]], + "<ul style=\"color:rgb(0, 0, 255)\"><li>foo</li><li>bar</li></ul><p>[baz]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul style=text-indent:1em><li>foo<li>bar<li>[baz]</ul>", + [["defaultparagraphseparator","div"],["insertunorderedlist",""]], + "<ul style=\"text-indent:1em\"><li>foo</li><li>bar</li></ul><div>[baz]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul style=text-indent:1em><li>foo<li>bar<li>[baz]</ul>", + [["defaultparagraphseparator","p"],["insertunorderedlist",""]], + "<ul style=\"text-indent:1em\"><li>foo</li><li>bar</li></ul><p>[baz]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertunorderedlist":[false,true,"",false,false,""]}], +["<ul><li>foo</ul> <p>[bar]", + [["defaultparagraphseparator","div"],["insertunorderedlist",""]], + "<ul><li>foo</li> <li>[bar]</li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertunorderedlist":[false,false,"",false,true,""]}], +["<ul><li>foo</ul> <p>[bar]", + [["defaultparagraphseparator","p"],["insertunorderedlist",""]], + "<ul><li>foo</li> <li>[bar]</li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertunorderedlist":[false,false,"",false,true,""]}], +["<p>[foo]</p> <ul><li>bar</ul>", + [["defaultparagraphseparator","div"],["insertunorderedlist",""]], + "<ul><li>[foo]</li> <li>bar</li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertunorderedlist":[false,false,"",false,true,""]}], +["<p>[foo]</p> <ul><li>bar</ul>", + [["defaultparagraphseparator","p"],["insertunorderedlist",""]], + "<ul><li>[foo]</li> <li>bar</li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertunorderedlist":[false,false,"",false,true,""]}], +["<ul><li>foo</ul> <p>[bar]</p> <ul><li>baz</ul>", + [["defaultparagraphseparator","div"],["insertunorderedlist",""]], + "<ul><li>foo</li> <li>[bar]</li> <li>baz</li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertunorderedlist":[false,false,"",false,true,""]}], +["<ul><li>foo</ul> <p>[bar]</p> <ul><li>baz</ul>", + [["defaultparagraphseparator","p"],["insertunorderedlist",""]], + "<ul><li>foo</li> <li>[bar]</li> <li>baz</li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertunorderedlist":[false,false,"",false,true,""]}], +["{<div style=\"font-size: 1.3em\">1</div><div style=\"font-size: 1.1em\">2</div>}", + [["defaultparagraphseparator","div"],["insertunorderedlist",""]], + "<ul>{<li style=\"font-size:1.3em\">1</li><li style=\"font-size:1.1em\">2</li>}</ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"insertunorderedlist":[false,false,"",false,true,""]}], +["{<div style=\"font-size: 1.3em\">1</div><div style=\"font-size: 1.1em\">2</div>}", + [["defaultparagraphseparator","p"],["insertunorderedlist",""]], + "<ul>{<li style=\"font-size:1.3em\">1</li><li style=\"font-size:1.1em\">2</li>}</ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"insertunorderedlist":[false,false,"",false,true,""]}], +["{}", + [["insertunorderedlist",""],["inserttext","abc"]], + ["<ul><li>abc</li></ul>", + "<ul><li>abc<br></li></ul>"], + [true,true], + {"insertunorderedlist":[false,false,"false",false,true,"true"]}], +["<div>{}</div>", + [["insertunorderedlist",""],["inserttext","abc"]], + ["<div><ul><li>abc</li></ul></div>", + "<div><ul><li>abc<br></li></ul></div>"], + [true,true], + {"insertunorderedlist":[false,false,"false",false,true,"true"]}], +["<div>{}<br></div>", + [["insertunorderedlist",""],["inserttext","abc"]], + ["<div><ul><li>abc</li></ul></div>", + "<div><ul><li>abc<br></li></ul></div>"], + [true,true], + {"insertunorderedlist":[false,false,"false",false,true,"true"]}], +["<p>{}</p>", + [["insertunorderedlist",""],["inserttext","abc"]], + ["<ul><li>abc</li></ul>", + "<ul><li>abc<br></li></ul>"], + [true,true], + {"insertunorderedlist":[false,false,"false",false,true,"true"]}], +["<p>{}<br></p>", + [["insertunorderedlist",""],["inserttext","abc"]], + ["<ul><li>abc</li></ul>", + "<ul><li>abc<br></li></ul>"], + [true,true], + {"insertunorderedlist":[false,false,"false",false,true,"true"]}], + +// <div> version of above cases (#73-) +["<div>[foo</div>bar]<div>baz</div>", + [["insertunorderedlist",""]], + ["<div><ul><li>[foo</li><li>bar]</li></ul></div><div>baz</div>", + "<ul><li>[foo</li><li>bar]</li></ul><div>baz</div>"], + [true], + {}], +["<div>[foo</div><div>bar]</div><div>baz</div>", + [["insertunorderedlist",""]], + ["<div><ul><li>[foo</li><li>bar]</li></ul></div><div>baz</div>", + "<ul><li>[foo</li><li>bar]</li></ul><div>baz</div>"], + [true], + {}], + +// empty <div>s should be converted to empty list items. +["<div>[abc</div><div><br></div><div>def]</div>", + [["insertunorderedlist",""]], + ["<div><ul><li>[abc</li><li><br></li><li>def]</li></ul></div>", + "<ul><li>[abc</li><li><br></li><li>def]</li></ul>"], + [true], + {}], +["<div>{<br></div><div>abc</div><div>def]</div>", + [["insertunorderedlist",""]], + ["<div><ul><li>{<br></li><li>abc</li><li>def]</li></ul></div>", + "<ul><li>{<br></li><li>abc</li><li>def]</li></ul>"], + [true], + {}], +// but don't listify the last empty <div> if only its start boundary is in the +//range. +["<div>[abc</div><div>def</div><div>}<br></div>", + [["insertunorderedlist",""]], + ["<div><ul><li>[abc</li><li>def]</li></ul></div><div><br></div>", + "<ul><li>[abc</li><li>def]</li></ul><div><br></div>"], + [true], + {}], +["<div>[abc</div><div>def</div><div>]ghi</div>", + [["insertunorderedlist",""]], + ["<div><ul><li>[abc</li><li>def]</li></ul></div><div>ghi</div>", + "<ul><li>[abc</li><li>def]</li></ul><div>ghi</div>"], + [true], + {}], + +// "dir" attribute should be preserved for the list element to make the +// bullets aligned correctly. +["<div dir=\"rtl\">a[]bc</div><div dir=\"rtl\">def</div>", + [["insertunorderedlist",""]], + ["<div dir=\"rtl\"><ul><li>abc</li></ul></div><div dir=\"rtl\">def</div>", + "<ul dir=\"rtl\"><li>abc</li></ul><div dir=\"rtl\">def</div>"], + [true], + {}], +["<div dir=\"rtl\">a[bc</div><div dir=\"rtl\">de]f</div>", + [["insertunorderedlist",""]], + ["<div dir=\"rtl\"><ul><li>abc</li><li>def</li></ul></div>", + "<ul dir=\"rtl\"><li>abc</li><li>def</li></ul>"], + [true], + {}], +// but do not copy `dir` attributes to corresponding <li>s because different +// one from the value of the parent list element causes odd looks and anyway +// the `dir` attribute does not affect the text direction. +["<div dir=\"rtl\">a[bc</div><div dir=\"ltr\">de]f</div>", + [["insertunorderedlist",""]], + ["<div dir=\"rtl\"><ul><li>abc</li><li>def</li></ul></div>", + "<ul dir=\"rtl\"><li>abc</li><li>def</li></ul>"], + [true], + {}], + +// The other attributes should be clonsed to each list item. +["<div id=\"a\">a[bc</div><div id=\"b\">de]f</div>", + [["insertunorderedlist",""]], + ["<div><ul><li id=\"a\">abc</li><li id=\"b\">def</li></ul></div>", + "<ul><li id=\"a\">abc</li><li id=\"b\">def</li></ul>"], + [true], + {}], +["<div class=\"a\">a[bc</div><div class=\"b\">de]f</div>", + [["insertunorderedlist",""]], + ["<div><ul><li class=\"a\">abc</li><li class=\"b\">def</li></ul></div>", + "<ul><li class=\"a\">abc</li><li class=\"b\">def</li></ul>"], + [true], + {}], +["<div title=\"a\">a[bc</div><div title=\"b\">de]f</div>", + [["insertunorderedlist",""]], + ["<div><ul><li title=\"a\">abc</li><li title=\"b\">def</li></ul></div>", + "<ul><li title=\"a\">abc</li><li title=\"b\">def</li></ul>"], + [true], + {}], +] diff --git a/testing/web-platform/tests/editing/data/italic.js b/testing/web-platform/tests/editing/data/italic.js new file mode 100644 index 0000000000..bb744135e3 --- /dev/null +++ b/testing/web-platform/tests/editing/data/italic.js @@ -0,0 +1,680 @@ +// For documentation of the format, see README in this directory. +var browserTests = [ +["foo[]bar", + [["italic",""]], + "foo[]bar", + [true], + {"italic":[false,false,"",false,true,""]}], +["<p>[foo</p> <p>bar]</p>", + [["stylewithcss","true"],["italic",""]], + "<p><span style=\"font-style:italic\">[foo</span></p> <p><span style=\"font-style:italic\">bar]</span></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[false,false,"",false,true,""]}], +["<p>[foo</p> <p>bar]</p>", + [["stylewithcss","false"],["italic",""]], + "<p><i>[foo</i></p> <p><i>bar]</i></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[false,false,"",false,true,""]}], +["<span>[foo</span> <span>bar]</span>", + [["stylewithcss","true"],["italic",""]], + "<span style=\"font-style:italic\"><span>[foo</span> <span>bar]</span></span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[false,false,"",false,true,""]}], +["<span>[foo</span> <span>bar]</span>", + [["stylewithcss","false"],["italic",""]], + "<i><span>[foo</span> <span>bar]</span></i>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[false,false,"",false,true,""]}], +["<p>[foo</p><p> <span>bar</span> </p><p>baz]</p>", + [["stylewithcss","true"],["italic",""]], + "<p><span style=\"font-style:italic\">[foo</span></p><p> <span style=\"font-style:italic\"><span>bar</span></span> </p><p><span style=\"font-style:italic\">baz]</span></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[false,false,"",false,true,""]}], +["<p>[foo</p><p> <span>bar</span> </p><p>baz]</p>", + [["stylewithcss","false"],["italic",""]], + "<p><i>[foo</i></p><p> <i><span>bar</span></i> </p><p><i>baz]</i></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[false,false,"",false,true,""]}], +["<p>[foo<p><br><p>bar]", + [["stylewithcss","true"],["italic",""]], + "<p><span style=\"font-style:italic\">[foo</span></p><p><span style=\"font-style:italic\"><br></span></p><p><span style=\"font-style:italic\">bar]</span></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[false,false,"",false,true,""]}], +["<p>[foo<p><br><p>bar]", + [["stylewithcss","false"],["italic",""]], + "<p><i>[foo</i></p><p><i><br></i></p><p><i>bar]</i></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[false,false,"",false,true,""]}], +["<b>foo[]bar</b>", + [["italic",""]], + "<b>foo[]bar</b>", + [true], + {"italic":[false,false,"",false,true,""]}], +["<i>foo[]bar</i>", + [["italic",""]], + "<i>foo[]bar</i>", + [true], + {"italic":[false,true,"",false,false,""]}], +["<span>foo</span>{}<span>bar</span>", + [["italic",""]], + "<span>foo</span>{}<span>bar</span>", + [true], + {"italic":[false,false,"",false,true,""]}], +["<span>foo[</span><span>]bar</span>", + [["italic",""]], + "<span>foo[</span><span>]bar</span>", + [true], + {"italic":[false,false,"",false,true,""]}], +["foo[bar]baz", + [["stylewithcss","true"],["italic",""]], + "foo<span style=\"font-style:italic\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[false,false,"",false,true,""]}], +["foo[bar]baz", + [["stylewithcss","false"],["italic",""]], + "foo<i>[bar]</i>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[false,false,"",false,true,""]}], +["foo[bar<b>baz]qoz</b>quz", + [["stylewithcss","true"],["italic",""]], + "foo<span style=\"font-style:italic\">[bar</span><b><span style=\"font-style:italic\">baz]</span>qoz</b>quz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[false,false,"",false,true,""]}], +["foo[bar<b>baz]qoz</b>quz", + [["stylewithcss","false"],["italic",""]], + "foo<i>[bar</i><b><i>baz]</i>qoz</b>quz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[false,false,"",false,true,""]}], +["foo[bar<i>baz]qoz</i>quz", + [["italic",""]], + "foo<i>[barbaz]qoz</i>quz", + [true], + {"italic":[true,false,"",false,true,""]}], +["{<p><p> <p>foo</p>}", + [["stylewithcss","true"],["italic",""]], + "{<p></p><p> </p><p><span style=\"font-style:italic\">foo</span></p>}", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[false,false,"",false,true,""]}], +["{<p><p> <p>foo</p>}", + [["stylewithcss","false"],["italic",""]], + "{<p></p><p> </p><p><i>foo</i></p>}", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[false,false,"",false,true,""]}], +["<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>", + [["stylewithcss","true"],["italic",""]], + "<table><tbody><tr><td>foo</td><td>b<span style=\"font-style:italic\">[a]</span>r</td><td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[false,false,"",false,true,""]}], +["<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>", + [["stylewithcss","false"],["italic",""]], + "<table><tbody><tr><td>foo</td><td>b<i>[a]</i>r</td><td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[false,false,"",false,true,""]}], +["<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table>", + [["stylewithcss","true"],["italic",""]], + "<table><tbody><tr><td>foo</td>{<td><span style=\"font-style:italic\">bar</span></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[false,false,"",false,true,""]}], +["<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table>", + [["stylewithcss","false"],["italic",""]], + "<table><tbody><tr><td>foo</td>{<td><i>bar</i></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[false,false,"",false,true,""]}], +["<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table>", + [["stylewithcss","true"],["italic",""]], + "<table><tbody><tr>{<td><span style=\"font-style:italic\">foo</span></td><td><span style=\"font-style:italic\">bar</span></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[false,false,"",false,true,""]}], +["<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table>", + [["stylewithcss","false"],["italic",""]], + "<table><tbody><tr>{<td><i>foo</i></td><td><i>bar</i></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[false,false,"",false,true,""]}], +["<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>", + [["stylewithcss","true"],["italic",""]], + "<table><tbody>{<tr><td><span style=\"font-style:italic\">foo</span></td><td><span style=\"font-style:italic\">bar</span></td><td><span style=\"font-style:italic\">baz</span></td></tr>}</tbody></table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[false,false,"",false,true,""]}], +["<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>", + [["stylewithcss","false"],["italic",""]], + "<table><tbody>{<tr><td><i>foo</i></td><td><i>bar</i></td><td><i>baz</i></td></tr>}</tbody></table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[false,false,"",false,true,""]}], +["<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>", + [["stylewithcss","true"],["italic",""]], + "<table>{<tbody><tr><td><span style=\"font-style:italic\">foo</span></td><td><span style=\"font-style:italic\">bar</span></td><td><span style=\"font-style:italic\">baz</span></td></tr></tbody>}</table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[false,false,"",false,true,""]}], +["<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>", + [["stylewithcss","false"],["italic",""]], + "<table>{<tbody><tr><td><i>foo</i></td><td><i>bar</i></td><td><i>baz</i></td></tr></tbody>}</table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[false,false,"",false,true,""]}], +["{<table><tr><td>foo<td>bar<td>baz</table>}", + [["stylewithcss","true"],["italic",""]], + "{<table><tbody><tr><td><span style=\"font-style:italic\">foo</span></td><td><span style=\"font-style:italic\">bar</span></td><td><span style=\"font-style:italic\">baz</span></td></tr></tbody></table>}", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[false,false,"",false,true,""]}], +["{<table><tr><td>foo<td>bar<td>baz</table>}", + [["stylewithcss","false"],["italic",""]], + "{<table><tbody><tr><td><i>foo</i></td><td><i>bar</i></td><td><i>baz</i></td></tr></tbody></table>}", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[false,false,"",false,true,""]}], +["foo<address>[bar]</address>baz", + [["stylewithcss","true"],["italic",""]], + "foo<address><span style=\"font-style:normal\">[bar]</span></address>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[false,true,"",false,false,""]}], +["foo<address>[bar]</address>baz", + [["stylewithcss","false"],["italic",""]], + "foo<address><span style=\"font-style:normal\">[bar]</span></address>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[false,true,"",false,false,""]}], +["foo<cite>[bar]</cite>baz", + [["stylewithcss","true"],["italic",""]], + "foo<cite><span style=\"font-style:normal\">[bar]</span></cite>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[false,true,"",false,false,""]}], +["foo<cite>[bar]</cite>baz", + [["stylewithcss","false"],["italic",""]], + "foo<cite><span style=\"font-style:normal\">[bar]</span></cite>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[false,true,"",false,false,""]}], +["foo<dfn>[bar]</dfn>baz", + [["stylewithcss","true"],["italic",""]], + "foo<dfn><span style=\"font-style:normal\">[bar]</span></dfn>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[false,true,"",false,false,""]}], +["foo<dfn>[bar]</dfn>baz", + [["stylewithcss","false"],["italic",""]], + "foo<dfn><span style=\"font-style:normal\">[bar]</span></dfn>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[false,true,"",false,false,""]}], +["foo<em>[bar]</em>baz", + [["italic",""]], + "foo[bar]baz", + [true], + {"italic":[false,true,"",false,false,""]}], +["foo<var>[bar]</var>baz", + [["stylewithcss","true"],["italic",""]], + "foo<var><span style=\"font-style:normal\">[bar]</span></var>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[false,true,"",false,false,""]}], +["foo<var>[bar]</var>baz", + [["stylewithcss","false"],["italic",""]], + "foo<var><span style=\"font-style:normal\">[bar]</span></var>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[false,true,"",false,false,""]}], +["foo{<address>bar</address>}baz", + [["stylewithcss","true"],["italic",""]], + "foo{<address><span style=\"font-style:normal\">bar</span></address>}baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[false,true,"",false,false,""]}], +["foo{<address>bar</address>}baz", + [["stylewithcss","false"],["italic",""]], + "foo{<address><span style=\"font-style:normal\">bar</span></address>}baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[false,true,"",false,false,""]}], +["foo{<cite>bar</cite>}baz", + [["stylewithcss","true"],["italic",""]], + "foo{<cite><span style=\"font-style:normal\">bar</span></cite>}baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[false,true,"",false,false,""]}], +["foo{<cite>bar</cite>}baz", + [["stylewithcss","false"],["italic",""]], + "foo{<cite><span style=\"font-style:normal\">bar</span></cite>}baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[false,true,"",false,false,""]}], +["foo{<dfn>bar</dfn>}baz", + [["stylewithcss","true"],["italic",""]], + "foo{<dfn><span style=\"font-style:normal\">bar</span></dfn>}baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[false,true,"",false,false,""]}], +["foo{<dfn>bar</dfn>}baz", + [["stylewithcss","false"],["italic",""]], + "foo{<dfn><span style=\"font-style:normal\">bar</span></dfn>}baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[false,true,"",false,false,""]}], +["foo{<em>bar</em>}baz", + [["italic",""]], + "foo{bar}baz", + [true], + {"italic":[false,true,"",false,false,""]}], +["foo{<var>bar</var>}baz", + [["stylewithcss","true"],["italic",""]], + "foo{<var><span style=\"font-style:normal\">bar</span></var>}baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[false,true,"",false,false,""]}], +["foo{<var>bar</var>}baz", + [["stylewithcss","false"],["italic",""]], + "foo{<var><span style=\"font-style:normal\">bar</span></var>}baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[false,true,"",false,false,""]}], +["foo<address>b[a]r</address>baz", + [["stylewithcss","true"],["italic",""]], + "foo<address>b<span style=\"font-style:normal\">[a]</span>r</address>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[false,true,"",false,false,""]}], +["foo<address>b[a]r</address>baz", + [["stylewithcss","false"],["italic",""]], + "foo<address>b<span style=\"font-style:normal\">[a]</span>r</address>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[false,true,"",false,false,""]}], +["foo<cite>b[a]r</cite>baz", + [["stylewithcss","true"],["italic",""]], + "foo<cite>b<span style=\"font-style:normal\">[a]</span>r</cite>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[false,true,"",false,false,""]}], +["foo<cite>b[a]r</cite>baz", + [["stylewithcss","false"],["italic",""]], + "foo<cite>b<span style=\"font-style:normal\">[a]</span>r</cite>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[false,true,"",false,false,""]}], +["foo<dfn>b[a]r</dfn>baz", + [["stylewithcss","true"],["italic",""]], + "foo<dfn>b<span style=\"font-style:normal\">[a]</span>r</dfn>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[false,true,"",false,false,""]}], +["foo<dfn>b[a]r</dfn>baz", + [["stylewithcss","false"],["italic",""]], + "foo<dfn>b<span style=\"font-style:normal\">[a]</span>r</dfn>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[false,true,"",false,false,""]}], +// Should not replace existing <em> when partially removing the italic style. +["foo<em>b[a]r</em>baz", + [["stylewithcss","true"],["italic",""]], + "foo<em>b</em>a<em>r</em>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[false,true,"",false,false,""]}], +["foo<em>b[a]r</em>baz", + [["stylewithcss","false"],["italic",""]], + "foo<em>b</em>a<em>r</em>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[false,true,"",false,false,""]}], +["foo<i>b[a]r</i>baz", + [["stylewithcss","true"],["italic",""]], + "foo<span style=\"font-style:italic\">b</span>[a]<span style=\"font-style:italic\">r</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[false,true,"",false,false,""]}], +["foo<i>b[a]r</i>baz", + [["stylewithcss","false"],["italic",""]], + "foo<i>b</i>[a]<i>r</i>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[false,true,"",false,false,""]}], +["foo<var>b[a]r</var>baz", + [["stylewithcss","true"],["italic",""]], + "foo<var>b<span style=\"font-style:normal\">[a]</span>r</var>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[false,true,"",false,false,""]}], +["foo<var>b[a]r</var>baz", + [["stylewithcss","false"],["italic",""]], + "foo<var>b<span style=\"font-style:normal\">[a]</span>r</var>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[false,true,"",false,false,""]}], +["fo[o<address>bar</address>b]az", + [["stylewithcss","true"],["italic",""]], + "fo<span style=\"font-style:italic\">[o</span><address>bar</address><span style=\"font-style:italic\">b]</span>az", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[true,false,"",false,true,""]}], +["fo[o<address>bar</address>b]az", + [["stylewithcss","false"],["italic",""]], + "fo<i>[o</i><address>bar</address><i>b]</i>az", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[true,false,"",false,true,""]}], +["fo[o<cite>bar</cite>b]az", + [["stylewithcss","true"],["italic",""]], + "fo<span style=\"font-style:italic\">[o<cite>bar</cite>b]</span>az", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[true,false,"",false,true,""]}], +["fo[o<cite>bar</cite>b]az", + [["stylewithcss","false"],["italic",""]], + "fo<i>[o<cite>bar</cite>b]</i>az", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[true,false,"",false,true,""]}], +["fo[o<dfn>bar</dfn>b]az", + [["stylewithcss","true"],["italic",""]], + "fo<span style=\"font-style:italic\">[o<dfn>bar</dfn>b]</span>az", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[true,false,"",false,true,""]}], +["fo[o<dfn>bar</dfn>b]az", + [["stylewithcss","false"],["italic",""]], + "fo<i>[o<dfn>bar</dfn>b]</i>az", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[true,false,"",false,true,""]}], +// Replace <em> with <i> or <span> when whole of it is wrapped in a new element. +["fo[o<em>bar</em>b]az", + [["stylewithcss","true"],["italic",""]], + "fo<span style=\"font-style:italic\">[obarb]</span>az", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[true,false,"",false,true,""]}], +["fo[o<em>bar</em>b]az", + [["stylewithcss","false"],["italic",""]], + "fo<i>[obarb]</i>az", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[true,false,"",false,true,""]}], +["fo[o<var>bar</var>b]az", + [["stylewithcss","true"],["italic",""]], + "fo<span style=\"font-style:italic\">[o<var>bar</var>b]</span>az", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[true,false,"",false,true,""]}], +["fo[o<var>bar</var>b]az", + [["stylewithcss","false"],["italic",""]], + "fo<i>[o<var>bar</var>b]</i>az", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[true,false,"",false,true,""]}], +["foo[<address>bar</address>baz]", + [["stylewithcss","true"],["italic",""]], + "foo[<address>bar</address><span style=\"font-style:italic\">baz]</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[true,false,"",false,true,""]}], +["foo[<address>bar</address>baz]", + [["stylewithcss","false"],["italic",""]], + "foo[<address>bar</address><i>baz]</i>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[true,false,"",false,true,""]}], +["foo[<cite>bar</cite>baz]", + [["stylewithcss","true"],["italic",""]], + "foo[<cite>bar</cite><span style=\"font-style:italic\">baz]</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[true,false,"",false,true,""]}], +["foo[<cite>bar</cite>baz]", + [["stylewithcss","false"],["italic",""]], + "foo[<cite>bar</cite><i>baz]</i>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[true,false,"",false,true,""]}], +["foo[<dfn>bar</dfn>baz]", + [["stylewithcss","true"],["italic",""]], + "foo[<dfn>bar</dfn><span style=\"font-style:italic\">baz]</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[true,false,"",false,true,""]}], +["foo[<dfn>bar</dfn>baz]", + [["stylewithcss","false"],["italic",""]], + "foo[<dfn>bar</dfn><i>baz]</i>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[true,false,"",false,true,""]}], +["foo[<em>bar</em>baz]", + [["stylewithcss","true"],["italic",""]], + "foo[<span style=\"font-style:italic\">barbaz]</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[true,false,"",false,true,""]}], +["foo[<em>bar</em>baz]", + [["stylewithcss","false"],["italic",""]], + "foo[<i>barbaz]</i>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[true,false,"",false,true,""]}], +["foo[<i>bar</i>baz]", + [["stylewithcss","true"],["italic",""]], + "foo[<span style=\"font-style:italic\">barbaz]</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[true,false,"",false,true,""]}], +["foo[<i>bar</i>baz]", + [["stylewithcss","false"],["italic",""]], + "foo[<i>barbaz]</i>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[true,false,"",false,true,""]}], +["foo[<var>bar</var>baz]", + [["stylewithcss","true"],["italic",""]], + "foo[<var>bar</var><span style=\"font-style:italic\">baz]</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[true,false,"",false,true,""]}], +["foo[<var>bar</var>baz]", + [["stylewithcss","false"],["italic",""]], + "foo[<var>bar</var><i>baz]</i>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[true,false,"",false,true,""]}], +["[foo<address>bar</address>]baz", + [["stylewithcss","true"],["italic",""]], + "<span style=\"font-style:italic\">[foo</span><address>bar</address>]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[true,false,"",false,true,""]}], +["[foo<address>bar</address>]baz", + [["stylewithcss","false"],["italic",""]], + "<i>[foo</i><address>bar</address>]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[true,false,"",false,true,""]}], +["[foo<cite>bar</cite>]baz", + [["stylewithcss","true"],["italic",""]], + "<span style=\"font-style:italic\">[foo<cite>bar</cite></span>]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[true,false,"",false,true,""]}], +["[foo<cite>bar</cite>]baz", + [["stylewithcss","false"],["italic",""]], + "<i>[foo<cite>bar</cite></i>]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[true,false,"",false,true,""]}], +["[foo<dfn>bar</dfn>]baz", + [["stylewithcss","true"],["italic",""]], + "<span style=\"font-style:italic\">[foo<dfn>bar</dfn></span>]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[true,false,"",false,true,""]}], +["[foo<dfn>bar</dfn>]baz", + [["stylewithcss","false"],["italic",""]], + "<i>[foo<dfn>bar</dfn></i>]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[true,false,"",false,true,""]}], +["[foo<em>bar</em>]baz", + [["stylewithcss","true"],["italic",""]], + "<span style=\"font-style:italic\">[foobar</span>]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[true,false,"",false,true,""]}], +["[foo<em>bar</em>]baz", + [["stylewithcss","false"],["italic",""]], + "<i>[foobar</i>]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[true,false,"",false,true,""]}], +["[foo<i>bar</i>]baz", + [["stylewithcss","true"],["italic",""]], + "<span style=\"font-style:italic\">[foobar</span>]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[true,false,"",false,true,""]}], +["[foo<i>bar</i>]baz", + [["stylewithcss","false"],["italic",""]], + "<i>[foobar</i>]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[true,false,"",false,true,""]}], +["[foo<var>bar</var>]baz", + [["stylewithcss","true"],["italic",""]], + "<span style=\"font-style:italic\">[foo<var>bar</var></span>]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[true,false,"",false,true,""]}], +["[foo<var>bar</var>]baz", + [["stylewithcss","false"],["italic",""]], + "<i>[foo<var>bar</var></i>]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[true,false,"",false,true,""]}], +["foo<span style=\"font-style: italic\">[bar]</span>baz", + [["stylewithcss","true"],["italic",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[false,true,"",false,false,""]}], +["foo<span style=\"font-style: italic\">[bar]</span>baz", + [["stylewithcss","false"],["italic",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[false,true,"",false,false,""]}], +["foo<span style=\"font-style: oblique\">[bar]</span>baz", + [["stylewithcss","true"],["italic",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[false,true,"",false,false,""]}], +["foo<span style=\"font-style: oblique\">[bar]</span>baz", + [["stylewithcss","false"],["italic",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[false,true,"",false,false,""]}], +["foo<span style=\"font-style: oblique\">b[a]r</span>baz", + [["stylewithcss","true"],["italic",""]], + "foo<span style=\"font-style:oblique\">b</span>[a]<span style=\"font-style:oblique\">r</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[false,true,"",false,false,""]}], +["foo<span style=\"font-style: oblique\">b[a]r</span>baz", + [["stylewithcss","false"],["italic",""]], + "foo<span style=\"font-style:oblique\">b</span>[a]<span style=\"font-style:oblique\">r</span>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[false,true,"",false,false,""]}], +["<i>{<p>foo</p><p>bar</p>}<p>baz</p></i>", + [["stylewithcss","true"],["italic",""]], + "{<p>foo</p><p>bar</p>}<p><span style=\"font-style:italic\">baz</span></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[false,true,"",false,false,""]}], +["<i>{<p>foo</p><p>bar</p>}<p>baz</p></i>", + [["stylewithcss","false"],["italic",""]], + "{<p>foo</p><p>bar</p>}<p><i>baz</i></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[false,true,"",false,false,""]}], +["<i><p>foo[<b>bar</b>}</p><p>baz</p></i>", + [["stylewithcss","true"],["italic",""]], + "<p><span style=\"font-style:italic\">foo[</span><b>bar</b>}</p><p><span style=\"font-style:italic\">baz</span></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[false,true,"",false,false,""]}], +["<i><p>foo[<b>bar</b>}</p><p>baz</p></i>", + [["stylewithcss","false"],["italic",""]], + "<p><i>foo[</i><b>bar</b>}</p><p><i>baz</i></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[false,true,"",false,false,""]}], +["foo [bar <b>baz] qoz</b> quz sic", + [["stylewithcss","true"],["italic",""]], + "foo <span style=\"font-style:italic\">[bar </span><b><span style=\"font-style:italic\">baz]</span> qoz</b> quz sic", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[false,false,"",false,true,""]}], +["foo [bar <b>baz] qoz</b> quz sic", + [["stylewithcss","false"],["italic",""]], + "foo <i>[bar </i><b><i>baz]</i> qoz</b> quz sic", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[false,false,"",false,true,""]}], +["foo bar <b>baz [qoz</b> quz] sic", + [["stylewithcss","true"],["italic",""]], + "foo bar <b>baz <span style=\"font-style:italic\">[qoz</span></b><span style=\"font-style:italic\"> quz]</span> sic", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[false,false,"",false,true,""]}], +["foo bar <b>baz [qoz</b> quz] sic", + [["stylewithcss","false"],["italic",""]], + "foo bar <b>baz <i>[qoz</i></b><i> quz]</i> sic", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[false,false,"",false,true,""]}], +["foo [bar <i>baz] qoz</i> quz sic", + [["italic",""]], + "foo <i>[bar baz] qoz</i> quz sic", + [true], + {"italic":[true,false,"",false,true,""]}], +["foo bar <i>baz [qoz</i> quz] sic", + [["italic",""]], + "foo bar <i>baz [qoz quz]</i> sic", + [true], + {"italic":[true,false,"",false,true,""]}], +["fo[o<i>b]ar</i>baz", + [["italic",""]], + "fo<i>[ob]ar</i>baz", + [true], + {"italic":[true,false,"",false,true,""]}], +["foo<i>ba[r</i>b]az", + [["italic",""]], + "foo<i>ba[rb]</i>az", + [true], + {"italic":[true,false,"",false,true,""]}], +["fo[o<i>bar</i>b]az", + [["stylewithcss","true"],["italic",""]], + "fo<span style=\"font-style:italic\">[obarb]</span>az", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[true,false,"",false,true,""]}], +["fo[o<i>bar</i>b]az", + [["stylewithcss","false"],["italic",""]], + "fo<i>[obarb]</i>az", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[true,false,"",false,true,""]}], +["foo[<i>b]ar</i>baz", + [["stylewithcss","true"],["italic",""]], + "foo[b]<span style=\"font-style:italic\">ar</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[false,true,"",false,false,""]}], +["foo[<i>b]ar</i>baz", + [["stylewithcss","false"],["italic",""]], + "foo[b]<i>ar</i>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[false,true,"",false,false,""]}], +["foo<i>ba[r</i>]baz", + [["stylewithcss","true"],["italic",""]], + "foo<span style=\"font-style:italic\">ba</span>[r]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[false,true,"",false,false,""]}], +["foo<i>ba[r</i>]baz", + [["stylewithcss","false"],["italic",""]], + "foo<i>ba</i>[r]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[false,true,"",false,false,""]}], +["foo[<i>bar</i>]baz", + [["stylewithcss","true"],["italic",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[false,true,"",false,false,""]}], +["foo[<i>bar</i>]baz", + [["stylewithcss","false"],["italic",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[false,true,"",false,false,""]}], +["foo<i>[bar]</i>baz", + [["stylewithcss","true"],["italic",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[false,true,"",false,false,""]}], +["foo<i>[bar]</i>baz", + [["stylewithcss","false"],["italic",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[false,true,"",false,false,""]}], +["foo{<i>bar</i>}baz", + [["stylewithcss","true"],["italic",""]], + "foo{bar}baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[false,true,"",false,false,""]}], +["foo{<i>bar</i>}baz", + [["stylewithcss","false"],["italic",""]], + "foo{bar}baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[false,true,"",false,false,""]}], +["fo[o<span style=font-style:italic>b]ar</span>baz", + [["italic",""]], + "fo<span style=\"font-style:italic\">[ob]ar</span>baz", + [true], + {"italic":[true,false,"",false,true,""]}], +["fo[o<span style=font-style:oblique>b]ar</span>baz", + [["stylewithcss","true"],["italic",""]], + "fo<span style=\"font-style:italic\">[o</span><span style=\"font-style:oblique\"><span style=\"font-style:italic\">b]</span>ar</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[true,false,"",false,true,""]}], +["fo[o<span style=font-style:oblique>b]ar</span>baz", + [["stylewithcss","false"],["italic",""]], + "fo<i>[o</i><span style=\"font-style:oblique\"><i>b]</i>ar</span>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[true,false,"",false,true,""]}], +["<span style=font-style:italic>fo[o</span><span style=font-style:oblique>b]ar</span>", + [["stylewithcss","true"],["italic",""]], + "<span style=\"font-style:italic\">fo</span>[ob]<span style=\"font-style:oblique\">ar</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[false,true,"",false,false,""]}], +["<span style=font-style:italic>fo[o</span><span style=font-style:oblique>b]ar</span>", + [["stylewithcss","false"],["italic",""]], + "<i>fo</i>[ob]<span style=\"font-style:oblique\">ar</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[false,true,"",false,false,""]}], +["<span style=font-style:oblique>fo[o</span><span style=font-style:italic>b]ar</span>", + [["stylewithcss","true"],["italic",""]], + "<span style=\"font-style:oblique\">fo</span>[ob]<span style=\"font-style:italic\">ar</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[false,true,"",false,false,""]}], +["<span style=font-style:oblique>fo[o</span><span style=font-style:italic>b]ar</span>", + [["stylewithcss","false"],["italic",""]], + "<span style=\"font-style:oblique\">fo</span>[ob]<i>ar</i>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[false,true,"",false,false,""]}], +["<i>fo[o</i><address>b]ar</address>", + [["stylewithcss","true"],["italic",""]], + "<span style=\"font-style:italic\">fo</span>[o<address><span style=\"font-style:normal\">b]</span>ar</address>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"italic":[false,true,"",false,false,""]}], +["<i>fo[o</i><address>b]ar</address>", + [["stylewithcss","false"],["italic",""]], + "<i>fo</i>[o<address><span style=\"font-style:normal\">b]</span>ar</address>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"italic":[false,true,"",false,false,""]}] +] diff --git a/testing/web-platform/tests/editing/data/justifycenter.js b/testing/web-platform/tests/editing/data/justifycenter.js new file mode 100644 index 0000000000..19cac03045 --- /dev/null +++ b/testing/web-platform/tests/editing/data/justifycenter.js @@ -0,0 +1,1491 @@ +// For documentation of the format, see README in this directory. +var browserTests = [ +["foo[]bar<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\">foo[]bar</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["foo[]bar<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\">foo[]bar</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["foo[]bar<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\">foo[]bar</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["foo[]bar<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\">foo[]bar</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<span>foo</span>{}<span>bar</span><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\"><span>foo</span>{}<span>bar</span></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<span>foo</span>{}<span>bar</span><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\"><span>foo</span>{}<span>bar</span></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<span>foo</span>{}<span>bar</span><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\"><span>foo</span>{}<span>bar</span></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<span>foo</span>{}<span>bar</span><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\"><span>foo</span>{}<span>bar</span></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<span>foo[</span><span>]bar</span><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\"><span>foo[</span><span>]bar</span></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<span>foo[</span><span>]bar</span><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\"><span>foo[</span><span>]bar</span></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<span>foo[</span><span>]bar</span><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\"><span>foo[</span><span>]bar</span></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<span>foo[</span><span>]bar</span><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\"><span>foo[</span><span>]bar</span></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["foo[bar]baz<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\">foo[bar]baz</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["foo[bar]baz<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\">foo[bar]baz</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["foo[bar]baz<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\">foo[bar]baz</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["foo[bar]baz<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\">foo[bar]baz</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["foo[bar<b>baz]qoz</b>quz<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\">foo[bar<b>baz]qoz</b>quz</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["foo[bar<b>baz]qoz</b>quz<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\">foo[bar<b>baz]qoz</b>quz</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["foo[bar<b>baz]qoz</b>quz<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\">foo[bar<b>baz]qoz</b>quz</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["foo[bar<b>baz]qoz</b>quz<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\">foo[bar<b>baz]qoz</b>quz</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<p>foo[]bar<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\"><p>foo[]bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<p>foo[]bar<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\"><p>foo[]bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<p>foo[]bar<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\"><p>foo[]bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<p>foo[]bar<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\"><p>foo[]bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<p>foo[bar]baz<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\"><p>foo[bar]baz</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<p>foo[bar]baz<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\"><p>foo[bar]baz</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<p>foo[bar]baz<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\"><p>foo[bar]baz</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<p>foo[bar]baz<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\"><p>foo[bar]baz</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<h1>foo[bar]baz</h1><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\"><h1>foo[bar]baz</h1></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<h1>foo[bar]baz</h1><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\"><h1>foo[bar]baz</h1></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<h1>foo[bar]baz</h1><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\"><h1>foo[bar]baz</h1></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<h1>foo[bar]baz</h1><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\"><h1>foo[bar]baz</h1></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<pre>foo[bar]baz</pre><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\"><pre>foo[bar]baz</pre></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<pre>foo[bar]baz</pre><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\"><pre>foo[bar]baz</pre></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<pre>foo[bar]baz</pre><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\"><pre>foo[bar]baz</pre></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<pre>foo[bar]baz</pre><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\"><pre>foo[bar]baz</pre></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<xmp>foo[bar]baz</xmp><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\"><xmp>foo[bar]baz</xmp></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<xmp>foo[bar]baz</xmp><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\"><xmp>foo[bar]baz</xmp></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<xmp>foo[bar]baz</xmp><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\"><xmp>foo[bar]baz</xmp></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<xmp>foo[bar]baz</xmp><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\"><xmp>foo[bar]baz</xmp></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<center><p>[foo]<p>bar</center><p>extra", + [["justifycenter",""]], + "<center><p>[foo]</p><p>bar</p></center><p>extra</p>", + [true], + {"justifycenter":[false,true,"center",false,true,"center"]}], +["<center><p>[foo<p>bar]</center><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\"><p>[foo</p><p>bar]</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,true,"center",false,true,"center"]}], +["<center><p>[foo<p>bar]</center><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\"><p>[foo</p><p>bar]</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,true,"center",false,true,"center"]}], +["<center><p>[foo<p>bar]</center><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\"><p>[foo</p><p>bar]</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,true,"center",false,true,"center"]}], +["<center><p>[foo<p>bar]</center><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\"><p>[foo</p><p>bar]</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,true,"center",false,true,"center"]}], +["<table><tbody><tr><td>foo<td>b[a]r<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<table><tbody><tr><td>foo</td><td><div style=\"text-align:center\">b[a]r</div></td><td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<table><tbody><tr><td>foo<td>b[a]r<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<table><tbody><tr><td>foo</td><td><div style=\"text-align:center\">b[a]r</div></td><td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<table><tbody><tr><td>foo<td>b[a]r<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<table><tbody><tr><td>foo</td><td><div style=\"text-align:center\">b[a]r</div></td><td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<table><tbody><tr><td>foo<td>b[a]r<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<table><tbody><tr><td>foo</td><td><div style=\"text-align:center\">b[a]r</div></td><td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<table><tbody><tr><td>foo</td>{<td><div style=\"text-align:center\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<table><tbody><tr><td>foo</td>{<td><div style=\"text-align:center\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<table><tbody><tr><td>foo</td>{<td><div style=\"text-align:center\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<table><tbody><tr><td>foo</td>{<td><div style=\"text-align:center\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<table><tbody><tr>{<td><div style=\"text-align:center\">foo</div></td><td><div style=\"text-align:center\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<table><tbody><tr>{<td><div style=\"text-align:center\">foo</div></td><td><div style=\"text-align:center\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<table><tbody><tr>{<td><div style=\"text-align:center\">foo</div></td><td><div style=\"text-align:center\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<table><tbody><tr>{<td><div style=\"text-align:center\">foo</div></td><td><div style=\"text-align:center\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["{<table><tr><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["{<table><tr><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["{<table><tr><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["{<table><tr><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<table align=center><tbody><tr><td>foo<td>b[a]r<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<table align=\"center\"><tbody><tr><td>foo</td><td><div style=\"text-align:center\">b[a]r</div></td><td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<table align=center><tbody><tr><td>foo<td>b[a]r<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<table align=\"center\"><tbody><tr><td>foo</td><td><div style=\"text-align:center\">b[a]r</div></td><td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<table align=center><tbody><tr><td>foo<td>b[a]r<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<table align=\"center\"><tbody><tr><td>foo</td><td><div style=\"text-align:center\">b[a]r</div></td><td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<table align=center><tbody><tr><td>foo<td>b[a]r<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<table align=\"center\"><tbody><tr><td>foo</td><td><div style=\"text-align:center\">b[a]r</div></td><td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<table align=center><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<table align=\"center\"><tbody><tr><td>foo</td>{<td><div style=\"text-align:center\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<table align=center><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<table align=\"center\"><tbody><tr><td>foo</td>{<td><div style=\"text-align:center\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<table align=center><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<table align=\"center\"><tbody><tr><td>foo</td>{<td><div style=\"text-align:center\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<table align=center><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<table align=\"center\"><tbody><tr><td>foo</td>{<td><div style=\"text-align:center\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<table align=center><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<table align=\"center\"><tbody><tr>{<td><div style=\"text-align:center\">foo</div></td><td><div style=\"text-align:center\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<table align=center><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<table align=\"center\"><tbody><tr>{<td><div style=\"text-align:center\">foo</div></td><td><div style=\"text-align:center\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<table align=center><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<table align=\"center\"><tbody><tr>{<td><div style=\"text-align:center\">foo</div></td><td><div style=\"text-align:center\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<table align=center><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<table align=\"center\"><tbody><tr>{<td><div style=\"text-align:center\">foo</div></td><td><div style=\"text-align:center\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<table align=center><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<table align=center><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<table align=center><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<table align=center><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<table align=center data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<table align=center data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<table align=center data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<table align=center data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["{<table align=center><tr><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["{<table align=center><tr><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["{<table align=center><tr><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["{<table align=center><tr><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<table><tbody align=center><tr><td>foo<td>b[a]r<td>baz</table><p>extra", + [["justifycenter",""]], + "<table><tbody align=\"center\"><tr><td>foo</td><td>b[a]r</td><td>baz</td></tr></tbody></table><p>extra</p>", + [true], + {"justifycenter":[false,true,"center",false,true,"center"]}], +["<table><tbody align=center><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["justifycenter",""]], + "<table><tbody align=\"center\"><tr><td>foo</td>{<td>bar</td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true], + {"justifycenter":[false,true,"center",false,true,"center"]}], +["<table><tbody align=center><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["justifycenter",""]], + "<table><tbody align=\"center\"><tr>{<td>foo</td><td>bar</td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true], + {"justifycenter":[false,true,"center",false,true,"center"]}], +["<table><tbody align=center data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,true,"center",false,true,"center"]}], +["<table><tbody align=center data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,true,"center",false,true,"center"]}], +["<table><tbody align=center data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,true,"center",false,true,"center"]}], +["<table><tbody align=center data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,true,"center",false,true,"center"]}], +["<table data-start=0 data-end=1><tbody align=center><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,true,"center",false,true,"center"]}], +["<table data-start=0 data-end=1><tbody align=center><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,true,"center",false,true,"center"]}], +["<table data-start=0 data-end=1><tbody align=center><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,true,"center",false,true,"center"]}], +["<table data-start=0 data-end=1><tbody align=center><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,true,"center",false,true,"center"]}], +["{<table><tbody align=center><tr><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,true,"center",false,true,"center"]}], +["{<table><tbody align=center><tr><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,true,"center",false,true,"center"]}], +["{<table><tbody align=center><tr><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,true,"center",false,true,"center"]}], +["{<table><tbody align=center><tr><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,true,"center",false,true,"center"]}], +["<table><tbody><tr align=center><td>foo<td>b[a]r<td>baz</table><p>extra", + [["justifycenter",""]], + "<table><tbody><tr align=\"center\"><td>foo</td><td>b[a]r</td><td>baz</td></tr></tbody></table><p>extra</p>", + [true], + {"justifycenter":[false,true,"center",false,true,"center"]}], +["<table><tbody><tr align=center data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["justifycenter",""]], + "<table><tbody><tr align=\"center\"><td>foo</td>{<td>bar</td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true], + {"justifycenter":[false,true,"center",false,true,"center"]}], +["<table><tbody><tr align=center data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["justifycenter",""]], + "<table><tbody><tr align=\"center\">{<td>foo</td><td>bar</td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true], + {"justifycenter":[false,true,"center",false,true,"center"]}], +["<table><tbody data-start=0 data-end=1><tr align=center><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,true,"center",false,true,"center"]}], +["<table><tbody data-start=0 data-end=1><tr align=center><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,true,"center",false,true,"center"]}], +["<table><tbody data-start=0 data-end=1><tr align=center><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,true,"center",false,true,"center"]}], +["<table><tbody data-start=0 data-end=1><tr align=center><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,true,"center",false,true,"center"]}], +["<table data-start=0 data-end=1><tbody><tr align=center><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,true,"center",false,true,"center"]}], +["<table data-start=0 data-end=1><tbody><tr align=center><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,true,"center",false,true,"center"]}], +["<table data-start=0 data-end=1><tbody><tr align=center><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,true,"center",false,true,"center"]}], +["<table data-start=0 data-end=1><tbody><tr align=center><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,true,"center",false,true,"center"]}], +["{<table><tr align=center><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,true,"center",false,true,"center"]}], +["{<table><tr align=center><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,true,"center",false,true,"center"]}], +["{<table><tr align=center><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,true,"center",false,true,"center"]}], +["{<table><tr align=center><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,true,"center",false,true,"center"]}], +["<div align=center><p>[foo]<p>bar</div><p>extra", + [["justifycenter",""]], + "<div align=\"center\"><p>[foo]</p><p>bar</p></div><p>extra</p>", + [true], + {"justifycenter":[false,true,"center",false,true,"center"]}], +["<div align=center><p>[foo<p>bar}</div><p>extra", + [["stylewithcss","true"],["justifycenter",""]], + "<div style=\"text-align:center\"><p>[foo</p><p>bar}</p></div><p>extra</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"justifycenter":[false,true,"center",false,true,"center"]}], +["<div align=center><p>[foo<p>bar}</div><p>extra", + [["stylewithcss","false"],["justifycenter",""]], + "<div style=\"text-align:center\"><p>[foo</p><p>bar}</p></div><p>extra</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"justifycenter":[false,true,"center",false,true,"center"]}], +["<div style=text-align:center><p>[foo]<p>bar</div><p>extra", + [["justifycenter",""]], + "<div style=\"text-align:center\"><p>[foo]</p><p>bar</p></div><p>extra</p>", + [true], + {"justifycenter":[false,true,"center",false,true,"center"]}], +["<div style=text-align:center><p>[foo<p>bar]</div><p>extra", + [["justifycenter",""]], + "<div style=\"text-align:center\"><p>[foo</p><p>bar]</p></div><p>extra</p>", + [true], + {"justifycenter":[false,true,"center",false,true,"center"]}], +["<div align=justify><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div align=\"justify\"><div style=\"text-align:center\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"justify",false,true,"center"]}], +["<div align=justify><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div align=\"justify\"><div style=\"text-align:center\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,false,"justify",false,true,"center"]}], +["<div align=justify><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div align=\"justify\"><div style=\"text-align:center\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"justify",false,true,"center"]}], +["<div align=justify><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div align=\"justify\"><div style=\"text-align:center\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,false,"justify",false,true,"center"]}], +["<div align=justify><p>[foo<p>bar}</div><p>extra", + [["stylewithcss","true"],["justifycenter",""]], + "<div style=\"text-align:center\"><p>[foo</p><p>bar}</p></div><p>extra</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"justifycenter":[false,false,"justify",false,true,"center"]}], +["<div align=justify><p>[foo<p>bar}</div><p>extra", + [["stylewithcss","false"],["justifycenter",""]], + "<div style=\"text-align:center\"><p>[foo</p><p>bar}</p></div><p>extra</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"justifycenter":[false,false,"justify",false,true,"center"]}], +["<div style=text-align:justify><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:justify\"><div style=\"text-align:center\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"justify",false,true,"center"]}], +["<div style=text-align:justify><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:justify\"><div style=\"text-align:center\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,false,"justify",false,true,"center"]}], +["<div style=text-align:justify><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:justify\"><div style=\"text-align:center\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"justify",false,true,"center"]}], +["<div style=text-align:justify><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:justify\"><div style=\"text-align:center\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,false,"justify",false,true,"center"]}], +["<div style=text-align:justify><p>[foo<p>bar]</div><p>extra", + [["justifycenter",""]], + "<div style=\"text-align:center\"><p>[foo</p><p>bar]</p></div><p>extra</p>", + [true], + {"justifycenter":[false,false,"justify",false,true,"center"]}], +["<div align=left><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div align=\"left\"><div style=\"text-align:center\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<div align=left><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div align=\"left\"><div style=\"text-align:center\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<div align=left><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div align=\"left\"><div style=\"text-align:center\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<div align=left><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div align=\"left\"><div style=\"text-align:center\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<div align=left><p>[foo<p>bar}</div><p>extra", + [["stylewithcss","true"],["justifycenter",""]], + "<div style=\"text-align:center\"><p>[foo</p><p>bar}</p></div><p>extra</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"justifycenter":[false,false,"left",false,true,"center"]}], +["<div align=left><p>[foo<p>bar}</div><p>extra", + [["stylewithcss","false"],["justifycenter",""]], + "<div style=\"text-align:center\"><p>[foo</p><p>bar}</p></div><p>extra</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"justifycenter":[false,false,"left",false,true,"center"]}], +["<div style=text-align:left><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:left\"><div style=\"text-align:center\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<div style=text-align:left><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:left\"><div style=\"text-align:center\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<div style=text-align:left><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:left\"><div style=\"text-align:center\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<div style=text-align:left><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:left\"><div style=\"text-align:center\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<div style=text-align:left><p>[foo<p>bar]</div><p>extra", + [["justifycenter",""]], + "<div style=\"text-align:center\"><p>[foo</p><p>bar]</p></div><p>extra</p>", + [true], + {"justifycenter":[false,false,"left",false,true,"center"]}], +["<div align=right><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div align=\"right\"><div style=\"text-align:center\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"right",false,true,"center"]}], +["<div align=right><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div align=\"right\"><div style=\"text-align:center\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,false,"right",false,true,"center"]}], +["<div align=right><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div align=\"right\"><div style=\"text-align:center\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"right",false,true,"center"]}], +["<div align=right><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div align=\"right\"><div style=\"text-align:center\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,false,"right",false,true,"center"]}], +["<div align=right><p>[foo<p>bar}</div><p>extra", + [["stylewithcss","true"],["justifycenter",""]], + "<div style=\"text-align:center\"><p>[foo</p><p>bar}</p></div><p>extra</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"justifycenter":[false,false,"right",false,true,"center"]}], +["<div align=right><p>[foo<p>bar}</div><p>extra", + [["stylewithcss","false"],["justifycenter",""]], + "<div style=\"text-align:center\"><p>[foo</p><p>bar}</p></div><p>extra</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"justifycenter":[false,false,"right",false,true,"center"]}], +["<div style=text-align:right><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:right\"><div style=\"text-align:center\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"right",false,true,"center"]}], +["<div style=text-align:right><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:right\"><div style=\"text-align:center\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,false,"right",false,true,"center"]}], +["<div style=text-align:right><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:right\"><div style=\"text-align:center\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"right",false,true,"center"]}], +["<div style=text-align:right><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:right\"><div style=\"text-align:center\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,false,"right",false,true,"center"]}], +["<div style=text-align:right><p>[foo<p>bar]</div><p>extra", + [["justifycenter",""]], + "<div style=\"text-align:center\"><p>[foo</p><p>bar]</p></div><p>extra</p>", + [true], + {"justifycenter":[false,false,"right",false,true,"center"]}], +["<center>foo</center>[bar]<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<center>foo</center><div style=\"text-align:center\">[bar]</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<center>foo</center>[bar]<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<center>foo</center><div style=\"text-align:center\">[bar]</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<center>foo</center>[bar]<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<center>foo</center><div style=\"text-align:center\">[bar]</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<center>foo</center>[bar]<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<center>foo</center><div style=\"text-align:center\">[bar]</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["[foo]<center>bar</center><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\">[foo]</div><center>bar</center><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["[foo]<center>bar</center><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\">[foo]</div><center>bar</center><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["[foo]<center>bar</center><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\">[foo]</div><center>bar</center><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["[foo]<center>bar</center><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\">[foo]</div><center>bar</center><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<center>foo</center>[bar]<center>baz</center><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<center>foo</center><div style=\"text-align:center\">[bar]</div><center>baz</center><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<center>foo</center>[bar]<center>baz</center><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<center>foo</center><div style=\"text-align:center\">[bar]</div><center>baz</center><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<center>foo</center>[bar]<center>baz</center><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<center>foo</center><div style=\"text-align:center\">[bar]</div><center>baz</center><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<center>foo</center>[bar]<center>baz</center><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<center>foo</center><div style=\"text-align:center\">[bar]</div><center>baz</center><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<div align=center>foo</div>[bar]<p>extra", + [["justifycenter",""]], + "<div align=\"center\">foo<br>[bar]</div><p>extra</p>", + [true], + {"justifycenter":[false,false,"left",false,true,"center"]}], +["[foo]<div align=center>bar</div><p>extra", + [["justifycenter",""]], + "<div align=\"center\">[foo]<br>bar</div><p>extra</p>", + [true], + {"justifycenter":[false,false,"left",false,true,"center"]}], +["<div align=center>foo</div>[bar]<div align=center>baz</div><p>extra", + [["defaultparagraphseparator","div"],["justifycenter",""]], + "<div align=\"center\">foo<br>[bar]<br>baz</div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<div align=center>foo</div>[bar]<div align=center>baz</div><p>extra", + [["defaultparagraphseparator","p"],["justifycenter",""]], + "<div align=\"center\">foo<br>[bar]<br>baz</div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<div align=center><p>foo</div><p>[bar]<p>extra", + [["justifycenter",""]], + "<div align=\"center\"><p>foo</p><p>[bar]</p></div><p>extra</p>", + [true], + {"justifycenter":[false,false,"left",false,true,"center"]}], +["<p>[foo]<div align=center><p>bar</div><p>extra", + [["justifycenter",""]], + "<div align=\"center\"><p>[foo]</p><p>bar</p></div><p>extra</p>", + [true], + {"justifycenter":[false,false,"left",false,true,"center"]}], +["<div align=center><p>foo</div><p>[bar]<div align=center><p>baz</div><p>extra", + [["defaultparagraphseparator","div"],["justifycenter",""]], + "<div align=\"center\"><p>foo</p><p>[bar]</p><p>baz</p></div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<div align=center><p>foo</div><p>[bar]<div align=center><p>baz</div><p>extra", + [["defaultparagraphseparator","p"],["justifycenter",""]], + "<div align=\"center\"><p>foo</p><p>[bar]</p><p>baz</p></div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<div style=text-align:center>foo</div>[bar]<p>extra", + [["justifycenter",""]], + "<div style=\"text-align:center\">foo<br>[bar]</div><p>extra</p>", + [true], + {"justifycenter":[false,false,"left",false,true,"center"]}], +["[foo]<div style=text-align:center>bar</div><p>extra", + [["justifycenter",""]], + "<div style=\"text-align:center\">[foo]<br>bar</div><p>extra</p>", + [true], + {"justifycenter":[false,false,"left",false,true,"center"]}], +["<div style=text-align:center>foo</div>[bar]<div style=text-align:center>baz</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\">foo<br>[bar]<br>baz</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<div style=text-align:center>foo</div>[bar]<div style=text-align:center>baz</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\">foo<br>[bar]<br>baz</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<div style=text-align:center>foo</div>[bar]<div style=text-align:center>baz</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\">foo<br>[bar]<br>baz</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<div style=text-align:center>foo</div>[bar]<div style=text-align:center>baz</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\">foo<br>[bar]<br>baz</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<div style=text-align:center><p>foo</div><p>[bar]<p>extra", + [["justifycenter",""]], + "<div style=\"text-align:center\"><p>foo</p><p>[bar]</p></div><p>extra</p>", + [true], + {"justifycenter":[false,false,"left",false,true,"center"]}], +["<p>[foo]<div style=text-align:center><p>bar</div><p>extra", + [["justifycenter",""]], + "<div style=\"text-align:center\"><p>[foo]</p><p>bar</p></div><p>extra</p>", + [true], + {"justifycenter":[false,false,"left",false,true,"center"]}], +["<div style=text-align:center><p>foo</div><p>[bar]<div style=text-align:center><p>baz</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\"><p>foo</p><p>[bar]</p><p>baz</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<div style=text-align:center><p>foo</div><p>[bar]<div style=text-align:center><p>baz</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\"><p>foo</p><p>[bar]</p><p>baz</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<div style=text-align:center><p>foo</div><p>[bar]<div style=text-align:center><p>baz</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\"><p>foo</p><p>[bar]</p><p>baz</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<div style=text-align:center><p>foo</div><p>[bar]<div style=text-align:center><p>baz</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\"><p>foo</p><p>[bar]</p><p>baz</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<p align=center>foo<p>[bar]<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<p align=\"center\">foo</p><div style=\"text-align:center\"><p>[bar]</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<p align=center>foo<p>[bar]<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<p align=\"center\">foo</p><div style=\"text-align:center\"><p>[bar]</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<p align=center>foo<p>[bar]<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<p align=\"center\">foo</p><div style=\"text-align:center\"><p>[bar]</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<p align=center>foo<p>[bar]<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<p align=\"center\">foo</p><div style=\"text-align:center\"><p>[bar]</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<p>[foo]<p align=center>bar<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\"><p>[foo]</p></div><p align=\"center\">bar</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<p>[foo]<p align=center>bar<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\"><p>[foo]</p></div><p align=\"center\">bar</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<p>[foo]<p align=center>bar<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\"><p>[foo]</p></div><p align=\"center\">bar</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<p>[foo]<p align=center>bar<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\"><p>[foo]</p></div><p align=\"center\">bar</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<p align=center>foo<p>[bar]<p align=center>baz<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<p align=\"center\">foo</p><div style=\"text-align:center\"><p>[bar]</p></div><p align=\"center\">baz</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<p align=center>foo<p>[bar]<p align=center>baz<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<p align=\"center\">foo</p><div style=\"text-align:center\"><p>[bar]</p></div><p align=\"center\">baz</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<p align=center>foo<p>[bar]<p align=center>baz<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<p align=\"center\">foo</p><div style=\"text-align:center\"><p>[bar]</p></div><p align=\"center\">baz</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<p align=center>foo<p>[bar]<p align=center>baz<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<p align=\"center\">foo</p><div style=\"text-align:center\"><p>[bar]</p></div><p align=\"center\">baz</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<center>[foo</center>bar]<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\">[foo<br>bar]</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[true,false,"center",false,true,"center"]}], +["<center>[foo</center>bar]<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\">[foo<br>bar]</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[true,false,"center",false,true,"center"]}], +["<center>[foo</center>bar]<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\">[foo<br>bar]</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[true,false,"center",false,true,"center"]}], +["<center>[foo</center>bar]<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\">[foo<br>bar]</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[true,false,"center",false,true,"center"]}], +["<center>fo[o</center>b]ar<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\">fo[o<br>b]ar</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[true,false,"center",false,true,"center"]}], +["<center>fo[o</center>b]ar<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\">fo[o<br>b]ar</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[true,false,"center",false,true,"center"]}], +["<center>fo[o</center>b]ar<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\">fo[o<br>b]ar</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[true,false,"center",false,true,"center"]}], +["<center>fo[o</center>b]ar<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\">fo[o<br>b]ar</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[true,false,"center",false,true,"center"]}], +["<div align=center>[foo</div>bar]<p>extra", + [["stylewithcss","true"],["justifycenter",""]], + "<div style=\"text-align:center\">[foo<br>bar]</div><p>extra</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"justifycenter":[true,false,"center",false,true,"center"]}], +["<div align=center>[foo</div>bar]<p>extra", + [["stylewithcss","false"],["justifycenter",""]], + "<div style=\"text-align:center\">[foo<br>bar]</div><p>extra</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"justifycenter":[true,false,"center",false,true,"center"]}], +["<div align=center>fo[o</div>b]ar<p>extra", + [["stylewithcss","true"],["justifycenter",""]], + "<div style=\"text-align:center\">fo[o<br>b]ar</div><p>extra</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"justifycenter":[true,false,"center",false,true,"center"]}], +["<div align=center>fo[o</div>b]ar<p>extra", + [["stylewithcss","false"],["justifycenter",""]], + "<div style=\"text-align:center\">fo[o<br>b]ar</div><p>extra</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"justifycenter":[true,false,"center",false,true,"center"]}], +["<div style=text-align:center>[foo</div>bar]<p>extra", + [["justifycenter",""]], + "<div style=\"text-align:center\">[foo<br>bar]</div><p>extra</p>", + [true], + {"justifycenter":[true,false,"center",false,true,"center"]}], +["<div style=text-align:center>fo[o</div>b]ar<p>extra", + [["justifycenter",""]], + "<div style=\"text-align:center\">fo[o<br>b]ar</div><p>extra</p>", + [true], + {"justifycenter":[true,false,"center",false,true,"center"]}], +["<span style=text-align:center>[foo]</span><p>extra", + [["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\">[foo]</div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<span style=text-align:center>[foo]</span><p>extra", + [["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\">[foo]</div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<span style=text-align:center>f[o]o</span><p>extra", + [["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\">f[o]o</div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<span style=text-align:center>f[o]o</span><p>extra", + [["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\">f[o]o</div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<div style=text-align:center>[foo<div style=text-align:left contenteditable=false>bar</div>baz]</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\">[foo</div><div style=\"text-align:left\" contenteditable=\"false\">bar</div><div style=\"text-align:center\">baz]</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,true,"center",false,true,"center"]}], +["<div style=text-align:center>[foo<div style=text-align:left contenteditable=false>bar</div>baz]</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\">[foo</div><div style=\"text-align:left\" contenteditable=\"false\">bar</div><div style=\"text-align:center\">baz]</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,true,"center",false,true,"center"]}], +["<div style=text-align:center>[foo<div style=text-align:left contenteditable=false>bar</div>baz]</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\">[foo</div><div style=\"text-align:left\" contenteditable=\"false\">bar</div><div style=\"text-align:center\">baz]</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,true,"center",false,true,"center"]}], +["<div style=text-align:center>[foo<div style=text-align:left contenteditable=false>bar</div>baz]</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\">[foo</div><div style=\"text-align:left\" contenteditable=\"false\">bar</div><div style=\"text-align:center\">baz]</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,true,"center",false,true,"center"]}], +["<div align=nonsense><p>[foo]</div><p>extra", + [["stylewithcss","true"],["justifycenter",""]], + "<div style=\"text-align:center\"><p>[foo]</p></div><p>extra</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"justifycenter":[false,false,"left",false,true,"center"]}], +["<div align=nonsense><p>[foo]</div><p>extra", + [["stylewithcss","false"],["justifycenter",""]], + "<div style=\"text-align:center\"><p>[foo]</p></div><p>extra</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"justifycenter":[false,false,"left",false,true,"center"]}], +["<div style=text-align:inherit><p>[foo]</div><p>extra", + [["justifycenter",""]], + "<div style=\"text-align:center\"><p>[foo]</p></div><p>extra</p>", + [true], + {"justifycenter":[false,false,"left",false,true,"center"]}], +["<quasit align=right><p>[foo]</p></quasit><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\"><quasit><p>[foo]</p></quasit></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<quasit align=right><p>[foo]</p></quasit><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\"><quasit><p>[foo]</p></quasit></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<quasit align=right><p>[foo]</p></quasit><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\"><quasit><p>[foo]</p></quasit></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<quasit align=right><p>[foo]</p></quasit><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\"><quasit><p>[foo]</p></quasit></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<div align=center>{<div align=left>foo</div>}</div>", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\">{foo}</div>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<div align=center>{<div align=left>foo</div>}</div>", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\">{foo}</div>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<div align=center>{<div align=left>foo</div>}</div>", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\">{foo}</div>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<div align=center>{<div align=left>foo</div>}</div>", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\">{foo}</div>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<div align=left>{<div align=center>foo</div>}</div>", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\">{foo}</div>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,true,"center",false,true,"center"]}], +["<div align=left>{<div align=center>foo</div>}</div>", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\">{foo}</div>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,true,"center",false,true,"center"]}], +["<div align=left>{<div align=center>foo</div>}</div>", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\">{foo}</div>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,true,"center",false,true,"center"]}], +["<div align=left>{<div align=center>foo</div>}</div>", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\">{foo}</div>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,true,"center",false,true,"center"]}], +["<div align=center>{<div align=left>foo</div>bar}</div>", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\">{foo<br>bar}</div>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[true,false,"left",false,true,"center"]}], +["<div align=center>{<div align=left>foo</div>bar}</div>", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\">{foo<br>bar}</div>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[true,false,"left",false,true,"center"]}], +["<div align=center>{<div align=left>foo</div>bar}</div>", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\">{foo<br>bar}</div>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[true,false,"left",false,true,"center"]}], +["<div align=center>{<div align=left>foo</div>bar}</div>", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\">{foo<br>bar}</div>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[true,false,"left",false,true,"center"]}], +["<div align=left>{<div align=center>foo</div>bar}</div>", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\">{foo<br>bar}</div>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[true,false,"center",false,true,"center"]}], +["<div align=left>{<div align=center>foo</div>bar}</div>", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\">{foo<br>bar}</div>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[true,false,"center",false,true,"center"]}], +["<div align=left>{<div align=center>foo</div>bar}</div>", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\">{foo<br>bar}</div>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[true,false,"center",false,true,"center"]}], +["<div align=left>{<div align=center>foo</div>bar}</div>", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\">{foo<br>bar}</div>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[true,false,"center",false,true,"center"]}], +["<div align=center>{<div align=left>foo</div><img src=/img/lion.svg>}</div>", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\">{foo<br><img src=\"/img/lion.svg\">}</div>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[true,false,"left",false,true,"center"]}], +["<div align=center>{<div align=left>foo</div><img src=/img/lion.svg>}</div>", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\">{foo<br><img src=\"/img/lion.svg\">}</div>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[true,false,"left",false,true,"center"]}], +["<div align=center>{<div align=left>foo</div><img src=/img/lion.svg>}</div>", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\">{foo<br><img src=\"/img/lion.svg\">}</div>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[true,false,"left",false,true,"center"]}], +["<div align=center>{<div align=left>foo</div><img src=/img/lion.svg>}</div>", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\">{foo<br><img src=\"/img/lion.svg\">}</div>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[true,false,"left",false,true,"center"]}], +["<div align=left>{<div align=center>foo</div><img src=/img/lion.svg>}</div>", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\">{foo<br><img src=\"/img/lion.svg\">}</div>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[true,false,"center",false,true,"center"]}], +["<div align=left>{<div align=center>foo</div><img src=/img/lion.svg>}</div>", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\">{foo<br><img src=\"/img/lion.svg\">}</div>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[true,false,"center",false,true,"center"]}], +["<div align=left>{<div align=center>foo</div><img src=/img/lion.svg>}</div>", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\">{foo<br><img src=\"/img/lion.svg\">}</div>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[true,false,"center",false,true,"center"]}], +["<div align=left>{<div align=center>foo</div><img src=/img/lion.svg>}</div>", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\">{foo<br><img src=\"/img/lion.svg\">}</div>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[true,false,"center",false,true,"center"]}], +["<div align=center>{<div align=left>foo</div><!-- bar -->}</div>", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\">{foo<!-- bar -->}</div>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<div align=center>{<div align=left>foo</div><!-- bar -->}</div>", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\">{foo<!-- bar -->}</div>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<div align=center>{<div align=left>foo</div><!-- bar -->}</div>", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\">{foo<!-- bar -->}</div>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<div align=center>{<div align=left>foo</div><!-- bar -->}</div>", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\">{foo<!-- bar -->}</div>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<div align=left>{<div align=center>foo</div><!-- bar -->}</div>", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\">{foo<!-- bar -->}</div>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,true,"center",false,true,"center"]}], +["<div align=left>{<div align=center>foo</div><!-- bar -->}</div>", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\">{foo<!-- bar -->}</div>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,true,"center",false,true,"center"]}], +["<div align=left>{<div align=center>foo</div><!-- bar -->}</div>", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\">{foo<!-- bar -->}</div>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,true,"center",false,true,"center"]}], +["<div align=left>{<div align=center>foo</div><!-- bar -->}</div>", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\">{foo<!-- bar -->}</div>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,true,"center",false,true,"center"]}], +["<div style=text-align:start>[foo]</div><p>extra", + [["justifycenter",""]], + "<div style=\"text-align:center\">[foo]</div><p>extra</p>", + [true], + {"justifycenter":[false,false,"left",false,true,"center"]}], +["<div style=text-align:end>[foo]</div><p>extra", + [["justifycenter",""]], + "<div style=\"text-align:center\">[foo]</div><p>extra</p>", + [true], + {"justifycenter":[false,false,"right",false,true,"center"]}], +["<div dir=rtl style=text-align:start>[foo]</div><p>extra", + [["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\"><div dir=\"rtl\">[foo]</div></div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"right",false,true,"center"]}], +["<div dir=rtl style=text-align:start>[foo]</div><p>extra", + [["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\"><div dir=\"rtl\">[foo]</div></div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"right",false,true,"center"]}], +["<div dir=rtl style=text-align:end>[foo]</div><p>extra", + [["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\"><div dir=\"rtl\">[foo]</div></div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<div dir=rtl style=text-align:end>[foo]</div><p>extra", + [["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\"><div dir=\"rtl\">[foo]</div></div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<div style=text-align:center><p>foo</div> <p>[bar]", + [["justifycenter",""]], + "<div style=\"text-align:center\"><p>foo</p> <p>[bar]</p></div>", + [true], + {"justifycenter":[false,false,"left",false,true,"center"]}], +["<div align=center><p>foo</div> <p>[bar]", + [["justifycenter",""]], + "<div align=\"center\"><p>foo</p> <p>[bar]</p></div>", + [true], + {"justifycenter":[false,false,"left",false,true,"center"]}], +["<center><p>foo</center> <p>[bar]", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<center><p>foo</p></center><div style=\"text-align:center\"> <p>[bar]</p></div>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<center><p>foo</center> <p>[bar]", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<center><p>foo</p></center><div style=\"text-align:center\"> <p>[bar]</p></div>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<center><p>foo</center> <p>[bar]", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<center><p>foo</p></center><div style=\"text-align:center\"> <p>[bar]</p></div>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<center><p>foo</center> <p>[bar]", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<center><p>foo</p></center><div style=\"text-align:center\"> <p>[bar]</p></div>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<p>[foo]</p> <div style=text-align:center><p>bar</div>", + [["justifycenter",""]], + "<div style=\"text-align:center\"><p>[foo]</p> <p>bar</p></div>", + [true], + {"justifycenter":[false,false,"left",false,true,"center"]}], +["<p>[foo]</p> <div align=center><p>bar</div>", + [["justifycenter",""]], + "<div align=\"center\"><p>[foo]</p> <p>bar</p></div>", + [true], + {"justifycenter":[false,false,"left",false,true,"center"]}], +["<p>[foo]</p> <center><p>bar</center>", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\"><p>[foo]</p> </div><center><p>bar</p></center>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<p>[foo]</p> <center><p>bar</center>", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\"><p>[foo]</p> </div><center><p>bar</p></center>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<p>[foo]</p> <center><p>bar</center>", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\"><p>[foo]</p> </div><center><p>bar</p></center>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<p>[foo]</p> <center><p>bar</center>", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\"><p>[foo]</p> </div><center><p>bar</p></center>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<div style=text-align:center><p>foo</div> <p>[bar]</p> <div style=text-align:center><p>baz</div>", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\"><p>foo</p> <p>[bar]</p> <p>baz</p></div>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<div style=text-align:center><p>foo</div> <p>[bar]</p> <div style=text-align:center><p>baz</div>", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<div style=\"text-align:center\"><p>foo</p> <p>[bar]</p> <p>baz</p></div>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<div style=text-align:center><p>foo</div> <p>[bar]</p> <div style=text-align:center><p>baz</div>", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\"><p>foo</p> <p>[bar]</p> <p>baz</p></div>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<div style=text-align:center><p>foo</div> <p>[bar]</p> <div style=text-align:center><p>baz</div>", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<div style=\"text-align:center\"><p>foo</p> <p>[bar]</p> <p>baz</p></div>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<div align=center><p>foo</div> <p>[bar]</p> <div align=center><p>baz</div>", + [["defaultparagraphseparator","div"],["justifycenter",""]], + "<div align=\"center\"><p>foo</p> <p>[bar]</p> <p>baz</p></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<div align=center><p>foo</div> <p>[bar]</p> <div align=center><p>baz</div>", + [["defaultparagraphseparator","p"],["justifycenter",""]], + "<div align=\"center\"><p>foo</p> <p>[bar]</p> <p>baz</p></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<center><p>foo</center> <p>[bar]</p> <center><p>baz</center>", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<center><p>foo</p></center><div style=\"text-align:center\"> <p>[bar]</p> </div><center><p>baz</p></center>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<center><p>foo</center> <p>[bar]</p> <center><p>baz</center>", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifycenter",""]], + "<center><p>foo</p></center><div style=\"text-align:center\"> <p>[bar]</p> </div><center><p>baz</p></center>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<center><p>foo</center> <p>[bar]</p> <center><p>baz</center>", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<center><p>foo</p></center><div style=\"text-align:center\"> <p>[bar]</p> </div><center><p>baz</p></center>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<center><p>foo</center> <p>[bar]</p> <center><p>baz</center>", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifycenter",""]], + "<center><p>foo</p></center><div style=\"text-align:center\"> <p>[bar]</p> </div><center><p>baz</p></center>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifycenter":[false,false,"left",false,true,"center"]}], +["<div contenteditable=false align=center><p contenteditable>f[]oo</p></div>", + [], + ["<div contenteditable=\"false\" align=\"center\"><p contenteditable=\"\">foo</p></div>", + "<div align=\"center\" contenteditable=\"false\"><p contenteditable=\"\">foo</p></div>"], + [true], + {"justifyleft":[false,false,"center",false,false,"center"], + "justifycenter":[false,true,"center",false,true,"center"], + "justifyfull":[false,false,"center",false,false,"center"], + "justifyright":[false,false,"center",false,false,"center"]}], +["<div contenteditable=false style=text-align:center><p contenteditable>f[]oo</p></div>", + [], + ["<div contenteditable=\"false\" style=\"text-align:center\"><p contenteditable=\"\">foo</p></div>", + "<div style=\"text-align:center\" contenteditable=\"false\"><p contenteditable=\"\">foo</p></div>"], + [true], + {"justifyleft":[false,false,"center",false,false,"center"], + "justifycenter":[false,true,"center",false,true,"center"], + "justifyfull":[false,false,"center",false,false,"center"], + "justifyright":[false,false,"center",false,false,"center"]}], +] diff --git a/testing/web-platform/tests/editing/data/justifyfull.js b/testing/web-platform/tests/editing/data/justifyfull.js new file mode 100644 index 0000000000..602ae11893 --- /dev/null +++ b/testing/web-platform/tests/editing/data/justifyfull.js @@ -0,0 +1,1168 @@ +// For documentation of the format, see README in this directory. +var browserTests = [ +["foo[]bar<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\">foo[]bar</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["foo[]bar<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\">foo[]bar</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["foo[]bar<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\">foo[]bar</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["foo[]bar<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\">foo[]bar</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<span>foo</span>{}<span>bar</span><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\"><span>foo</span>{}<span>bar</span></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<span>foo</span>{}<span>bar</span><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\"><span>foo</span>{}<span>bar</span></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<span>foo</span>{}<span>bar</span><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\"><span>foo</span>{}<span>bar</span></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<span>foo</span>{}<span>bar</span><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\"><span>foo</span>{}<span>bar</span></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<span>foo[</span><span>]bar</span><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\"><span>foo[</span><span>]bar</span></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<span>foo[</span><span>]bar</span><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\"><span>foo[</span><span>]bar</span></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<span>foo[</span><span>]bar</span><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\"><span>foo[</span><span>]bar</span></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<span>foo[</span><span>]bar</span><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\"><span>foo[</span><span>]bar</span></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["foo[bar]baz<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\">foo[bar]baz</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["foo[bar]baz<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\">foo[bar]baz</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["foo[bar]baz<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\">foo[bar]baz</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["foo[bar]baz<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\">foo[bar]baz</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["foo[bar<b>baz]qoz</b>quz<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\">foo[bar<b>baz]qoz</b>quz</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["foo[bar<b>baz]qoz</b>quz<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\">foo[bar<b>baz]qoz</b>quz</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["foo[bar<b>baz]qoz</b>quz<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\">foo[bar<b>baz]qoz</b>quz</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["foo[bar<b>baz]qoz</b>quz<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\">foo[bar<b>baz]qoz</b>quz</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<p>foo[]bar<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\"><p>foo[]bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<p>foo[]bar<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\"><p>foo[]bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<p>foo[]bar<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\"><p>foo[]bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<p>foo[]bar<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\"><p>foo[]bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<p>foo[bar]baz<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\"><p>foo[bar]baz</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<p>foo[bar]baz<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\"><p>foo[bar]baz</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<p>foo[bar]baz<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\"><p>foo[bar]baz</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<p>foo[bar]baz<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\"><p>foo[bar]baz</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<h1>foo[bar]baz</h1><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\"><h1>foo[bar]baz</h1></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<h1>foo[bar]baz</h1><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\"><h1>foo[bar]baz</h1></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<h1>foo[bar]baz</h1><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\"><h1>foo[bar]baz</h1></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<h1>foo[bar]baz</h1><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\"><h1>foo[bar]baz</h1></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<pre>foo[bar]baz</pre><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\"><pre>foo[bar]baz</pre></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<pre>foo[bar]baz</pre><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\"><pre>foo[bar]baz</pre></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<pre>foo[bar]baz</pre><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\"><pre>foo[bar]baz</pre></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<pre>foo[bar]baz</pre><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\"><pre>foo[bar]baz</pre></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<xmp>foo[bar]baz</xmp><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\"><xmp>foo[bar]baz</xmp></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<xmp>foo[bar]baz</xmp><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\"><xmp>foo[bar]baz</xmp></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<xmp>foo[bar]baz</xmp><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\"><xmp>foo[bar]baz</xmp></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<xmp>foo[bar]baz</xmp><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\"><xmp>foo[bar]baz</xmp></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<center><p>[foo]<p>bar</center><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<center><div style=\"text-align:justify\"><p>[foo]</p></div><p>bar</p></center><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,false,"center",false,true,"justify"]}], +["<center><p>[foo]<p>bar</center><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<center><div style=\"text-align:justify\"><p>[foo]</p></div><p>bar</p></center><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,false,"center",false,true,"justify"]}], +["<center><p>[foo]<p>bar</center><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<center><div style=\"text-align:justify\"><p>[foo]</p></div><p>bar</p></center><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,false,"center",false,true,"justify"]}], +["<center><p>[foo]<p>bar</center><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<center><div style=\"text-align:justify\"><p>[foo]</p></div><p>bar</p></center><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyfull":[false,false,"center",false,true,"justify"]}], +["<center><p>[foo<p>bar]</center><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\"><p>[foo</p><p>bar]</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,false,"center",false,true,"justify"]}], +["<center><p>[foo<p>bar]</center><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\"><p>[foo</p><p>bar]</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,false,"center",false,true,"justify"]}], +["<center><p>[foo<p>bar]</center><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\"><p>[foo</p><p>bar]</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,false,"center",false,true,"justify"]}], +["<center><p>[foo<p>bar]</center><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\"><p>[foo</p><p>bar]</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyfull":[false,false,"center",false,true,"justify"]}], +["<table><tbody><tr><td>foo<td>b[a]r<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<table><tbody><tr><td>foo</td><td><div style=\"text-align:justify\">b[a]r</div></td><td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<table><tbody><tr><td>foo<td>b[a]r<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<table><tbody><tr><td>foo</td><td><div style=\"text-align:justify\">b[a]r</div></td><td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<table><tbody><tr><td>foo<td>b[a]r<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<table><tbody><tr><td>foo</td><td><div style=\"text-align:justify\">b[a]r</div></td><td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<table><tbody><tr><td>foo<td>b[a]r<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<table><tbody><tr><td>foo</td><td><div style=\"text-align:justify\">b[a]r</div></td><td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<table><tbody><tr><td>foo</td>{<td><div style=\"text-align:justify\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<table><tbody><tr><td>foo</td>{<td><div style=\"text-align:justify\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<table><tbody><tr><td>foo</td>{<td><div style=\"text-align:justify\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<table><tbody><tr><td>foo</td>{<td><div style=\"text-align:justify\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<table><tbody><tr>{<td><div style=\"text-align:justify\">foo</div></td><td><div style=\"text-align:justify\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<table><tbody><tr>{<td><div style=\"text-align:justify\">foo</div></td><td><div style=\"text-align:justify\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<table><tbody><tr>{<td><div style=\"text-align:justify\">foo</div></td><td><div style=\"text-align:justify\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<table><tbody><tr>{<td><div style=\"text-align:justify\">foo</div></td><td><div style=\"text-align:justify\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["{<table><tr><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["{<table><tr><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["{<table><tr><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["{<table><tr><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<table align=justify><tbody><tr><td>foo<td>b[a]r<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<table align=\"justify\"><tbody><tr><td>foo</td><td><div style=\"text-align:justify\">b[a]r</div></td><td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<table align=justify><tbody><tr><td>foo<td>b[a]r<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<table align=\"justify\"><tbody><tr><td>foo</td><td><div style=\"text-align:justify\">b[a]r</div></td><td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<table align=justify><tbody><tr><td>foo<td>b[a]r<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<table align=\"justify\"><tbody><tr><td>foo</td><td><div style=\"text-align:justify\">b[a]r</div></td><td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<table align=justify><tbody><tr><td>foo<td>b[a]r<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<table align=\"justify\"><tbody><tr><td>foo</td><td><div style=\"text-align:justify\">b[a]r</div></td><td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<table align=justify><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<table align=\"justify\"><tbody><tr><td>foo</td>{<td><div style=\"text-align:justify\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<table align=justify><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<table align=\"justify\"><tbody><tr><td>foo</td>{<td><div style=\"text-align:justify\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<table align=justify><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<table align=\"justify\"><tbody><tr><td>foo</td>{<td><div style=\"text-align:justify\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<table align=justify><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<table align=\"justify\"><tbody><tr><td>foo</td>{<td><div style=\"text-align:justify\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<table align=justify><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<table align=\"justify\"><tbody><tr>{<td><div style=\"text-align:justify\">foo</div></td><td><div style=\"text-align:justify\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<table align=justify><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<table align=\"justify\"><tbody><tr>{<td><div style=\"text-align:justify\">foo</div></td><td><div style=\"text-align:justify\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<table align=justify><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<table align=\"justify\"><tbody><tr>{<td><div style=\"text-align:justify\">foo</div></td><td><div style=\"text-align:justify\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<table align=justify><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<table align=\"justify\"><tbody><tr>{<td><div style=\"text-align:justify\">foo</div></td><td><div style=\"text-align:justify\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<table align=justify><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<table align=justify><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<table align=justify><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<table align=justify><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<table align=justify data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<table align=justify data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<table align=justify data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<table align=justify data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["{<table align=justify><tr><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["{<table align=justify><tr><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["{<table align=justify><tr><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["{<table align=justify><tr><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<table><tbody align=justify><tr><td>foo<td>b[a]r<td>baz</table><p>extra", + [["justifyfull",""]], + "<table><tbody align=\"justify\"><tr><td>foo</td><td>b[a]r</td><td>baz</td></tr></tbody></table><p>extra</p>", + [true], + {"justifyfull":[false,true,"justify",false,true,"justify"]}], +["<table><tbody align=justify><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["justifyfull",""]], + "<table><tbody align=\"justify\"><tr><td>foo</td>{<td>bar</td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true], + {"justifyfull":[false,true,"justify",false,true,"justify"]}], +["<table><tbody align=justify><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["justifyfull",""]], + "<table><tbody align=\"justify\"><tr>{<td>foo</td><td>bar</td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true], + {"justifyfull":[false,true,"justify",false,true,"justify"]}], +["<table><tbody align=justify data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,true,"justify",false,true,"justify"]}], +["<table><tbody align=justify data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,true,"justify",false,true,"justify"]}], +["<table><tbody align=justify data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,true,"justify",false,true,"justify"]}], +["<table><tbody align=justify data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyfull":[false,true,"justify",false,true,"justify"]}], +["<table data-start=0 data-end=1><tbody align=justify><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,true,"justify",false,true,"justify"]}], +["<table data-start=0 data-end=1><tbody align=justify><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,true,"justify",false,true,"justify"]}], +["<table data-start=0 data-end=1><tbody align=justify><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,true,"justify",false,true,"justify"]}], +["<table data-start=0 data-end=1><tbody align=justify><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyfull":[false,true,"justify",false,true,"justify"]}], +["{<table><tbody align=justify><tr><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,true,"justify",false,true,"justify"]}], +["{<table><tbody align=justify><tr><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,true,"justify",false,true,"justify"]}], +["{<table><tbody align=justify><tr><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,true,"justify",false,true,"justify"]}], +["{<table><tbody align=justify><tr><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyfull":[false,true,"justify",false,true,"justify"]}], +["<table><tbody><tr align=justify><td>foo<td>b[a]r<td>baz</table><p>extra", + [["justifyfull",""]], + "<table><tbody><tr align=\"justify\"><td>foo</td><td>b[a]r</td><td>baz</td></tr></tbody></table><p>extra</p>", + [true], + {"justifyfull":[false,true,"justify",false,true,"justify"]}], +["<table><tbody><tr align=justify data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["justifyfull",""]], + "<table><tbody><tr align=\"justify\"><td>foo</td>{<td>bar</td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true], + {"justifyfull":[false,true,"justify",false,true,"justify"]}], +["<table><tbody><tr align=justify data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["justifyfull",""]], + "<table><tbody><tr align=\"justify\">{<td>foo</td><td>bar</td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true], + {"justifyfull":[false,true,"justify",false,true,"justify"]}], +["<table><tbody data-start=0 data-end=1><tr align=justify><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,true,"justify",false,true,"justify"]}], +["<table><tbody data-start=0 data-end=1><tr align=justify><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,true,"justify",false,true,"justify"]}], +["<table><tbody data-start=0 data-end=1><tr align=justify><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,true,"justify",false,true,"justify"]}], +["<table><tbody data-start=0 data-end=1><tr align=justify><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyfull":[false,true,"justify",false,true,"justify"]}], +["<table data-start=0 data-end=1><tbody><tr align=justify><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,true,"justify",false,true,"justify"]}], +["<table data-start=0 data-end=1><tbody><tr align=justify><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,true,"justify",false,true,"justify"]}], +["<table data-start=0 data-end=1><tbody><tr align=justify><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,true,"justify",false,true,"justify"]}], +["<table data-start=0 data-end=1><tbody><tr align=justify><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyfull":[false,true,"justify",false,true,"justify"]}], +["{<table><tr align=justify><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,true,"justify",false,true,"justify"]}], +["{<table><tr align=justify><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,true,"justify",false,true,"justify"]}], +["{<table><tr align=justify><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,true,"justify",false,true,"justify"]}], +["{<table><tr align=justify><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyfull":[false,true,"justify",false,true,"justify"]}], +["<div align=center><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div align=\"center\"><div style=\"text-align:justify\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,false,"center",false,true,"justify"]}], +["<div align=center><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div align=\"center\"><div style=\"text-align:justify\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,false,"center",false,true,"justify"]}], +["<div align=center><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div align=\"center\"><div style=\"text-align:justify\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,false,"center",false,true,"justify"]}], +["<div align=center><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div align=\"center\"><div style=\"text-align:justify\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyfull":[false,false,"center",false,true,"justify"]}], +["<div align=center><p>[foo<p>bar}</div><p>extra", + [["stylewithcss","true"],["justifyfull",""]], + "<div style=\"text-align:justify\"><p>[foo</p><p>bar}</p></div><p>extra</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"justifyfull":[false,false,"center",false,true,"justify"]}], +["<div align=center><p>[foo<p>bar}</div><p>extra", + [["stylewithcss","false"],["justifyfull",""]], + "<div style=\"text-align:justify\"><p>[foo</p><p>bar}</p></div><p>extra</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"justifyfull":[false,false,"center",false,true,"justify"]}], +["<div style=text-align:center><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:center\"><div style=\"text-align:justify\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,false,"center",false,true,"justify"]}], +["<div style=text-align:center><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:center\"><div style=\"text-align:justify\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,false,"center",false,true,"justify"]}], +["<div style=text-align:center><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:center\"><div style=\"text-align:justify\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,false,"center",false,true,"justify"]}], +["<div style=text-align:center><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:center\"><div style=\"text-align:justify\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyfull":[false,false,"center",false,true,"justify"]}], +["<div style=text-align:center><p>[foo<p>bar]</div><p>extra", + [["justifyfull",""]], + "<div style=\"text-align:justify\"><p>[foo</p><p>bar]</p></div><p>extra</p>", + [true], + {"justifyfull":[false,false,"center",false,true,"justify"]}], +["<div align=justify><p>[foo]<p>bar</div><p>extra", + [["justifyfull",""]], + "<div align=\"justify\"><p>[foo]</p><p>bar</p></div><p>extra</p>", + [true], + {"justifyfull":[false,true,"justify",false,true,"justify"]}], +["<div align=justify><p>[foo<p>bar}</div><p>extra", + [["stylewithcss","true"],["justifyfull",""]], + "<div style=\"text-align:justify\"><p>[foo</p><p>bar}</p></div><p>extra</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"justifyfull":[false,true,"justify",false,true,"justify"]}], +["<div align=justify><p>[foo<p>bar}</div><p>extra", + [["stylewithcss","false"],["justifyfull",""]], + "<div style=\"text-align:justify\"><p>[foo</p><p>bar}</p></div><p>extra</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"justifyfull":[false,true,"justify",false,true,"justify"]}], +["<div style=text-align:justify><p>[foo]<p>bar</div><p>extra", + [["justifyfull",""]], + "<div style=\"text-align:justify\"><p>[foo]</p><p>bar</p></div><p>extra</p>", + [true], + {"justifyfull":[false,true,"justify",false,true,"justify"]}], +["<div style=text-align:justify><p>[foo<p>bar]</div><p>extra", + [["justifyfull",""]], + "<div style=\"text-align:justify\"><p>[foo</p><p>bar]</p></div><p>extra</p>", + [true], + {"justifyfull":[false,true,"justify",false,true,"justify"]}], +["<div align=left><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div align=\"left\"><div style=\"text-align:justify\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<div align=left><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div align=\"left\"><div style=\"text-align:justify\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<div align=left><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div align=\"left\"><div style=\"text-align:justify\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<div align=left><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div align=\"left\"><div style=\"text-align:justify\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<div align=left><p>[foo<p>bar}</div><p>extra", + [["stylewithcss","true"],["justifyfull",""]], + "<div style=\"text-align:justify\"><p>[foo</p><p>bar}</p></div><p>extra</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<div align=left><p>[foo<p>bar}</div><p>extra", + [["stylewithcss","false"],["justifyfull",""]], + "<div style=\"text-align:justify\"><p>[foo</p><p>bar}</p></div><p>extra</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<div style=text-align:left><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:left\"><div style=\"text-align:justify\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<div style=text-align:left><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:left\"><div style=\"text-align:justify\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<div style=text-align:left><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:left\"><div style=\"text-align:justify\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<div style=text-align:left><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:left\"><div style=\"text-align:justify\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<div style=text-align:left><p>[foo<p>bar]</div><p>extra", + [["justifyfull",""]], + "<div style=\"text-align:justify\"><p>[foo</p><p>bar]</p></div><p>extra</p>", + [true], + {"justifyfull":[false,false,"left",false,true,"justify"]}], +["<div align=right><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div align=\"right\"><div style=\"text-align:justify\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,false,"right",false,true,"justify"]}], +["<div align=right><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div align=\"right\"><div style=\"text-align:justify\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,false,"right",false,true,"justify"]}], +["<div align=right><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div align=\"right\"><div style=\"text-align:justify\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,false,"right",false,true,"justify"]}], +["<div align=right><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div align=\"right\"><div style=\"text-align:justify\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyfull":[false,false,"right",false,true,"justify"]}], +["<div align=right><p>[foo<p>bar}</div><p>extra", + [["stylewithcss","true"],["justifyfull",""]], + "<div style=\"text-align:justify\"><p>[foo</p><p>bar}</p></div><p>extra</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"justifyfull":[false,false,"right",false,true,"justify"]}], +["<div align=right><p>[foo<p>bar}</div><p>extra", + [["stylewithcss","false"],["justifyfull",""]], + "<div style=\"text-align:justify\"><p>[foo</p><p>bar}</p></div><p>extra</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"justifyfull":[false,false,"right",false,true,"justify"]}], +["<div style=text-align:right><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:right\"><div style=\"text-align:justify\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,false,"right",false,true,"justify"]}], +["<div style=text-align:right><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:right\"><div style=\"text-align:justify\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,false,"right",false,true,"justify"]}], +["<div style=text-align:right><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:right\"><div style=\"text-align:justify\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,false,"right",false,true,"justify"]}], +["<div style=text-align:right><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:right\"><div style=\"text-align:justify\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyfull":[false,false,"right",false,true,"justify"]}], +["<div style=text-align:right><p>[foo<p>bar]</div><p>extra", + [["justifyfull",""]], + "<div style=\"text-align:justify\"><p>[foo</p><p>bar]</p></div><p>extra</p>", + [true], + {"justifyfull":[false,false,"right",false,true,"justify"]}], +["<div align=justify>foo</div>[bar]<p>extra", + [["justifyfull",""]], + "<div align=\"justify\">foo<br>[bar]</div><p>extra</p>", + [true], + {"justifyfull":[false,false,"left",false,true,"justify"]}], +["[foo]<div align=justify>bar</div><p>extra", + [["justifyfull",""]], + "<div align=\"justify\">[foo]<br>bar</div><p>extra</p>", + [true], + {"justifyfull":[false,false,"left",false,true,"justify"]}], +["<div align=justify>foo</div>[bar]<div align=justify>baz</div><p>extra", + [["defaultparagraphseparator","div"],["justifyfull",""]], + "<div align=\"justify\">foo<br>[bar]<br>baz</div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<div align=justify>foo</div>[bar]<div align=justify>baz</div><p>extra", + [["defaultparagraphseparator","p"],["justifyfull",""]], + "<div align=\"justify\">foo<br>[bar]<br>baz</div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<div align=justify><p>foo</div><p>[bar]<p>extra", + [["justifyfull",""]], + "<div align=\"justify\"><p>foo</p><p>[bar]</p></div><p>extra</p>", + [true], + {"justifyfull":[false,false,"left",false,true,"justify"]}], +["<p>[foo]<div align=justify><p>bar</div><p>extra", + [["justifyfull",""]], + "<div align=\"justify\"><p>[foo]</p><p>bar</p></div><p>extra</p>", + [true], + {"justifyfull":[false,false,"left",false,true,"justify"]}], +["<div align=justify><p>foo</div><p>[bar]<div align=justify><p>baz</div><p>extra", + [["defaultparagraphseparator","div"],["justifyfull",""]], + "<div align=\"justify\"><p>foo</p><p>[bar]</p><p>baz</p></div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<div align=justify><p>foo</div><p>[bar]<div align=justify><p>baz</div><p>extra", + [["defaultparagraphseparator","p"],["justifyfull",""]], + "<div align=\"justify\"><p>foo</p><p>[bar]</p><p>baz</p></div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<div style=text-align:justify>foo</div>[bar]<p>extra", + [["justifyfull",""]], + "<div style=\"text-align:justify\">foo<br>[bar]</div><p>extra</p>", + [true], + {"justifyfull":[false,false,"left",false,true,"justify"]}], +["[foo]<div style=text-align:justify>bar</div><p>extra", + [["justifyfull",""]], + "<div style=\"text-align:justify\">[foo]<br>bar</div><p>extra</p>", + [true], + {"justifyfull":[false,false,"left",false,true,"justify"]}], +["<div style=text-align:justify>foo</div>[bar]<div style=text-align:justify>baz</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\">foo<br>[bar]<br>baz</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<div style=text-align:justify>foo</div>[bar]<div style=text-align:justify>baz</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\">foo<br>[bar]<br>baz</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<div style=text-align:justify>foo</div>[bar]<div style=text-align:justify>baz</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\">foo<br>[bar]<br>baz</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<div style=text-align:justify>foo</div>[bar]<div style=text-align:justify>baz</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\">foo<br>[bar]<br>baz</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<div style=text-align:justify><p>foo</div><p>[bar]<p>extra", + [["justifyfull",""]], + "<div style=\"text-align:justify\"><p>foo</p><p>[bar]</p></div><p>extra</p>", + [true], + {"justifyfull":[false,false,"left",false,true,"justify"]}], +["<p>[foo]<div style=text-align:justify><p>bar</div><p>extra", + [["justifyfull",""]], + "<div style=\"text-align:justify\"><p>[foo]</p><p>bar</p></div><p>extra</p>", + [true], + {"justifyfull":[false,false,"left",false,true,"justify"]}], +["<div style=text-align:justify><p>foo</div><p>[bar]<div style=text-align:justify><p>baz</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\"><p>foo</p><p>[bar]</p><p>baz</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<div style=text-align:justify><p>foo</div><p>[bar]<div style=text-align:justify><p>baz</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\"><p>foo</p><p>[bar]</p><p>baz</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<div style=text-align:justify><p>foo</div><p>[bar]<div style=text-align:justify><p>baz</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\"><p>foo</p><p>[bar]</p><p>baz</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<div style=text-align:justify><p>foo</div><p>[bar]<div style=text-align:justify><p>baz</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\"><p>foo</p><p>[bar]</p><p>baz</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<p align=justify>foo<p>[bar]<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<p align=\"justify\">foo</p><div style=\"text-align:justify\"><p>[bar]</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<p align=justify>foo<p>[bar]<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<p align=\"justify\">foo</p><div style=\"text-align:justify\"><p>[bar]</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<p align=justify>foo<p>[bar]<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<p align=\"justify\">foo</p><div style=\"text-align:justify\"><p>[bar]</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<p align=justify>foo<p>[bar]<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<p align=\"justify\">foo</p><div style=\"text-align:justify\"><p>[bar]</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<p>[foo]<p align=justify>bar<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\"><p>[foo]</p></div><p align=\"justify\">bar</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<p>[foo]<p align=justify>bar<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\"><p>[foo]</p></div><p align=\"justify\">bar</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<p>[foo]<p align=justify>bar<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\"><p>[foo]</p></div><p align=\"justify\">bar</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<p>[foo]<p align=justify>bar<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\"><p>[foo]</p></div><p align=\"justify\">bar</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<p align=justify>foo<p>[bar]<p align=justify>baz<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<p align=\"justify\">foo</p><div style=\"text-align:justify\"><p>[bar]</p></div><p align=\"justify\">baz</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<p align=justify>foo<p>[bar]<p align=justify>baz<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<p align=\"justify\">foo</p><div style=\"text-align:justify\"><p>[bar]</p></div><p align=\"justify\">baz</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<p align=justify>foo<p>[bar]<p align=justify>baz<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<p align=\"justify\">foo</p><div style=\"text-align:justify\"><p>[bar]</p></div><p align=\"justify\">baz</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<p align=justify>foo<p>[bar]<p align=justify>baz<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<p align=\"justify\">foo</p><div style=\"text-align:justify\"><p>[bar]</p></div><p align=\"justify\">baz</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<div align=justify>[foo</div>bar]<p>extra", + [["stylewithcss","true"],["justifyfull",""]], + "<div style=\"text-align:justify\">[foo<br>bar]</div><p>extra</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"justifyfull":[true,false,"justify",false,true,"justify"]}], +["<div align=justify>[foo</div>bar]<p>extra", + [["stylewithcss","false"],["justifyfull",""]], + "<div style=\"text-align:justify\">[foo<br>bar]</div><p>extra</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"justifyfull":[true,false,"justify",false,true,"justify"]}], +["<div align=justify>fo[o</div>b]ar<p>extra", + [["stylewithcss","true"],["justifyfull",""]], + "<div style=\"text-align:justify\">fo[o<br>b]ar</div><p>extra</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"justifyfull":[true,false,"justify",false,true,"justify"]}], +["<div align=justify>fo[o</div>b]ar<p>extra", + [["stylewithcss","false"],["justifyfull",""]], + "<div style=\"text-align:justify\">fo[o<br>b]ar</div><p>extra</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"justifyfull":[true,false,"justify",false,true,"justify"]}], +["<div style=text-align:justify>[foo</div>bar]<p>extra", + [["justifyfull",""]], + "<div style=\"text-align:justify\">[foo<br>bar]</div><p>extra</p>", + [true], + {"justifyfull":[true,false,"justify",false,true,"justify"]}], +["<div style=text-align:justify>fo[o</div>b]ar<p>extra", + [["justifyfull",""]], + "<div style=\"text-align:justify\">fo[o<br>b]ar</div><p>extra</p>", + [true], + {"justifyfull":[true,false,"justify",false,true,"justify"]}], +["<span style=text-align:justify>[foo]</span><p>extra", + [["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\">[foo]</div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<span style=text-align:justify>[foo]</span><p>extra", + [["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\">[foo]</div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<span style=text-align:justify>f[o]o</span><p>extra", + [["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\">f[o]o</div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<span style=text-align:justify>f[o]o</span><p>extra", + [["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\">f[o]o</div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<div style=text-align:justify>[foo<div style=text-align:left contenteditable=false>bar</div>baz]</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\">[foo</div><div style=\"text-align:left\" contenteditable=\"false\">bar</div><div style=\"text-align:justify\">baz]</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,true,"justify",false,true,"justify"]}], +["<div style=text-align:justify>[foo<div style=text-align:left contenteditable=false>bar</div>baz]</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\">[foo</div><div style=\"text-align:left\" contenteditable=\"false\">bar</div><div style=\"text-align:justify\">baz]</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,true,"justify",false,true,"justify"]}], +["<div style=text-align:justify>[foo<div style=text-align:left contenteditable=false>bar</div>baz]</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\">[foo</div><div style=\"text-align:left\" contenteditable=\"false\">bar</div><div style=\"text-align:justify\">baz]</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,true,"justify",false,true,"justify"]}], +["<div style=text-align:justify>[foo<div style=text-align:left contenteditable=false>bar</div>baz]</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\">[foo</div><div style=\"text-align:left\" contenteditable=\"false\">bar</div><div style=\"text-align:justify\">baz]</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyfull":[false,true,"justify",false,true,"justify"]}], +["<div align=nonsense><p>[foo]</div><p>extra", + [["stylewithcss","true"],["justifyfull",""]], + "<div style=\"text-align:justify\"><p>[foo]</p></div><p>extra</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<div align=nonsense><p>[foo]</div><p>extra", + [["stylewithcss","false"],["justifyfull",""]], + "<div style=\"text-align:justify\"><p>[foo]</p></div><p>extra</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<div style=text-align:inherit><p>[foo]</div><p>extra", + [["justifyfull",""]], + "<div style=\"text-align:justify\"><p>[foo]</p></div><p>extra</p>", + [true], + {"justifyfull":[false,false,"left",false,true,"justify"]}], +["<quasit align=center><p>[foo]</p></quasit><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\"><quasit><p>[foo]</p></quasit></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<quasit align=center><p>[foo]</p></quasit><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\"><quasit><p>[foo]</p></quasit></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<quasit align=center><p>[foo]</p></quasit><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\"><quasit><p>[foo]</p></quasit></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<quasit align=center><p>[foo]</p></quasit><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\"><quasit><p>[foo]</p></quasit></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<div style=text-align:start>[foo]</div><p>extra", + [["justifyfull",""]], + "<div style=\"text-align:justify\">[foo]</div><p>extra</p>", + [true], + {"justifyfull":[false,false,"left",false,true,"justify"]}], +["<div style=text-align:end>[foo]</div><p>extra", + [["justifyfull",""]], + "<div style=\"text-align:justify\">[foo]</div><p>extra</p>", + [true], + {"justifyfull":[false,false,"right",false,true,"justify"]}], +["<div dir=rtl style=text-align:start>[foo]</div><p>extra", + [["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\"><div dir=\"rtl\">[foo]</div></div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,false,"right",false,true,"justify"]}], +["<div dir=rtl style=text-align:start>[foo]</div><p>extra", + [["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\"><div dir=\"rtl\">[foo]</div></div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,false,"right",false,true,"justify"]}], +["<div dir=rtl style=text-align:end>[foo]</div><p>extra", + [["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\"><div dir=\"rtl\">[foo]</div></div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<div dir=rtl style=text-align:end>[foo]</div><p>extra", + [["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\"><div dir=\"rtl\">[foo]</div></div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<div style=text-align:justify><p>foo</div> <p>[bar]", + [["justifyfull",""]], + "<div style=\"text-align:justify\"><p>foo</p> <p>[bar]</p></div>", + [true], + {"justifyfull":[false,false,"left",false,true,"justify"]}], +["<div align=justify><p>foo</div> <p>[bar]", + [["justifyfull",""]], + "<div align=\"justify\"><p>foo</p> <p>[bar]</p></div>", + [true], + {"justifyfull":[false,false,"left",false,true,"justify"]}], +["<p>[foo]</p> <div style=text-align:justify><p>bar</div>", + [["justifyfull",""]], + "<div style=\"text-align:justify\"><p>[foo]</p> <p>bar</p></div>", + [true], + {"justifyfull":[false,false,"left",false,true,"justify"]}], +["<p>[foo]</p> <div align=justify><p>bar</div>", + [["justifyfull",""]], + "<div align=\"justify\"><p>[foo]</p> <p>bar</p></div>", + [true], + {"justifyfull":[false,false,"left",false,true,"justify"]}], +["<div style=text-align:justify><p>foo</div> <p>[bar]</p> <div style=text-align:justify><p>baz</div>", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\"><p>foo</p> <p>[bar]</p> <p>baz</p></div>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<div style=text-align:justify><p>foo</div> <p>[bar]</p> <div style=text-align:justify><p>baz</div>", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyfull",""]], + "<div style=\"text-align:justify\"><p>foo</p> <p>[bar]</p> <p>baz</p></div>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<div style=text-align:justify><p>foo</div> <p>[bar]</p> <div style=text-align:justify><p>baz</div>", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\"><p>foo</p> <p>[bar]</p> <p>baz</p></div>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<div style=text-align:justify><p>foo</div> <p>[bar]</p> <div style=text-align:justify><p>baz</div>", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyfull",""]], + "<div style=\"text-align:justify\"><p>foo</p> <p>[bar]</p> <p>baz</p></div>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<div align=justify><p>foo</div> <p>[bar]</p> <div align=justify><p>baz</div>", + [["defaultparagraphseparator","div"],["justifyfull",""]], + "<div align=\"justify\"><p>foo</p> <p>[bar]</p> <p>baz</p></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["<div align=justify><p>foo</div> <p>[bar]</p> <div align=justify><p>baz</div>", + [["defaultparagraphseparator","p"],["justifyfull",""]], + "<div align=\"justify\"><p>foo</p> <p>[bar]</p> <p>baz</p></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyfull":[false,false,"left",false,true,"justify"]}] +] diff --git a/testing/web-platform/tests/editing/data/justifyleft.js b/testing/web-platform/tests/editing/data/justifyleft.js new file mode 100644 index 0000000000..8b4cd5e2ea --- /dev/null +++ b/testing/web-platform/tests/editing/data/justifyleft.js @@ -0,0 +1,766 @@ +// For documentation of the format, see README in this directory. +var browserTests = [ +["foo[]bar<p>extra", + [["justifyleft",""]], + "foo[]bar<p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<span>foo</span>{}<span>bar</span><p>extra", + [["justifyleft",""]], + "<span>foo</span>{}<span>bar</span><p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<span>foo[</span><span>]bar</span><p>extra", + [["justifyleft",""]], + "<span>foo[</span><span>]bar</span><p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["foo[bar]baz<p>extra", + [["justifyleft",""]], + "foo[bar]baz<p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["foo[bar<b>baz]qoz</b>quz<p>extra", + [["justifyleft",""]], + "foo[bar<b>baz]qoz</b>quz<p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<p>foo[]bar<p>extra", + [["justifyleft",""]], + "<p>foo[]bar</p><p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<p>foo[bar]baz<p>extra", + [["justifyleft",""]], + "<p>foo[bar]baz</p><p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<h1>foo[bar]baz</h1><p>extra", + [["justifyleft",""]], + "<h1>foo[bar]baz</h1><p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<pre>foo[bar]baz</pre><p>extra", + [["justifyleft",""]], + "<pre>foo[bar]baz</pre><p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<xmp>foo[bar]baz</xmp><p>extra", + [["justifyleft",""]], + "<xmp>foo[bar]baz</xmp><p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<center><p>[foo]<p>bar</center><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyleft",""]], + "<center><div style=\"text-align:left\"><p>[foo]</p></div><p>bar</p></center><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyleft":[false,false,"center",false,true,"left"]}], +["<center><p>[foo]<p>bar</center><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyleft",""]], + "<center><div style=\"text-align:left\"><p>[foo]</p></div><p>bar</p></center><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyleft":[false,false,"center",false,true,"left"]}], +["<center><p>[foo]<p>bar</center><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyleft",""]], + "<center><div style=\"text-align:left\"><p>[foo]</p></div><p>bar</p></center><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyleft":[false,false,"center",false,true,"left"]}], +["<center><p>[foo]<p>bar</center><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyleft",""]], + "<center><div style=\"text-align:left\"><p>[foo]</p></div><p>bar</p></center><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyleft":[false,false,"center",false,true,"left"]}], +["<center><p>[foo<p>bar]</center><p>extra", + [["justifyleft",""]], + "<p>[foo</p><p>bar]</p><p>extra</p>", + [true], + {"justifyleft":[false,false,"center",false,true,"left"]}], +["<table><tbody><tr><td>foo<td>b[a]r<td>baz</table><p>extra", + [["justifyleft",""]], + "<table><tbody><tr><td>foo</td><td>b[a]r</td><td>baz</td></tr></tbody></table><p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["justifyleft",""]], + "<table><tbody><tr><td>foo</td>{<td>bar</td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["justifyleft",""]], + "<table><tbody><tr>{<td>foo</td><td>bar</td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra", + [["justifyleft",""]], + "<table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table><p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table><p>extra", + [["justifyleft",""]], + "<table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table><p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["{<table><tr><td>foo<td>bar<td>baz</table>}<p>extra", + [["justifyleft",""]], + "{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}<p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<table align=left><tbody><tr><td>foo<td>b[a]r<td>baz</table><p>extra", + [["justifyleft",""]], + "<table align=\"left\"><tbody><tr><td>foo</td><td>b[a]r</td><td>baz</td></tr></tbody></table><p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<table align=left><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["justifyleft",""]], + "<table align=\"left\"><tbody><tr><td>foo</td>{<td>bar</td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<table align=left><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["justifyleft",""]], + "<table align=\"left\"><tbody><tr>{<td>foo</td><td>bar</td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<table align=left><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra", + [["justifyleft",""]], + "<table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table><p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<table align=left data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table><p>extra", + [["justifyleft",""]], + "<table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table><p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["{<table align=left><tr><td>foo<td>bar<td>baz</table>}<p>extra", + [["justifyleft",""]], + "{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}<p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<table><tbody align=left><tr><td>foo<td>b[a]r<td>baz</table><p>extra", + [["justifyleft",""]], + "<table><tbody align=\"left\"><tr><td>foo</td><td>b[a]r</td><td>baz</td></tr></tbody></table><p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<table><tbody align=left><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["justifyleft",""]], + "<table><tbody align=\"left\"><tr><td>foo</td>{<td>bar</td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<table><tbody align=left><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["justifyleft",""]], + "<table><tbody align=\"left\"><tr>{<td>foo</td><td>bar</td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<table><tbody align=left data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra", + [["justifyleft",""]], + "<table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table><p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<table data-start=0 data-end=1><tbody align=left><tr><td>foo<td>bar<td>baz</table><p>extra", + [["justifyleft",""]], + "<table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table><p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["{<table><tbody align=left><tr><td>foo<td>bar<td>baz</table>}<p>extra", + [["justifyleft",""]], + "{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}<p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<table><tbody><tr align=left><td>foo<td>b[a]r<td>baz</table><p>extra", + [["justifyleft",""]], + "<table><tbody><tr align=\"left\"><td>foo</td><td>b[a]r</td><td>baz</td></tr></tbody></table><p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<table><tbody><tr align=left data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["justifyleft",""]], + "<table><tbody><tr align=\"left\"><td>foo</td>{<td>bar</td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<table><tbody><tr align=left data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["justifyleft",""]], + "<table><tbody><tr align=\"left\">{<td>foo</td><td>bar</td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<table><tbody data-start=0 data-end=1><tr align=left><td>foo<td>bar<td>baz</table><p>extra", + [["justifyleft",""]], + "<table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table><p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<table data-start=0 data-end=1><tbody><tr align=left><td>foo<td>bar<td>baz</table><p>extra", + [["justifyleft",""]], + "<table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table><p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["{<table><tr align=left><td>foo<td>bar<td>baz</table>}<p>extra", + [["justifyleft",""]], + "{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}<p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<div align=center><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyleft",""]], + "<div align=\"center\"><div style=\"text-align:left\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyleft":[false,false,"center",false,true,"left"]}], +["<div align=center><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyleft",""]], + "<div align=\"center\"><div style=\"text-align:left\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyleft":[false,false,"center",false,true,"left"]}], +["<div align=center><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyleft",""]], + "<div align=\"center\"><div style=\"text-align:left\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyleft":[false,false,"center",false,true,"left"]}], +["<div align=center><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyleft",""]], + "<div align=\"center\"><div style=\"text-align:left\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyleft":[false,false,"center",false,true,"left"]}], +["<div align=center><p>[foo<p>bar}</div><p>extra", + [["defaultparagraphseparator","div"],["justifyleft",""]], + "<p>[foo</p><p>bar}</p><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyleft":[false,false,"center",false,true,"left"]}], +["<div align=center><p>[foo<p>bar}</div><p>extra", + [["defaultparagraphseparator","p"],["justifyleft",""]], + "<p>[foo</p><p>bar}</p><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyleft":[false,false,"center",false,true,"left"]}], +["<div style=text-align:center><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyleft",""]], + "<div style=\"text-align:center\"><div style=\"text-align:left\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyleft":[false,false,"center",false,true,"left"]}], +["<div style=text-align:center><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyleft",""]], + "<div style=\"text-align:center\"><div style=\"text-align:left\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyleft":[false,false,"center",false,true,"left"]}], +["<div style=text-align:center><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyleft",""]], + "<div style=\"text-align:center\"><div style=\"text-align:left\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyleft":[false,false,"center",false,true,"left"]}], +["<div style=text-align:center><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyleft",""]], + "<div style=\"text-align:center\"><div style=\"text-align:left\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyleft":[false,false,"center",false,true,"left"]}], +["<div style=text-align:center><p>[foo<p>bar]</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyleft",""]], + "<p>[foo</p><p>bar]</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyleft":[false,false,"center",false,true,"left"]}], +["<div style=text-align:center><p>[foo<p>bar]</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyleft",""]], + "<p>[foo</p><p>bar]</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyleft":[false,false,"center",false,true,"left"]}], +["<div style=text-align:center><p>[foo<p>bar]</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyleft",""]], + "<p>[foo</p><p>bar]</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyleft":[false,false,"center",false,true,"left"]}], +["<div style=text-align:center><p>[foo<p>bar]</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyleft",""]], + "<p>[foo</p><p>bar]</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyleft":[false,false,"center",false,true,"left"]}], +["<div align=justify><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyleft",""]], + "<div align=\"justify\"><div style=\"text-align:left\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyleft":[false,false,"justify",false,true,"left"]}], +["<div align=justify><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyleft",""]], + "<div align=\"justify\"><div style=\"text-align:left\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyleft":[false,false,"justify",false,true,"left"]}], +["<div align=justify><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyleft",""]], + "<div align=\"justify\"><div style=\"text-align:left\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyleft":[false,false,"justify",false,true,"left"]}], +["<div align=justify><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyleft",""]], + "<div align=\"justify\"><div style=\"text-align:left\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyleft":[false,false,"justify",false,true,"left"]}], +["<div align=justify><p>[foo<p>bar}</div><p>extra", + [["defaultparagraphseparator","div"],["justifyleft",""]], + "<p>[foo</p><p>bar}</p><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyleft":[false,false,"justify",false,true,"left"]}], +["<div align=justify><p>[foo<p>bar}</div><p>extra", + [["defaultparagraphseparator","p"],["justifyleft",""]], + "<p>[foo</p><p>bar}</p><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyleft":[false,false,"justify",false,true,"left"]}], +["<div style=text-align:justify><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyleft",""]], + "<div style=\"text-align:justify\"><div style=\"text-align:left\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyleft":[false,false,"justify",false,true,"left"]}], +["<div style=text-align:justify><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyleft",""]], + "<div style=\"text-align:justify\"><div style=\"text-align:left\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyleft":[false,false,"justify",false,true,"left"]}], +["<div style=text-align:justify><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyleft",""]], + "<div style=\"text-align:justify\"><div style=\"text-align:left\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyleft":[false,false,"justify",false,true,"left"]}], +["<div style=text-align:justify><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyleft",""]], + "<div style=\"text-align:justify\"><div style=\"text-align:left\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyleft":[false,false,"justify",false,true,"left"]}], +["<div style=text-align:justify><p>[foo<p>bar]</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyleft",""]], + "<p>[foo</p><p>bar]</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyleft":[false,false,"justify",false,true,"left"]}], +["<div style=text-align:justify><p>[foo<p>bar]</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyleft",""]], + "<p>[foo</p><p>bar]</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyleft":[false,false,"justify",false,true,"left"]}], +["<div style=text-align:justify><p>[foo<p>bar]</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyleft",""]], + "<p>[foo</p><p>bar]</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyleft":[false,false,"justify",false,true,"left"]}], +["<div style=text-align:justify><p>[foo<p>bar]</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyleft",""]], + "<p>[foo</p><p>bar]</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyleft":[false,false,"justify",false,true,"left"]}], +["<div align=left><p>[foo]<p>bar</div><p>extra", + [["justifyleft",""]], + "<div align=\"left\"><p>[foo]</p><p>bar</p></div><p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<div align=left><p>[foo<p>bar}</div><p>extra", + [["defaultparagraphseparator","div"],["justifyleft",""]], + "<p>[foo</p><p>bar}</p><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyleft":[false,true,"left",false,true,"left"]}], +["<div align=left><p>[foo<p>bar}</div><p>extra", + [["defaultparagraphseparator","p"],["justifyleft",""]], + "<p>[foo</p><p>bar}</p><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyleft":[false,true,"left",false,true,"left"]}], +["<div style=text-align:left><p>[foo]<p>bar</div><p>extra", + [["justifyleft",""]], + "<div style=\"text-align:left\"><p>[foo]</p><p>bar</p></div><p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<div style=text-align:left><p>[foo<p>bar]</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyleft",""]], + "<p>[foo</p><p>bar]</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyleft":[false,true,"left",false,true,"left"]}], +["<div style=text-align:left><p>[foo<p>bar]</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyleft",""]], + "<p>[foo</p><p>bar]</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyleft":[false,true,"left",false,true,"left"]}], +["<div style=text-align:left><p>[foo<p>bar]</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyleft",""]], + "<p>[foo</p><p>bar]</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyleft":[false,true,"left",false,true,"left"]}], +["<div style=text-align:left><p>[foo<p>bar]</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyleft",""]], + "<p>[foo</p><p>bar]</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyleft":[false,true,"left",false,true,"left"]}], +["<div align=right><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyleft",""]], + "<div align=\"right\"><div style=\"text-align:left\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyleft":[false,false,"right",false,true,"left"]}], +["<div align=right><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyleft",""]], + "<div align=\"right\"><div style=\"text-align:left\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyleft":[false,false,"right",false,true,"left"]}], +["<div align=right><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyleft",""]], + "<div align=\"right\"><div style=\"text-align:left\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyleft":[false,false,"right",false,true,"left"]}], +["<div align=right><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyleft",""]], + "<div align=\"right\"><div style=\"text-align:left\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyleft":[false,false,"right",false,true,"left"]}], +["<div align=right><p>[foo<p>bar}</div><p>extra", + [["defaultparagraphseparator","div"],["justifyleft",""]], + "<p>[foo</p><p>bar}</p><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyleft":[false,false,"right",false,true,"left"]}], +["<div align=right><p>[foo<p>bar}</div><p>extra", + [["defaultparagraphseparator","p"],["justifyleft",""]], + "<p>[foo</p><p>bar}</p><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyleft":[false,false,"right",false,true,"left"]}], +["<div style=text-align:right><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyleft",""]], + "<div style=\"text-align:right\"><div style=\"text-align:left\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyleft":[false,false,"right",false,true,"left"]}], +["<div style=text-align:right><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyleft",""]], + "<div style=\"text-align:right\"><div style=\"text-align:left\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyleft":[false,false,"right",false,true,"left"]}], +["<div style=text-align:right><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyleft",""]], + "<div style=\"text-align:right\"><div style=\"text-align:left\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyleft":[false,false,"right",false,true,"left"]}], +["<div style=text-align:right><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyleft",""]], + "<div style=\"text-align:right\"><div style=\"text-align:left\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyleft":[false,false,"right",false,true,"left"]}], +["<div style=text-align:right><p>[foo<p>bar]</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyleft",""]], + "<p>[foo</p><p>bar]</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyleft":[false,false,"right",false,true,"left"]}], +["<div style=text-align:right><p>[foo<p>bar]</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyleft",""]], + "<p>[foo</p><p>bar]</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyleft":[false,false,"right",false,true,"left"]}], +["<div style=text-align:right><p>[foo<p>bar]</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyleft",""]], + "<p>[foo</p><p>bar]</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyleft":[false,false,"right",false,true,"left"]}], +["<div style=text-align:right><p>[foo<p>bar]</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyleft",""]], + "<p>[foo</p><p>bar]</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyleft":[false,false,"right",false,true,"left"]}], +["<div align=left>foo</div>[bar]<p>extra", + [["justifyleft",""]], + "<div align=\"left\">foo</div>[bar]<p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["[foo]<div align=left>bar</div><p>extra", + [["justifyleft",""]], + "[foo]<div align=\"left\">bar</div><p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<div align=left>foo</div>[bar]<div align=left>baz</div><p>extra", + [["justifyleft",""]], + "<div align=\"left\">foo</div>[bar]<div align=\"left\">baz</div><p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<div align=left><p>foo</div><p>[bar]<p>extra", + [["justifyleft",""]], + "<div align=\"left\"><p>foo</p></div><p>[bar]</p><p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<p>[foo]<div align=left><p>bar</div><p>extra", + [["justifyleft",""]], + "<p>[foo]</p><div align=\"left\"><p>bar</p></div><p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<div align=left><p>foo</div><p>[bar]<div align=left><p>baz</div><p>extra", + [["justifyleft",""]], + "<div align=\"left\"><p>foo</p></div><p>[bar]</p><div align=\"left\"><p>baz</p></div><p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<div style=text-align:left>foo</div>[bar]<p>extra", + [["justifyleft",""]], + "<div style=\"text-align:left\">foo</div>[bar]<p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["[foo]<div style=text-align:left>bar</div><p>extra", + [["justifyleft",""]], + "[foo]<div style=\"text-align:left\">bar</div><p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<div style=text-align:left>foo</div>[bar]<div style=text-align:left>baz</div><p>extra", + [["justifyleft",""]], + "<div style=\"text-align:left\">foo</div>[bar]<div style=\"text-align:left\">baz</div><p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<div style=text-align:left><p>foo</div><p>[bar]<p>extra", + [["justifyleft",""]], + "<div style=\"text-align:left\"><p>foo</p></div><p>[bar]</p><p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<p>[foo]<div style=text-align:left><p>bar</div><p>extra", + [["justifyleft",""]], + "<p>[foo]</p><div style=\"text-align:left\"><p>bar</p></div><p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<div style=text-align:left><p>foo</div><p>[bar]<div style=text-align:left><p>baz</div><p>extra", + [["justifyleft",""]], + "<div style=\"text-align:left\"><p>foo</p></div><p>[bar]</p><div style=\"text-align:left\"><p>baz</p></div><p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<p align=left>foo<p>[bar]<p>extra", + [["justifyleft",""]], + "<p align=\"left\">foo</p><p>[bar]</p><p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<p>[foo]<p align=left>bar<p>extra", + [["justifyleft",""]], + "<p>[foo]</p><p align=\"left\">bar</p><p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<p align=left>foo<p>[bar]<p align=left>baz<p>extra", + [["justifyleft",""]], + "<p align=\"left\">foo</p><p>[bar]</p><p align=\"left\">baz</p><p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<div align=left>[foo</div>bar]<p>extra", + [["defaultparagraphseparator","div"],["justifyleft",""]], + "[foo<br>bar]<p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyleft":[false,true,"left",false,true,"left"]}], +["<div align=left>[foo</div>bar]<p>extra", + [["defaultparagraphseparator","p"],["justifyleft",""]], + "[foo<br>bar]<p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyleft":[false,true,"left",false,true,"left"]}], +["<div align=left>fo[o</div>b]ar<p>extra", + [["defaultparagraphseparator","div"],["justifyleft",""]], + "fo[o<br>b]ar<p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyleft":[false,true,"left",false,true,"left"]}], +["<div align=left>fo[o</div>b]ar<p>extra", + [["defaultparagraphseparator","p"],["justifyleft",""]], + "fo[o<br>b]ar<p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyleft":[false,true,"left",false,true,"left"]}], +["<div style=text-align:left>[foo</div>bar]<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyleft",""]], + "[foo<br>bar]<p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyleft":[false,true,"left",false,true,"left"]}], +["<div style=text-align:left>[foo</div>bar]<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyleft",""]], + "[foo<br>bar]<p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyleft":[false,true,"left",false,true,"left"]}], +["<div style=text-align:left>[foo</div>bar]<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyleft",""]], + "[foo<br>bar]<p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyleft":[false,true,"left",false,true,"left"]}], +["<div style=text-align:left>[foo</div>bar]<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyleft",""]], + "[foo<br>bar]<p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyleft":[false,true,"left",false,true,"left"]}], +["<div style=text-align:left>fo[o</div>b]ar<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyleft",""]], + "fo[o<br>b]ar<p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyleft":[false,true,"left",false,true,"left"]}], +["<div style=text-align:left>fo[o</div>b]ar<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyleft",""]], + "fo[o<br>b]ar<p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyleft":[false,true,"left",false,true,"left"]}], +["<div style=text-align:left>fo[o</div>b]ar<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyleft",""]], + "fo[o<br>b]ar<p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyleft":[false,true,"left",false,true,"left"]}], +["<div style=text-align:left>fo[o</div>b]ar<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyleft",""]], + "fo[o<br>b]ar<p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyleft":[false,true,"left",false,true,"left"]}], +["<span style=text-align:left>[foo]</span><p>extra", + [["stylewithcss","true"],["justifyleft",""]], + "[foo]<p>extra</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"justifyleft":[false,true,"left",false,true,"left"]}], +["<span style=text-align:left>[foo]</span><p>extra", + [["stylewithcss","false"],["justifyleft",""]], + "[foo]<p>extra</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"justifyleft":[false,true,"left",false,true,"left"]}], +["<span style=text-align:left>f[o]o</span><p>extra", + [["stylewithcss","true"],["justifyleft",""]], + "f[o]o<p>extra</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"justifyleft":[false,true,"left",false,true,"left"]}], +["<span style=text-align:left>f[o]o</span><p>extra", + [["stylewithcss","false"],["justifyleft",""]], + "f[o]o<p>extra</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"justifyleft":[false,true,"left",false,true,"left"]}], +["<div style=text-align:left>[foo<div style=text-align:left contenteditable=false>bar</div>baz]</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyleft",""]], + "[foo<div style=\"text-align:left\" contenteditable=\"false\">bar</div>baz]<p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyleft":[false,true,"left",false,true,"left"]}], +["<div style=text-align:left>[foo<div style=text-align:left contenteditable=false>bar</div>baz]</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyleft",""]], + "[foo<div style=\"text-align:left\" contenteditable=\"false\">bar</div>baz]<p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyleft":[false,true,"left",false,true,"left"]}], +["<div style=text-align:left>[foo<div style=text-align:left contenteditable=false>bar</div>baz]</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyleft",""]], + "[foo<div style=\"text-align:left\" contenteditable=\"false\">bar</div>baz]<p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyleft":[false,true,"left",false,true,"left"]}], +["<div style=text-align:left>[foo<div style=text-align:left contenteditable=false>bar</div>baz]</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyleft",""]], + "[foo<div style=\"text-align:left\" contenteditable=\"false\">bar</div>baz]<p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyleft":[false,true,"left",false,true,"left"]}], +["<div align=nonsense><p>[foo]</div><p>extra", + [["defaultparagraphseparator","div"],["justifyleft",""]], + "<p>[foo]</p><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyleft":[false,true,"left",false,true,"left"]}], +["<div align=nonsense><p>[foo]</div><p>extra", + [["defaultparagraphseparator","p"],["justifyleft",""]], + "<p>[foo]</p><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyleft":[false,true,"left",false,true,"left"]}], +["<div style=text-align:inherit><p>[foo]</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyleft",""]], + "<p>[foo]</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyleft":[false,true,"left",false,true,"left"]}], +["<div style=text-align:inherit><p>[foo]</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyleft",""]], + "<p>[foo]</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyleft":[false,true,"left",false,true,"left"]}], +["<div style=text-align:inherit><p>[foo]</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyleft",""]], + "<p>[foo]</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyleft":[false,true,"left",false,true,"left"]}], +["<div style=text-align:inherit><p>[foo]</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyleft",""]], + "<p>[foo]</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyleft":[false,true,"left",false,true,"left"]}], +["<quasit align=center><p>[foo]</p></quasit><p>extra", + [["justifyleft",""]], + "<quasit><p>[foo]</p></quasit><p>extra</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<div style=text-align:start>[foo]</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyleft",""]], + "[foo]<p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyleft":[false,true,"left",false,true,"left"]}], +["<div style=text-align:start>[foo]</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyleft",""]], + "[foo]<p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyleft":[false,true,"left",false,true,"left"]}], +["<div style=text-align:start>[foo]</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyleft",""]], + "[foo]<p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyleft":[false,true,"left",false,true,"left"]}], +["<div style=text-align:start>[foo]</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyleft",""]], + "[foo]<p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyleft":[false,true,"left",false,true,"left"]}], +["<div style=text-align:end>[foo]</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyleft",""]], + "[foo]<p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyleft":[false,false,"right",false,true,"left"]}], +["<div style=text-align:end>[foo]</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyleft",""]], + "[foo]<p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyleft":[false,false,"right",false,true,"left"]}], +["<div style=text-align:end>[foo]</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyleft",""]], + "[foo]<p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyleft":[false,false,"right",false,true,"left"]}], +["<div style=text-align:end>[foo]</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyleft",""]], + "[foo]<p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyleft":[false,false,"right",false,true,"left"]}], +["<div dir=rtl style=text-align:start>[foo]</div><p>extra", + [["defaultparagraphseparator","div"],["justifyleft",""]], + "<div style=\"text-align:left\"><div dir=\"rtl\">[foo]</div></div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyleft":[false,false,"right",false,true,"left"]}], +["<div dir=rtl style=text-align:start>[foo]</div><p>extra", + [["defaultparagraphseparator","p"],["justifyleft",""]], + "<div style=\"text-align:left\"><div dir=\"rtl\">[foo]</div></div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyleft":[false,false,"right",false,true,"left"]}], +["<div dir=rtl style=text-align:end>[foo]</div><p>extra", + [["defaultparagraphseparator","div"],["justifyleft",""]], + "<div style=\"text-align:left\"><div dir=\"rtl\">[foo]</div></div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyleft":[false,true,"left",false,true,"left"]}], +["<div dir=rtl style=text-align:end>[foo]</div><p>extra", + [["defaultparagraphseparator","p"],["justifyleft",""]], + "<div style=\"text-align:left\"><div dir=\"rtl\">[foo]</div></div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyleft":[false,true,"left",false,true,"left"]}], +["<div style=text-align:left><p>foo</div> <p>[bar]", + [["justifyleft",""]], + "<div style=\"text-align:left\"><p>foo</p></div> <p>[bar]</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<div align=left><p>foo</div> <p>[bar]", + [["justifyleft",""]], + "<div align=\"left\"><p>foo</p></div> <p>[bar]</p>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<p>[foo]</p> <div style=text-align:left><p>bar</div>", + [["justifyleft",""]], + "<p>[foo]</p> <div style=\"text-align:left\"><p>bar</p></div>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<p>[foo]</p> <div align=left><p>bar</div>", + [["justifyleft",""]], + "<p>[foo]</p> <div align=\"left\"><p>bar</p></div>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<div style=text-align:left><p>foo</div> <p>[bar]</p> <div style=text-align:left><p>baz</div>", + [["justifyleft",""]], + "<div style=\"text-align:left\"><p>foo</p></div> <p>[bar]</p> <div style=\"text-align:left\"><p>baz</p></div>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<div align=left><p>foo</div> <p>[bar]</p> <div align=left><p>baz</div>", + [["justifyleft",""]], + "<div align=\"left\"><p>foo</p></div> <p>[bar]</p> <div align=\"left\"><p>baz</p></div>", + [true], + {"justifyleft":[false,true,"left",false,true,"left"]}], +["<div contenteditable=false align=left><p contenteditable>f[]oo</p></div>", + [], + ["<div contenteditable=\"false\" align=\"left\"><p contenteditable=\"\">foo</p></div>", + "<div align=\"left\" contenteditable=\"false\"><p contenteditable=\"\">foo</p></div>"], + [true], + {"justifyleft":[false,true,"left",false,true,"left"], + "justifycenter":[false,false,"left",false,false,"left"], + "justifyfull":[false,false,"left",false,false,"left"], + "justifyright":[false,false,"left",false,false,"left"]}], +["<div contenteditable=false style=text-align:left><p contenteditable>f[]oo</p></div>", + [], + ["<div contenteditable=\"false\" style=\"text-align:left\"><p contenteditable=\"\">foo</p></div>", + "<div style=\"text-align:left\" contenteditable=\"false\"><p contenteditable=\"\">foo</p></div>"], + [true], + {"justifyleft":[false,true,"left",false,true,"left"], + "justifycenter":[false,false,"left",false,false,"left"], + "justifyfull":[false,false,"left",false,false,"left"], + "justifyright":[false,false,"left",false,false,"left"]}], +] diff --git a/testing/web-platform/tests/editing/data/justifyright.js b/testing/web-platform/tests/editing/data/justifyright.js new file mode 100644 index 0000000000..b8a4239799 --- /dev/null +++ b/testing/web-platform/tests/editing/data/justifyright.js @@ -0,0 +1,1186 @@ +// For documentation of the format, see README in this directory. +var browserTests = [ +["foo[]bar<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\">foo[]bar</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["foo[]bar<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\">foo[]bar</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["foo[]bar<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\">foo[]bar</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["foo[]bar<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\">foo[]bar</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<span>foo</span>{}<span>bar</span><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\"><span>foo</span>{}<span>bar</span></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<span>foo</span>{}<span>bar</span><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\"><span>foo</span>{}<span>bar</span></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<span>foo</span>{}<span>bar</span><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\"><span>foo</span>{}<span>bar</span></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<span>foo</span>{}<span>bar</span><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\"><span>foo</span>{}<span>bar</span></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<span>foo[</span><span>]bar</span><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\"><span>foo[</span><span>]bar</span></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<span>foo[</span><span>]bar</span><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\"><span>foo[</span><span>]bar</span></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<span>foo[</span><span>]bar</span><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\"><span>foo[</span><span>]bar</span></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<span>foo[</span><span>]bar</span><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\"><span>foo[</span><span>]bar</span></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["foo[bar]baz<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\">foo[bar]baz</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["foo[bar]baz<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\">foo[bar]baz</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["foo[bar]baz<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\">foo[bar]baz</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["foo[bar]baz<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\">foo[bar]baz</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["foo[bar<b>baz]qoz</b>quz<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\">foo[bar<b>baz]qoz</b>quz</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["foo[bar<b>baz]qoz</b>quz<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\">foo[bar<b>baz]qoz</b>quz</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["foo[bar<b>baz]qoz</b>quz<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\">foo[bar<b>baz]qoz</b>quz</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["foo[bar<b>baz]qoz</b>quz<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\">foo[bar<b>baz]qoz</b>quz</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<p>foo[]bar<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\"><p>foo[]bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<p>foo[]bar<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\"><p>foo[]bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<p>foo[]bar<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\"><p>foo[]bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<p>foo[]bar<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\"><p>foo[]bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<p>foo[bar]baz<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\"><p>foo[bar]baz</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<p>foo[bar]baz<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\"><p>foo[bar]baz</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<p>foo[bar]baz<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\"><p>foo[bar]baz</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<p>foo[bar]baz<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\"><p>foo[bar]baz</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<h1>foo[bar]baz</h1><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\"><h1>foo[bar]baz</h1></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<h1>foo[bar]baz</h1><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\"><h1>foo[bar]baz</h1></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<h1>foo[bar]baz</h1><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\"><h1>foo[bar]baz</h1></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<h1>foo[bar]baz</h1><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\"><h1>foo[bar]baz</h1></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<pre>foo[bar]baz</pre><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\"><pre>foo[bar]baz</pre></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<pre>foo[bar]baz</pre><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\"><pre>foo[bar]baz</pre></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<pre>foo[bar]baz</pre><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\"><pre>foo[bar]baz</pre></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<pre>foo[bar]baz</pre><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\"><pre>foo[bar]baz</pre></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<xmp>foo[bar]baz</xmp><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\"><xmp>foo[bar]baz</xmp></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<xmp>foo[bar]baz</xmp><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\"><xmp>foo[bar]baz</xmp></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<xmp>foo[bar]baz</xmp><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\"><xmp>foo[bar]baz</xmp></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<xmp>foo[bar]baz</xmp><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\"><xmp>foo[bar]baz</xmp></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<center><p>[foo]<p>bar</center><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyright",""]], + "<center><div style=\"text-align:right\"><p>[foo]</p></div><p>bar</p></center><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,false,"center",false,true,"right"]}], +["<center><p>[foo]<p>bar</center><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]], + "<center><div style=\"text-align:right\"><p>[foo]</p></div><p>bar</p></center><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,false,"center",false,true,"right"]}], +["<center><p>[foo]<p>bar</center><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyright",""]], + "<center><div style=\"text-align:right\"><p>[foo]</p></div><p>bar</p></center><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,false,"center",false,true,"right"]}], +["<center><p>[foo]<p>bar</center><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyright",""]], + "<center><div style=\"text-align:right\"><p>[foo]</p></div><p>bar</p></center><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyright":[false,false,"center",false,true,"right"]}], +["<center><p>[foo<p>bar]</center><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\"><p>[foo</p><p>bar]</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,false,"center",false,true,"right"]}], +["<center><p>[foo<p>bar]</center><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\"><p>[foo</p><p>bar]</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,false,"center",false,true,"right"]}], +["<center><p>[foo<p>bar]</center><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\"><p>[foo</p><p>bar]</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,false,"center",false,true,"right"]}], +["<center><p>[foo<p>bar]</center><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\"><p>[foo</p><p>bar]</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyright":[false,false,"center",false,true,"right"]}], +["<table><tbody><tr><td>foo<td>b[a]r<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyright",""]], + "<table><tbody><tr><td>foo</td><td><div style=\"text-align:right\">b[a]r</div></td><td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<table><tbody><tr><td>foo<td>b[a]r<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]], + "<table><tbody><tr><td>foo</td><td><div style=\"text-align:right\">b[a]r</div></td><td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<table><tbody><tr><td>foo<td>b[a]r<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyright",""]], + "<table><tbody><tr><td>foo</td><td><div style=\"text-align:right\">b[a]r</div></td><td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<table><tbody><tr><td>foo<td>b[a]r<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyright",""]], + "<table><tbody><tr><td>foo</td><td><div style=\"text-align:right\">b[a]r</div></td><td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyright",""]], + "<table><tbody><tr><td>foo</td>{<td><div style=\"text-align:right\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]], + "<table><tbody><tr><td>foo</td>{<td><div style=\"text-align:right\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyright",""]], + "<table><tbody><tr><td>foo</td>{<td><div style=\"text-align:right\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyright",""]], + "<table><tbody><tr><td>foo</td>{<td><div style=\"text-align:right\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyright",""]], + "<table><tbody><tr>{<td><div style=\"text-align:right\">foo</div></td><td><div style=\"text-align:right\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]], + "<table><tbody><tr>{<td><div style=\"text-align:right\">foo</div></td><td><div style=\"text-align:right\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyright",""]], + "<table><tbody><tr>{<td><div style=\"text-align:right\">foo</div></td><td><div style=\"text-align:right\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyright",""]], + "<table><tbody><tr>{<td><div style=\"text-align:right\">foo</div></td><td><div style=\"text-align:right\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["{<table><tr><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["{<table><tr><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["{<table><tr><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["{<table><tr><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<table align=right><tbody><tr><td>foo<td>b[a]r<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyright",""]], + "<table align=\"right\"><tbody><tr><td>foo</td><td><div style=\"text-align:right\">b[a]r</div></td><td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<table align=right><tbody><tr><td>foo<td>b[a]r<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]], + "<table align=\"right\"><tbody><tr><td>foo</td><td><div style=\"text-align:right\">b[a]r</div></td><td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<table align=right><tbody><tr><td>foo<td>b[a]r<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyright",""]], + "<table align=\"right\"><tbody><tr><td>foo</td><td><div style=\"text-align:right\">b[a]r</div></td><td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<table align=right><tbody><tr><td>foo<td>b[a]r<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyright",""]], + "<table align=\"right\"><tbody><tr><td>foo</td><td><div style=\"text-align:right\">b[a]r</div></td><td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<table align=right><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyright",""]], + "<table align=\"right\"><tbody><tr><td>foo</td>{<td><div style=\"text-align:right\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<table align=right><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]], + "<table align=\"right\"><tbody><tr><td>foo</td>{<td><div style=\"text-align:right\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<table align=right><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyright",""]], + "<table align=\"right\"><tbody><tr><td>foo</td>{<td><div style=\"text-align:right\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<table align=right><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyright",""]], + "<table align=\"right\"><tbody><tr><td>foo</td>{<td><div style=\"text-align:right\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<table align=right><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyright",""]], + "<table align=\"right\"><tbody><tr>{<td><div style=\"text-align:right\">foo</div></td><td><div style=\"text-align:right\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<table align=right><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]], + "<table align=\"right\"><tbody><tr>{<td><div style=\"text-align:right\">foo</div></td><td><div style=\"text-align:right\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<table align=right><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyright",""]], + "<table align=\"right\"><tbody><tr>{<td><div style=\"text-align:right\">foo</div></td><td><div style=\"text-align:right\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<table align=right><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyright",""]], + "<table align=\"right\"><tbody><tr>{<td><div style=\"text-align:right\">foo</div></td><td><div style=\"text-align:right\">bar</div></td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<table align=right><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<table align=right><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<table align=right><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<table align=right><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<table align=right data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<table align=right data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<table align=right data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<table align=right data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["{<table align=right><tr><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["{<table align=right><tr><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["{<table align=right><tr><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["{<table align=right><tr><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<table><tbody align=right><tr><td>foo<td>b[a]r<td>baz</table><p>extra", + [["justifyright",""]], + "<table><tbody align=\"right\"><tr><td>foo</td><td>b[a]r</td><td>baz</td></tr></tbody></table><p>extra</p>", + [true], + {"justifyright":[false,true,"right",false,true,"right"]}], +["<table><tbody align=right><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["justifyright",""]], + "<table><tbody align=\"right\"><tr><td>foo</td>{<td>bar</td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true], + {"justifyright":[false,true,"right",false,true,"right"]}], +["<table><tbody align=right><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["justifyright",""]], + "<table><tbody align=\"right\"><tr>{<td>foo</td><td>bar</td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true], + {"justifyright":[false,true,"right",false,true,"right"]}], +["<table><tbody align=right data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,true,"right",false,true,"right"]}], +["<table><tbody align=right data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,true,"right",false,true,"right"]}], +["<table><tbody align=right data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,true,"right",false,true,"right"]}], +["<table><tbody align=right data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyright":[false,true,"right",false,true,"right"]}], +["<table data-start=0 data-end=1><tbody align=right><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,true,"right",false,true,"right"]}], +["<table data-start=0 data-end=1><tbody align=right><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,true,"right",false,true,"right"]}], +["<table data-start=0 data-end=1><tbody align=right><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,true,"right",false,true,"right"]}], +["<table data-start=0 data-end=1><tbody align=right><tr><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyright":[false,true,"right",false,true,"right"]}], +["{<table><tbody align=right><tr><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,true,"right",false,true,"right"]}], +["{<table><tbody align=right><tr><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,true,"right",false,true,"right"]}], +["{<table><tbody align=right><tr><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,true,"right",false,true,"right"]}], +["{<table><tbody align=right><tr><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyright":[false,true,"right",false,true,"right"]}], +["<table><tbody><tr align=right><td>foo<td>b[a]r<td>baz</table><p>extra", + [["justifyright",""]], + "<table><tbody><tr align=\"right\"><td>foo</td><td>b[a]r</td><td>baz</td></tr></tbody></table><p>extra</p>", + [true], + {"justifyright":[false,true,"right",false,true,"right"]}], +["<table><tbody><tr align=right data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["justifyright",""]], + "<table><tbody><tr align=\"right\"><td>foo</td>{<td>bar</td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true], + {"justifyright":[false,true,"right",false,true,"right"]}], +["<table><tbody><tr align=right data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra", + [["justifyright",""]], + "<table><tbody><tr align=\"right\">{<td>foo</td><td>bar</td>}<td>baz</td></tr></tbody></table><p>extra</p>", + [true], + {"justifyright":[false,true,"right",false,true,"right"]}], +["<table><tbody data-start=0 data-end=1><tr align=right><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,true,"right",false,true,"right"]}], +["<table><tbody data-start=0 data-end=1><tr align=right><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,true,"right",false,true,"right"]}], +["<table><tbody data-start=0 data-end=1><tr align=right><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,true,"right",false,true,"right"]}], +["<table><tbody data-start=0 data-end=1><tr align=right><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\"><table><tbody>{<tr><td>foo</td><td>bar</td><td>baz</td></tr>}</tbody></table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyright":[false,true,"right",false,true,"right"]}], +["<table data-start=0 data-end=1><tbody><tr align=right><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,true,"right",false,true,"right"]}], +["<table data-start=0 data-end=1><tbody><tr align=right><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,true,"right",false,true,"right"]}], +["<table data-start=0 data-end=1><tbody><tr align=right><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,true,"right",false,true,"right"]}], +["<table data-start=0 data-end=1><tbody><tr align=right><td>foo<td>bar<td>baz</table><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\"><table>{<tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody>}</table></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyright":[false,true,"right",false,true,"right"]}], +["{<table><tr align=right><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,true,"right",false,true,"right"]}], +["{<table><tr align=right><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,true,"right",false,true,"right"]}], +["{<table><tr align=right><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,true,"right",false,true,"right"]}], +["{<table><tr align=right><td>foo<td>bar<td>baz</table>}<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\">{<table><tbody><tr><td>foo</td><td>bar</td><td>baz</td></tr></tbody></table>}</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyright":[false,true,"right",false,true,"right"]}], +["<div align=center><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div align=\"center\"><div style=\"text-align:right\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,false,"center",false,true,"right"]}], +["<div align=center><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div align=\"center\"><div style=\"text-align:right\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,false,"center",false,true,"right"]}], +["<div align=center><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div align=\"center\"><div style=\"text-align:right\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,false,"center",false,true,"right"]}], +["<div align=center><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div align=\"center\"><div style=\"text-align:right\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyright":[false,false,"center",false,true,"right"]}], +["<div align=center><p>[foo<p>bar}</div><p>extra", + [["stylewithcss","true"],["justifyright",""]], + "<div style=\"text-align:right\"><p>[foo</p><p>bar}</p></div><p>extra</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"justifyright":[false,false,"center",false,true,"right"]}], +["<div align=center><p>[foo<p>bar}</div><p>extra", + [["stylewithcss","false"],["justifyright",""]], + "<div style=\"text-align:right\"><p>[foo</p><p>bar}</p></div><p>extra</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"justifyright":[false,false,"center",false,true,"right"]}], +["<div style=text-align:center><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:center\"><div style=\"text-align:right\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,false,"center",false,true,"right"]}], +["<div style=text-align:center><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:center\"><div style=\"text-align:right\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,false,"center",false,true,"right"]}], +["<div style=text-align:center><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:center\"><div style=\"text-align:right\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,false,"center",false,true,"right"]}], +["<div style=text-align:center><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:center\"><div style=\"text-align:right\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyright":[false,false,"center",false,true,"right"]}], +["<div style=text-align:center><p>[foo<p>bar]</div><p>extra", + [["justifyright",""]], + "<div style=\"text-align:right\"><p>[foo</p><p>bar]</p></div><p>extra</p>", + [true], + {"justifyright":[false,false,"center",false,true,"right"]}], +["<div align=justify><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div align=\"justify\"><div style=\"text-align:right\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,false,"justify",false,true,"right"]}], +["<div align=justify><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div align=\"justify\"><div style=\"text-align:right\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,false,"justify",false,true,"right"]}], +["<div align=justify><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div align=\"justify\"><div style=\"text-align:right\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,false,"justify",false,true,"right"]}], +["<div align=justify><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div align=\"justify\"><div style=\"text-align:right\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyright":[false,false,"justify",false,true,"right"]}], +["<div align=justify><p>[foo<p>bar}</div><p>extra", + [["stylewithcss","true"],["justifyright",""]], + "<div style=\"text-align:right\"><p>[foo</p><p>bar}</p></div><p>extra</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"justifyright":[false,false,"justify",false,true,"right"]}], +["<div align=justify><p>[foo<p>bar}</div><p>extra", + [["stylewithcss","false"],["justifyright",""]], + "<div style=\"text-align:right\"><p>[foo</p><p>bar}</p></div><p>extra</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"justifyright":[false,false,"justify",false,true,"right"]}], +["<div style=text-align:justify><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:justify\"><div style=\"text-align:right\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,false,"justify",false,true,"right"]}], +["<div style=text-align:justify><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:justify\"><div style=\"text-align:right\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,false,"justify",false,true,"right"]}], +["<div style=text-align:justify><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:justify\"><div style=\"text-align:right\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,false,"justify",false,true,"right"]}], +["<div style=text-align:justify><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:justify\"><div style=\"text-align:right\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyright":[false,false,"justify",false,true,"right"]}], +["<div style=text-align:justify><p>[foo<p>bar]</div><p>extra", + [["justifyright",""]], + "<div style=\"text-align:right\"><p>[foo</p><p>bar]</p></div><p>extra</p>", + [true], + {"justifyright":[false,false,"justify",false,true,"right"]}], +["<div align=left><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div align=\"left\"><div style=\"text-align:right\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<div align=left><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div align=\"left\"><div style=\"text-align:right\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<div align=left><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div align=\"left\"><div style=\"text-align:right\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<div align=left><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div align=\"left\"><div style=\"text-align:right\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<div align=left><p>[foo<p>bar}</div><p>extra", + [["stylewithcss","true"],["justifyright",""]], + "<div style=\"text-align:right\"><p>[foo</p><p>bar}</p></div><p>extra</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"justifyright":[false,false,"left",false,true,"right"]}], +["<div align=left><p>[foo<p>bar}</div><p>extra", + [["stylewithcss","false"],["justifyright",""]], + "<div style=\"text-align:right\"><p>[foo</p><p>bar}</p></div><p>extra</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"justifyright":[false,false,"left",false,true,"right"]}], +["<div style=text-align:left><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:left\"><div style=\"text-align:right\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<div style=text-align:left><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:left\"><div style=\"text-align:right\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<div style=text-align:left><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:left\"><div style=\"text-align:right\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<div style=text-align:left><p>[foo]<p>bar</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:left\"><div style=\"text-align:right\"><p>[foo]</p></div><p>bar</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<div style=text-align:left><p>[foo<p>bar]</div><p>extra", + [["justifyright",""]], + "<div style=\"text-align:right\"><p>[foo</p><p>bar]</p></div><p>extra</p>", + [true], + {"justifyright":[false,false,"left",false,true,"right"]}], +["<div align=right><p>[foo]<p>bar</div><p>extra", + [["justifyright",""]], + "<div align=\"right\"><p>[foo]</p><p>bar</p></div><p>extra</p>", + [true], + {"justifyright":[false,true,"right",false,true,"right"]}], +["<div align=right><p>[foo<p>bar}</div><p>extra", + [["stylewithcss","true"],["justifyright",""]], + "<div style=\"text-align:right\"><p>[foo</p><p>bar}</p></div><p>extra</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"justifyright":[false,true,"right",false,true,"right"]}], +["<div align=right><p>[foo<p>bar}</div><p>extra", + [["stylewithcss","false"],["justifyright",""]], + "<div style=\"text-align:right\"><p>[foo</p><p>bar}</p></div><p>extra</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"justifyright":[false,true,"right",false,true,"right"]}], +["<div style=text-align:right><p>[foo]<p>bar</div><p>extra", + [["justifyright",""]], + "<div style=\"text-align:right\"><p>[foo]</p><p>bar</p></div><p>extra</p>", + [true], + {"justifyright":[false,true,"right",false,true,"right"]}], +["<div style=text-align:right><p>[foo<p>bar]</div><p>extra", + [["justifyright",""]], + "<div style=\"text-align:right\"><p>[foo</p><p>bar]</p></div><p>extra</p>", + [true], + {"justifyright":[false,true,"right",false,true,"right"]}], +["<div align=right>foo</div>[bar]<p>extra", + [["justifyright",""]], + "<div align=\"right\">foo<br>[bar]</div><p>extra</p>", + [true], + {"justifyright":[false,false,"left",false,true,"right"]}], +["[foo]<div align=right>bar</div><p>extra", + [["justifyright",""]], + "<div align=\"right\">[foo]<br>bar</div><p>extra</p>", + [true], + {"justifyright":[false,false,"left",false,true,"right"]}], +["<div align=right>foo</div>[bar]<div align=right>baz</div><p>extra", + [["defaultparagraphseparator","div"],["justifyright",""]], + "<div align=\"right\">foo<br>[bar]<br>baz</div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<div align=right>foo</div>[bar]<div align=right>baz</div><p>extra", + [["defaultparagraphseparator","p"],["justifyright",""]], + "<div align=\"right\">foo<br>[bar]<br>baz</div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<div align=right><p>foo</div><p>[bar]<p>extra", + [["justifyright",""]], + "<div align=\"right\"><p>foo</p><p>[bar]</p></div><p>extra</p>", + [true], + {"justifyright":[false,false,"left",false,true,"right"]}], +["<p>[foo]<div align=right><p>bar</div><p>extra", + [["justifyright",""]], + "<div align=\"right\"><p>[foo]</p><p>bar</p></div><p>extra</p>", + [true], + {"justifyright":[false,false,"left",false,true,"right"]}], +["<div align=right><p>foo</div><p>[bar]<div align=right><p>baz</div><p>extra", + [["defaultparagraphseparator","div"],["justifyright",""]], + "<div align=\"right\"><p>foo</p><p>[bar]</p><p>baz</p></div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<div align=right><p>foo</div><p>[bar]<div align=right><p>baz</div><p>extra", + [["defaultparagraphseparator","p"],["justifyright",""]], + "<div align=\"right\"><p>foo</p><p>[bar]</p><p>baz</p></div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<div style=text-align:right>foo</div>[bar]<p>extra", + [["justifyright",""]], + "<div style=\"text-align:right\">foo<br>[bar]</div><p>extra</p>", + [true], + {"justifyright":[false,false,"left",false,true,"right"]}], +["[foo]<div style=text-align:right>bar</div><p>extra", + [["justifyright",""]], + "<div style=\"text-align:right\">[foo]<br>bar</div><p>extra</p>", + [true], + {"justifyright":[false,false,"left",false,true,"right"]}], +["<div style=text-align:right>foo</div>[bar]<div style=text-align:right>baz</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\">foo<br>[bar]<br>baz</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<div style=text-align:right>foo</div>[bar]<div style=text-align:right>baz</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\">foo<br>[bar]<br>baz</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<div style=text-align:right>foo</div>[bar]<div style=text-align:right>baz</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\">foo<br>[bar]<br>baz</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<div style=text-align:right>foo</div>[bar]<div style=text-align:right>baz</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\">foo<br>[bar]<br>baz</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<div style=text-align:right><p>foo</div><p>[bar]<p>extra", + [["justifyright",""]], + "<div style=\"text-align:right\"><p>foo</p><p>[bar]</p></div><p>extra</p>", + [true], + {"justifyright":[false,false,"left",false,true,"right"]}], +["<p>[foo]<div style=text-align:right><p>bar</div><p>extra", + [["justifyright",""]], + "<div style=\"text-align:right\"><p>[foo]</p><p>bar</p></div><p>extra</p>", + [true], + {"justifyright":[false,false,"left",false,true,"right"]}], +["<div style=text-align:right><p>foo</div><p>[bar]<div style=text-align:right><p>baz</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\"><p>foo</p><p>[bar]</p><p>baz</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<div style=text-align:right><p>foo</div><p>[bar]<div style=text-align:right><p>baz</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\"><p>foo</p><p>[bar]</p><p>baz</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<div style=text-align:right><p>foo</div><p>[bar]<div style=text-align:right><p>baz</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\"><p>foo</p><p>[bar]</p><p>baz</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<div style=text-align:right><p>foo</div><p>[bar]<div style=text-align:right><p>baz</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\"><p>foo</p><p>[bar]</p><p>baz</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<p align=right>foo<p>[bar]<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyright",""]], + "<p align=\"right\">foo</p><div style=\"text-align:right\"><p>[bar]</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<p align=right>foo<p>[bar]<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]], + "<p align=\"right\">foo</p><div style=\"text-align:right\"><p>[bar]</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<p align=right>foo<p>[bar]<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyright",""]], + "<p align=\"right\">foo</p><div style=\"text-align:right\"><p>[bar]</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<p align=right>foo<p>[bar]<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyright",""]], + "<p align=\"right\">foo</p><div style=\"text-align:right\"><p>[bar]</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<p>[foo]<p align=right>bar<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\"><p>[foo]</p></div><p align=\"right\">bar</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<p>[foo]<p align=right>bar<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\"><p>[foo]</p></div><p align=\"right\">bar</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<p>[foo]<p align=right>bar<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\"><p>[foo]</p></div><p align=\"right\">bar</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<p>[foo]<p align=right>bar<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\"><p>[foo]</p></div><p align=\"right\">bar</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<p align=right>foo<p>[bar]<p align=right>baz<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyright",""]], + "<p align=\"right\">foo</p><div style=\"text-align:right\"><p>[bar]</p></div><p align=\"right\">baz</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<p align=right>foo<p>[bar]<p align=right>baz<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]], + "<p align=\"right\">foo</p><div style=\"text-align:right\"><p>[bar]</p></div><p align=\"right\">baz</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<p align=right>foo<p>[bar]<p align=right>baz<p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyright",""]], + "<p align=\"right\">foo</p><div style=\"text-align:right\"><p>[bar]</p></div><p align=\"right\">baz</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<p align=right>foo<p>[bar]<p align=right>baz<p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyright",""]], + "<p align=\"right\">foo</p><div style=\"text-align:right\"><p>[bar]</p></div><p align=\"right\">baz</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<div align=right>[foo</div>bar]<p>extra", + [["stylewithcss","true"],["justifyright",""]], + "<div style=\"text-align:right\">[foo<br>bar]</div><p>extra</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"justifyright":[true,false,"right",false,true,"right"]}], +["<div align=right>[foo</div>bar]<p>extra", + [["stylewithcss","false"],["justifyright",""]], + "<div style=\"text-align:right\">[foo<br>bar]</div><p>extra</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"justifyright":[true,false,"right",false,true,"right"]}], +["<div align=right>fo[o</div>b]ar<p>extra", + [["stylewithcss","true"],["justifyright",""]], + "<div style=\"text-align:right\">fo[o<br>b]ar</div><p>extra</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"justifyright":[true,false,"right",false,true,"right"]}], +["<div align=right>fo[o</div>b]ar<p>extra", + [["stylewithcss","false"],["justifyright",""]], + "<div style=\"text-align:right\">fo[o<br>b]ar</div><p>extra</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"justifyright":[true,false,"right",false,true,"right"]}], +["<div style=text-align:right>[foo</div>bar]<p>extra", + [["justifyright",""]], + "<div style=\"text-align:right\">[foo<br>bar]</div><p>extra</p>", + [true], + {"justifyright":[true,false,"right",false,true,"right"]}], +["<div style=text-align:right>fo[o</div>b]ar<p>extra", + [["justifyright",""]], + "<div style=\"text-align:right\">fo[o<br>b]ar</div><p>extra</p>", + [true], + {"justifyright":[true,false,"right",false,true,"right"]}], +["<span style=text-align:right>[foo]</span><p>extra", + [["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\">[foo]</div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<span style=text-align:right>[foo]</span><p>extra", + [["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\">[foo]</div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<span style=text-align:right>f[o]o</span><p>extra", + [["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\">f[o]o</div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<span style=text-align:right>f[o]o</span><p>extra", + [["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\">f[o]o</div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<div style=text-align:right>[foo<div style=text-align:left contenteditable=false>bar</div>baz]</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\">[foo</div><div style=\"text-align:left\" contenteditable=\"false\">bar</div><div style=\"text-align:right\">baz]</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,true,"right",false,true,"right"]}], +["<div style=text-align:right>[foo<div style=text-align:left contenteditable=false>bar</div>baz]</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\">[foo</div><div style=\"text-align:left\" contenteditable=\"false\">bar</div><div style=\"text-align:right\">baz]</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,true,"right",false,true,"right"]}], +["<div style=text-align:right>[foo<div style=text-align:left contenteditable=false>bar</div>baz]</div><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\">[foo</div><div style=\"text-align:left\" contenteditable=\"false\">bar</div><div style=\"text-align:right\">baz]</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,true,"right",false,true,"right"]}], +["<div style=text-align:right>[foo<div style=text-align:left contenteditable=false>bar</div>baz]</div><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\">[foo</div><div style=\"text-align:left\" contenteditable=\"false\">bar</div><div style=\"text-align:right\">baz]</div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyright":[false,true,"right",false,true,"right"]}], +["<div align=nonsense><p>[foo]</div><p>extra", + [["stylewithcss","true"],["justifyright",""]], + "<div style=\"text-align:right\"><p>[foo]</p></div><p>extra</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"justifyright":[false,false,"left",false,true,"right"]}], +["<div align=nonsense><p>[foo]</div><p>extra", + [["stylewithcss","false"],["justifyright",""]], + "<div style=\"text-align:right\"><p>[foo]</p></div><p>extra</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"justifyright":[false,false,"left",false,true,"right"]}], +["<div style=text-align:inherit><p>[foo]</div><p>extra", + [["justifyright",""]], + "<div style=\"text-align:right\"><p>[foo]</p></div><p>extra</p>", + [true], + {"justifyright":[false,false,"left",false,true,"right"]}], +["<quasit align=center><p>[foo]</p></quasit><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\"><quasit><p>[foo]</p></quasit></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<quasit align=center><p>[foo]</p></quasit><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\"><quasit><p>[foo]</p></quasit></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<quasit align=center><p>[foo]</p></quasit><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\"><quasit><p>[foo]</p></quasit></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<quasit align=center><p>[foo]</p></quasit><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\"><quasit><p>[foo]</p></quasit></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<div style=text-align:start>[foo]</div><p>extra", + [["justifyright",""]], + "<div style=\"text-align:right\">[foo]</div><p>extra</p>", + [true], + {"justifyright":[false,false,"left",false,true,"right"]}], +["<div style=text-align:end>[foo]</div><p>extra", + [["justifyright",""]], + "<div style=\"text-align:right\">[foo]</div><p>extra</p>", + [true], + {"justifyright":[false,true,"right",false,true,"right"]}], +["<div dir=rtl style=text-align:start>[foo]</div><p>extra", + [["stylewithcss","true"],["justifyright",""]], + "<div dir=\"rtl\">[foo]</div><p>extra</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"justifyright":[false,true,"right",false,true,"right"]}], +["<div dir=rtl style=text-align:start>[foo]</div><p>extra", + [["stylewithcss","false"],["justifyright",""]], + "<div dir=\"rtl\">[foo]</div><p>extra</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"justifyright":[false,true,"right",false,true,"right"]}], +["<div dir=rtl style=text-align:end>[foo]</div><p>extra", + [["stylewithcss","true"],["justifyright",""]], + "<div dir=\"rtl\">[foo]</div><p>extra</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"justifyright":[false,false,"left",false,true,"right"]}], +["<div dir=rtl style=text-align:end>[foo]</div><p>extra", + [["stylewithcss","false"],["justifyright",""]], + "<div dir=\"rtl\">[foo]</div><p>extra</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"justifyright":[false,false,"left",false,true,"right"]}], +["<div style=text-align:right><p>foo</div> <p>[bar]", + [["justifyright",""]], + "<div style=\"text-align:right\"><p>foo</p> <p>[bar]</p></div>", + [true], + {"justifyright":[false,false,"left",false,true,"right"]}], +["<div align=right><p>foo</div> <p>[bar]", + [["justifyright",""]], + "<div align=\"right\"><p>foo</p> <p>[bar]</p></div>", + [true], + {"justifyright":[false,false,"left",false,true,"right"]}], +["<p>[foo]</p> <div style=text-align:right><p>bar</div>", + [["justifyright",""]], + "<div style=\"text-align:right\"><p>[foo]</p> <p>bar</p></div>", + [true], + {"justifyright":[false,false,"left",false,true,"right"]}], +["<p>[foo]</p> <div align=right><p>bar</div>", + [["justifyright",""]], + "<div align=\"right\"><p>[foo]</p> <p>bar</p></div>", + [true], + {"justifyright":[false,false,"left",false,true,"right"]}], +["<div style=text-align:right><p>foo</div> <p>[bar]</p> <div style=text-align:right><p>baz</div>", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\"><p>foo</p> <p>[bar]</p> <p>baz</p></div>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<div style=text-align:right><p>foo</div> <p>[bar]</p> <div style=text-align:right><p>baz</div>", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["justifyright",""]], + "<div style=\"text-align:right\"><p>foo</p> <p>[bar]</p> <p>baz</p></div>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<div style=text-align:right><p>foo</div> <p>[bar]</p> <div style=text-align:right><p>baz</div>", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\"><p>foo</p> <p>[bar]</p> <p>baz</p></div>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<div style=text-align:right><p>foo</div> <p>[bar]</p> <div style=text-align:right><p>baz</div>", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["justifyright",""]], + "<div style=\"text-align:right\"><p>foo</p> <p>[bar]</p> <p>baz</p></div>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<div align=right><p>foo</div> <p>[bar]</p> <div align=right><p>baz</div>", + [["defaultparagraphseparator","div"],["justifyright",""]], + "<div align=\"right\"><p>foo</p> <p>[bar]</p> <p>baz</p></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"justifyright":[false,false,"left",false,true,"right"]}], +["<div align=right><p>foo</div> <p>[bar]</p> <div align=right><p>baz</div>", + [["defaultparagraphseparator","p"],["justifyright",""]], + "<div align=\"right\"><p>foo</p> <p>[bar]</p> <p>baz</p></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"justifyright":[false,false,"left",false,true,"right"]}], +["<div contenteditable=false align=right><p contenteditable>f[]oo</p></div>", + [], + ["<div contenteditable=\"false\" align=\"right\"><p contenteditable=\"\">foo</p></div>", + "<div align=\"right\" contenteditable=\"false\"><p contenteditable=\"\">foo</p></div>"], + [true], + {"justifyleft":[false,false,"right",false,false,"right"], + "justifycenter":[false,false,"right",false,false,"right"], + "justifyfull":[false,false,"right",false,false,"right"], + "justifyright":[false,true,"right",false,true,"right"]}], +["<div contenteditable=false style=text-align:right><p contenteditable>f[]oo</p></div>", + [], + ["<div contenteditable=\"false\" style=\"text-align:right\"><p contenteditable=\"\">foo</p></div>", + "<div style=\"text-align:right\" contenteditable=\"false\"><p contenteditable=\"\">foo</p></div>"], + [true], + {"justifyleft":[false,false,"right",false,false,"right"], + "justifycenter":[false,false,"right",false,false,"right"], + "justifyfull":[false,false,"right",false,false,"right"], + "justifyright":[false,true,"right",false,true,"right"]}], +] diff --git a/testing/web-platform/tests/editing/data/misc.js b/testing/web-platform/tests/editing/data/misc.js new file mode 100644 index 0000000000..83c02ab769 --- /dev/null +++ b/testing/web-platform/tests/editing/data/misc.js @@ -0,0 +1,238 @@ +// For documentation of the format, see README in this directory. +var browserTests = [ +["foo[bar]baz", + [["defaultparagraphseparator",""]], + "foo[bar]baz", + [false], + {"defaultparagraphseparator":[false,false,"div",false,false,"div"]}], +["foo[bar]baz", + [["defaultparagraphseparator","div"]], + "foo[bar]baz", + [true], + {"defaultparagraphseparator":[false,false,"div",false,false,"div"]}], +["foo[bar]baz", + [["defaultparagraphseparator","p"]], + "foo[bar]baz", + [true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"]}], +["foo[bar]baz", + [["defaultparagraphseparator","DIV"]], + "foo[bar]baz", + [true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"]}], +["foo[bar]baz", + [["defaultparagraphseparator"," p "]], + "foo[bar]baz", + [false], + {"defaultparagraphseparator":[false,false,"div",false,false,"div"]}], +["foo[bar]baz", + [["defaultparagraphseparator","<p>"]], + "foo[bar]baz", + [false], + {"defaultparagraphseparator":[false,false,"div",false,false,"div"]}], +["foo[bar]baz", + [["defaultparagraphseparator","P"]], + "foo[bar]baz", + [true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"]}], +["foo[bar]baz", + [["defaultparagraphseparator"," div "]], + "foo[bar]baz", + [false], + {"defaultparagraphseparator":[false,false,"p",false,false,"p"]}], +["foo[bar]baz", + [["defaultparagraphseparator","<div>"]], + "foo[bar]baz", + [false], + {"defaultparagraphseparator":[false,false,"p",false,false,"p"]}], +["foo[bar]baz", + [["defaultparagraphseparator","li"]], + "foo[bar]baz", + [false], + {"defaultparagraphseparator":[false,false,"p",false,false,"p"]}], +["foo[bar]baz", + [["defaultparagraphseparator","blockquote"]], + "foo[bar]baz", + [false], + {"defaultparagraphseparator":[false,false,"p",false,false,"p"]}], +["foo[bar]baz", + [["selectall",""]], + "foo[bar]baz", + [true], + {"selectall":[false,false,"",false,false,""]}], +["foo[bar]baz", + [["stylewithcss","true"]], + "foo[bar]baz", + [true], + {"stylewithcss":[false,false,"",false,true,""]}], +["foo[bar]baz", + [["stylewithcss","TRUE"]], + "foo[bar]baz", + [true], + {"stylewithcss":[false,true,"",false,true,""]}], +["foo[bar]baz", + [["stylewithcss","TrUe"]], + "foo[bar]baz", + [true], + {"stylewithcss":[false,true,"",false,true,""]}], +["foo[bar]baz", + [["stylewithcss","true "]], + "foo[bar]baz", + [true], + {"stylewithcss":[false,true,"",false,true,""]}], +["foo[bar]baz", + [["stylewithcss"," true"]], + "foo[bar]baz", + [true], + {"stylewithcss":[false,true,"",false,true,""]}], +["foo[bar]baz", + [["stylewithcss","truer"]], + "foo[bar]baz", + [true], + {"stylewithcss":[false,true,"",false,true,""]}], +["foo[bar]baz", + [["stylewithcss"," true "]], + "foo[bar]baz", + [true], + {"stylewithcss":[false,true,"",false,true,""]}], +["foo[bar]baz", + [["stylewithcss"," TrUe"]], + "foo[bar]baz", + [true], + {"stylewithcss":[false,true,"",false,true,""]}], +["foo[bar]baz", + [["stylewithcss",""]], + "foo[bar]baz", + [true], + {"stylewithcss":[false,true,"",false,true,""]}], +["foo[bar]baz", + [["stylewithcss"," "]], + "foo[bar]baz", + [true], + {"stylewithcss":[false,true,"",false,true,""]}], +["foo[bar]baz", + [["stylewithcss","false"]], + "foo[bar]baz", + [true], + {"stylewithcss":[false,true,"",false,false,""]}], +["foo[bar]baz", + [["stylewithcss","FALSE"]], + "foo[bar]baz", + [true], + {"stylewithcss":[false,false,"",false,false,""]}], +["foo[bar]baz", + [["stylewithcss","FaLsE"]], + "foo[bar]baz", + [true], + {"stylewithcss":[false,false,"",false,false,""]}], +["foo[bar]baz", + [["stylewithcss"," false"]], + "foo[bar]baz", + [true], + {"stylewithcss":[false,false,"",false,true,""]}], +["foo[bar]baz", + [["stylewithcss","false "]], + "foo[bar]baz", + [true], + {"stylewithcss":[false,true,"",false,true,""]}], +["foo[bar]baz", + [["stylewithcss","falser"]], + "foo[bar]baz", + [true], + {"stylewithcss":[false,true,"",false,true,""]}], +["foo[bar]baz", + [["stylewithcss","falsé"]], + "foo[bar]baz", + [true], + {"stylewithcss":[false,true,"",false,true,""]}], +["foo[bar]baz", + [["usecss","true"]], + "foo[bar]baz", + [true], + {"usecss":[false,false,"",false,false,""]}], +["foo[bar]baz", + [["usecss","TRUE"]], + "foo[bar]baz", + [true], + {"usecss":[false,false,"",false,false,""]}], +["foo[bar]baz", + [["usecss","TrUe"]], + "foo[bar]baz", + [true], + {"usecss":[false,false,"",false,false,""]}], +["foo[bar]baz", + [["usecss","true "]], + "foo[bar]baz", + [true], + {"usecss":[false,false,"",false,false,""]}], +["foo[bar]baz", + [["usecss"," true"]], + "foo[bar]baz", + [true], + {"usecss":[false,false,"",false,false,""]}], +["foo[bar]baz", + [["usecss","truer"]], + "foo[bar]baz", + [true], + {"usecss":[false,false,"",false,false,""]}], +["foo[bar]baz", + [["usecss"," true "]], + "foo[bar]baz", + [true], + {"usecss":[false,false,"",false,false,""]}], +["foo[bar]baz", + [["usecss"," TrUe"]], + "foo[bar]baz", + [true], + {"usecss":[false,false,"",false,false,""]}], +["foo[bar]baz", + [["usecss",""]], + "foo[bar]baz", + [true], + {"usecss":[false,false,"",false,false,""]}], +["foo[bar]baz", + [["usecss"," "]], + "foo[bar]baz", + [true], + {"usecss":[false,false,"",false,false,""]}], +["foo[bar]baz", + [["usecss","false"]], + "foo[bar]baz", + [true], + {"usecss":[false,false,"",false,false,""]}], +["foo[bar]baz", + [["usecss","FALSE"]], + "foo[bar]baz", + [true], + {"usecss":[false,false,"",false,false,""]}], +["foo[bar]baz", + [["usecss","FaLsE"]], + "foo[bar]baz", + [true], + {"usecss":[false,false,"",false,false,""]}], +["foo[bar]baz", + [["usecss"," false"]], + "foo[bar]baz", + [true], + {"usecss":[false,false,"",false,false,""]}], +["foo[bar]baz", + [["usecss","false "]], + "foo[bar]baz", + [true], + {"usecss":[false,false,"",false,false,""]}], +["foo[bar]baz", + [["usecss","falser"]], + "foo[bar]baz", + [true], + {"usecss":[false,false,"",false,false,""]}], +["foo[bar]baz", + [["usecss","falsé"]], + "foo[bar]baz", + [true], + {"usecss":[false,false,"",false,false,""]}], +["foo[bar]baz", + [["quasit",""]], + "foo[bar]baz", + [false], + {"quasit":[false,false,"",false,false,""]}] +] diff --git a/testing/web-platform/tests/editing/data/multitest.js b/testing/web-platform/tests/editing/data/multitest.js new file mode 100644 index 0000000000..e85f54addf --- /dev/null +++ b/testing/web-platform/tests/editing/data/multitest.js @@ -0,0 +1,3247 @@ +// For documentation of the format, see README in this directory. +var browserTests = [ +["foo[]bar", + [["bold",""],["inserttext","a"]], + "foo<b>a[]</b>bar", + [true,true], + {"bold":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["bold",""],["delete",""]], + "fo[]bar", + [true,true], + {"bold":[false,false,"",false,true,""],"delete":[false,false,"",false,false,""]}], +["foo[]bar", + [["bold",""],["delete",""],["inserttext","a"]], + "fo<b>a[]</b>bar", + [true,true,true], + {"bold":[false,false,"",false,true,""],"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["bold",""],["formatblock","<div>"]], + "<div>foo[]bar</div>", + [true,true], + {"bold":[false,false,"",false,true,""],"formatblock":[false,false,"",false,false,"div"]}], +["foo[]bar", + [["bold",""],["formatblock","<div>"],["inserttext","a"]], + "<div>foo<b>a[]</b>bar</div>", + [true,true,true], + {"bold":[false,false,"",false,true,""],"formatblock":[false,false,"",false,false,"div"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["bold",""],["forwarddelete",""]], + "foo[]ar", + [true,true], + {"bold":[false,false,"",false,true,""],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]bar", + [["bold",""],["forwarddelete",""],["inserttext","a"]], + "foo<b>a[]</b>ar", + [true,true,true], + {"bold":[false,false,"",false,true,""],"forwarddelete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["bold",""],["indent",""]], + "<blockquote>foo[]bar</blockquote>", + [true,true], + {"bold":[false,false,"",false,true,""],"indent":[false,false,"",false,false,""]}], +["foo[]bar", + [["bold",""],["indent",""],["inserttext","a"]], + "<blockquote>foo<b>a[]</b>bar</blockquote>", + [true,true,true], + {"bold":[false,false,"",false,true,""],"indent":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["bold",""],["inserthorizontalrule",""]], + "foo<hr>{}bar", + [true,true], + {"bold":[false,false,"",false,true,""],"inserthorizontalrule":[false,false,"",false,false,""]}], +["foo[]bar", + [["bold",""],["inserthorizontalrule",""],["inserttext","a"]], + "foo<hr><b>a[]</b>bar", + [true,true,true], + {"bold":[false,false,"",false,true,""],"inserthorizontalrule":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["bold",""],["inserthtml","ab<b>c</b>d"]], + "fooab<b>c</b>d{}bar", + [true,true], + {"bold":[false,false,"",false,true,""],"inserthtml":[false,false,"",false,false,""]}], +["foo[]bar", + [["bold",""],["inserthtml","ab<b>c</b>d"],["inserttext","a"]], + "fooab<b>c</b>d<b>a[]</b>bar", + [true,true,true], + {"bold":[false,false,"",false,true,""],"inserthtml":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["bold",""],["insertimage","/img/lion.svg"]], + "foo<img src=\"/img/lion.svg\">{}bar", + [true,true], + {"bold":[false,false,"",false,true,""],"insertimage":[false,false,"",false,false,""]}], +["foo[]bar", + [["bold",""],["insertimage","/img/lion.svg"],["inserttext","a"]], + "foo<img src=\"/img/lion.svg\"><b>a[]</b>bar", + [true,true,true], + {"bold":[false,false,"",false,true,""],"insertimage":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["bold",""],["insertlinebreak",""]], + "foo<br>{}bar", + [true,true], + {"bold":[false,false,"",false,true,""],"insertlinebreak":[false,false,"",false,false,""]}], +["foo[]bar", + [["bold",""],["insertlinebreak",""],["inserttext","a"]], + "foo<br><b>a[]</b>bar", + [true,true,true], + {"bold":[false,false,"",false,true,""],"insertlinebreak":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["bold",""],["insertorderedlist",""]], + "<ol><li>foo[]bar</li></ol>", + [true,true], + {"bold":[false,false,"",false,true,""],"insertorderedlist":[false,false,"",false,true,""]}], +["foo[]bar", + [["bold",""],["insertorderedlist",""],["inserttext","a"]], + "<ol><li>foo<b>a[]</b>bar</li></ol>", + [true,true,true], + {"bold":[false,false,"",false,true,""],"insertorderedlist":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["bold",""],["insertparagraph",""]], + "<p>foo</p><p>{}bar</p>", + [true,true], + {"bold":[false,false,"",false,true,""],"insertparagraph":[false,false,"",false,false,""]}], +["foo[]bar", + [["bold",""],["insertparagraph",""],["inserttext","a"]], + "<p>foo</p><p><b>a[]</b>bar</p>", + [true,true,true], + {"bold":[false,false,"",false,true,""],"insertparagraph":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["bold",""],["insertunorderedlist",""]], + "<ul><li>foo[]bar</li></ul>", + [true,true], + {"bold":[false,false,"",false,true,""],"insertunorderedlist":[false,false,"",false,true,""]}], +["foo[]bar", + [["bold",""],["insertunorderedlist",""],["inserttext","a"]], + "<ul><li>foo<b>a[]</b>bar</li></ul>", + [true,true,true], + {"bold":[false,false,"",false,true,""],"insertunorderedlist":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["bold",""],["justifycenter",""]], + "<div style=\"text-align:center\">foo[]bar</div>", + [true,true], + {"bold":[false,false,"",false,true,""],"justifycenter":[false,false,"left",false,true,"center"]}], +["foo[]bar", + [["bold",""],["justifycenter",""],["inserttext","a"]], + "<div style=\"text-align:center\">foo<b>a[]</b>bar</div>", + [true,true,true], + {"bold":[false,false,"",false,true,""],"justifycenter":[false,false,"left",false,true,"center"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["bold",""],["justifyfull",""]], + "<div style=\"text-align:justify\">foo[]bar</div>", + [true,true], + {"bold":[false,false,"",false,true,""],"justifyfull":[false,false,"left",false,true,"justify"]}], +["foo[]bar", + [["bold",""],["justifyfull",""],["inserttext","a"]], + "<div style=\"text-align:justify\">foo<b>a[]</b>bar</div>", + [true,true,true], + {"bold":[false,false,"",false,true,""],"justifyfull":[false,false,"left",false,true,"justify"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["bold",""],["justifyleft",""]], + "foo[]bar", + [true,true], + {"bold":[false,false,"",false,true,""],"justifyleft":[false,true,"left",false,true,"left"]}], +["foo[]bar", + [["bold",""],["justifyleft",""],["inserttext","a"]], + "foo<b>a[]</b>bar", + [true,true,true], + {"bold":[false,false,"",false,true,""],"justifyleft":[false,true,"left",false,true,"left"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["bold",""],["justifyright",""]], + "<div style=\"text-align:right\">foo[]bar</div>", + [true,true], + {"bold":[false,false,"",false,true,""],"justifyright":[false,false,"left",false,true,"right"]}], +["foo[]bar", + [["bold",""],["justifyright",""],["inserttext","a"]], + "<div style=\"text-align:right\">foo<b>a[]</b>bar</div>", + [true,true,true], + {"bold":[false,false,"",false,true,""],"justifyright":[false,false,"left",false,true,"right"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["bold",""],["outdent",""]], + "foo[]bar", + [true,true], + {"bold":[false,false,"",false,true,""],"outdent":[false,false,"",false,false,""]}], +["foo[]bar", + [["bold",""],["outdent",""],["inserttext","a"]], + "foo<b>a[]</b>bar", + [true,true,true], + {"bold":[false,false,"",false,true,""],"outdent":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["italic",""],["inserttext","a"]], + "foo<i>a[]</i>bar", + [true,true], + {"italic":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["italic",""],["delete",""]], + "fo[]bar", + [true,true], + {"italic":[false,false,"",false,true,""],"delete":[false,false,"",false,false,""]}], +["foo[]bar", + [["italic",""],["delete",""],["inserttext","a"]], + "fo<i>a[]</i>bar", + [true,true,true], + {"italic":[false,false,"",false,true,""],"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["italic",""],["formatblock","<div>"]], + "<div>foo[]bar</div>", + [true,true], + {"italic":[false,false,"",false,true,""],"formatblock":[false,false,"",false,false,"div"]}], +["foo[]bar", + [["italic",""],["formatblock","<div>"],["inserttext","a"]], + "<div>foo<i>a[]</i>bar</div>", + [true,true,true], + {"italic":[false,false,"",false,true,""],"formatblock":[false,false,"",false,false,"div"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["italic",""],["forwarddelete",""]], + "foo[]ar", + [true,true], + {"italic":[false,false,"",false,true,""],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]bar", + [["italic",""],["forwarddelete",""],["inserttext","a"]], + "foo<i>a[]</i>ar", + [true,true,true], + {"italic":[false,false,"",false,true,""],"forwarddelete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["italic",""],["indent",""]], + "<blockquote>foo[]bar</blockquote>", + [true,true], + {"italic":[false,false,"",false,true,""],"indent":[false,false,"",false,false,""]}], +["foo[]bar", + [["italic",""],["indent",""],["inserttext","a"]], + "<blockquote>foo<i>a[]</i>bar</blockquote>", + [true,true,true], + {"italic":[false,false,"",false,true,""],"indent":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["italic",""],["inserthorizontalrule",""]], + "foo<hr>{}bar", + [true,true], + {"italic":[false,false,"",false,true,""],"inserthorizontalrule":[false,false,"",false,false,""]}], +["foo[]bar", + [["italic",""],["inserthorizontalrule",""],["inserttext","a"]], + "foo<hr><i>a[]</i>bar", + [true,true,true], + {"italic":[false,false,"",false,true,""],"inserthorizontalrule":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["italic",""],["inserthtml","ab<b>c</b>d"]], + "fooab<b>c</b>d{}bar", + [true,true], + {"italic":[false,false,"",false,true,""],"inserthtml":[false,false,"",false,false,""]}], +["foo[]bar", + [["italic",""],["inserthtml","ab<b>c</b>d"],["inserttext","a"]], + "fooab<b>c</b>d<i>a[]</i>bar", + [true,true,true], + {"italic":[false,false,"",false,true,""],"inserthtml":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["italic",""],["insertimage","/img/lion.svg"]], + "foo<img src=\"/img/lion.svg\">{}bar", + [true,true], + {"italic":[false,false,"",false,true,""],"insertimage":[false,false,"",false,false,""]}], +["foo[]bar", + [["italic",""],["insertimage","/img/lion.svg"],["inserttext","a"]], + "foo<img src=\"/img/lion.svg\"><i>a[]</i>bar", + [true,true,true], + {"italic":[false,false,"",false,true,""],"insertimage":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["italic",""],["insertlinebreak",""]], + "foo<br>{}bar", + [true,true], + {"italic":[false,false,"",false,true,""],"insertlinebreak":[false,false,"",false,false,""]}], +["foo[]bar", + [["italic",""],["insertlinebreak",""],["inserttext","a"]], + "foo<br><i>a[]</i>bar", + [true,true,true], + {"italic":[false,false,"",false,true,""],"insertlinebreak":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["italic",""],["insertorderedlist",""]], + "<ol><li>foo[]bar</li></ol>", + [true,true], + {"italic":[false,false,"",false,true,""],"insertorderedlist":[false,false,"",false,true,""]}], +["foo[]bar", + [["italic",""],["insertorderedlist",""],["inserttext","a"]], + "<ol><li>foo<i>a[]</i>bar</li></ol>", + [true,true,true], + {"italic":[false,false,"",false,true,""],"insertorderedlist":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["italic",""],["insertparagraph",""]], + "<p>foo</p><p>{}bar</p>", + [true,true], + {"italic":[false,false,"",false,true,""],"insertparagraph":[false,false,"",false,false,""]}], +["foo[]bar", + [["italic",""],["insertparagraph",""],["inserttext","a"]], + "<p>foo</p><p><i>a[]</i>bar</p>", + [true,true,true], + {"italic":[false,false,"",false,true,""],"insertparagraph":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["italic",""],["insertunorderedlist",""]], + "<ul><li>foo[]bar</li></ul>", + [true,true], + {"italic":[false,false,"",false,true,""],"insertunorderedlist":[false,false,"",false,true,""]}], +["foo[]bar", + [["italic",""],["insertunorderedlist",""],["inserttext","a"]], + "<ul><li>foo<i>a[]</i>bar</li></ul>", + [true,true,true], + {"italic":[false,false,"",false,true,""],"insertunorderedlist":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["italic",""],["justifycenter",""]], + "<div style=\"text-align:center\">foo[]bar</div>", + [true,true], + {"italic":[false,false,"",false,true,""],"justifycenter":[false,false,"left",false,true,"center"]}], +["foo[]bar", + [["italic",""],["justifycenter",""],["inserttext","a"]], + "<div style=\"text-align:center\">foo<i>a[]</i>bar</div>", + [true,true,true], + {"italic":[false,false,"",false,true,""],"justifycenter":[false,false,"left",false,true,"center"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["italic",""],["justifyfull",""]], + "<div style=\"text-align:justify\">foo[]bar</div>", + [true,true], + {"italic":[false,false,"",false,true,""],"justifyfull":[false,false,"left",false,true,"justify"]}], +["foo[]bar", + [["italic",""],["justifyfull",""],["inserttext","a"]], + "<div style=\"text-align:justify\">foo<i>a[]</i>bar</div>", + [true,true,true], + {"italic":[false,false,"",false,true,""],"justifyfull":[false,false,"left",false,true,"justify"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["italic",""],["justifyleft",""]], + "foo[]bar", + [true,true], + {"italic":[false,false,"",false,true,""],"justifyleft":[false,true,"left",false,true,"left"]}], +["foo[]bar", + [["italic",""],["justifyleft",""],["inserttext","a"]], + "foo<i>a[]</i>bar", + [true,true,true], + {"italic":[false,false,"",false,true,""],"justifyleft":[false,true,"left",false,true,"left"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["italic",""],["justifyright",""]], + "<div style=\"text-align:right\">foo[]bar</div>", + [true,true], + {"italic":[false,false,"",false,true,""],"justifyright":[false,false,"left",false,true,"right"]}], +["foo[]bar", + [["italic",""],["justifyright",""],["inserttext","a"]], + "<div style=\"text-align:right\">foo<i>a[]</i>bar</div>", + [true,true,true], + {"italic":[false,false,"",false,true,""],"justifyright":[false,false,"left",false,true,"right"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["italic",""],["outdent",""]], + "foo[]bar", + [true,true], + {"italic":[false,false,"",false,true,""],"outdent":[false,false,"",false,false,""]}], +["foo[]bar", + [["italic",""],["outdent",""],["inserttext","a"]], + "foo<i>a[]</i>bar", + [true,true,true], + {"italic":[false,false,"",false,true,""],"outdent":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["strikethrough",""],["inserttext","a"]], + "foo<s>a[]</s>bar", + [true,true], + {"strikethrough":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["strikethrough",""],["delete",""]], + "fo[]bar", + [true,true], + {"strikethrough":[false,false,"",false,true,""],"delete":[false,false,"",false,false,""]}], +["foo[]bar", + [["strikethrough",""],["delete",""],["inserttext","a"]], + "fo<s>a[]</s>bar", + [true,true,true], + {"strikethrough":[false,false,"",false,true,""],"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["strikethrough",""],["formatblock","<div>"]], + "<div>foo[]bar</div>", + [true,true], + {"strikethrough":[false,false,"",false,true,""],"formatblock":[false,false,"",false,false,"div"]}], +["foo[]bar", + [["strikethrough",""],["formatblock","<div>"],["inserttext","a"]], + "<div>foo<s>a[]</s>bar</div>", + [true,true,true], + {"strikethrough":[false,false,"",false,true,""],"formatblock":[false,false,"",false,false,"div"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["strikethrough",""],["forwarddelete",""]], + "foo[]ar", + [true,true], + {"strikethrough":[false,false,"",false,true,""],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]bar", + [["strikethrough",""],["forwarddelete",""],["inserttext","a"]], + "foo<s>a[]</s>ar", + [true,true,true], + {"strikethrough":[false,false,"",false,true,""],"forwarddelete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["strikethrough",""],["indent",""]], + "<blockquote>foo[]bar</blockquote>", + [true,true], + {"strikethrough":[false,false,"",false,true,""],"indent":[false,false,"",false,false,""]}], +["foo[]bar", + [["strikethrough",""],["indent",""],["inserttext","a"]], + "<blockquote>foo<s>a[]</s>bar</blockquote>", + [true,true,true], + {"strikethrough":[false,false,"",false,true,""],"indent":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["strikethrough",""],["inserthorizontalrule",""]], + "foo<hr>{}bar", + [true,true], + {"strikethrough":[false,false,"",false,true,""],"inserthorizontalrule":[false,false,"",false,false,""]}], +["foo[]bar", + [["strikethrough",""],["inserthorizontalrule",""],["inserttext","a"]], + "foo<hr><s>a[]</s>bar", + [true,true,true], + {"strikethrough":[false,false,"",false,true,""],"inserthorizontalrule":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["strikethrough",""],["inserthtml","ab<b>c</b>d"]], + "fooab<b>c</b>d{}bar", + [true,true], + {"strikethrough":[false,false,"",false,true,""],"inserthtml":[false,false,"",false,false,""]}], +["foo[]bar", + [["strikethrough",""],["inserthtml","ab<b>c</b>d"],["inserttext","a"]], + "fooab<b>c</b>d<s>a[]</s>bar", + [true,true,true], + {"strikethrough":[false,false,"",false,true,""],"inserthtml":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["strikethrough",""],["insertimage","/img/lion.svg"]], + "foo<img src=\"/img/lion.svg\">{}bar", + [true,true], + {"strikethrough":[false,false,"",false,true,""],"insertimage":[false,false,"",false,false,""]}], +["foo[]bar", + [["strikethrough",""],["insertimage","/img/lion.svg"],["inserttext","a"]], + "foo<img src=\"/img/lion.svg\"><s>a[]</s>bar", + [true,true,true], + {"strikethrough":[false,false,"",false,true,""],"insertimage":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["strikethrough",""],["insertlinebreak",""]], + "foo<br>{}bar", + [true,true], + {"strikethrough":[false,false,"",false,true,""],"insertlinebreak":[false,false,"",false,false,""]}], +["foo[]bar", + [["strikethrough",""],["insertlinebreak",""],["inserttext","a"]], + "foo<br><s>a[]</s>bar", + [true,true,true], + {"strikethrough":[false,false,"",false,true,""],"insertlinebreak":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["strikethrough",""],["insertorderedlist",""]], + "<ol><li>foo[]bar</li></ol>", + [true,true], + {"strikethrough":[false,false,"",false,true,""],"insertorderedlist":[false,false,"",false,true,""]}], +["foo[]bar", + [["strikethrough",""],["insertorderedlist",""],["inserttext","a"]], + "<ol><li>foo<s>a[]</s>bar</li></ol>", + [true,true,true], + {"strikethrough":[false,false,"",false,true,""],"insertorderedlist":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["strikethrough",""],["insertparagraph",""]], + "<p>foo</p><p>{}bar</p>", + [true,true], + {"strikethrough":[false,false,"",false,true,""],"insertparagraph":[false,false,"",false,false,""]}], +["foo[]bar", + [["strikethrough",""],["insertparagraph",""],["inserttext","a"]], + "<p>foo</p><p><s>a[]</s>bar</p>", + [true,true,true], + {"strikethrough":[false,false,"",false,true,""],"insertparagraph":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["strikethrough",""],["insertunorderedlist",""]], + "<ul><li>foo[]bar</li></ul>", + [true,true], + {"strikethrough":[false,false,"",false,true,""],"insertunorderedlist":[false,false,"",false,true,""]}], +["foo[]bar", + [["strikethrough",""],["insertunorderedlist",""],["inserttext","a"]], + "<ul><li>foo<s>a[]</s>bar</li></ul>", + [true,true,true], + {"strikethrough":[false,false,"",false,true,""],"insertunorderedlist":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["strikethrough",""],["justifycenter",""]], + "<div style=\"text-align:center\">foo[]bar</div>", + [true,true], + {"strikethrough":[false,false,"",false,true,""],"justifycenter":[false,false,"left",false,true,"center"]}], +["foo[]bar", + [["strikethrough",""],["justifycenter",""],["inserttext","a"]], + "<div style=\"text-align:center\">foo<s>a[]</s>bar</div>", + [true,true,true], + {"strikethrough":[false,false,"",false,true,""],"justifycenter":[false,false,"left",false,true,"center"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["strikethrough",""],["justifyfull",""]], + "<div style=\"text-align:justify\">foo[]bar</div>", + [true,true], + {"strikethrough":[false,false,"",false,true,""],"justifyfull":[false,false,"left",false,true,"justify"]}], +["foo[]bar", + [["strikethrough",""],["justifyfull",""],["inserttext","a"]], + "<div style=\"text-align:justify\">foo<s>a[]</s>bar</div>", + [true,true,true], + {"strikethrough":[false,false,"",false,true,""],"justifyfull":[false,false,"left",false,true,"justify"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["strikethrough",""],["justifyleft",""]], + "foo[]bar", + [true,true], + {"strikethrough":[false,false,"",false,true,""],"justifyleft":[false,true,"left",false,true,"left"]}], +["foo[]bar", + [["strikethrough",""],["justifyleft",""],["inserttext","a"]], + "foo<s>a[]</s>bar", + [true,true,true], + {"strikethrough":[false,false,"",false,true,""],"justifyleft":[false,true,"left",false,true,"left"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["strikethrough",""],["justifyright",""]], + "<div style=\"text-align:right\">foo[]bar</div>", + [true,true], + {"strikethrough":[false,false,"",false,true,""],"justifyright":[false,false,"left",false,true,"right"]}], +["foo[]bar", + [["strikethrough",""],["justifyright",""],["inserttext","a"]], + "<div style=\"text-align:right\">foo<s>a[]</s>bar</div>", + [true,true,true], + {"strikethrough":[false,false,"",false,true,""],"justifyright":[false,false,"left",false,true,"right"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["strikethrough",""],["outdent",""]], + "foo[]bar", + [true,true], + {"strikethrough":[false,false,"",false,true,""],"outdent":[false,false,"",false,false,""]}], +["foo[]bar", + [["strikethrough",""],["outdent",""],["inserttext","a"]], + "foo<s>a[]</s>bar", + [true,true,true], + {"strikethrough":[false,false,"",false,true,""],"outdent":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["subscript",""],["inserttext","a"]], + "foo<sub>a[]</sub>bar", + [true,true], + {"subscript":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["subscript",""],["delete",""]], + "fo[]bar", + [true,true], + {"subscript":[false,false,"",false,true,""],"delete":[false,false,"",false,false,""]}], +["foo[]bar", + [["subscript",""],["delete",""],["inserttext","a"]], + "fo<sub><font size=\"3\">a[]</font></sub>bar", + [true,true,true], + {"subscript":[false,false,"",false,true,""],"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["subscript",""],["formatblock","<div>"]], + "<div>foo[]bar</div>", + [true,true], + {"subscript":[false,false,"",false,true,""],"formatblock":[false,false,"",false,false,"div"]}], +["foo[]bar", + [["subscript",""],["formatblock","<div>"],["inserttext","a"]], + "<div>foo<sub>a[]</sub>bar</div>", + [true,true,true], + {"subscript":[false,false,"",false,true,""],"formatblock":[false,false,"",false,false,"div"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["subscript",""],["forwarddelete",""]], + "foo[]ar", + [true,true], + {"subscript":[false,false,"",false,true,""],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]bar", + [["subscript",""],["forwarddelete",""],["inserttext","a"]], + "foo<sub><font size=\"3\">a[]</font></sub>ar", + [true,true,true], + {"subscript":[false,false,"",false,true,""],"forwarddelete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["subscript",""],["indent",""]], + "<blockquote>foo[]bar</blockquote>", + [true,true], + {"subscript":[false,false,"",false,true,""],"indent":[false,false,"",false,false,""]}], +["foo[]bar", + [["subscript",""],["indent",""],["inserttext","a"]], + "<blockquote>foo<sub>a[]</sub>bar</blockquote>", + [true,true,true], + {"subscript":[false,false,"",false,true,""],"indent":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["subscript",""],["inserthorizontalrule",""]], + "foo<hr>{}bar", + [true,true], + {"subscript":[false,false,"",false,true,""],"inserthorizontalrule":[false,false,"",false,false,""]}], +["foo[]bar", + [["subscript",""],["inserthorizontalrule",""],["inserttext","a"]], + "foo<hr><sub>a[]</sub>bar", + [true,true,true], + {"subscript":[false,false,"",false,true,""],"inserthorizontalrule":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["subscript",""],["inserthtml","ab<b>c</b>d"]], + "fooab<b>c</b>d{}bar", + [true,true], + {"subscript":[false,false,"",false,true,""],"inserthtml":[false,false,"",false,false,""]}], +["foo[]bar", + [["subscript",""],["inserthtml","ab<b>c</b>d"],["inserttext","a"]], + "fooab<b>c</b>d<sub>a[]</sub>bar", + [true,true,true], + {"subscript":[false,false,"",false,true,""],"inserthtml":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["subscript",""],["insertimage","/img/lion.svg"]], + "foo<img src=\"/img/lion.svg\">{}bar", + [true,true], + {"subscript":[false,false,"",false,true,""],"insertimage":[false,false,"",false,false,""]}], +["foo[]bar", + [["subscript",""],["insertimage","/img/lion.svg"],["inserttext","a"]], + "foo<img src=\"/img/lion.svg\"><sub>a[]</sub>bar", + [true,true,true], + {"subscript":[false,false,"",false,true,""],"insertimage":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["subscript",""],["insertlinebreak",""]], + "foo<br>{}bar", + [true,true], + {"subscript":[false,false,"",false,true,""],"insertlinebreak":[false,false,"",false,false,""]}], +["foo[]bar", + [["subscript",""],["insertlinebreak",""],["inserttext","a"]], + "foo<br><sub>a[]</sub>bar", + [true,true,true], + {"subscript":[false,false,"",false,true,""],"insertlinebreak":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["subscript",""],["insertorderedlist",""]], + "<ol><li>foo[]bar</li></ol>", + [true,true], + {"subscript":[false,false,"",false,true,""],"insertorderedlist":[false,false,"",false,true,""]}], +["foo[]bar", + [["subscript",""],["insertorderedlist",""],["inserttext","a"]], + "<ol><li>foo<sub>a[]</sub>bar</li></ol>", + [true,true,true], + {"subscript":[false,false,"",false,true,""],"insertorderedlist":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["subscript",""],["insertparagraph",""]], + "<p>foo</p><p>{}bar</p>", + [true,true], + {"subscript":[false,false,"",false,true,""],"insertparagraph":[false,false,"",false,false,""]}], +["foo[]bar", + [["subscript",""],["insertparagraph",""],["inserttext","a"]], + "<p>foo</p><p><sub>a[]</sub>bar</p>", + [true,true,true], + {"subscript":[false,false,"",false,true,""],"insertparagraph":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["subscript",""],["insertunorderedlist",""]], + "<ul><li>foo[]bar</li></ul>", + [true,true], + {"subscript":[false,false,"",false,true,""],"insertunorderedlist":[false,false,"",false,true,""]}], +["foo[]bar", + [["subscript",""],["insertunorderedlist",""],["inserttext","a"]], + "<ul><li>foo<sub>a[]</sub>bar</li></ul>", + [true,true,true], + {"subscript":[false,false,"",false,true,""],"insertunorderedlist":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["subscript",""],["justifycenter",""]], + "<div style=\"text-align:center\">foo[]bar</div>", + [true,true], + {"subscript":[false,false,"",false,true,""],"justifycenter":[false,false,"left",false,true,"center"]}], +["foo[]bar", + [["subscript",""],["justifycenter",""],["inserttext","a"]], + "<div style=\"text-align:center\">foo<sub>a[]</sub>bar</div>", + [true,true,true], + {"subscript":[false,false,"",false,true,""],"justifycenter":[false,false,"left",false,true,"center"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["subscript",""],["justifyfull",""]], + "<div style=\"text-align:justify\">foo[]bar</div>", + [true,true], + {"subscript":[false,false,"",false,true,""],"justifyfull":[false,false,"left",false,true,"justify"]}], +["foo[]bar", + [["subscript",""],["justifyfull",""],["inserttext","a"]], + "<div style=\"text-align:justify\">foo<sub>a[]</sub>bar</div>", + [true,true,true], + {"subscript":[false,false,"",false,true,""],"justifyfull":[false,false,"left",false,true,"justify"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["subscript",""],["justifyleft",""]], + "foo[]bar", + [true,true], + {"subscript":[false,false,"",false,true,""],"justifyleft":[false,true,"left",false,true,"left"]}], +["foo[]bar", + [["subscript",""],["justifyleft",""],["inserttext","a"]], + "foo<sub>a[]</sub>bar", + [true,true,true], + {"subscript":[false,false,"",false,true,""],"justifyleft":[false,true,"left",false,true,"left"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["subscript",""],["justifyright",""]], + "<div style=\"text-align:right\">foo[]bar</div>", + [true,true], + {"subscript":[false,false,"",false,true,""],"justifyright":[false,false,"left",false,true,"right"]}], +["foo[]bar", + [["subscript",""],["justifyright",""],["inserttext","a"]], + "<div style=\"text-align:right\">foo<sub>a[]</sub>bar</div>", + [true,true,true], + {"subscript":[false,false,"",false,true,""],"justifyright":[false,false,"left",false,true,"right"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["subscript",""],["outdent",""]], + "foo[]bar", + [true,true], + {"subscript":[false,false,"",false,true,""],"outdent":[false,false,"",false,false,""]}], +["foo[]bar", + [["subscript",""],["outdent",""],["inserttext","a"]], + "foo<sub>a[]</sub>bar", + [true,true,true], + {"subscript":[false,false,"",false,true,""],"outdent":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["superscript",""],["inserttext","a"]], + "foo<sup>a[]</sup>bar", + [true,true], + {"superscript":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["superscript",""],["delete",""]], + "fo[]bar", + [true,true], + {"superscript":[false,false,"",false,true,""],"delete":[false,false,"",false,false,""]}], +["foo[]bar", + [["superscript",""],["delete",""],["inserttext","a"]], + "fo<sup><font size=\"3\">a[]</font></sup>bar", + [true,true,true], + {"superscript":[false,false,"",false,true,""],"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["superscript",""],["formatblock","<div>"]], + "<div>foo[]bar</div>", + [true,true], + {"superscript":[false,false,"",false,true,""],"formatblock":[false,false,"",false,false,"div"]}], +["foo[]bar", + [["superscript",""],["formatblock","<div>"],["inserttext","a"]], + "<div>foo<sup>a[]</sup>bar</div>", + [true,true,true], + {"superscript":[false,false,"",false,true,""],"formatblock":[false,false,"",false,false,"div"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["superscript",""],["forwarddelete",""]], + "foo[]ar", + [true,true], + {"superscript":[false,false,"",false,true,""],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]bar", + [["superscript",""],["forwarddelete",""],["inserttext","a"]], + "foo<sup><font size=\"3\">a[]</font></sup>ar", + [true,true,true], + {"superscript":[false,false,"",false,true,""],"forwarddelete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["superscript",""],["indent",""]], + "<blockquote>foo[]bar</blockquote>", + [true,true], + {"superscript":[false,false,"",false,true,""],"indent":[false,false,"",false,false,""]}], +["foo[]bar", + [["superscript",""],["indent",""],["inserttext","a"]], + "<blockquote>foo<sup>a[]</sup>bar</blockquote>", + [true,true,true], + {"superscript":[false,false,"",false,true,""],"indent":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["superscript",""],["inserthorizontalrule",""]], + "foo<hr>{}bar", + [true,true], + {"superscript":[false,false,"",false,true,""],"inserthorizontalrule":[false,false,"",false,false,""]}], +["foo[]bar", + [["superscript",""],["inserthorizontalrule",""],["inserttext","a"]], + "foo<hr><sup>a[]</sup>bar", + [true,true,true], + {"superscript":[false,false,"",false,true,""],"inserthorizontalrule":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["superscript",""],["inserthtml","ab<b>c</b>d"]], + "fooab<b>c</b>d{}bar", + [true,true], + {"superscript":[false,false,"",false,true,""],"inserthtml":[false,false,"",false,false,""]}], +["foo[]bar", + [["superscript",""],["inserthtml","ab<b>c</b>d"],["inserttext","a"]], + "fooab<b>c</b>d<sup>a[]</sup>bar", + [true,true,true], + {"superscript":[false,false,"",false,true,""],"inserthtml":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["superscript",""],["insertimage","/img/lion.svg"]], + "foo<img src=\"/img/lion.svg\">{}bar", + [true,true], + {"superscript":[false,false,"",false,true,""],"insertimage":[false,false,"",false,false,""]}], +["foo[]bar", + [["superscript",""],["insertimage","/img/lion.svg"],["inserttext","a"]], + "foo<img src=\"/img/lion.svg\"><sup>a[]</sup>bar", + [true,true,true], + {"superscript":[false,false,"",false,true,""],"insertimage":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["superscript",""],["insertlinebreak",""]], + "foo<br>{}bar", + [true,true], + {"superscript":[false,false,"",false,true,""],"insertlinebreak":[false,false,"",false,false,""]}], +["foo[]bar", + [["superscript",""],["insertlinebreak",""],["inserttext","a"]], + "foo<br><sup>a[]</sup>bar", + [true,true,true], + {"superscript":[false,false,"",false,true,""],"insertlinebreak":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["superscript",""],["insertorderedlist",""]], + "<ol><li>foo[]bar</li></ol>", + [true,true], + {"superscript":[false,false,"",false,true,""],"insertorderedlist":[false,false,"",false,true,""]}], +["foo[]bar", + [["superscript",""],["insertorderedlist",""],["inserttext","a"]], + "<ol><li>foo<sup>a[]</sup>bar</li></ol>", + [true,true,true], + {"superscript":[false,false,"",false,true,""],"insertorderedlist":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["superscript",""],["insertparagraph",""]], + "<p>foo</p><p>{}bar</p>", + [true,true], + {"superscript":[false,false,"",false,true,""],"insertparagraph":[false,false,"",false,false,""]}], +["foo[]bar", + [["superscript",""],["insertparagraph",""],["inserttext","a"]], + "<p>foo</p><p><sup>a[]</sup>bar</p>", + [true,true,true], + {"superscript":[false,false,"",false,true,""],"insertparagraph":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["superscript",""],["insertunorderedlist",""]], + "<ul><li>foo[]bar</li></ul>", + [true,true], + {"superscript":[false,false,"",false,true,""],"insertunorderedlist":[false,false,"",false,true,""]}], +["foo[]bar", + [["superscript",""],["insertunorderedlist",""],["inserttext","a"]], + "<ul><li>foo<sup>a[]</sup>bar</li></ul>", + [true,true,true], + {"superscript":[false,false,"",false,true,""],"insertunorderedlist":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["superscript",""],["justifycenter",""]], + "<div style=\"text-align:center\">foo[]bar</div>", + [true,true], + {"superscript":[false,false,"",false,true,""],"justifycenter":[false,false,"left",false,true,"center"]}], +["foo[]bar", + [["superscript",""],["justifycenter",""],["inserttext","a"]], + "<div style=\"text-align:center\">foo<sup>a[]</sup>bar</div>", + [true,true,true], + {"superscript":[false,false,"",false,true,""],"justifycenter":[false,false,"left",false,true,"center"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["superscript",""],["justifyfull",""]], + "<div style=\"text-align:justify\">foo[]bar</div>", + [true,true], + {"superscript":[false,false,"",false,true,""],"justifyfull":[false,false,"left",false,true,"justify"]}], +["foo[]bar", + [["superscript",""],["justifyfull",""],["inserttext","a"]], + "<div style=\"text-align:justify\">foo<sup>a[]</sup>bar</div>", + [true,true,true], + {"superscript":[false,false,"",false,true,""],"justifyfull":[false,false,"left",false,true,"justify"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["superscript",""],["justifyleft",""]], + "foo[]bar", + [true,true], + {"superscript":[false,false,"",false,true,""],"justifyleft":[false,true,"left",false,true,"left"]}], +["foo[]bar", + [["superscript",""],["justifyleft",""],["inserttext","a"]], + "foo<sup>a[]</sup>bar", + [true,true,true], + {"superscript":[false,false,"",false,true,""],"justifyleft":[false,true,"left",false,true,"left"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["superscript",""],["justifyright",""]], + "<div style=\"text-align:right\">foo[]bar</div>", + [true,true], + {"superscript":[false,false,"",false,true,""],"justifyright":[false,false,"left",false,true,"right"]}], +["foo[]bar", + [["superscript",""],["justifyright",""],["inserttext","a"]], + "<div style=\"text-align:right\">foo<sup>a[]</sup>bar</div>", + [true,true,true], + {"superscript":[false,false,"",false,true,""],"justifyright":[false,false,"left",false,true,"right"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["superscript",""],["outdent",""]], + "foo[]bar", + [true,true], + {"superscript":[false,false,"",false,true,""],"outdent":[false,false,"",false,false,""]}], +["foo[]bar", + [["superscript",""],["outdent",""],["inserttext","a"]], + "foo<sup>a[]</sup>bar", + [true,true,true], + {"superscript":[false,false,"",false,true,""],"outdent":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["underline",""],["inserttext","a"]], + "foo<u>a[]</u>bar", + [true,true], + {"underline":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["underline",""],["delete",""]], + "fo[]bar", + [true,true], + {"underline":[false,false,"",false,true,""],"delete":[false,false,"",false,false,""]}], +["foo[]bar", + [["underline",""],["delete",""],["inserttext","a"]], + "fo<u>a[]</u>bar", + [true,true,true], + {"underline":[false,false,"",false,true,""],"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["underline",""],["formatblock","<div>"]], + "<div>foo[]bar</div>", + [true,true], + {"underline":[false,false,"",false,true,""],"formatblock":[false,false,"",false,false,"div"]}], +["foo[]bar", + [["underline",""],["formatblock","<div>"],["inserttext","a"]], + "<div>foo<u>a[]</u>bar</div>", + [true,true,true], + {"underline":[false,false,"",false,true,""],"formatblock":[false,false,"",false,false,"div"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["underline",""],["forwarddelete",""]], + "foo[]ar", + [true,true], + {"underline":[false,false,"",false,true,""],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]bar", + [["underline",""],["forwarddelete",""],["inserttext","a"]], + "foo<u>a[]</u>ar", + [true,true,true], + {"underline":[false,false,"",false,true,""],"forwarddelete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["underline",""],["indent",""]], + "<blockquote>foo[]bar</blockquote>", + [true,true], + {"underline":[false,false,"",false,true,""],"indent":[false,false,"",false,false,""]}], +["foo[]bar", + [["underline",""],["indent",""],["inserttext","a"]], + "<blockquote>foo<u>a[]</u>bar</blockquote>", + [true,true,true], + {"underline":[false,false,"",false,true,""],"indent":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["underline",""],["inserthorizontalrule",""]], + "foo<hr>{}bar", + [true,true], + {"underline":[false,false,"",false,true,""],"inserthorizontalrule":[false,false,"",false,false,""]}], +["foo[]bar", + [["underline",""],["inserthorizontalrule",""],["inserttext","a"]], + "foo<hr><u>a[]</u>bar", + [true,true,true], + {"underline":[false,false,"",false,true,""],"inserthorizontalrule":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["underline",""],["inserthtml","ab<b>c</b>d"]], + "fooab<b>c</b>d{}bar", + [true,true], + {"underline":[false,false,"",false,true,""],"inserthtml":[false,false,"",false,false,""]}], +["foo[]bar", + [["underline",""],["inserthtml","ab<b>c</b>d"],["inserttext","a"]], + "fooab<b>c</b>d<u>a[]</u>bar", + [true,true,true], + {"underline":[false,false,"",false,true,""],"inserthtml":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["underline",""],["insertimage","/img/lion.svg"]], + "foo<img src=\"/img/lion.svg\">{}bar", + [true,true], + {"underline":[false,false,"",false,true,""],"insertimage":[false,false,"",false,false,""]}], +["foo[]bar", + [["underline",""],["insertimage","/img/lion.svg"],["inserttext","a"]], + "foo<img src=\"/img/lion.svg\"><u>a[]</u>bar", + [true,true,true], + {"underline":[false,false,"",false,true,""],"insertimage":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["underline",""],["insertlinebreak",""]], + "foo<br>{}bar", + [true,true], + {"underline":[false,false,"",false,true,""],"insertlinebreak":[false,false,"",false,false,""]}], +["foo[]bar", + [["underline",""],["insertlinebreak",""],["inserttext","a"]], + "foo<br><u>a[]</u>bar", + [true,true,true], + {"underline":[false,false,"",false,true,""],"insertlinebreak":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["underline",""],["insertorderedlist",""]], + "<ol><li>foo[]bar</li></ol>", + [true,true], + {"underline":[false,false,"",false,true,""],"insertorderedlist":[false,false,"",false,true,""]}], +["foo[]bar", + [["underline",""],["insertorderedlist",""],["inserttext","a"]], + "<ol><li>foo<u>a[]</u>bar</li></ol>", + [true,true,true], + {"underline":[false,false,"",false,true,""],"insertorderedlist":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["underline",""],["insertparagraph",""]], + "<p>foo</p><p>{}bar</p>", + [true,true], + {"underline":[false,false,"",false,true,""],"insertparagraph":[false,false,"",false,false,""]}], +["foo[]bar", + [["underline",""],["insertparagraph",""],["inserttext","a"]], + "<p>foo</p><p><u>a[]</u>bar</p>", + [true,true,true], + {"underline":[false,false,"",false,true,""],"insertparagraph":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["underline",""],["insertunorderedlist",""]], + "<ul><li>foo[]bar</li></ul>", + [true,true], + {"underline":[false,false,"",false,true,""],"insertunorderedlist":[false,false,"",false,true,""]}], +["foo[]bar", + [["underline",""],["insertunorderedlist",""],["inserttext","a"]], + "<ul><li>foo<u>a[]</u>bar</li></ul>", + [true,true,true], + {"underline":[false,false,"",false,true,""],"insertunorderedlist":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["underline",""],["justifycenter",""]], + "<div style=\"text-align:center\">foo[]bar</div>", + [true,true], + {"underline":[false,false,"",false,true,""],"justifycenter":[false,false,"left",false,true,"center"]}], +["foo[]bar", + [["underline",""],["justifycenter",""],["inserttext","a"]], + "<div style=\"text-align:center\">foo<u>a[]</u>bar</div>", + [true,true,true], + {"underline":[false,false,"",false,true,""],"justifycenter":[false,false,"left",false,true,"center"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["underline",""],["justifyfull",""]], + "<div style=\"text-align:justify\">foo[]bar</div>", + [true,true], + {"underline":[false,false,"",false,true,""],"justifyfull":[false,false,"left",false,true,"justify"]}], +["foo[]bar", + [["underline",""],["justifyfull",""],["inserttext","a"]], + "<div style=\"text-align:justify\">foo<u>a[]</u>bar</div>", + [true,true,true], + {"underline":[false,false,"",false,true,""],"justifyfull":[false,false,"left",false,true,"justify"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["underline",""],["justifyleft",""]], + "foo[]bar", + [true,true], + {"underline":[false,false,"",false,true,""],"justifyleft":[false,true,"left",false,true,"left"]}], +["foo[]bar", + [["underline",""],["justifyleft",""],["inserttext","a"]], + "foo<u>a[]</u>bar", + [true,true,true], + {"underline":[false,false,"",false,true,""],"justifyleft":[false,true,"left",false,true,"left"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["underline",""],["justifyright",""]], + "<div style=\"text-align:right\">foo[]bar</div>", + [true,true], + {"underline":[false,false,"",false,true,""],"justifyright":[false,false,"left",false,true,"right"]}], +["foo[]bar", + [["underline",""],["justifyright",""],["inserttext","a"]], + "<div style=\"text-align:right\">foo<u>a[]</u>bar</div>", + [true,true,true], + {"underline":[false,false,"",false,true,""],"justifyright":[false,false,"left",false,true,"right"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["underline",""],["outdent",""]], + "foo[]bar", + [true,true], + {"underline":[false,false,"",false,true,""],"outdent":[false,false,"",false,false,""]}], +["foo[]bar", + [["underline",""],["outdent",""],["inserttext","a"]], + "foo<u>a[]</u>bar", + [true,true,true], + {"underline":[false,false,"",false,true,""],"outdent":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["backcolor","#00FFFF"],["inserttext","a"]], + "foo<span style=\"background-color:rgb(0, 255, 255)\">a[]</span>bar", + [true,true], + {"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["backcolor","#00FFFF"],["delete",""]], + "fo[]bar", + [true,true], + {"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"delete":[false,false,"",false,false,""]}], +["foo[]bar", + [["backcolor","#00FFFF"],["delete",""],["inserttext","a"]], + "fo<span style=\"background-color:rgb(0, 255, 255)\">a[]</span>bar", + [true,true,true], + {"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["backcolor","#00FFFF"],["formatblock","<div>"]], + "<div>foo[]bar</div>", + [true,true], + {"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"formatblock":[false,false,"",false,false,"div"]}], +["foo[]bar", + [["backcolor","#00FFFF"],["formatblock","<div>"],["inserttext","a"]], + "<div>foo<span style=\"background-color:rgb(0, 255, 255)\">a[]</span>bar</div>", + [true,true,true], + {"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"formatblock":[false,false,"",false,false,"div"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["backcolor","#00FFFF"],["forwarddelete",""]], + "foo[]ar", + [true,true], + {"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]bar", + [["backcolor","#00FFFF"],["forwarddelete",""],["inserttext","a"]], + "foo<span style=\"background-color:rgb(0, 255, 255)\">a[]</span>ar", + [true,true,true], + {"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"forwarddelete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["backcolor","#00FFFF"],["indent",""]], + "<blockquote>foo[]bar</blockquote>", + [true,true], + {"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"indent":[false,false,"",false,false,""]}], +["foo[]bar", + [["backcolor","#00FFFF"],["indent",""],["inserttext","a"]], + "<blockquote>foo<span style=\"background-color:rgb(0, 255, 255)\">a[]</span>bar</blockquote>", + [true,true,true], + {"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"indent":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["backcolor","#00FFFF"],["inserthorizontalrule",""]], + "foo<hr>{}bar", + [true,true], + {"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"inserthorizontalrule":[false,false,"",false,false,""]}], +["foo[]bar", + [["backcolor","#00FFFF"],["inserthorizontalrule",""],["inserttext","a"]], + "foo<hr><span style=\"background-color:rgb(0, 255, 255)\">a[]</span>bar", + [true,true,true], + {"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"inserthorizontalrule":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["backcolor","#00FFFF"],["inserthtml","ab<b>c</b>d"]], + "fooab<b>c</b>d{}bar", + [true,true], + {"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"inserthtml":[false,false,"",false,false,""]}], +["foo[]bar", + [["backcolor","#00FFFF"],["inserthtml","ab<b>c</b>d"],["inserttext","a"]], + "fooab<b>c</b>d<span style=\"background-color:rgb(0, 255, 255)\">a[]</span>bar", + [true,true,true], + {"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"inserthtml":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["backcolor","#00FFFF"],["insertimage","/img/lion.svg"]], + "foo<img src=\"/img/lion.svg\">{}bar", + [true,true], + {"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"insertimage":[false,false,"",false,false,""]}], +["foo[]bar", + [["backcolor","#00FFFF"],["insertimage","/img/lion.svg"],["inserttext","a"]], + "foo<img src=\"/img/lion.svg\"><span style=\"background-color:rgb(0, 255, 255)\">a[]</span>bar", + [true,true,true], + {"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"insertimage":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["backcolor","#00FFFF"],["insertlinebreak",""]], + "foo<br>{}bar", + [true,true], + {"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"insertlinebreak":[false,false,"",false,false,""]}], +["foo[]bar", + [["backcolor","#00FFFF"],["insertlinebreak",""],["inserttext","a"]], + "foo<br><span style=\"background-color:rgb(0, 255, 255)\">a[]</span>bar", + [true,true,true], + {"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"insertlinebreak":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["backcolor","#00FFFF"],["insertorderedlist",""]], + "<ol><li>foo[]bar</li></ol>", + [true,true], + {"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"insertorderedlist":[false,false,"",false,true,""]}], +["foo[]bar", + [["backcolor","#00FFFF"],["insertorderedlist",""],["inserttext","a"]], + "<ol><li>foo<span style=\"background-color:rgb(0, 255, 255)\">a[]</span>bar</li></ol>", + [true,true,true], + {"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"insertorderedlist":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["backcolor","#00FFFF"],["insertparagraph",""]], + "<p>foo</p><p>{}bar</p>", + [true,true], + {"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"insertparagraph":[false,false,"",false,false,""]}], +["foo[]bar", + [["backcolor","#00FFFF"],["insertparagraph",""],["inserttext","a"]], + "<p>foo</p><p><span style=\"background-color:rgb(0, 255, 255)\">a[]</span>bar</p>", + [true,true,true], + {"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"insertparagraph":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["backcolor","#00FFFF"],["insertunorderedlist",""]], + "<ul><li>foo[]bar</li></ul>", + [true,true], + {"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"insertunorderedlist":[false,false,"",false,true,""]}], +["foo[]bar", + [["backcolor","#00FFFF"],["insertunorderedlist",""],["inserttext","a"]], + "<ul><li>foo<span style=\"background-color:rgb(0, 255, 255)\">a[]</span>bar</li></ul>", + [true,true,true], + {"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"insertunorderedlist":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["backcolor","#00FFFF"],["justifycenter",""]], + "<div style=\"text-align:center\">foo[]bar</div>", + [true,true], + {"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"justifycenter":[false,false,"left",false,true,"center"]}], +["foo[]bar", + [["backcolor","#00FFFF"],["justifycenter",""],["inserttext","a"]], + "<div style=\"text-align:center\">foo<span style=\"background-color:rgb(0, 255, 255)\">a[]</span>bar</div>", + [true,true,true], + {"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"justifycenter":[false,false,"left",false,true,"center"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["backcolor","#00FFFF"],["justifyfull",""]], + "<div style=\"text-align:justify\">foo[]bar</div>", + [true,true], + {"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["foo[]bar", + [["backcolor","#00FFFF"],["justifyfull",""],["inserttext","a"]], + "<div style=\"text-align:justify\">foo<span style=\"background-color:rgb(0, 255, 255)\">a[]</span>bar</div>", + [true,true,true], + {"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"justifyfull":[false,false,"left",false,true,"justify"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["backcolor","#00FFFF"],["justifyleft",""]], + "foo[]bar", + [true,true], + {"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"justifyleft":[false,true,"left",false,true,"left"]}], +["foo[]bar", + [["backcolor","#00FFFF"],["justifyleft",""],["inserttext","a"]], + "foo<span style=\"background-color:rgb(0, 255, 255)\">a[]</span>bar", + [true,true,true], + {"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"justifyleft":[false,true,"left",false,true,"left"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["backcolor","#00FFFF"],["justifyright",""]], + "<div style=\"text-align:right\">foo[]bar</div>", + [true,true], + {"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"justifyright":[false,false,"left",false,true,"right"]}], +["foo[]bar", + [["backcolor","#00FFFF"],["justifyright",""],["inserttext","a"]], + "<div style=\"text-align:right\">foo<span style=\"background-color:rgb(0, 255, 255)\">a[]</span>bar</div>", + [true,true,true], + {"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"justifyright":[false,false,"left",false,true,"right"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["backcolor","#00FFFF"],["outdent",""]], + "foo[]bar", + [true,true], + {"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"outdent":[false,false,"",false,false,""]}], +["foo[]bar", + [["backcolor","#00FFFF"],["outdent",""],["inserttext","a"]], + "foo<span style=\"background-color:rgb(0, 255, 255)\">a[]</span>bar", + [true,true,true], + {"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"outdent":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["createlink","http://www.google.com/"],["inserttext","a"]], + "foo<a href=\"http://www.google.com/\">a[]</a>bar", + [true,true], + {"createlink":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["createlink","http://www.google.com/"],["delete",""]], + "fo[]bar", + [true,true], + {"createlink":[false,false,"",false,false,""],"delete":[false,false,"",false,false,""]}], +["foo[]bar", + [["createlink","http://www.google.com/"],["delete",""],["inserttext","a"]], + "fo<a href=\"http://www.google.com/\"><font color=\"#000000\">a[]</font></a>bar", + [true,true,true], + {"createlink":[false,false,"",false,false,""],"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["createlink","http://www.google.com/"],["formatblock","<div>"]], + "<div>foo[]bar</div>", + [true,true], + {"createlink":[false,false,"",false,false,""],"formatblock":[false,false,"",false,false,"div"]}], +["foo[]bar", + [["createlink","http://www.google.com/"],["formatblock","<div>"],["inserttext","a"]], + "<div>foo<a href=\"http://www.google.com/\">a[]</a>bar</div>", + [true,true,true], + {"createlink":[false,false,"",false,false,""],"formatblock":[false,false,"",false,false,"div"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["createlink","http://www.google.com/"],["forwarddelete",""]], + "foo[]ar", + [true,true], + {"createlink":[false,false,"",false,false,""],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]bar", + [["createlink","http://www.google.com/"],["forwarddelete",""],["inserttext","a"]], + "foo<a href=\"http://www.google.com/\"><font color=\"#000000\">a[]</font></a>ar", + [true,true,true], + {"createlink":[false,false,"",false,false,""],"forwarddelete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["createlink","http://www.google.com/"],["indent",""]], + "<blockquote>foo[]bar</blockquote>", + [true,true], + {"createlink":[false,false,"",false,false,""],"indent":[false,false,"",false,false,""]}], +["foo[]bar", + [["createlink","http://www.google.com/"],["indent",""],["inserttext","a"]], + "<blockquote>foo<a href=\"http://www.google.com/\">a[]</a>bar</blockquote>", + [true,true,true], + {"createlink":[false,false,"",false,false,""],"indent":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["createlink","http://www.google.com/"],["inserthorizontalrule",""]], + "foo<hr>{}bar", + [true,true], + {"createlink":[false,false,"",false,false,""],"inserthorizontalrule":[false,false,"",false,false,""]}], +["foo[]bar", + [["createlink","http://www.google.com/"],["inserthorizontalrule",""],["inserttext","a"]], + "foo<hr><a href=\"http://www.google.com/\">a[]</a>bar", + [true,true,true], + {"createlink":[false,false,"",false,false,""],"inserthorizontalrule":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["createlink","http://www.google.com/"],["inserthtml","ab<b>c</b>d"]], + "fooab<b>c</b>d{}bar", + [true,true], + {"createlink":[false,false,"",false,false,""],"inserthtml":[false,false,"",false,false,""]}], +["foo[]bar", + [["createlink","http://www.google.com/"],["inserthtml","ab<b>c</b>d"],["inserttext","a"]], + "fooab<b>c</b>d<a href=\"http://www.google.com/\">a[]</a>bar", + [true,true,true], + {"createlink":[false,false,"",false,false,""],"inserthtml":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["createlink","http://www.google.com/"],["insertimage","/img/lion.svg"]], + "foo<img src=\"/img/lion.svg\">{}bar", + [true,true], + {"createlink":[false,false,"",false,false,""],"insertimage":[false,false,"",false,false,""]}], +["foo[]bar", + [["createlink","http://www.google.com/"],["insertimage","/img/lion.svg"],["inserttext","a"]], + "foo<img src=\"/img/lion.svg\"><a href=\"http://www.google.com/\">a[]</a>bar", + [true,true,true], + {"createlink":[false,false,"",false,false,""],"insertimage":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["createlink","http://www.google.com/"],["insertlinebreak",""]], + "foo<br>{}bar", + [true,true], + {"createlink":[false,false,"",false,false,""],"insertlinebreak":[false,false,"",false,false,""]}], +["foo[]bar", + [["createlink","http://www.google.com/"],["insertlinebreak",""],["inserttext","a"]], + "foo<br><a href=\"http://www.google.com/\">a[]</a>bar", + [true,true,true], + {"createlink":[false,false,"",false,false,""],"insertlinebreak":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["createlink","http://www.google.com/"],["insertorderedlist",""]], + "<ol><li>foo[]bar</li></ol>", + [true,true], + {"createlink":[false,false,"",false,false,""],"insertorderedlist":[false,false,"",false,true,""]}], +["foo[]bar", + [["createlink","http://www.google.com/"],["insertorderedlist",""],["inserttext","a"]], + "<ol><li>foo<a href=\"http://www.google.com/\">a[]</a>bar</li></ol>", + [true,true,true], + {"createlink":[false,false,"",false,false,""],"insertorderedlist":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["createlink","http://www.google.com/"],["insertparagraph",""]], + "<p>foo</p><p>{}bar</p>", + [true,true], + {"createlink":[false,false,"",false,false,""],"insertparagraph":[false,false,"",false,false,""]}], +["foo[]bar", + [["createlink","http://www.google.com/"],["insertparagraph",""],["inserttext","a"]], + "<p>foo</p><p><a href=\"http://www.google.com/\">a[]</a>bar</p>", + [true,true,true], + {"createlink":[false,false,"",false,false,""],"insertparagraph":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["createlink","http://www.google.com/"],["insertunorderedlist",""]], + "<ul><li>foo[]bar</li></ul>", + [true,true], + {"createlink":[false,false,"",false,false,""],"insertunorderedlist":[false,false,"",false,true,""]}], +["foo[]bar", + [["createlink","http://www.google.com/"],["insertunorderedlist",""],["inserttext","a"]], + "<ul><li>foo<a href=\"http://www.google.com/\">a[]</a>bar</li></ul>", + [true,true,true], + {"createlink":[false,false,"",false,false,""],"insertunorderedlist":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["createlink","http://www.google.com/"],["justifycenter",""]], + "<div style=\"text-align:center\">foo[]bar</div>", + [true,true], + {"createlink":[false,false,"",false,false,""],"justifycenter":[false,false,"left",false,true,"center"]}], +["foo[]bar", + [["createlink","http://www.google.com/"],["justifycenter",""],["inserttext","a"]], + "<div style=\"text-align:center\">foo<a href=\"http://www.google.com/\">a[]</a>bar</div>", + [true,true,true], + {"createlink":[false,false,"",false,false,""],"justifycenter":[false,false,"left",false,true,"center"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["createlink","http://www.google.com/"],["justifyfull",""]], + "<div style=\"text-align:justify\">foo[]bar</div>", + [true,true], + {"createlink":[false,false,"",false,false,""],"justifyfull":[false,false,"left",false,true,"justify"]}], +["foo[]bar", + [["createlink","http://www.google.com/"],["justifyfull",""],["inserttext","a"]], + "<div style=\"text-align:justify\">foo<a href=\"http://www.google.com/\">a[]</a>bar</div>", + [true,true,true], + {"createlink":[false,false,"",false,false,""],"justifyfull":[false,false,"left",false,true,"justify"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["createlink","http://www.google.com/"],["justifyleft",""]], + "foo[]bar", + [true,true], + {"createlink":[false,false,"",false,false,""],"justifyleft":[false,true,"left",false,true,"left"]}], +["foo[]bar", + [["createlink","http://www.google.com/"],["justifyleft",""],["inserttext","a"]], + "foo<a href=\"http://www.google.com/\">a[]</a>bar", + [true,true,true], + {"createlink":[false,false,"",false,false,""],"justifyleft":[false,true,"left",false,true,"left"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["createlink","http://www.google.com/"],["justifyright",""]], + "<div style=\"text-align:right\">foo[]bar</div>", + [true,true], + {"createlink":[false,false,"",false,false,""],"justifyright":[false,false,"left",false,true,"right"]}], +["foo[]bar", + [["createlink","http://www.google.com/"],["justifyright",""],["inserttext","a"]], + "<div style=\"text-align:right\">foo<a href=\"http://www.google.com/\">a[]</a>bar</div>", + [true,true,true], + {"createlink":[false,false,"",false,false,""],"justifyright":[false,false,"left",false,true,"right"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["createlink","http://www.google.com/"],["outdent",""]], + "foo[]bar", + [true,true], + {"createlink":[false,false,"",false,false,""],"outdent":[false,false,"",false,false,""]}], +["foo[]bar", + [["createlink","http://www.google.com/"],["outdent",""],["inserttext","a"]], + "foo<a href=\"http://www.google.com/\">a[]</a>bar", + [true,true,true], + {"createlink":[false,false,"",false,false,""],"outdent":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontname","sans-serif"],["inserttext","a"]], + "foo<font face=\"sans-serif\">a[]</font>bar", + [true,true], + {"fontname":[false,false,"serif",false,false,"sans-serif"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontname","sans-serif"],["delete",""]], + "fo[]bar", + [true,true], + {"fontname":[false,false,"serif",false,false,"sans-serif"],"delete":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontname","sans-serif"],["delete",""],["inserttext","a"]], + "fo<font face=\"sans-serif\">a[]</font>bar", + [true,true,true], + {"fontname":[false,false,"serif",false,false,"sans-serif"],"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontname","sans-serif"],["formatblock","<div>"]], + "<div>foo[]bar</div>", + [true,true], + {"fontname":[false,false,"serif",false,false,"sans-serif"],"formatblock":[false,false,"",false,false,"div"]}], +["foo[]bar", + [["fontname","sans-serif"],["formatblock","<div>"],["inserttext","a"]], + "<div>foo<font face=\"sans-serif\">a[]</font>bar</div>", + [true,true,true], + {"fontname":[false,false,"serif",false,false,"sans-serif"],"formatblock":[false,false,"",false,false,"div"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontname","sans-serif"],["forwarddelete",""]], + "foo[]ar", + [true,true], + {"fontname":[false,false,"serif",false,false,"sans-serif"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontname","sans-serif"],["forwarddelete",""],["inserttext","a"]], + "foo<font face=\"sans-serif\">a[]</font>ar", + [true,true,true], + {"fontname":[false,false,"serif",false,false,"sans-serif"],"forwarddelete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontname","sans-serif"],["indent",""]], + "<blockquote>foo[]bar</blockquote>", + [true,true], + {"fontname":[false,false,"serif",false,false,"sans-serif"],"indent":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontname","sans-serif"],["indent",""],["inserttext","a"]], + "<blockquote>foo<font face=\"sans-serif\">a[]</font>bar</blockquote>", + [true,true,true], + {"fontname":[false,false,"serif",false,false,"sans-serif"],"indent":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontname","sans-serif"],["inserthorizontalrule",""]], + "foo<hr>{}bar", + [true,true], + {"fontname":[false,false,"serif",false,false,"sans-serif"],"inserthorizontalrule":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontname","sans-serif"],["inserthorizontalrule",""],["inserttext","a"]], + "foo<hr><font face=\"sans-serif\">a[]</font>bar", + [true,true,true], + {"fontname":[false,false,"serif",false,false,"sans-serif"],"inserthorizontalrule":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontname","sans-serif"],["inserthtml","ab<b>c</b>d"]], + "fooab<b>c</b>d{}bar", + [true,true], + {"fontname":[false,false,"serif",false,false,"sans-serif"],"inserthtml":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontname","sans-serif"],["inserthtml","ab<b>c</b>d"],["inserttext","a"]], + "fooab<b>c</b>d<font face=\"sans-serif\">a[]</font>bar", + [true,true,true], + {"fontname":[false,false,"serif",false,false,"sans-serif"],"inserthtml":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontname","sans-serif"],["insertimage","/img/lion.svg"]], + "foo<img src=\"/img/lion.svg\">{}bar", + [true,true], + {"fontname":[false,false,"serif",false,false,"sans-serif"],"insertimage":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontname","sans-serif"],["insertimage","/img/lion.svg"],["inserttext","a"]], + "foo<img src=\"/img/lion.svg\"><font face=\"sans-serif\">a[]</font>bar", + [true,true,true], + {"fontname":[false,false,"serif",false,false,"sans-serif"],"insertimage":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontname","sans-serif"],["insertlinebreak",""]], + "foo<br>{}bar", + [true,true], + {"fontname":[false,false,"serif",false,false,"sans-serif"],"insertlinebreak":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontname","sans-serif"],["insertlinebreak",""],["inserttext","a"]], + "foo<br><font face=\"sans-serif\">a[]</font>bar", + [true,true,true], + {"fontname":[false,false,"serif",false,false,"sans-serif"],"insertlinebreak":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontname","sans-serif"],["insertorderedlist",""]], + "<ol><li>foo[]bar</li></ol>", + [true,true], + {"fontname":[false,false,"serif",false,false,"sans-serif"],"insertorderedlist":[false,false,"",false,true,""]}], +["foo[]bar", + [["fontname","sans-serif"],["insertorderedlist",""],["inserttext","a"]], + "<ol><li>foo<font face=\"sans-serif\">a[]</font>bar</li></ol>", + [true,true,true], + {"fontname":[false,false,"serif",false,false,"sans-serif"],"insertorderedlist":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontname","sans-serif"],["insertparagraph",""]], + "<p>foo</p><p>{}bar</p>", + [true,true], + {"fontname":[false,false,"serif",false,false,"sans-serif"],"insertparagraph":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontname","sans-serif"],["insertparagraph",""],["inserttext","a"]], + "<p>foo</p><p><font face=\"sans-serif\">a[]</font>bar</p>", + [true,true,true], + {"fontname":[false,false,"serif",false,false,"sans-serif"],"insertparagraph":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontname","sans-serif"],["insertunorderedlist",""]], + "<ul><li>foo[]bar</li></ul>", + [true,true], + {"fontname":[false,false,"serif",false,false,"sans-serif"],"insertunorderedlist":[false,false,"",false,true,""]}], +["foo[]bar", + [["fontname","sans-serif"],["insertunorderedlist",""],["inserttext","a"]], + "<ul><li>foo<font face=\"sans-serif\">a[]</font>bar</li></ul>", + [true,true,true], + {"fontname":[false,false,"serif",false,false,"sans-serif"],"insertunorderedlist":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontname","sans-serif"],["justifycenter",""]], + "<div style=\"text-align:center\">foo[]bar</div>", + [true,true], + {"fontname":[false,false,"serif",false,false,"sans-serif"],"justifycenter":[false,false,"left",false,true,"center"]}], +["foo[]bar", + [["fontname","sans-serif"],["justifycenter",""],["inserttext","a"]], + "<div style=\"text-align:center\">foo<font face=\"sans-serif\">a[]</font>bar</div>", + [true,true,true], + {"fontname":[false,false,"serif",false,false,"sans-serif"],"justifycenter":[false,false,"left",false,true,"center"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontname","sans-serif"],["justifyfull",""]], + "<div style=\"text-align:justify\">foo[]bar</div>", + [true,true], + {"fontname":[false,false,"serif",false,false,"sans-serif"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["foo[]bar", + [["fontname","sans-serif"],["justifyfull",""],["inserttext","a"]], + "<div style=\"text-align:justify\">foo<font face=\"sans-serif\">a[]</font>bar</div>", + [true,true,true], + {"fontname":[false,false,"serif",false,false,"sans-serif"],"justifyfull":[false,false,"left",false,true,"justify"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontname","sans-serif"],["justifyleft",""]], + "foo[]bar", + [true,true], + {"fontname":[false,false,"serif",false,false,"sans-serif"],"justifyleft":[false,true,"left",false,true,"left"]}], +["foo[]bar", + [["fontname","sans-serif"],["justifyleft",""],["inserttext","a"]], + "foo<font face=\"sans-serif\">a[]</font>bar", + [true,true,true], + {"fontname":[false,false,"serif",false,false,"sans-serif"],"justifyleft":[false,true,"left",false,true,"left"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontname","sans-serif"],["justifyright",""]], + "<div style=\"text-align:right\">foo[]bar</div>", + [true,true], + {"fontname":[false,false,"serif",false,false,"sans-serif"],"justifyright":[false,false,"left",false,true,"right"]}], +["foo[]bar", + [["fontname","sans-serif"],["justifyright",""],["inserttext","a"]], + "<div style=\"text-align:right\">foo<font face=\"sans-serif\">a[]</font>bar</div>", + [true,true,true], + {"fontname":[false,false,"serif",false,false,"sans-serif"],"justifyright":[false,false,"left",false,true,"right"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontname","sans-serif"],["outdent",""]], + "foo[]bar", + [true,true], + {"fontname":[false,false,"serif",false,false,"sans-serif"],"outdent":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontname","sans-serif"],["outdent",""],["inserttext","a"]], + "foo<font face=\"sans-serif\">a[]</font>bar", + [true,true,true], + {"fontname":[false,false,"serif",false,false,"sans-serif"],"outdent":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontsize","4"],["inserttext","a"]], + "foo<font size=\"4\">a[]</font>bar", + [true,true], + {"fontsize":[false,false,"3",false,false,"4"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontsize","4"],["delete",""]], + "fo[]bar", + [true,true], + {"fontsize":[false,false,"3",false,false,"4"],"delete":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontsize","4"],["delete",""],["inserttext","a"]], + "fo<font size=\"4\">a[]</font>bar", + [true,true,true], + {"fontsize":[false,false,"3",false,false,"4"],"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontsize","4"],["formatblock","<div>"]], + "<div>foo[]bar</div>", + [true,true], + {"fontsize":[false,false,"3",false,false,"4"],"formatblock":[false,false,"",false,false,"div"]}], +["foo[]bar", + [["fontsize","4"],["formatblock","<div>"],["inserttext","a"]], + "<div>foo<font size=\"4\">a[]</font>bar</div>", + [true,true,true], + {"fontsize":[false,false,"3",false,false,"4"],"formatblock":[false,false,"",false,false,"div"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontsize","4"],["forwarddelete",""]], + "foo[]ar", + [true,true], + {"fontsize":[false,false,"3",false,false,"4"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontsize","4"],["forwarddelete",""],["inserttext","a"]], + "foo<font size=\"4\">a[]</font>ar", + [true,true,true], + {"fontsize":[false,false,"3",false,false,"4"],"forwarddelete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontsize","4"],["indent",""]], + "<blockquote>foo[]bar</blockquote>", + [true,true], + {"fontsize":[false,false,"3",false,false,"4"],"indent":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontsize","4"],["indent",""],["inserttext","a"]], + "<blockquote>foo<font size=\"4\">a[]</font>bar</blockquote>", + [true,true,true], + {"fontsize":[false,false,"3",false,false,"4"],"indent":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontsize","4"],["inserthorizontalrule",""]], + "foo<hr>{}bar", + [true,true], + {"fontsize":[false,false,"3",false,false,"4"],"inserthorizontalrule":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontsize","4"],["inserthorizontalrule",""],["inserttext","a"]], + "foo<hr><font size=\"4\">a[]</font>bar", + [true,true,true], + {"fontsize":[false,false,"3",false,false,"4"],"inserthorizontalrule":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontsize","4"],["inserthtml","ab<b>c</b>d"]], + "fooab<b>c</b>d{}bar", + [true,true], + {"fontsize":[false,false,"3",false,false,"4"],"inserthtml":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontsize","4"],["inserthtml","ab<b>c</b>d"],["inserttext","a"]], + "fooab<b>c</b>d<font size=\"4\">a[]</font>bar", + [true,true,true], + {"fontsize":[false,false,"3",false,false,"4"],"inserthtml":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontsize","4"],["insertimage","/img/lion.svg"]], + "foo<img src=\"/img/lion.svg\">{}bar", + [true,true], + {"fontsize":[false,false,"3",false,false,"4"],"insertimage":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontsize","4"],["insertimage","/img/lion.svg"],["inserttext","a"]], + "foo<img src=\"/img/lion.svg\"><font size=\"4\">a[]</font>bar", + [true,true,true], + {"fontsize":[false,false,"3",false,false,"4"],"insertimage":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontsize","4"],["insertlinebreak",""]], + "foo<br>{}bar", + [true,true], + {"fontsize":[false,false,"3",false,false,"4"],"insertlinebreak":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontsize","4"],["insertlinebreak",""],["inserttext","a"]], + "foo<br><font size=\"4\">a[]</font>bar", + [true,true,true], + {"fontsize":[false,false,"3",false,false,"4"],"insertlinebreak":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontsize","4"],["insertorderedlist",""]], + "<ol><li>foo[]bar</li></ol>", + [true,true], + {"fontsize":[false,false,"3",false,false,"4"],"insertorderedlist":[false,false,"",false,true,""]}], +["foo[]bar", + [["fontsize","4"],["insertorderedlist",""],["inserttext","a"]], + "<ol><li>foo<font size=\"4\">a[]</font>bar</li></ol>", + [true,true,true], + {"fontsize":[false,false,"3",false,false,"4"],"insertorderedlist":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontsize","4"],["insertparagraph",""]], + "<p>foo</p><p>{}bar</p>", + [true,true], + {"fontsize":[false,false,"3",false,false,"4"],"insertparagraph":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontsize","4"],["insertparagraph",""],["inserttext","a"]], + "<p>foo</p><p><font size=\"4\">a[]</font>bar</p>", + [true,true,true], + {"fontsize":[false,false,"3",false,false,"4"],"insertparagraph":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontsize","4"],["insertunorderedlist",""]], + "<ul><li>foo[]bar</li></ul>", + [true,true], + {"fontsize":[false,false,"3",false,false,"4"],"insertunorderedlist":[false,false,"",false,true,""]}], +["foo[]bar", + [["fontsize","4"],["insertunorderedlist",""],["inserttext","a"]], + "<ul><li>foo<font size=\"4\">a[]</font>bar</li></ul>", + [true,true,true], + {"fontsize":[false,false,"3",false,false,"4"],"insertunorderedlist":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontsize","4"],["justifycenter",""]], + "<div style=\"text-align:center\">foo[]bar</div>", + [true,true], + {"fontsize":[false,false,"3",false,false,"4"],"justifycenter":[false,false,"left",false,true,"center"]}], +["foo[]bar", + [["fontsize","4"],["justifycenter",""],["inserttext","a"]], + "<div style=\"text-align:center\">foo<font size=\"4\">a[]</font>bar</div>", + [true,true,true], + {"fontsize":[false,false,"3",false,false,"4"],"justifycenter":[false,false,"left",false,true,"center"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontsize","4"],["justifyfull",""]], + "<div style=\"text-align:justify\">foo[]bar</div>", + [true,true], + {"fontsize":[false,false,"3",false,false,"4"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["foo[]bar", + [["fontsize","4"],["justifyfull",""],["inserttext","a"]], + "<div style=\"text-align:justify\">foo<font size=\"4\">a[]</font>bar</div>", + [true,true,true], + {"fontsize":[false,false,"3",false,false,"4"],"justifyfull":[false,false,"left",false,true,"justify"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontsize","4"],["justifyleft",""]], + "foo[]bar", + [true,true], + {"fontsize":[false,false,"3",false,false,"4"],"justifyleft":[false,true,"left",false,true,"left"]}], +["foo[]bar", + [["fontsize","4"],["justifyleft",""],["inserttext","a"]], + "foo<font size=\"4\">a[]</font>bar", + [true,true,true], + {"fontsize":[false,false,"3",false,false,"4"],"justifyleft":[false,true,"left",false,true,"left"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontsize","4"],["justifyright",""]], + "<div style=\"text-align:right\">foo[]bar</div>", + [true,true], + {"fontsize":[false,false,"3",false,false,"4"],"justifyright":[false,false,"left",false,true,"right"]}], +["foo[]bar", + [["fontsize","4"],["justifyright",""],["inserttext","a"]], + "<div style=\"text-align:right\">foo<font size=\"4\">a[]</font>bar</div>", + [true,true,true], + {"fontsize":[false,false,"3",false,false,"4"],"justifyright":[false,false,"left",false,true,"right"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontsize","4"],["outdent",""]], + "foo[]bar", + [true,true], + {"fontsize":[false,false,"3",false,false,"4"],"outdent":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontsize","4"],["outdent",""],["inserttext","a"]], + "foo<font size=\"4\">a[]</font>bar", + [true,true,true], + {"fontsize":[false,false,"3",false,false,"4"],"outdent":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["forecolor","#0000FF"],["inserttext","a"]], + "foo<font color=\"#0000ff\">a[]</font>bar", + [true,true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["forecolor","#0000FF"],["delete",""]], + "fo[]bar", + [true,true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"],"delete":[false,false,"",false,false,""]}], +["foo[]bar", + [["forecolor","#0000FF"],["delete",""],["inserttext","a"]], + "fo<font color=\"#0000ff\">a[]</font>bar", + [true,true,true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"],"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["forecolor","#0000FF"],["formatblock","<div>"]], + "<div>foo[]bar</div>", + [true,true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"],"formatblock":[false,false,"",false,false,"div"]}], +["foo[]bar", + [["forecolor","#0000FF"],["formatblock","<div>"],["inserttext","a"]], + "<div>foo<font color=\"#0000ff\">a[]</font>bar</div>", + [true,true,true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"],"formatblock":[false,false,"",false,false,"div"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["forecolor","#0000FF"],["forwarddelete",""]], + "foo[]ar", + [true,true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]bar", + [["forecolor","#0000FF"],["forwarddelete",""],["inserttext","a"]], + "foo<font color=\"#0000ff\">a[]</font>ar", + [true,true,true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"],"forwarddelete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["forecolor","#0000FF"],["indent",""]], + "<blockquote>foo[]bar</blockquote>", + [true,true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"],"indent":[false,false,"",false,false,""]}], +["foo[]bar", + [["forecolor","#0000FF"],["indent",""],["inserttext","a"]], + "<blockquote>foo<font color=\"#0000ff\">a[]</font>bar</blockquote>", + [true,true,true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"],"indent":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["forecolor","#0000FF"],["inserthorizontalrule",""]], + "foo<hr>{}bar", + [true,true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"],"inserthorizontalrule":[false,false,"",false,false,""]}], +["foo[]bar", + [["forecolor","#0000FF"],["inserthorizontalrule",""],["inserttext","a"]], + "foo<hr><font color=\"#0000ff\">a[]</font>bar", + [true,true,true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"],"inserthorizontalrule":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["forecolor","#0000FF"],["inserthtml","ab<b>c</b>d"]], + "fooab<b>c</b>d{}bar", + [true,true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"],"inserthtml":[false,false,"",false,false,""]}], +["foo[]bar", + [["forecolor","#0000FF"],["inserthtml","ab<b>c</b>d"],["inserttext","a"]], + "fooab<b>c</b>d<font color=\"#0000ff\">a[]</font>bar", + [true,true,true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"],"inserthtml":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["forecolor","#0000FF"],["insertimage","/img/lion.svg"]], + "foo<img src=\"/img/lion.svg\">{}bar", + [true,true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"],"insertimage":[false,false,"",false,false,""]}], +["foo[]bar", + [["forecolor","#0000FF"],["insertimage","/img/lion.svg"],["inserttext","a"]], + "foo<img src=\"/img/lion.svg\"><font color=\"#0000ff\">a[]</font>bar", + [true,true,true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"],"insertimage":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["forecolor","#0000FF"],["insertlinebreak",""]], + "foo<br>{}bar", + [true,true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"],"insertlinebreak":[false,false,"",false,false,""]}], +["foo[]bar", + [["forecolor","#0000FF"],["insertlinebreak",""],["inserttext","a"]], + "foo<br><font color=\"#0000ff\">a[]</font>bar", + [true,true,true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"],"insertlinebreak":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["forecolor","#0000FF"],["insertorderedlist",""]], + "<ol><li>foo[]bar</li></ol>", + [true,true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"],"insertorderedlist":[false,false,"",false,true,""]}], +["foo[]bar", + [["forecolor","#0000FF"],["insertorderedlist",""],["inserttext","a"]], + "<ol><li>foo<font color=\"#0000ff\">a[]</font>bar</li></ol>", + [true,true,true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"],"insertorderedlist":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["forecolor","#0000FF"],["insertparagraph",""]], + "<p>foo</p><p>{}bar</p>", + [true,true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"],"insertparagraph":[false,false,"",false,false,""]}], +["foo[]bar", + [["forecolor","#0000FF"],["insertparagraph",""],["inserttext","a"]], + "<p>foo</p><p><font color=\"#0000ff\">a[]</font>bar</p>", + [true,true,true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"],"insertparagraph":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["forecolor","#0000FF"],["insertunorderedlist",""]], + "<ul><li>foo[]bar</li></ul>", + [true,true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"],"insertunorderedlist":[false,false,"",false,true,""]}], +["foo[]bar", + [["forecolor","#0000FF"],["insertunorderedlist",""],["inserttext","a"]], + "<ul><li>foo<font color=\"#0000ff\">a[]</font>bar</li></ul>", + [true,true,true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"],"insertunorderedlist":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["forecolor","#0000FF"],["justifycenter",""]], + "<div style=\"text-align:center\">foo[]bar</div>", + [true,true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"],"justifycenter":[false,false,"left",false,true,"center"]}], +["foo[]bar", + [["forecolor","#0000FF"],["justifycenter",""],["inserttext","a"]], + "<div style=\"text-align:center\">foo<font color=\"#0000ff\">a[]</font>bar</div>", + [true,true,true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"],"justifycenter":[false,false,"left",false,true,"center"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["forecolor","#0000FF"],["justifyfull",""]], + "<div style=\"text-align:justify\">foo[]bar</div>", + [true,true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["foo[]bar", + [["forecolor","#0000FF"],["justifyfull",""],["inserttext","a"]], + "<div style=\"text-align:justify\">foo<font color=\"#0000ff\">a[]</font>bar</div>", + [true,true,true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"],"justifyfull":[false,false,"left",false,true,"justify"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["forecolor","#0000FF"],["justifyleft",""]], + "foo[]bar", + [true,true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"],"justifyleft":[false,true,"left",false,true,"left"]}], +["foo[]bar", + [["forecolor","#0000FF"],["justifyleft",""],["inserttext","a"]], + "foo<font color=\"#0000ff\">a[]</font>bar", + [true,true,true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"],"justifyleft":[false,true,"left",false,true,"left"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["forecolor","#0000FF"],["justifyright",""]], + "<div style=\"text-align:right\">foo[]bar</div>", + [true,true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"],"justifyright":[false,false,"left",false,true,"right"]}], +["foo[]bar", + [["forecolor","#0000FF"],["justifyright",""],["inserttext","a"]], + "<div style=\"text-align:right\">foo<font color=\"#0000ff\">a[]</font>bar</div>", + [true,true,true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"],"justifyright":[false,false,"left",false,true,"right"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["forecolor","#0000FF"],["outdent",""]], + "foo[]bar", + [true,true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"],"outdent":[false,false,"",false,false,""]}], +["foo[]bar", + [["forecolor","#0000FF"],["outdent",""],["inserttext","a"]], + "foo<font color=\"#0000ff\">a[]</font>bar", + [true,true,true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"],"outdent":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["hilitecolor","#00FFFF"],["inserttext","a"]], + "foo<span style=\"background-color:rgb(0, 255, 255)\">a[]</span>bar", + [true,true], + {"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["hilitecolor","#00FFFF"],["delete",""]], + "fo[]bar", + [true,true], + {"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"delete":[false,false,"",false,false,""]}], +["foo[]bar", + [["hilitecolor","#00FFFF"],["delete",""],["inserttext","a"]], + "fo<span style=\"background-color:rgb(0, 255, 255)\">a[]</span>bar", + [true,true,true], + {"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["hilitecolor","#00FFFF"],["formatblock","<div>"]], + "<div>foo[]bar</div>", + [true,true], + {"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"formatblock":[false,false,"",false,false,"div"]}], +["foo[]bar", + [["hilitecolor","#00FFFF"],["formatblock","<div>"],["inserttext","a"]], + "<div>foo<span style=\"background-color:rgb(0, 255, 255)\">a[]</span>bar</div>", + [true,true,true], + {"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"formatblock":[false,false,"",false,false,"div"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["hilitecolor","#00FFFF"],["forwarddelete",""]], + "foo[]ar", + [true,true], + {"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"forwarddelete":[false,false,"",false,false,""]}], +["foo[]bar", + [["hilitecolor","#00FFFF"],["forwarddelete",""],["inserttext","a"]], + "foo<span style=\"background-color:rgb(0, 255, 255)\">a[]</span>ar", + [true,true,true], + {"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"forwarddelete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["hilitecolor","#00FFFF"],["indent",""]], + "<blockquote>foo[]bar</blockquote>", + [true,true], + {"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"indent":[false,false,"",false,false,""]}], +["foo[]bar", + [["hilitecolor","#00FFFF"],["indent",""],["inserttext","a"]], + "<blockquote>foo<span style=\"background-color:rgb(0, 255, 255)\">a[]</span>bar</blockquote>", + [true,true,true], + {"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"indent":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["hilitecolor","#00FFFF"],["inserthorizontalrule",""]], + "foo<hr>{}bar", + [true,true], + {"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"inserthorizontalrule":[false,false,"",false,false,""]}], +["foo[]bar", + [["hilitecolor","#00FFFF"],["inserthorizontalrule",""],["inserttext","a"]], + "foo<hr><span style=\"background-color:rgb(0, 255, 255)\">a[]</span>bar", + [true,true,true], + {"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"inserthorizontalrule":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["hilitecolor","#00FFFF"],["inserthtml","ab<b>c</b>d"]], + "fooab<b>c</b>d{}bar", + [true,true], + {"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"inserthtml":[false,false,"",false,false,""]}], +["foo[]bar", + [["hilitecolor","#00FFFF"],["inserthtml","ab<b>c</b>d"],["inserttext","a"]], + "fooab<b>c</b>d<span style=\"background-color:rgb(0, 255, 255)\">a[]</span>bar", + [true,true,true], + {"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"inserthtml":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["hilitecolor","#00FFFF"],["insertimage","/img/lion.svg"]], + "foo<img src=\"/img/lion.svg\">{}bar", + [true,true], + {"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"insertimage":[false,false,"",false,false,""]}], +["foo[]bar", + [["hilitecolor","#00FFFF"],["insertimage","/img/lion.svg"],["inserttext","a"]], + "foo<img src=\"/img/lion.svg\"><span style=\"background-color:rgb(0, 255, 255)\">a[]</span>bar", + [true,true,true], + {"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"insertimage":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["hilitecolor","#00FFFF"],["insertlinebreak",""]], + "foo<br>{}bar", + [true,true], + {"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"insertlinebreak":[false,false,"",false,false,""]}], +["foo[]bar", + [["hilitecolor","#00FFFF"],["insertlinebreak",""],["inserttext","a"]], + "foo<br><span style=\"background-color:rgb(0, 255, 255)\">a[]</span>bar", + [true,true,true], + {"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"insertlinebreak":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["hilitecolor","#00FFFF"],["insertorderedlist",""]], + "<ol><li>foo[]bar</li></ol>", + [true,true], + {"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"insertorderedlist":[false,false,"",false,true,""]}], +["foo[]bar", + [["hilitecolor","#00FFFF"],["insertorderedlist",""],["inserttext","a"]], + "<ol><li>foo<span style=\"background-color:rgb(0, 255, 255)\">a[]</span>bar</li></ol>", + [true,true,true], + {"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"insertorderedlist":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["hilitecolor","#00FFFF"],["insertparagraph",""]], + "<p>foo</p><p>{}bar</p>", + [true,true], + {"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"insertparagraph":[false,false,"",false,false,""]}], +["foo[]bar", + [["hilitecolor","#00FFFF"],["insertparagraph",""],["inserttext","a"]], + "<p>foo</p><p><span style=\"background-color:rgb(0, 255, 255)\">a[]</span>bar</p>", + [true,true,true], + {"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"insertparagraph":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["hilitecolor","#00FFFF"],["insertunorderedlist",""]], + "<ul><li>foo[]bar</li></ul>", + [true,true], + {"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"insertunorderedlist":[false,false,"",false,true,""]}], +["foo[]bar", + [["hilitecolor","#00FFFF"],["insertunorderedlist",""],["inserttext","a"]], + "<ul><li>foo<span style=\"background-color:rgb(0, 255, 255)\">a[]</span>bar</li></ul>", + [true,true,true], + {"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"insertunorderedlist":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["hilitecolor","#00FFFF"],["justifycenter",""]], + "<div style=\"text-align:center\">foo[]bar</div>", + [true,true], + {"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"justifycenter":[false,false,"left",false,true,"center"]}], +["foo[]bar", + [["hilitecolor","#00FFFF"],["justifycenter",""],["inserttext","a"]], + "<div style=\"text-align:center\">foo<span style=\"background-color:rgb(0, 255, 255)\">a[]</span>bar</div>", + [true,true,true], + {"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"justifycenter":[false,false,"left",false,true,"center"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["hilitecolor","#00FFFF"],["justifyfull",""]], + "<div style=\"text-align:justify\">foo[]bar</div>", + [true,true], + {"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"justifyfull":[false,false,"left",false,true,"justify"]}], +["foo[]bar", + [["hilitecolor","#00FFFF"],["justifyfull",""],["inserttext","a"]], + "<div style=\"text-align:justify\">foo<span style=\"background-color:rgb(0, 255, 255)\">a[]</span>bar</div>", + [true,true,true], + {"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"justifyfull":[false,false,"left",false,true,"justify"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["hilitecolor","#00FFFF"],["justifyleft",""]], + "foo[]bar", + [true,true], + {"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"justifyleft":[false,true,"left",false,true,"left"]}], +["foo[]bar", + [["hilitecolor","#00FFFF"],["justifyleft",""],["inserttext","a"]], + "foo<span style=\"background-color:rgb(0, 255, 255)\">a[]</span>bar", + [true,true,true], + {"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"justifyleft":[false,true,"left",false,true,"left"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["hilitecolor","#00FFFF"],["justifyright",""]], + "<div style=\"text-align:right\">foo[]bar</div>", + [true,true], + {"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"justifyright":[false,false,"left",false,true,"right"]}], +["foo[]bar", + [["hilitecolor","#00FFFF"],["justifyright",""],["inserttext","a"]], + "<div style=\"text-align:right\">foo<span style=\"background-color:rgb(0, 255, 255)\">a[]</span>bar</div>", + [true,true,true], + {"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"justifyright":[false,false,"left",false,true,"right"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["hilitecolor","#00FFFF"],["outdent",""]], + "foo[]bar", + [true,true], + {"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"outdent":[false,false,"",false,false,""]}], +["foo[]bar", + [["hilitecolor","#00FFFF"],["outdent",""],["inserttext","a"]], + "foo<span style=\"background-color:rgb(0, 255, 255)\">a[]</span>bar", + [true,true,true], + {"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"outdent":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["superscript",""],["subscript",""],["inserttext","a"]], + "foo<sub>a[]</sub>bar", + [true,true,true], + {"superscript":[false,false,"",false,false,""],"subscript":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["subscript",""],["superscript",""],["inserttext","a"]], + "foo<sup>a[]</sup>bar", + [true,true,true], + {"subscript":[false,false,"",false,false,""],"superscript":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["createlink","http://www.google.com/"],["forecolor","#0000FF"],["inserttext","a"]], + "foo<a href=\"http://www.google.com/\">a[]</a>bar", + [true,true,true], + {"createlink":[false,false,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["forecolor","#0000FF"],["createlink","http://www.google.com/"],["inserttext","a"]], + "foo<a href=\"http://www.google.com/\">a[]</a>bar", + [true,true,true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"],"createlink":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["createlink","http://www.google.com/"],["forecolor","blue"],["inserttext","a"]], + "foo<a href=\"http://www.google.com/\">a[]</a>bar", + [true,true,true], + {"createlink":[false,false,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["forecolor","blue"],["createlink","http://www.google.com/"],["inserttext","a"]], + "foo<a href=\"http://www.google.com/\">a[]</a>bar", + [true,true,true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 255)"],"createlink":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["createlink","http://www.google.com/"],["forecolor","brown"],["inserttext","a"]], + "foo<a href=\"http://www.google.com/\"><font color=\"#a52a2a\">a[]</font></a>bar", + [true,true,true], + {"createlink":[false,false,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(165, 42, 42)"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["forecolor","brown"],["createlink","http://www.google.com/"],["inserttext","a"]], + "foo<a href=\"http://www.google.com/\"><font color=\"#a52a2a\">a[]</font></a>bar", + [true,true,true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(165, 42, 42)"],"createlink":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["createlink","http://www.google.com/"],["forecolor","black"],["inserttext","a"]], + "foo<a href=\"http://www.google.com/\"><font color=\"#000000\">a[]</font></a>bar", + [true,true,true], + {"createlink":[false,false,"",false,false,""],"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 0)"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["forecolor","black"],["createlink","http://www.google.com/"],["inserttext","a"]], + "foo<a href=\"http://www.google.com/\"><font color=\"#000000\">a[]</font></a>bar", + [true,true,true], + {"forecolor":[false,false,"rgb(0, 0, 0)",false,false,"rgb(0, 0, 0)"],"createlink":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["createlink","http://www.google.com/"],["underline",""],["inserttext","a"]], + "foo<a href=\"http://www.google.com/\">a[]</a>bar", + [true,true,true], + {"createlink":[false,false,"",false,false,""],"underline":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["underline",""],["createlink","http://www.google.com/"],["inserttext","a"]], + "foo<a href=\"http://www.google.com/\">a[]</a>bar", + [true,true,true], + {"underline":[false,false,"",false,true,""],"createlink":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["createlink","http://www.google.com/"],["underline","","first application"],["underline","","second application"],["inserttext","a"]], + "foo<a href=\"http://www.google.com/\">a[]</a>bar", + [true,true,true,true], + {"createlink":[false,false,"",false,false,""],"underline":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["underline","","first application"],["underline","","second application"],["createlink","http://www.google.com/"],["inserttext","a"]], + "foo<a href=\"http://www.google.com/\">a[]</a>bar", + [true,true,true,true], + {"underline":[false,false,"",false,true,""],"createlink":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["subscript",""],["fontsize","2"],["inserttext","a"]], + "foo<sub>a[]</sub>bar", + [true,true,true], + {"subscript":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"2"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontsize","2"],["subscript",""],["inserttext","a"]], + "foo<sub>a[]</sub>bar", + [true,true,true], + {"fontsize":[false,false,"3",false,false,"2"],"subscript":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["subscript",""],["fontsize","3"],["inserttext","a"]], + "foo<font size=\"3\"><sub>a[]</sub></font>bar", // <font> should be outer-most element + [true,true,true], + {"subscript":[false,false,"",false,true,""],"fontsize":[false,false,"3",false,false,"3"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["fontsize","3"],["subscript",""],["inserttext","a"]], + "foo<font size=\"3\"><sub>a[]</sub></font>bar", // <font> should be outer-most element + [true,true,true], + {"fontsize":[false,false,"3",false,false,"3"],"subscript":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["hilitecolor","aqua"],["backcolor","tan"],["inserttext","a"]], + "foo<span style=\"background-color:rgb(210, 180, 140)\">a[]</span>bar", + [true,true,true], + {"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(210, 180, 140)"],"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(210, 180, 140)"],"inserttext":[false,false,"",false,false,""]}], +["foo[]bar", + [["backcolor","tan"],["hilitecolor","aqua"],["inserttext","a"]], + "foo<span style=\"background-color:rgb(0, 255, 255)\">a[]</span>bar", + [true,true,true], + {"backcolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"hilitecolor":[false,false,"rgba(0, 0, 0, 0)",false,false,"rgb(0, 255, 255)"],"inserttext":[false,false,"",false,false,""]}], +["foo<b>[bar]</b>baz", + [["delete",""],["inserttext","a"]], + "foo<b>a[]</b>baz", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<i>[bar]</i>baz", + [["delete",""],["inserttext","a"]], + "foo<i>a[]</i>baz", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<s>[bar]</s>baz", + [["delete",""],["inserttext","a"]], + "foo<s>a[]</s>baz", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<sub>[bar]</sub>baz", + [["delete",""],["inserttext","a"]], + "foo<sub>a[]</sub>baz", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<sup>[bar]</sup>baz", + [["delete",""],["inserttext","a"]], + "foo<sup>a[]</sup>baz", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<u>[bar]</u>baz", + [["delete",""],["inserttext","a"]], + "foo<u>a[]</u>baz", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<a href=http://www.google.com>[bar]</a>baz", + [["delete",""],["inserttext","a"]], + "foo<a href=\"http://www.google.com\">a[]</a>baz", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<font face=sans-serif>[bar]</font>baz", + [["delete",""],["inserttext","a"]], + "foo<font face=\"sans-serif\">a[]</font>baz", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<font size=4>[bar]</font>baz", + [["delete",""],["inserttext","a"]], + "foo<font size=\"4\">a[]</font>baz", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<font color=#0000FF>[bar]</font>baz", + [["delete",""],["inserttext","a"]], + "foo<font color=\"#0000ff\">a[]</font>baz", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<span style=background-color:#00FFFF>[bar]</span>baz", + [["delete",""],["inserttext","a"]], + "foo<span style=\"background-color:rgb(0, 255, 255)\">a[]</span>baz", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<a href=http://www.google.com><font color=blue>[bar]</font></a>baz", + [["delete",""],["inserttext","a"]], + "foo<a href=\"http://www.google.com\">a[]</a>baz", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<font color=blue><a href=http://www.google.com>[bar]</a></font>baz", + [["delete",""],["inserttext","a"]], + "foo<a href=\"http://www.google.com\">a[]</a>baz", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<a href=http://www.google.com><font color=brown>[bar]</font></a>baz", + [["delete",""],["inserttext","a"]], + "foo<a href=\"http://www.google.com\"><font color=\"#a52a2a\">a[]</font></a>baz", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<font color=brown><a href=http://www.google.com>[bar]</a></font>baz", + [["delete",""],["inserttext","a"]], + "foo<a href=\"http://www.google.com\">a[]</a>baz", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<a href=http://www.google.com><font color=black>[bar]</font></a>baz", + [["delete",""],["inserttext","a"]], + "foo<a href=\"http://www.google.com\"><font color=\"#000000\">a[]</font></a>baz", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<a href=http://www.google.com><u>[bar]</u></a>baz", + [["delete",""],["inserttext","a"]], + "foo<a href=\"http://www.google.com\">a[]</a>baz", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<u><a href=http://www.google.com>[bar]</a></u>baz", + [["delete",""],["inserttext","a"]], + "foo<a href=\"http://www.google.com\">a[]</a>baz", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<sub><font size=2>[bar]</font></sub>baz", + [["delete",""],["inserttext","a"]], + "foo<sub>a[]</sub>baz", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<font size=2><sub>[bar]</sub></font>baz", + [["delete",""],["inserttext","a"]], + "foo<font size=\"1\"><sub>a[]</sub></font>baz", // <font> should be outer-most element + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<sub><font size=3>[bar]</font></sub>baz", + [["delete",""],["inserttext","a"]], + "foo<font size=\"3\"><sub>a[]</sub></font>baz", // <font> should be outer-most element + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<font size=3><sub>[bar]</sub></font>baz", + [["delete",""],["inserttext","a"]], + "foo<sub>a[]</sub>baz", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<b>bar]</b>baz", + [["delete",""],["inserttext","a"]], + "a[]baz", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<i>bar]</i>baz", + [["delete",""],["inserttext","a"]], + "a[]baz", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<s>bar]</s>baz", + [["delete",""],["inserttext","a"]], + "a[]baz", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<sub>bar]</sub>baz", + [["delete",""],["inserttext","a"]], + "a[]baz", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<sup>bar]</sup>baz", + [["delete",""],["inserttext","a"]], + "a[]baz", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<u>bar]</u>baz", + [["delete",""],["inserttext","a"]], + "a[]baz", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<a href=http://www.google.com>bar]</a>baz", + [["delete",""],["inserttext","a"]], + "a[]baz", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<font face=sans-serif>bar]</font>baz", + [["delete",""],["inserttext","a"]], + "a[]baz", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<font size=4>bar]</font>baz", + [["delete",""],["inserttext","a"]], + "a[]baz", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<font color=#0000FF>bar]</font>baz", + [["delete",""],["inserttext","a"]], + "a[]baz", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<span style=background-color:#00FFFF>bar]</span>baz", + [["delete",""],["inserttext","a"]], + "a[]baz", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<a href=http://www.google.com><font color=blue>bar]</font></a>baz", + [["delete",""],["inserttext","a"]], + "a[]baz", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<font color=blue><a href=http://www.google.com>bar]</a></font>baz", + [["delete",""],["inserttext","a"]], + "a[]baz", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<a href=http://www.google.com><font color=brown>bar]</font></a>baz", + [["delete",""],["inserttext","a"]], + "a[]baz", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<font color=brown><a href=http://www.google.com>bar]</a></font>baz", + [["delete",""],["inserttext","a"]], + "a[]baz", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<a href=http://www.google.com><font color=black>bar]</font></a>baz", + [["delete",""],["inserttext","a"]], + "a[]baz", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<a href=http://www.google.com><u>bar]</u></a>baz", + [["delete",""],["inserttext","a"]], + "a[]baz", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<u><a href=http://www.google.com>bar]</a></u>baz", + [["delete",""],["inserttext","a"]], + "a[]baz", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<sub><font size=2>bar]</font></sub>baz", + [["delete",""],["inserttext","a"]], + "a[]baz", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<font size=2><sub>bar]</sub></font>baz", + [["delete",""],["inserttext","a"]], + "a[]baz", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<sub><font size=3>bar]</font></sub>baz", + [["delete",""],["inserttext","a"]], + "a[]baz", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["[foo<font size=3><sub>bar]</sub></font>baz", + [["delete",""],["inserttext","a"]], + "a[]baz", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<b>[bar</b>baz]", + [["delete",""],["inserttext","a"]], + "foo<b>a[]</b>", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<i>[bar</i>baz]", + [["delete",""],["inserttext","a"]], + "foo<i>a[]</i>", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<s>[bar</s>baz]", + [["delete",""],["inserttext","a"]], + "foo<s>a[]</s>", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<sub>[bar</sub>baz]", + [["delete",""],["inserttext","a"]], + "foo<sub>a[]</sub>", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<sup>[bar</sup>baz]", + [["delete",""],["inserttext","a"]], + "foo<sup>a[]</sup>", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<u>[bar</u>baz]", + [["delete",""],["inserttext","a"]], + "foo<u>a[]</u>", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<a href=http://www.google.com>[bar</a>baz]", + [["delete",""],["inserttext","a"]], + "foo<a href=\"http://www.google.com\">a[]</a>", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<font face=sans-serif>[bar</font>baz]", + [["delete",""],["inserttext","a"]], + "foo<font face=\"sans-serif\">a[]</font>", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<font size=4>[bar</font>baz]", + [["delete",""],["inserttext","a"]], + "foo<font size=\"4\">a[]</font>", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<font color=#0000FF>[bar</font>baz]", + [["delete",""],["inserttext","a"]], + "foo<font color=\"#0000ff\">a[]</font>", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<span style=background-color:#00FFFF>[bar</span>baz]", + [["delete",""],["inserttext","a"]], + "foo<span style=\"background-color:rgb(0, 255, 255)\">a[]</span>", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<a href=http://www.google.com><font color=blue>[bar</font></a>baz]", + [["delete",""],["inserttext","a"]], + "foo<a href=\"http://www.google.com\">a[]</a>", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<font color=blue><a href=http://www.google.com>[bar</a></font>baz]", + [["delete",""],["inserttext","a"]], + "foo<a href=\"http://www.google.com\">a[]</a>", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<a href=http://www.google.com><font color=brown>[bar</font></a>baz]", + [["delete",""],["inserttext","a"]], + "foo<a href=\"http://www.google.com\"><font color=\"#a52a2a\">a[]</font></a>", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<font color=brown><a href=http://www.google.com>[bar</a></font>baz]", + [["delete",""],["inserttext","a"]], + "foo<a href=\"http://www.google.com\">a[]</a>", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<a href=http://www.google.com><font color=black>[bar</font></a>baz]", + [["delete",""],["inserttext","a"]], + "foo<a href=\"http://www.google.com\"><font color=\"#000000\">a[]</font></a>", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<a href=http://www.google.com><u>[bar</u></a>baz]", + [["delete",""],["inserttext","a"]], + "foo<a href=\"http://www.google.com\">a[]</a>", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<u><a href=http://www.google.com>[bar</a></u>baz]", + [["delete",""],["inserttext","a"]], + "foo<a href=\"http://www.google.com\">a[]</a>", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<sub><font size=2>[bar</font></sub>baz]", + [["delete",""],["inserttext","a"]], + "foo<sub>a[]</sub>", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<font size=2><sub>[bar</sub></font>baz]", + [["delete",""],["inserttext","a"]], + "foo<font size=\"1\"><sub>a[]</sub></font>", // <font> should be outer-most element + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<sub><font size=3>[bar</font></sub>baz]", + [["delete",""],["inserttext","a"]], + "foo<font size=\"3\"><sub>a[]</sub></font>", // <font> should be outer-most element + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["foo<font size=3><sub>[bar</sub></font>baz]", + [["delete",""],["inserttext","a"]], + "foo<sub>a[]</sub>", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["<blockquote><font color=blue>[foo]</font></blockquote>", + [["delete",""],["inserttext","a"]], + "<blockquote><font color=\"blue\">a[]</font></blockquote>", + [true,true], + {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}], +["<div><b>[abc]</b></div>", + [["styleWithCSS", "false"],["delete",""],["inserttext","a"]], + ["<b>a</b>", + "<b>a</b><br>"], // The <div> should be deleted by "delete" + [true,true,true], + {"bold":[false,true,"",false,true,""]}], +["<div>abc<b>[def]</b></div>", + [["styleWithCSS","false"],["delete",""],["inserttext","d"]], + ["<div>abc<b>d</b></div>", + "<div>abc<b>d</b><br></div>"], + [true,true,true], + {"bold":[false,true,"",false,true,""]}], +["<div><b>[abc]</b></div>", + [["styleWithCSS", "false"],["delete",""],["insertparagraph",""],["inserttext","a"]], + ["<br><div><b>a</b></div>", + "<br><div><b>a</b><br></div>"], // The <div> should be deleted by "delete", but new text should be in new <div> + [true,true,true,true], + {"bold":[false,true,"",false,true,""]}], +["<div>abc<b>[def]</b></div>", + [["styleWithCSS", "false"], ["delete",""],["insertparagraph",""],["inserttext","d"]], + ["<div>abc</div><div><b>d</b></div>", + "<div>abc</div><div><b>d</b><br></div>", + "<div>abc<br></div><div><b>d</b></div>", + "<div>abc<br></div><div><b>d</b><br></div>"], + [true,true,true,true], + {"bold":[false,true,"",false,true,""]}], +["<div><b>[abc]</b></div>", + [["styleWithCSS", "false"],["insertparagraph",""],["inserttext","a"]], + ["<br><div><b>a</b></div>", + "<br><div><b>a</b><br></div>"], // The <div> should be deleted by "insertparagraph", but new text should be in new <div> + [true,true,true], + {"bold":[false,true,"",false,true,""]}], +["<div>abc<b>[def]</b></div>", + [["styleWithCSS", "false"],["insertparagraph",""],["inserttext","d"]], + ["<div>abc</div><div><b>d</b></div>", + "<div>abc</div><div><b>d</b><br></div>", + "<div>abc<br></div><div><b>d</b></div>", + "<div>abc<br></div><div><b>d</b><br></div>"], + [true,true,true], + {"bold":[false,true,"",false,true,""]}], + +// Clearing style at end shouldn't leave empty inline element when there is +// <br> element in inline element +["<div><b>abc[]<br></b></div>", + [["styleWithCSS", "false"],["bold",""],["inserttext","d"]], + ["<div><b>abc</b>d</div>", + "<div><b>abc</b>d<br></div>"], + [true,true,true], + {"bold":[false,true,"",false,false,""]}], +["<div><i><b>abc[]<br></b></i></div>", + [["styleWithCSS", "false"],["bold",""],["inserttext","d"]], + ["<div><i><b>abc</b>d</i></div>", + "<div><i><b>abc</b>d<br></i></div>", + "<div><i><b>abc</b>d</i><br></div>"], + [true,true,true], + {"bold":[false,true,"",false,false,""]}], +["<div><i><b>abc[]</b><br></i></div>", + [["styleWithCSS", "false"],["bold",""],["inserttext","d"]], + ["<div><i><b>abc</b>d</i></div>", + "<div><i><b>abc</b>d<br></i></div>"], + [true,true,true], + {"bold":[false,true,"",false,false,""]}], +["<div><b><i>abc[]<br></i></b></div>", + [["styleWithCSS", "false"],["bold",""],["inserttext","d"]], + ["<div><b><i>abc</i></b><i>d</i></div>", + "<div><b><i>abc</i></b><i>d<br></i></div>", + "<div><b><i>abc</i></b><i>d</i><br></div>"], + [true,true,true], + {"bold":[false,true,"",false,false,""]}], +["<div><b><i>abc[]</i><br></b></div>", + [["styleWithCSS", "false"],["bold",""],["inserttext","d"]], + ["<div><b><i>abc</i></b><i>d</i></div>", + "<div><b><i>abc</i></b><i>d<br></i></div>", + "<div><b><i>abc</i></b><i>d</i><br></div>"], + [true,true,true], + {"bold":[false,true,"",false,false,""]}], +// In this case, second line text should be keep bold style. +["<div><b><i>abc[]<br></i><br></b></div>", + [["styleWithCSS", "false"],["bold",""],["inserttext","d"]], + "<div><b><i>abc</i></b><i>d<br></i><b><br></b></div>", + [true,true,true], + {"bold":[false,true,"",false,false,""]}], +// Tests putting caret to right paragraph at insert paragraph, and preserve +// the style. +["abc<b>[def</b>]ghi", + [["insertparagraph", ""],["inserttext","d"],["inserttext","e"],["inserttext","f"]], + ["<div>abc</div><div><b>def</b>ghi</div>", + "abc<div><b>def</b>ghi</div>"], + [true,true,true,true], + {}], +["abc[<b>def]</b>ghi", + [["insertparagraph", ""],["inserttext","d"],["inserttext","e"],["inserttext","f"]], + ["<div>abc</div><div><b>def</b>ghi</div>", + "abc<div><b>def</b>ghi</div>"], + [true,true,true,true], + {}], +["abc<b>[def]</b>ghi", + [["insertparagraph", ""],["inserttext","d"],["inserttext","e"],["inserttext","f"]], + ["<div>abc</div><div><b>def</b>ghi</div>", + "abc<div><b>def</b>ghi</div>"], + [true,true,true,true], + {}], +["abc<b>{def}</b>ghi", + [["insertparagraph", ""],["inserttext","d"],["inserttext","e"],["inserttext","f"]], + ["<div>abc</div><div><b>def</b>ghi</div>", + "abc<div><b>def</b>ghi</div>"], + [true,true,true,true], + {}], +["abc{<b>def</b>}ghi", + [["insertparagraph", ""],["inserttext","d"],["inserttext","e"],["inserttext","f"]], + ["<div>abc</div><div><b>def</b>ghi</div>", + "abc<div><b>def</b>ghi</div>"], + [true,true,true,true], + {}], + +// Tests preserving inline style of the last visible thing in the selection +// even after deleting selection. +// FYI: The expectations of the following similar tests are just based on +// Chrome, some of them may not be reasonable. +["<div>abc{<b><i>def</i></b>}ghi</div>", + [["delete",""],["inserttext","d"],["inserttext","e"],["inserttext","f"]], + "<div>abc<b><i>def</i></b>ghi</div>", + [true,true,true,true], + {}], +["<div>abc{<b><i>def</i></b>}ghi</div>", + [["forwarddelete",""],["inserttext","d"],["inserttext","e"],["inserttext","f"]], + "<div>abc<b><i>def</i></b>ghi</div>", + [true,true,true,true], + {}], +["<div>abc<b><i>[def]</i></b>ghi</div>", + [["delete",""],["inserttext","d"],["inserttext","e"],["inserttext","f"]], + "<div>abc<b><i>def</i></b>ghi</div>", + [true,true,true,true], + {}], +["<div>abc<b><i>[def]</i></b>ghi</div>", + [["forwarddelete",""],["inserttext","d"],["inserttext","e"],["inserttext","f"]], + "<div>abc<b><i>def</i></b>ghi</div>", + [true,true,true,true], + {}], +["<div>abc[<b><i>def]</i></b>ghi</div>", + [["delete",""],["inserttext","d"],["inserttext","e"],["inserttext","f"]], + "<div>abc<b><i>def</i></b>ghi</div>", + [true,true,true,true], + {}], +["<div>abc[<b><i>def]</i></b>ghi</div>", + [["forwarddelete",""],["inserttext","d"],["inserttext","e"],["inserttext","f"]], + "<div>abc<b><i>def</i></b>ghi</div>", + [true,true,true,true], + {}], +["<div>abc<b><i>[def</i></b>]ghi</div>", + [["delete",""],["inserttext","d"],["inserttext","e"],["inserttext","f"]], + "<div>abc<b><i>def</i></b>ghi</div>", + [true,true,true,true], + {}], +["<div>abc<b><i>[def</i></b>]ghi</div>", + [["forwarddelete",""],["inserttext","d"],["inserttext","e"],["inserttext","f"]], + "<div>abc<b><i>def</i></b>ghi</div>", + [true,true,true,true], + {}], +["<div>abc<b><i>[def</i></b>g]hi</div>", + [["delete",""],["inserttext","d"],["inserttext","e"],["inserttext","f"],["inserttext","g"]], + "<div>abc<b><i>defg</i></b>hi</div>", + [true,true,true,true,true], + {}], +["<div>abc<b><i>[def</i></b>g]hi</div>", + [["forwarddelete",""],["inserttext","d"],["inserttext","e"],["inserttext","f"],["inserttext","g"]], + "<div>abc<b><i>defg</i></b>hi</div>", + [true,true,true,true,true], + {}], +["<div>abc[<b><i>def</i></b>g]hi</div>", + [["delete",""],["inserttext","d"],["inserttext","e"],["inserttext","f"],["inserttext","g"]], + "<div>abc<b><i>defg</i></b>hi</div>", + [true,true,true,true,true], + {}], +["<div>abc[<b><i>def</i></b>g]hi</div>", + [["forwarddelete",""],["inserttext","d"],["inserttext","e"],["inserttext","f"],["inserttext","g"]], + "<div>abc<b><i>defg</i></b>hi</div>", + [true,true,true,true,true], + {}], +["<div>abc{<b><i>def</i></b>g]hi</div>", + [["delete",""],["inserttext","d"],["inserttext","e"],["inserttext","f"],["inserttext","g"]], + "<div>abc<b><i>defg</i></b>hi</div>", + [true,true,true,true,true], + {}], +["<div>abc{<b><i>def</i></b>g]hi</div>", + [["forwarddelete",""],["inserttext","d"],["inserttext","e"],["inserttext","f"],["inserttext","g"]], + "<div>abc<b><i>defg</i></b>hi</div>", + [true,true,true,true,true], + {}], +// ...in these cases, insertParagraph and insertLineBreak should work same as +// delete/forwarddelete (and the case replacing selection with insertText +// directly). +["<div>abc{<b><i>def</i></b>}ghi</div>", + [["insertparagraph",""],["inserttext","d"],["inserttext","e"],["inserttext","f"]], + "<div>abc</div><div><b><i>def</i></b>ghi</div>", + [true,true,true,true], + {}], +["<div>abc<b><i>[def]</i></b>ghi</div>", + [["insertparagraph",""],["inserttext","d"],["inserttext","e"],["inserttext","f"]], + "<div>abc</div><div><b><i>def</i></b>ghi</div>", + [true,true,true,true], + {}], +["<div>abc[<b><i>def]</i></b>ghi</div>", + [["insertparagraph",""],["inserttext","d"],["inserttext","e"],["inserttext","f"]], + "<div>abc</div><div><b><i>def</i></b>ghi</div>", + [true,true,true,true], + {}], +["<div>abc<b><i>[def</i></b>]ghi</div>", + [["insertparagraph",""],["inserttext","d"],["inserttext","e"],["inserttext","f"]], + "<div>abc</div><div><b><i>def</i></b>ghi</div>", + [true,true,true,true], + {}], +["<div>abc<b><i>[def</i></b>g]hi</div>", + [["insertparagraph",""],["inserttext","d"],["inserttext","e"],["inserttext","f"],["inserttext","g"]], + "<div>abc</div><div><b><i>defg</i></b>hi</div>", + [true,true,true,true,true], + {}], +["<div>abc[<b><i>def</i></b>g]hi</div>", + [["insertparagraph",""],["inserttext","d"],["inserttext","e"],["inserttext","f"],["inserttext","g"]], + "<div>abc</div><div><b><i>defg</i></b>hi</div>", + [true,true,true,true,true], + {}], +["<div>abc{<b><i>def</i></b>g]hi</div>", + [["insertparagraph",""],["inserttext","d"],["inserttext","e"],["inserttext","f"],["inserttext","g"]], + "<div>abc</div><div><b><i>defg</i></b>hi</div>", + [true,true,true,true,true], + {}], +// If visible first content of selection is not text, Chrome does not preserve +// the style of the content after deletion. This is same behavior as replacing +// the content with insertText directly. +["<div>abc[<b><i><img src=\"/img/lion.svg\">de]f</i></b>ghi</div>", + [["delete",""],["inserttext","d"],["inserttext","e"]], + "<div>abcde<b><i>f</i></b>ghi</div>", + [true,true,true], + {}], +["<div>abc[<b><i><img src=\"/img/lion.svg\">de]f</i></b>ghi</div>", + [["forwarddelete",""],["inserttext","d"],["inserttext","e"]], + "<div>abcde<b><i>f</i></b>ghi</div>", + [true,true,true], + {}], +["<div>abc[<b><i><img src=\"/img/lion.svg\">def]</i></b>ghi</div>", + [["delete",""],["inserttext","d"],["inserttext","e"],["inserttext","f"]], + "<div>abcdefghi</div>", + [true,true,true,true], + {}], +["<div>abc[<b><i><img src=\"/img/lion.svg\">def]</i></b>ghi</div>", + [["forwarddelete",""],["inserttext","d"],["inserttext","e"],["inserttext","f"]], + "<div>abcdefghi</div>", + [true,true,true,true], + {}], +["<div>abc[<b><i><img src=\"/img/lion.svg\">def</i></b>]ghi</div>", + [["delete",""],["inserttext","d"],["inserttext","e"],["inserttext","f"]], + "<div>abcdefghi</div>", + [true,true,true,true], + {}], +["<div>abc[<b><i><img src=\"/img/lion.svg\">def</i></b>]ghi</div>", + [["forwarddelete",""],["inserttext","d"],["inserttext","e"],["inserttext","f"]], + "<div>abcdefghi</div>", + [true,true,true,true], + {}], +["<div>abc{<b><i><img src=\"/img/lion.svg\">def</i></b>]ghi</div>", + [["delete",""],["inserttext","d"],["inserttext","e"],["inserttext","f"]], + "<div>abcdefghi</div>", + [true,true,true,true], + {}], +["<div>abc{<b><i><img src=\"/img/lion.svg\">def</i></b>]ghi</div>", + [["forwarddelete",""],["inserttext","d"],["inserttext","e"],["inserttext","f"]], + "<div>abcdefghi</div>", + [true,true,true,true], + {}], +// ...but if insertLineBreak and insertParagraph do not replace all of the +// styles of the first visible content, the style should be preserved because +// caret should be in the inline elements since the styled text is the first +// visible content in the line. +["<div>abc[<b><i><img src=\"/img/lion.svg\">de]f</i></b>ghi</div>", + [["insertparagraph",""],["inserttext","d"],["inserttext","e"]], + "<div>abc</div><div><b><i>def</i></b>ghi</div>", + [true,true,true], + {}], +["<div>abc[<b><i><img src=\"/img/lion.svg\">de]f</i></b>ghi</div>", + [["insertlinebreak",""],["inserttext","d"],["inserttext","e"]], + "<div>abc<br><b><i>def</i></b>ghi</div>", + [true,true,true], + {}], +["<div>abc[<b><i><img src=\"/img/lion.svg\">def]</i></b>ghi</div>", + [["insertparagraph",""],["inserttext","d"],["inserttext","e"],["inserttext","f"]], + "<div>abc</div><div>defghi</div>", + [true,true,true,true], + {}], +["<div>abc[<b><i><img src=\"/img/lion.svg\">def]</i></b>ghi</div>", + [["insertlinebreak",""],["inserttext","d"],["inserttext","e"],["inserttext","f"]], + "<div>abc<br>defghi</div>", + [true,true,true,true], + {}], +["<div>abc[<b><i><img src=\"/img/lion.svg\">def</i></b>]ghi</div>", + [["insertparagraph",""],["inserttext","d"],["inserttext","e"],["inserttext","f"]], + "<div>abc</div><div>defghi</div>", + [true,true,true,true], + {}], +["<div>abc[<b><i><img src=\"/img/lion.svg\">def</i></b>]ghi</div>", + [["insertlinebreak",""],["inserttext","d"],["inserttext","e"],["inserttext","f"]], + "<div>abc<br>defghi</div>", + [true,true,true,true], + {}], +["<div>abc{<b><i><img src=\"/img/lion.svg\">def</i></b>]ghi</div>", + [["insertparagraph",""],["inserttext","d"],["inserttext","e"],["inserttext","f"]], + "<div>abc</div><div>defghi</div>", + [true,true,true,true], + {}], +["<div>abc{<b><i><img src=\"/img/lion.svg\">def</i></b>]ghi</div>", + [["insertlinebreak",""],["inserttext","d"],["inserttext","e"],["inserttext","f"]], + "<div>abc<br>defghi</div>", + [true,true,true,true], + {}], +// Like the case replacing selection with insertText directly, don't preserve +// inline styles even if end boundary is styled after deletion because inline +// elements have gone. +["<div>ab[c<b><i>de]f</i></b>ghi</div>", + [["delete",""],["inserttext","c"],["inserttext","d"],["inserttext","e"]], + "<div>abcde<b><i>f</i></b>ghi</div>", + [true,true,true,true], + {}], +["<div>ab[c<b><i>de]f</i></b>ghi</div>", + [["forwarddelete",""],["inserttext","c"],["inserttext","d"],["inserttext","e"]], + "<div>abcde<b><i>f</i></b>ghi</div>", + [true,true,true,true], + {}], +// ...but same as the case that first visible content is not text, first +// visible content in the new line becomes styled text after insertParagraph +// and insertLineBreak. In these cases, new text should be styled too. +["<div>ab[c<b><i>de]f</i></b>ghi</div>", + [["insertparagraph",""],["inserttext","c"],["inserttext","d"],["inserttext","e"]], + "<div>ab</div><div><b><i>cdef</i></b>ghi</div>", + [true,true,true,true], + {}], +["<div>ab[c<b><i>de]f</i></b>ghi</div>", + [["insertlinebreak",""],["inserttext","c"],["inserttext","d"],["inserttext","e"]], + "<div>ab<br><b><i>cdef</i></b>ghi</div>", + [true,true,true,true], + {}], +// Different from replacing selection with insertText directly, after deleting +// the first visible thing of selection but not deleting the inline elements +// entirely, the inline styles should not be preserved. +// XXX: It seems that these results may not be expected by users because they +// are inconsistent with the result when selection ends at end of the +// styled text node. Why should not it preverses the style of first +// character in the range only when the text node is not deleted, but +// it should preserve the style when the text node is deleted? +["<div>abc[<b><i>de]f</i></b>ghi</div>", + [["delete",""],["inserttext","d"],["inserttext","e"]], + "<div>abcde<b><i>f</i></b>ghi</div>", + [true,true,true], + {}], +["<div>abc[<b><i>de]f</i></b>ghi</div>", + [["forwarddelete",""],["inserttext","d"],["inserttext","e"]], + "<div>abcde<b><i>f</i></b>ghi</div>", + [true,true,true], + {}], +["<div>abc{<b><i>de]f</i></b>ghi</div>", + [["delete",""],["inserttext","d"],["inserttext","e"]], + "<div>abcde<b><i>f</i></b>ghi</div>", + [true,true,true], + {}], +["<div>abc{<b><i>de]f</i></b>ghi</div>", + [["forwarddelete",""],["inserttext","d"],["inserttext","e"]], + "<div>abcde<b><i>f</i></b>ghi</div>", + [true,true,true], + {}], +// ...but insertParagraph and insertLineBreak put caret at start of the text +// in the new line, the styles should be presrved. +["<div>abc[<b><i>de]f</i></b>ghi</div>", + [["insertparagraph",""],["inserttext","d"],["inserttext","e"]], + "<div>abc</div><div><b><i>def</i></b>ghi</div>", + [true,true,true], + {}], +["<div>abc[<b><i>de]f</i></b>ghi</div>", + [["insertlinebreak",""],["inserttext","d"],["inserttext","e"]], + "<div>abc<br><b><i>def</i></b>ghi</div>", + [true,true,true], + {}], +["<div>abc{<b><i>de]f</i></b>ghi</div>", + [["insertparagraph",""],["inserttext","d"],["inserttext","e"]], + "<div>abc</div><div><b><i>def</i></b>ghi</div>", + [true,true,true], + {}], +["<div>abc{<b><i>de]f</i></b>ghi</div>", + [["insertlinebreak",""],["inserttext","d"],["inserttext","e"]], + "<div>abc<br><b><i>def</i></b>ghi</div>", + [true,true,true], + {}], +// Different from replacing selection with insertText directly, deletion removes +// unnecessary empty inline elements in the selection and caret is moved to end +// of the preceding text node in Chrome. Therefore, new text should be inserted +// outside the inline elements. +["<div>abc[<s></s><b><i>de]f</i></b>ghi</div>", + [["delete",""],["inserttext","d"],["inserttext","e"]], + "<div>abcde<b><i>f</i></b>ghi</div>", + [true,true,true], + {}], +["<div>abc[<s></s><b><i>de]f</i></b>ghi</div>", + [["forwarddelete",""],["inserttext","d"],["inserttext","e"]], + "<div>abcde<b><i>f</i></b>ghi</div>", + [true,true,true], + {}], +["<div>abc{<s></s><b><i>de]f</i></b>ghi</div>", + [["delete",""],["inserttext","d"],["inserttext","e"]], + "<div>abcde<b><i>f</i></b>ghi</div>", + [true,true,true], + {}], +["<div>abc{<s></s><b><i>de]f</i></b>ghi</div>", + [["forwarddelete",""],["inserttext","d"],["inserttext","e"]], + "<div>abcde<b><i>f</i></b>ghi</div>", + [true,true,true], + {}], +// ...but same as above, insertParagraph and insertLineBreak moves caret into +// start of the inline elements because there is the first visible content of +// the new line. Therefore, the style should be preserved. +["<div>abc[<s></s><b><i>de]f</i></b>ghi</div>", + [["insertparagraph",""],["inserttext","d"],["inserttext","e"]], + "<div>abc</div><div><b><i>def</i></b>ghi</div>", + [true,true,true], + {}], +["<div>abc[<s></s><b><i>de]f</i></b>ghi</div>", + [["insertlinebreak",""],["inserttext","d"],["inserttext","e"]], + "<div>abc<br><b><i>def</i></b>ghi</div>", + [true,true,true], + {}], +["<div>abc{<s></s><b><i>de]f</i></b>ghi</div>", + [["insertparagraph",""],["inserttext","d"],["inserttext","e"]], + "<div>abc</div><div><b><i>def</i></b>ghi</div>", + [true,true,true], + {}], +["<div>abc{<s></s><b><i>de]f</i></b>ghi</div>", + [["insertlinebreak",""],["inserttext","d"],["inserttext","e"]], + "<div>abc<br><b><i>def</i></b>ghi</div>", + [true,true,true], + {}], + +// <font> element should be reused when the font-size is change for new text. +["<font size=7>{}<br></font>", + [["stylewithcss","false"],["fontsize","4"],["insertText","a"]], + ["<font size=\"4\">a[]<br></font>", + "<font size=\"4\">a[]</font>"], + [true,true,true], + {"fontsize":[false,false,"7",false,false,"4"]}], +["<span style=font-weight:bold>{}<br></span></b>", + [["stylewithcss","true"],["italic",""],["insertText","a"]], + ["<span style=\"font-weight:bold; font-style:italic\">a[]<br></span>", + "<span style=\"font-weight:bold; font-style:italic\">a[]</span>"], + [true,true,true], + {}], + +// <font> element may be taller than parent inline elements. Therefore, for +// applying background color to new text, <font> element should be put inner- +// most. +["abc[]ef", + [["stylewithcss","false"],["fontSize","4"],["backColor","#00dddd"],["insertText","d"]], + ["abc<font size=\"4\"><span style=\"background-color:rgb(0, 221, 221)\">d</span></font>ef", + "abc<font size=\"4\" style=\"background-color:rgb(0, 221, 221)\">d</font>ef", + "abc<font style=\"background-color:rgb(0, 221, 221)\" size=\"4\">d</font>ef"], + [true,true,true,true], + {}], +["abc[]ef", + [["stylewithcss","false"],["foreColor","#ff0000"],["backColor","#00dddd"],["insertText","d"]], + ["abc<font color=\"#ff0000\"><span style=\"background-color:rgb(0, 221, 221)\">d</span></font>ef", + "abc<font color=\"#ff0000\" style=\"background-color:rgb(0, 221, 221)\">d</font>ef", + "abc<font style=\"background-color:rgb(0, 221, 221)\" color=\"#ff0000\">d</font>ef"], + [true,true,true,true], + {}], +["abc[]ef", + [["stylewithcss","false"],["fontName","monospace"],["backColor","#00dddd"],["insertText","d"]], + ["abc<font face=\"monospace\"><span style=\"background-color:rgb(0, 221, 221)\">d</span></font>ef", + "abc<font face=\"monospace\" style=\"background-color:rgb(0, 221, 221)\">d</font>ef", + "abc<font style=\"background-color:rgb(0, 221, 221)\" face=\"monospace\">d</font>ef"], + [true,true,true,true], + {}], +["abc[]ef", + [["stylewithcss","false"],["backColor","#00dddd"],["fontSize","4"],["insertText","d"]], + ["abc<font size=\"4\"><span style=\"background-color:rgb(0, 221, 221)\">d</span></font>ef", + "abc<font size=\"4\" style=\"background-color:rgb(0, 221, 221)\">d</font>ef", + "abc<font style=\"background-color:rgb(0, 221, 221)\" size=\"4\">d</font>ef"], + [true,true,true,true], + {}], +["abc[]ef", + [["stylewithcss","false"],["backColor","#00dddd"],["foreColor","#ff0000"],["insertText","d"]], + ["abc<font color=\"#ff0000\"><span style=\"background-color:rgb(0, 221, 221)\">d</span></font>ef", + "abc<font color=\"#ff0000\" style=\"background-color:rgb(0, 221, 221)\">d</font>ef", + "abc<font style=\"background-color:rgb(0, 221, 221)\" color=\"#ff0000\">d</font>ef"], + [true,true,true,true], + {}], +["abc[]ef", + [["stylewithcss","false"],["backColor","#00dddd"],["fontName","monospace"],["insertText","d"]], + ["abc<font face=\"monospace\"><span style=\"background-color:rgb(0, 221, 221)\">d</span></font>ef", + "abc<font face=\"monospace\" style=\"background-color:rgb(0, 221, 221)\">d</font>ef", + "abc<font style=\"background-color:rgb(0, 221, 221)\" face=\"monospace\">d</font>ef"], + [true,true,true,true], + {}], +["abc[]ef", + [["stylewithcss","false"],["fontName","monospace"],["foreColor","#ff0000"],["fontSize","7"],["backColor","#00dddd"],["insertText","d"]], + ["abc<font color=\"#ff0000\" face=\"monospace\" size=\"7\"><span style=\"background-color:rgb(0, 221, 221)\">[d]</span></font>ef", + "abc<font color=\"#ff0000\" size=\"7\" face=\"monospace\"><span style=\"background-color:rgb(0, 221, 221)\">[d]</span></font>ef", + "abc<font face=\"monospace\" color=\"#ff0000\" size=\"7\"><span style=\"background-color:rgb(0, 221, 221)\">[d]</span></font>ef", + "abc<font face=\"monospace\" size=\"7\" color=\"#ff0000\"><span style=\"background-color:rgb(0, 221, 221)\">[d]</span></font>ef", + "abc<font size=\"7\" color=\"#ff0000\" face=\"monospace\"><span style=\"background-color:rgb(0, 221, 221)\">[d]</span></font>ef", + "abc<font size=\"7\" face=\"monospace\" color=\"#ff0000\"><span style=\"background-color:rgb(0, 221, 221)\">[d]</span></font>ef", + "abc<font size=\"7\" color=\"#ff0000\" face=\"monospace\" style=\"background-color:rgb(0, 221, 221)\">[d]</font>ef", + "abc<font color=\"#ff0000\" face=\"monospace\" size=\"7\" style=\"background-color:rgb(0, 221, 221)\">[d]</font>ef", + "abc<font color=\"#ff0000\" size=\"7\" face=\"monospace\" style=\"background-color:rgb(0, 221, 221)\">[d]</font>ef", + "abc<font face=\"monospace\" color=\"#ff0000\" size=\"7\" style=\"background-color:rgb(0, 221, 221)\">[d]</font>ef", + "abc<font face=\"monospace\" size=\"7\" color=\"#ff0000\" style=\"background-color:rgb(0, 221, 221)\">[d]</font>ef", + "abc<font style=\"background-color:rgb(0, 221, 221)\" size=\"7\" color=\"#ff0000\" face=\"monospace\">[d]</font>ef", + "abc<font style=\"background-color:rgb(0, 221, 221)\" size=\"7\" face=\"monospace\" color=\"#ff0000\">[d]</font>ef", + "abc<font style=\"background-color:rgb(0, 221, 221)\" color=\"#ff0000\" face=\"monospace\" size=\"7\">[d]</font>ef", + "abc<font style=\"background-color:rgb(0, 221, 221)\" color=\"#ff0000\" size=\"7\" face=\"monospace\">[d]</font>ef", + "abc<font style=\"background-color:rgb(0, 221, 221)\" face=\"monospace\" color=\"#ff0000\" size=\"7\">[d]</font>ef", + "abc<font style=\"background-color:rgb(0, 221, 221)\" face=\"monospace\" size=\"7\" color=\"#ff0000\">[d]</font>ef", + "abc<font style=\"background-color:rgb(0, 221, 221)\" size=\"7\" color=\"#ff0000\" face=\"monospace\">[d]</font>ef", + "abc<font style=\"background-color:rgb(0, 221, 221)\" size=\"7\" face=\"monospace\" color=\"#ff0000\">[d]</font>ef"], + [true,true,true,true,true,true], + {}], + +// Typed text after joining paragraphs should be inserted into the previous text node. +["<p><span style=\"color:rgb(0, 0, 255)\">foo</span></p><p><span style=\"color:rgb(255, 0, 0)\">[]bar</span></p>", + [["styleWithCSS","false"],["delete",""],["insertText","A"]], + "<p><span style=\"color:rgb(0, 0, 255)\">fooA[]</span><span style=\"color:rgb(255, 0, 0)\">bar</span></p>", + [true,true,true], + {}], +["<p><span style=\"color:rgb(0, 0, 255)\">foo</span><br></p><p><span style=\"color:rgb(255, 0, 0)\">[]bar</span></p>", + [["styleWithCSS","false"],["delete",""],["insertText","A"]], + "<p><span style=\"color:rgb(0, 0, 255)\">fooA[]</span><span style=\"color:rgb(255, 0, 0)\">bar</span></p>", + [true,true,true], + {}], +["<p><span style=\"color:rgb(0, 0, 255)\">foo<br></span></p><p><span style=\"color:rgb(255, 0, 0)\">[]bar</span></p>", + [["styleWithCSS","false"],["delete",""],["insertText","A"]], + "<p><span style=\"color:rgb(0, 0, 255)\">fooA[]</span><span style=\"color:rgb(255, 0, 0)\">bar</span></p>", + [true,true,true], + {}], +["<p><span style=\"color:rgb(0, 0, 255)\">foo</span></p><span style=\"color:rgb(255, 0, 0)\">[]bar</span>", + [["styleWithCSS","false"],["delete",""],["insertText","A"]], + "<p><span style=\"color:rgb(0, 0, 255)\">fooA[]</span><span style=\"color:rgb(255, 0, 0)\">bar</span></p>", + [true,true,true], + {}], +["<p><span style=\"color:rgb(0, 0, 255)\">foo</span><br></p><span style=\"color:rgb(255, 0, 0)\">[]bar</span>", + [["styleWithCSS","false"],["delete",""],["insertText","A"]], + "<p><span style=\"color:rgb(0, 0, 255)\">fooA[]</span><span style=\"color:rgb(255, 0, 0)\">bar</span></p>", + [true,true,true], + {}], +["<p><span style=\"color:rgb(0, 0, 255)\">foo<br></span></p><span style=\"color:rgb(255, 0, 0)\">[]bar</span>", + [["styleWithCSS","false"],["delete",""],["insertText","A"]], + "<p><span style=\"color:rgb(0, 0, 255)\">fooA[]</span><span style=\"color:rgb(255, 0, 0)\">bar</span></p>", + [true,true,true], + {}], +["<span style=\"color:rgb(0, 0, 255)\">foo</span><br><p><span style=\"color:rgb(255, 0, 0)\">[]bar</span></p>", + [["styleWithCSS","false"],["delete",""],["insertText","A"]], + "<span style=\"color:rgb(0, 0, 255)\">fooA[]</span><span style=\"color:rgb(255, 0, 0)\">bar</span>", + [true,true,true], + {}], +["<span style=\"color:rgb(0, 0, 255)\">foo<br></span><p><span style=\"color:rgb(255, 0, 0)\">[]bar</span></p>", + [["styleWithCSS","false"],["delete",""],["insertText","A"]], + "<span style=\"color:rgb(0, 0, 255)\">fooA[]</span><span style=\"color:rgb(255, 0, 0)\">bar</span>", + [true,true,true], + {}], + +["<p><span style=\"color:rgb(0, 0, 255)\">foo[]</span></p><p><span style=\"color:rgb(255, 0, 0)\">bar</span></p>", + [["styleWithCSS","false"],["forwarddelete",""],["insertText","A"]], + "<p><span style=\"color:rgb(0, 0, 255)\">fooA[]</span><span style=\"color:rgb(255, 0, 0)\">bar</span></p>", + [true,true,true], + {}], +["<p><span style=\"color:rgb(0, 0, 255)\">foo[]</span><br></p><p><span style=\"color:rgb(255, 0, 0)\">bar</span></p>", + [["styleWithCSS","false"],["forwarddelete",""],["insertText","A"]], + "<p><span style=\"color:rgb(0, 0, 255)\">fooA[]</span><span style=\"color:rgb(255, 0, 0)\">bar</span></p>", + [true,true,true], + {}], +["<p><span style=\"color:rgb(0, 0, 255)\">foo[]<br></span></p><p><span style=\"color:rgb(255, 0, 0)\">bar</span></p>", + [["styleWithCSS","false"],["forwarddelete",""],["insertText","A"]], + "<p><span style=\"color:rgb(0, 0, 255)\">fooA[]</span><span style=\"color:rgb(255, 0, 0)\">bar</span></p>", + [true,true,true], + {}], +["<p><span style=\"color:rgb(0, 0, 255)\">foo[]</span></p><span style=\"color:rgb(255, 0, 0)\">bar</span>", + [["styleWithCSS","false"],["forwarddelete",""],["insertText","A"]], + "<p><span style=\"color:rgb(0, 0, 255)\">fooA[]</span><span style=\"color:rgb(255, 0, 0)\">bar</span></p>", + [true,true,true], + {}], +["<p><span style=\"color:rgb(0, 0, 255)\">foo[]</span><br></p><span style=\"color:rgb(255, 0, 0)\">bar</span>", + [["styleWithCSS","false"],["forwarddelete",""],["insertText","A"]], + "<p><span style=\"color:rgb(0, 0, 255)\">fooA[]</span><span style=\"color:rgb(255, 0, 0)\">bar</span></p>", + [true,true,true], + {}], +["<p><span style=\"color:rgb(0, 0, 255)\">foo[]<br></span></p><span style=\"color:rgb(255, 0, 0)\">bar</span>", + [["styleWithCSS","false"],["forwarddelete",""],["insertText","A"]], + "<p><span style=\"color:rgb(0, 0, 255)\">fooA[]</span><span style=\"color:rgb(255, 0, 0)\">bar</span></p>", + [true,true,true], + {}], +["<span style=\"color:rgb(0, 0, 255)\">foo[]</span><br><p><span style=\"color:rgb(255, 0, 0)\">bar</span></p>", + [["styleWithCSS","false"],["forwarddelete",""],["insertText","A"]], + "<span style=\"color:rgb(0, 0, 255)\">fooA[]</span><span style=\"color:rgb(255, 0, 0)\">bar</span>", + [true,true,true], + {}], +["<span style=\"color:rgb(0, 0, 255)\">foo[]<br></span><p><span style=\"color:rgb(255, 0, 0)\">bar</span></p>", + [["styleWithCSS","false"],["forwarddelete",""],["insertText","A"]], + "<span style=\"color:rgb(0, 0, 255)\">fooA[]</span><span style=\"color:rgb(255, 0, 0)\">bar</span>", + [true,true,true], + {}], + +// First style should be applied outer, that is same as applying styles to +// non-collapsed selection. +["a[]c", + [["styleWithCSS","false"],["bold",""],["italic",""],["insertText","b"]], + "a<b><i>b</i></b>c", + [true,true,true,true], + {}], +["a[]c", + [["styleWithCSS","false"],["italic",""],["bold",""],["insertText","b"]], + "a<i><b>b</b></i>c", + [true,true,true,true], + {}], +["<b>a[]</b>c", + [["styleWithCSS","false"],["bold",""],["italic",""],["insertText","b"]], + "<b>a</b><i>b</i>c", + [true,true,true,true], + {}], +["<i>a[]</i>c", + [["styleWithCSS","false"],["bold",""],["italic",""],["insertText","b"]], + "<i>a</i><b>b</b>c", + [true,true,true,true], + {}], +["a[]<b>c</b>", + [["styleWithCSS","false"],["bold",""],["italic",""],["insertText","b"]], + "a<b><i>b</i>c</b>", + [true,true,true,true], + {}], +["a[]<i>c</i>", + [["styleWithCSS","false"],["bold",""],["italic",""],["insertText","b"]], + "a<b><i>b</i></b><i>c</i>", + [true,true,true,true], + {}], +// but <font> should be applied outer-most. +["a[]c", + [["styleWithCSS","false"],["foreColor","#ff0000"],["bold",""],["insertText","b"]], + "a<font color=\"#ff0000\"><b>b</b></font>c", + [true,true,true,true], + {}], +["a[]c", + [["styleWithCSS","false"],["bold",""],["foreColor","#ff0000"],["insertText","b"]], + "a<font color=\"#ff0000\"><b>b</b></font>c", + [true,true,true,true], + {}], +["a[]c", + [["styleWithCSS","false"],["fontName","monospace"],["bold",""],["insertText","b"]], + "a<font face=\"monospace\"><b>b</b></font>c", + [true,true,true,true], + {}], +["a[]c", + [["styleWithCSS","false"],["bold",""],["fontName","monospace"],["insertText","b"]], + "a<font face=\"monospace\"><b>b</b></font>c", + [true,true,true,true], + {}], +["a[]c", + [["styleWithCSS","false"],["fontSize","5"],["bold",""],["insertText","b"]], + "a<font size=\"5\"><b>b</b></font>c", + [true,true,true,true], + {}], +["a[]c", + [["styleWithCSS","false"],["bold",""],["fontSize","5"],["insertText","b"]], + "a<font size=\"5\"><b>b</b></font>c", + [true,true,true,true], + {}], +["a[]c", + [["styleWithCSS","false"],["foreColor","#ff0000"],["bold",""],["fontSize","5"],["fontName","monospace"],["insertText","b"]], + ["a<font color=\"#ff0000\" face=\"monospace\" size=\"5\"><b>b</b></font>c", + "a<font color=\"#ff0000\" size=\"5\" face=\"monospace\"><b>b</b></font>c", + "a<font size=\"5\" color=\"#ff0000\" face=\"monospace\"><b>b</b></font>c", + "a<font size=\"5\" face=\"monospace\" color=\"#ff0000\"><b>b</b></font>c", + "a<font face=\"monospace\" size=\"5\" color=\"#ff0000\"><b>b</b></font>c", + "a<font face=\"monospace\" color=\"#ff0000\" size=\"5\"><b>b</b></font>c"], + [true,true,true,true,true,true], + {}], + +// After joining paragraphs, web app may set same style explicitly again. +// Note that the font styles are not toggle. Therefore, it's important to +// keep the style for the new text. +["<p><font size=\"5\">a</font></p><p>[]c</p>", + [["styleWithCSS","false"],["delete",""],["fontSize","5"],["insertText","b"]], + "<p><font size=\"5\">ab[]</font>c</p>", + [true,true,true,true], + {}], +["<p><font size=\"5\" color=\"#ff0000\">a</font></p><p>[]c</p>", + [["styleWithCSS","false"],["delete",""],["fontSize","5"],["foreColor","#ff0000"],["insertText","b"]], + "<p><font size=\"5\" color=\"#ff0000\">ab[]</font>c</p>", + [true,true,true,true,true], + {}], +["<p><font size=\"5\"><b>a</b></font></p><p>[]c</p>", + [["styleWithCSS","false"],["delete",""],["fontSize","5"],["insertText","b"]], + "<p><font size=\"5\"><b>ab[]</b></font>c</p>", + [true,true,true,true], + {}], +["<p><font size=\"5\"><b>a</b></font></p><p><i>[]c</i></p>", + [["styleWithCSS","false"],["delete",""],["fontSize","5"],["insertText","b"]], + "<p><font size=\"5\"><b>ab[]</b></font><i>c</i></p>", + [true,true,true,true], + {}], +// Same tests for forwardDelete +["<p><font size=\"5\">a[]</font></p><p>c</p>", + [["styleWithCSS","false"],["forwardDelete",""],["fontSize","5"],["insertText","b"]], + "<p><font size=\"5\">ab[]</font>c</p>", + [true,true,true,true], + {}], +["<p><font size=\"5\" color=\"#ff0000\">a[]</font></p><p>c</p>", + [["styleWithCSS","false"],["forwardDelete",""],["fontSize","5"],["foreColor","#ff0000"],["insertText","b"]], + "<p><font size=\"5\" color=\"#ff0000\">ab[]</font>c</p>", + [true,true,true,true,true], + {}], +["<p><font size=\"5\"><b>a[]</b></font></p><p>c</p>", + [["styleWithCSS","false"],["forwardDelete",""],["fontSize","5"],["insertText","b"]], + "<p><font size=\"5\"><b>ab[]</b></font>c</p>", + [true,true,true,true], + {}], +["<p><font size=\"5\"><b>a[]</b></font></p><p><i>c</i></p>", + [["styleWithCSS","false"],["forwardDelete",""],["fontSize","5"],["insertText","b"]], + "<p><font size=\"5\"><b>ab[]</b></font><i>c</i></p>", + [true,true,true,true], + {}], +// Don't remove parent blocks of selection start to insert new text into the +// selection start container. +["<div>{abc</div><div>def</div>}", + [["delete",""],["inserttext","g"],["inserttext","h"]], + ["<div>gh</div>", + "<div>gh<br></div>"], + [true,true,true], + {}], +["<div>abc</div><div>{def</div>}", + [["delete",""],["inserttext","g"],["inserttext","h"]], + ["<div>abc</div><div>gh</div>", + "<div>abc</div><div>gh<br></div>"], + [true,true,true], + {}], +["<div style=display:flex><span>{abc</span><span>def</span>}</div>", + [["delete",""],["inserttext","g"],["inserttext","h"]], + ["<div style=\"display:flex\"><span>gh</span></div>", + "<div style=\"display:flex\"><span>gh<br></span></div>"], + [true,true,true], + {}], +["<div style=display:flex><span>abc</span><span>{def</span>}</div>", + [["delete",""],["inserttext","g"],["inserttext","h"]], + ["<div style=\"display:flex\"><span>abc</span><span>gh</span></div>", + "<div style=\"display:flex\"><span>abc</span><span>gh<br></span></div>"], + [true,true,true], + {}], +["<div style=display:grid><span>{abc</span><span>def</span>}</div>", + [["delete",""],["inserttext","g"],["inserttext","h"]], + ["<div style=\"display:grid\"><span>gh</span></div>", + "<div style=\"display:grid\"><span>gh<br></span></div>"], + [true,true,true], + {}], +["<div style=display:grid><span>abc</span><span>{def</span>}</div>", + [["delete",""],["inserttext","g"],["inserttext","h"]], + ["<div style=\"display:grid\"><span>abc</span><span>gh</span></div>", + "<div style=\"display:grid\"><span>abc</span><span>gh<br></span></div>"], + [true,true,true], + {}], +// The inline style at selection start should be preserved for typed text. +["<div><b>{abc</b></div><div>def</div>}", + [["delete",""],["inserttext","g"],["inserttext","h"]], + ["<div><b>gh</b></div>", + "<div><b>gh<br></b></div>", + "<div><b>gh</b><br></div>"], + [true,true,true], + {}], +["<div>abc</div><div><b>{def</b></div>}", + [["delete",""],["inserttext","g"],["inserttext","h"]], + ["<div>abc</div><div><b>gh</b></div>", + "<div>abc</div><div><b>gh<br></b></div>", + "<div>abc</div><div><b>gh</b><br></div>"], + [true,true,true], + {}], +["<div style=display:flex><span><b>{abc</b></span><span>def</span>}</div>", + [["delete",""],["inserttext","g"],["inserttext","h"]], + ["<div style=\"display:flex\"><span><b>gh</b></span></div>", + "<div style=\"display:flex\"><span><b>gh<br></b></span></div>", + "<div style=\"display:flex\"><span><b>gh</b><br></span></div>"], + [true,true,true], + {}], +["<div style=display:flex><span>abc</span><span><b>{def</b></span>}</div>", + [["delete",""],["inserttext","g"],["inserttext","h"]], + ["<div style=\"display:flex\"><span>abc</span><span><b>gh</b></span></div>", + "<div style=\"display:flex\"><span>abc</span><span><b>gh<br></b></span></div>", + "<div style=\"display:flex\"><span>abc</span><span><b>gh</b><br></span></div>"], + [true,true,true], + {}], +["<div style=display:grid><span><b>{abc</b></span><span>def</span>}</div>", + [["delete",""],["inserttext","g"],["inserttext","h"]], + ["<div style=\"display:grid\"><span><b>gh</b></span></div>", + "<div style=\"display:grid\"><span><b>gh<br></b></span></div>", + "<div style=\"display:grid\"><span><b>gh</b><br></span></div>"], + [true,true,true], + {}], +["<div style=display:grid><span>abc</span><span><b>{def</b></span>}</div>", + [["delete",""],["inserttext","g"],["inserttext","h"]], + ["<div style=\"display:grid\"><span>abc</span><span><b>gh</b></span></div>", + "<div style=\"display:grid\"><span>abc</span><span><b>gh<br></b></span></div>", + "<div style=\"display:grid\"><span>abc</span><span><b>gh</b><br></span></div>"], + [true,true,true], + {}], +// Do not delete non-editable when deleting an editable character and preseve +// the style for new text. +["<b>X[]<span contenteditable=false>abc</span></b><i>def</i>", + [["delete",""],["inserttext","Y"]], + ["<b>Y<span contenteditable=\"false\">abc</span></b><i>def</i>", + "<b>Y</b><b><span contenteditable=\"false\">abc</span></b><i>def</i>"], + [true,true], + {}], +["<b><span contenteditable=false>abc</span>X[]</b><i>def</i>", + [["delete",""],["inserttext","Y"]], + ["<b><span contenteditable=\"false\">abc</span>Y</b><i>def</i>", + "<b><span contenteditable=\"false\">abc</span></b><b>Y</b><i>def</i>"], + [true,true], + {}], +["<b>[]X<span contenteditable=false>abc</span></b><i>def</i>", + [["forwarddelete",""],["inserttext","Y"]], + ["<b>Y<span contenteditable=\"false\">abc</span></b><i>def</i>", + "<b>Y</b><b><span contenteditable=\"false\">abc</span></b><i>def</i>"], + [true,true], + {}], +["<b><span contenteditable=false>abc</span>[]X</b><i>def</i>", + [["forwarddelete",""],["inserttext","Y"]], + ["<b><span contenteditable=\"false\">abc</span>Y</b><i>def</i>", + "<b><span contenteditable=\"false\">abc</span></b><b>Y</b><i>def</i>"], + [true,true], + {}], +] diff --git a/testing/web-platform/tests/editing/data/outdent.js b/testing/web-platform/tests/editing/data/outdent.js new file mode 100644 index 0000000000..ad613122ef --- /dev/null +++ b/testing/web-platform/tests/editing/data/outdent.js @@ -0,0 +1,883 @@ +// For documentation of the format, see README in this directory. +var browserTests = [ +["<blockquote><p>foo[bar]</p><p>baz</p></blockquote><p>extra", + [["outdent",""]], + "<p>foo[bar]</p><blockquote><p>baz</p></blockquote><p>extra</p>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<blockquote><p>foo[bar</p><p>b]az</p></blockquote><p>extra", + [["outdent",""]], + "<p>foo[bar</p><p>b]az</p><p>extra</p>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<blockquote><p>foo[bar]</p></blockquote><p>baz</p><p>extra", + [["outdent",""]], + "<p>foo[bar]</p><p>baz</p><p>extra</p>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<blockquote><p>foo[bar</p></blockquote><p>b]az</p><p>extra", + [["outdent",""]], + "<p>foo[bar</p><p>b]az</p><p>extra</p>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<blockquote style=\"margin-right: 0px;\" dir=\"ltr\"><p>foo[bar]</p><p>baz</p></blockquote><p>extra", + [["stylewithcss","true"],["outdent",""]], + "<p>foo[bar]</p><blockquote><p>baz</p></blockquote><p>extra</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"outdent":[false,false,"",false,false,""]}], +["<blockquote style=\"margin-right: 0px;\" dir=\"ltr\"><p>foo[bar]</p><p>baz</p></blockquote><p>extra", + [["stylewithcss","false"],["outdent",""]], + "<p>foo[bar]</p><blockquote><p>baz</p></blockquote><p>extra</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"outdent":[false,false,"",false,false,""]}], +["<blockquote style=\"margin-right: 0px;\" dir=\"ltr\"><p>foo[bar</p><p>b]az</p></blockquote><p>extra", + [["stylewithcss","true"],["outdent",""]], + "<p>foo[bar</p><p>b]az</p><p>extra</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"outdent":[false,false,"",false,false,""]}], +["<blockquote style=\"margin-right: 0px;\" dir=\"ltr\"><p>foo[bar</p><p>b]az</p></blockquote><p>extra", + [["stylewithcss","false"],["outdent",""]], + "<p>foo[bar</p><p>b]az</p><p>extra</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"outdent":[false,false,"",false,false,""]}], +["<blockquote style=\"margin-right: 0px;\" dir=\"ltr\"><p>foo[bar]</p></blockquote><p>baz</p><p>extra", + [["stylewithcss","true"],["outdent",""]], + "<p>foo[bar]</p><p>baz</p><p>extra</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"outdent":[false,false,"",false,false,""]}], +["<blockquote style=\"margin-right: 0px;\" dir=\"ltr\"><p>foo[bar]</p></blockquote><p>baz</p><p>extra", + [["stylewithcss","false"],["outdent",""]], + "<p>foo[bar]</p><p>baz</p><p>extra</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"outdent":[false,false,"",false,false,""]}], +["<blockquote style=\"margin-right: 0px;\" dir=\"ltr\"><p>foo[bar</p></blockquote><p>b]az</p><p>extra", + [["stylewithcss","true"],["outdent",""]], + "<p>foo[bar</p><p>b]az</p><p>extra</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"outdent":[false,false,"",false,false,""]}], +["<blockquote style=\"margin-right: 0px;\" dir=\"ltr\"><p>foo[bar</p></blockquote><p>b]az</p><p>extra", + [["stylewithcss","false"],["outdent",""]], + "<p>foo[bar</p><p>b]az</p><p>extra</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"outdent":[false,false,"",false,false,""]}], +["<p style=\"margin-left: 40px\">foo[bar]</p><p style=\"margin-left: 40px\">baz</p><p>extra", + [["outdent",""]], + "<p style=\"margin-left:40px\">foo[bar]</p><p style=\"margin-left:40px\">baz</p><p>extra</p>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<p style=\"margin-left: 40px\">foo[bar</p><p style=\"margin-left: 40px\">b]az</p><p>extra", + [["outdent",""]], + "<p style=\"margin-left:40px\">foo[bar</p><p style=\"margin-left:40px\">b]az</p><p>extra</p>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<p style=\"margin-left: 40px\">foo[bar]</p><p>baz</p><p>extra", + [["outdent",""]], + "<p style=\"margin-left:40px\">foo[bar]</p><p>baz</p><p>extra</p>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<p style=\"margin-left: 40px\">foo[bar</p><p>b]az</p><p>extra", + [["outdent",""]], + "<p style=\"margin-left:40px\">foo[bar</p><p>b]az</p><p>extra</p>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<blockquote class=\"webkit-indent-blockquote\" style=\"margin: 0 0 0 40px; border: none; padding: 0px;\"><p>foo[bar]</p><p>baz</p></blockquote><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["outdent",""]], + "<div class=\"webkit-indent-blockquote\"><p>foo[bar]</p><blockquote><p>baz</p></blockquote></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<blockquote class=\"webkit-indent-blockquote\" style=\"margin: 0 0 0 40px; border: none; padding: 0px;\"><p>foo[bar]</p><p>baz</p></blockquote><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["outdent",""]], + "<div class=\"webkit-indent-blockquote\"><p>foo[bar]</p><blockquote><p>baz</p></blockquote></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<blockquote class=\"webkit-indent-blockquote\" style=\"margin: 0 0 0 40px; border: none; padding: 0px;\"><p>foo[bar]</p><p>baz</p></blockquote><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["outdent",""]], + "<div class=\"webkit-indent-blockquote\"><p>foo[bar]</p><blockquote><p>baz</p></blockquote></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<blockquote class=\"webkit-indent-blockquote\" style=\"margin: 0 0 0 40px; border: none; padding: 0px;\"><p>foo[bar]</p><p>baz</p></blockquote><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["outdent",""]], + "<div class=\"webkit-indent-blockquote\"><p>foo[bar]</p><blockquote><p>baz</p></blockquote></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<blockquote class=\"webkit-indent-blockquote\" style=\"margin: 0 0 0 40px; border: none; padding: 0px;\"><p>foo[bar</p><p>b]az</p></blockquote><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["outdent",""]], + "<div class=\"webkit-indent-blockquote\"><p>foo[bar</p><p>b]az</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<blockquote class=\"webkit-indent-blockquote\" style=\"margin: 0 0 0 40px; border: none; padding: 0px;\"><p>foo[bar</p><p>b]az</p></blockquote><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["outdent",""]], + "<div class=\"webkit-indent-blockquote\"><p>foo[bar</p><p>b]az</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<blockquote class=\"webkit-indent-blockquote\" style=\"margin: 0 0 0 40px; border: none; padding: 0px;\"><p>foo[bar</p><p>b]az</p></blockquote><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["outdent",""]], + "<div class=\"webkit-indent-blockquote\"><p>foo[bar</p><p>b]az</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<blockquote class=\"webkit-indent-blockquote\" style=\"margin: 0 0 0 40px; border: none; padding: 0px;\"><p>foo[bar</p><p>b]az</p></blockquote><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["outdent",""]], + "<div class=\"webkit-indent-blockquote\"><p>foo[bar</p><p>b]az</p></div><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<blockquote class=\"webkit-indent-blockquote\" style=\"margin: 0 0 0 40px; border: none; padding: 0px;\"><p>foo[bar]</p></blockquote><p>baz</p><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["outdent",""]], + "<div class=\"webkit-indent-blockquote\"><p>foo[bar]</p></div><p>baz</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<blockquote class=\"webkit-indent-blockquote\" style=\"margin: 0 0 0 40px; border: none; padding: 0px;\"><p>foo[bar]</p></blockquote><p>baz</p><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["outdent",""]], + "<div class=\"webkit-indent-blockquote\"><p>foo[bar]</p></div><p>baz</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<blockquote class=\"webkit-indent-blockquote\" style=\"margin: 0 0 0 40px; border: none; padding: 0px;\"><p>foo[bar]</p></blockquote><p>baz</p><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["outdent",""]], + "<div class=\"webkit-indent-blockquote\"><p>foo[bar]</p></div><p>baz</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<blockquote class=\"webkit-indent-blockquote\" style=\"margin: 0 0 0 40px; border: none; padding: 0px;\"><p>foo[bar]</p></blockquote><p>baz</p><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["outdent",""]], + "<div class=\"webkit-indent-blockquote\"><p>foo[bar]</p></div><p>baz</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<blockquote class=\"webkit-indent-blockquote\" style=\"margin: 0 0 0 40px; border: none; padding: 0px;\"><p>foo[bar</p></blockquote><p>b]az</p><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","div"],["outdent",""]], + "<div class=\"webkit-indent-blockquote\"><p>foo[bar</p></div><p>b]az</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<blockquote class=\"webkit-indent-blockquote\" style=\"margin: 0 0 0 40px; border: none; padding: 0px;\"><p>foo[bar</p></blockquote><p>b]az</p><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","div"],["outdent",""]], + "<div class=\"webkit-indent-blockquote\"><p>foo[bar</p></div><p>b]az</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<blockquote class=\"webkit-indent-blockquote\" style=\"margin: 0 0 0 40px; border: none; padding: 0px;\"><p>foo[bar</p></blockquote><p>b]az</p><p>extra", + [["stylewithcss","true"],["defaultparagraphseparator","p"],["outdent",""]], + "<div class=\"webkit-indent-blockquote\"><p>foo[bar</p></div><p>b]az</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<blockquote class=\"webkit-indent-blockquote\" style=\"margin: 0 0 0 40px; border: none; padding: 0px;\"><p>foo[bar</p></blockquote><p>b]az</p><p>extra", + [["stylewithcss","false"],["defaultparagraphseparator","p"],["outdent",""]], + "<div class=\"webkit-indent-blockquote\"><p>foo[bar</p></div><p>b]az</p><p>extra</p>", + [true,true,true], + {"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<blockquote><blockquote>foo[bar]baz</blockquote></blockquote>", + [["outdent",""]], + "<blockquote>foo[bar]baz</blockquote>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<blockquote><blockquote data-abc=def>foo[bar]baz</blockquote></blockquote>", + [["outdent",""]], + "<blockquote data-abc=\"def\">foo[bar]baz</blockquote>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<blockquote data-abc=def><blockquote>foo[bar]baz</blockquote></blockquote>", + [["outdent",""]], + "<blockquote data-abc=\"def\">foo[bar]baz</blockquote>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<blockquote><div>foo[bar]baz</div></blockquote>", + [["outdent",""]], + "<div>foo[bar]baz</div>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<blockquote><div id=abc>foo[bar]baz</div></blockquote>", + [["outdent",""]], + "<div id=\"abc\">foo[bar]baz</div>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<blockquote id=abc>foo[bar]baz</blockquote>", + [["defaultparagraphseparator","div"],["outdent",""]], + "<div id=\"abc\">foo[bar]baz</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<blockquote id=abc>foo[bar]baz</blockquote>", + [["defaultparagraphseparator","p"],["outdent",""]], + "<div id=\"abc\">foo[bar]baz</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<blockquote style=\"color: blue\">foo[bar]baz</blockquote>", + [["defaultparagraphseparator","div"],["outdent",""]], + "<div style=\"color:rgb(0, 0, 255)\">foo[bar]baz</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<blockquote style=\"color: blue\">foo[bar]baz</blockquote>", + [["defaultparagraphseparator","p"],["outdent",""]], + "<div style=\"color:rgb(0, 0, 255)\">foo[bar]baz</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<blockquote><blockquote><p>foo[bar]<p>baz</blockquote></blockquote>", + [["outdent",""]], + "<blockquote><p>foo[bar]</p><blockquote><p>baz</p></blockquote></blockquote>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<blockquote><blockquote data-abc=def><p>foo[bar]<p>baz</blockquote></blockquote>", + [["outdent",""]], + "<blockquote data-abc=\"def\"><p>foo[bar]</p><blockquote><p>baz</p></blockquote></blockquote>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<blockquote data-abc=def><blockquote><p>foo[bar]<p>baz</blockquote></blockquote>", + [["outdent",""]], + "<blockquote data-abc=\"def\"><p>foo[bar]</p><blockquote><p>baz</p></blockquote></blockquote>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<blockquote><div><p>foo[bar]<p>baz</div></blockquote>", + [["outdent",""]], + "<div><p>foo[bar]</p><blockquote><p>baz</p></blockquote></div>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<blockquote><div id=abc><p>foo[bar]<p>baz</div></blockquote>", + [["outdent",""]], + "<div id=\"abc\"><p>foo[bar]</p><blockquote><p>baz</p></blockquote></div>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<blockquote id=abc><p>foo[bar]<p>baz</blockquote>", + [["defaultparagraphseparator","div"],["outdent",""]], + "<div id=\"abc\"><p>foo[bar]</p><blockquote><p>baz</p></blockquote></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<blockquote id=abc><p>foo[bar]<p>baz</blockquote>", + [["defaultparagraphseparator","p"],["outdent",""]], + "<div id=\"abc\"><p>foo[bar]</p><blockquote><p>baz</p></blockquote></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<blockquote style=\"color: blue\"><p>foo[bar]<p>baz</blockquote>", + [["defaultparagraphseparator","div"],["outdent",""]], + "<div style=\"color:rgb(0, 0, 255)\"><p>foo[bar]</p><blockquote><p>baz</p></blockquote></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<blockquote style=\"color: blue\"><p>foo[bar]<p>baz</blockquote>", + [["defaultparagraphseparator","p"],["outdent",""]], + "<div style=\"color:rgb(0, 0, 255)\"><p>foo[bar]</p><blockquote><p>baz</p></blockquote></div>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<blockquote><p><b>foo[bar]</b><p>baz</blockquote>", + [["outdent",""]], + "<p><b>foo[bar]</b></p><blockquote><p>baz</p></blockquote>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<blockquote><p><strong>foo[bar]</strong><p>baz</blockquote>", + [["outdent",""]], + "<p><strong>foo[bar]</strong></p><blockquote><p>baz</p></blockquote>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<blockquote><p><span>foo[bar]</span><p>baz</blockquote>", + [["outdent",""]], + "<p><span>foo[bar]</span></p><blockquote><p>baz</p></blockquote>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<blockquote><blockquote style=\"color: blue\"><p>foo[bar]</blockquote><p>baz</blockquote>", + [["outdent",""]], + "<blockquote style=\"color:rgb(0, 0, 255)\"><p>foo[bar]</p></blockquote><blockquote><p>baz</p></blockquote>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<blockquote style=\"color: blue\"><blockquote><p>foo[bar]</blockquote><p>baz</blockquote>", + [["outdent",""]], + "<blockquote style=\"color:rgb(0, 0, 255)\"><p>foo[bar]</p><p>baz</p></blockquote>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo<li>[bar]<li>baz</ol>", + [["defaultparagraphseparator","div"],["outdent",""]], + "<ol><li>foo</li></ol><div>[bar]</div><ol><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo<li>[bar]<li>baz</ol>", + [["defaultparagraphseparator","p"],["outdent",""]], + "<ol><li>foo</li></ol><p>[bar]</p><ol><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<ol data-start=1 data-end=2><li>foo<li>bar<li>baz</ol>", + [["defaultparagraphseparator","div"],["outdent",""]], + "<ol><li>foo</li>{</ol><div>bar</div>}<ol><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<ol data-start=1 data-end=2><li>foo<li>bar<li>baz</ol>", + [["defaultparagraphseparator","p"],["outdent",""]], + "<ol><li>foo</li>{</ol><p>bar</p>}<ol><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo</ol>[bar]", + [["outdent",""]], + "<ol><li>foo</li></ol>[bar]", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<ol><li>[foo]<br>bar<li>baz</ol>", + [["defaultparagraphseparator","div"],["outdent",""]], + "<div>[foo]<br>bar</div><ol><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<ol><li>[foo]<br>bar<li>baz</ol>", + [["defaultparagraphseparator","p"],["outdent",""]], + "<p>[foo]<br>bar</p><ol><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo<br>[bar]<li>baz</ol>", + [["defaultparagraphseparator","div"],["outdent",""]], + "<div>foo<br>[bar]</div><ol><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo<br>[bar]<li>baz</ol>", + [["defaultparagraphseparator","p"],["outdent",""]], + "<p>foo<br>[bar]</p><ol><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<ol><li><div>[foo]</div>bar<li>baz</ol>", + [["defaultparagraphseparator","div"],["outdent",""]], + "<div>[foo]</div><div>bar</div><ol><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<ol><li><div>[foo]</div>bar<li>baz</ol>", + [["defaultparagraphseparator","p"],["outdent",""]], + "<div>[foo]</div><p>bar</p><ol><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo<ol><li>[bar]<li>baz</ol><li>quz</ol>", + [["outdent",""]], + "<ol><li>foo</li><li>[bar]</li><ol><li>baz</li></ol><li>quz</li></ol>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo<ol><li>bar<li>[baz]</ol><li>quz</ol>", + [["outdent",""]], + "<ol><li>foo</li><ol><li>bar</li></ol><li>[baz]</li><li>quz</li></ol>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo</li><ol><li>[bar]<li>baz</ol><li>quz</ol>", + [["outdent",""]], + "<ol><li>foo</li><li>[bar]</li><ol><li>baz</li></ol><li>quz</li></ol>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo</li><ol data-start=0 data-end=1><li>bar<li>baz</ol><li>quz</ol>", + [["outdent",""]], + "<ol><li>foo</li>{<li>bar</li>}<ol><li>baz</li></ol><li>quz</li></ol>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo</li><ol><li>bar<li>[baz]</ol><li>quz</ol>", + [["outdent",""]], + "<ol><li>foo</li><ol><li>bar</li></ol><li>[baz]</li><li>quz</li></ol>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo</li><ol data-start=1 data-end=2><li>bar<li>baz</ol><li>quz</ol>", + [["outdent",""]], + "<ol><li>foo</li><ol><li>bar</li></ol>{<li>baz</li>}<li>quz</li></ol>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo<ol><li>b[a]r</ol><li>baz</ol>", + [["outdent",""]], + "<ol><li>foo</li><li>b[a]r</li><li>baz</li></ol>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo</li><ol><li>b[a]r</ol><li>baz</ol>", + [["outdent",""]], + "<ol><li>foo</li><li>b[a]r</li><li>baz</li></ol>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo{<ol><li>bar</ol>}<li>baz</ol>", + [["outdent",""]], + "<ol><li>foo</li>{<li>bar</li>}<li>baz</li></ol>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo</li>{<ol><li>bar</ol>}<li>baz</ol>", + [["outdent",""]], + "<ol><li>foo</li>{<li>bar</li>}<li>baz</li></ol>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<ol><li>[foo]<ol><li>bar</ol><li>baz</ol>", + [["defaultparagraphseparator","div"],["outdent",""]], + "<div>[foo]</div><ol><ol><li>bar</li></ol><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<ol><li>[foo]<ol><li>bar</ol><li>baz</ol>", + [["defaultparagraphseparator","p"],["outdent",""]], + "<p>[foo]</p><ol><ol><li>bar</li></ol><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<ol><li>[foo]</li><ol><li>bar</ol><li>baz</ol>", + [["defaultparagraphseparator","div"],["outdent",""]], + "<div>[foo]</div><ol><ol><li>bar</li></ol><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<ol><li>[foo]</li><ol><li>bar</ol><li>baz</ol>", + [["defaultparagraphseparator","p"],["outdent",""]], + "<p>[foo]</p><ol><ol><li>bar</li></ol><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo<li>[bar]<ol><li>baz</ol><li>quz</ol>", + [["defaultparagraphseparator","div"],["outdent",""]], + "<ol><li>foo</li></ol><div>[bar]</div><ol><ol><li>baz</li></ol><li>quz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo<li>[bar]<ol><li>baz</ol><li>quz</ol>", + [["defaultparagraphseparator","p"],["outdent",""]], + "<ol><li>foo</li></ol><p>[bar]</p><ol><ol><li>baz</li></ol><li>quz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo<li>[bar]</li><ol><li>baz</ol><li>quz</ol>", + [["defaultparagraphseparator","div"],["outdent",""]], + "<ol><li>foo</li></ol><div>[bar]</div><ol><ol><li>baz</li></ol><li>quz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo<li>[bar]</li><ol><li>baz</ol><li>quz</ol>", + [["defaultparagraphseparator","p"],["outdent",""]], + "<ol><li>foo</li></ol><p>[bar]</p><ol><ol><li>baz</li></ol><li>quz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo<ol><li>bar<li>baz</ol><li>[quz]</ol>", + [["defaultparagraphseparator","div"],["outdent",""]], + "<ol><li>foo<ol><li>bar</li><li>baz</li></ol></li></ol><div>[quz]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo<ol><li>bar<li>baz</ol><li>[quz]</ol>", + [["defaultparagraphseparator","p"],["outdent",""]], + "<ol><li>foo<ol><li>bar</li><li>baz</li></ol></li></ol><p>[quz]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo</li><ol><li>bar<li>baz</ol><li>[quz]</ol>", + [["defaultparagraphseparator","div"],["outdent",""]], + "<ol><li>foo</li><ol><li>bar</li><li>baz</li></ol></ol><div>[quz]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo</li><ol><li>bar<li>baz</ol><li>[quz]</ol>", + [["defaultparagraphseparator","p"],["outdent",""]], + "<ol><li>foo</li><ol><li>bar</li><li>baz</li></ol></ol><p>[quz]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo<li>b[ar<li>baz]</ol>", + [["defaultparagraphseparator","div"],["outdent",""]], + "<ol><li>foo</li></ol><div>b[ar</div><div>baz]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo<li>b[ar<li>baz]</ol>", + [["defaultparagraphseparator","p"],["outdent",""]], + "<ol><li>foo</li></ol><p>b[ar</p><p>baz]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<ol><li>[foo<ol><li>bar]</ol><li>baz</ol>", + [["defaultparagraphseparator","div"],["outdent",""]], + "<div>[foo</div><ol><li>bar]</li><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<ol><li>[foo<ol><li>bar]</ol><li>baz</ol>", + [["defaultparagraphseparator","p"],["outdent",""]], + "<p>[foo</p><ol><li>bar]</li><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<ol><li>[foo</li><ol><li>bar]</ol><li>baz</ol>", + [["defaultparagraphseparator","div"],["outdent",""]], + "<div>[foo</div><ol><li>bar]</li><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<ol><li>[foo</li><ol><li>bar]</ol><li>baz</ol>", + [["defaultparagraphseparator","p"],["outdent",""]], + "<p>[foo</p><ol><li>bar]</li><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo<ol><li>b[ar</ol><li>b]az</ol>", + [["defaultparagraphseparator","div"],["outdent",""]], + "<ol><li>foo</li><li>b[ar</li></ol><div>b]az</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo<ol><li>b[ar</ol><li>b]az</ol>", + [["defaultparagraphseparator","p"],["outdent",""]], + "<ol><li>foo</li><li>b[ar</li></ol><p>b]az</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo</li><ol><li>b[ar</ol><li>b]az</ol>", + [["defaultparagraphseparator","div"],["outdent",""]], + "<ol><li>foo</li><li>b[ar</li></ol><div>b]az</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo</li><ol><li>b[ar</ol><li>b]az</ol>", + [["defaultparagraphseparator","p"],["outdent",""]], + "<ol><li>foo</li><li>b[ar</li></ol><p>b]az</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<ol><li>[foo<ol><li>bar</ol><li>baz]</ol><p>extra", + [["defaultparagraphseparator","div"],["outdent",""]], + "<div>[foo</div><ol><li>bar</li></ol><div>baz]</div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<ol><li>[foo<ol><li>bar</ol><li>baz]</ol><p>extra", + [["defaultparagraphseparator","p"],["outdent",""]], + "<p>[foo</p><ol><li>bar</li></ol><p>baz]</p><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<ol><li>[foo</li><ol><li>bar</ol><li>baz]</ol><p>extra", + [["defaultparagraphseparator","div"],["outdent",""]], + "<div>[foo</div><ol><li>bar</li></ol><div>baz]</div><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<ol><li>[foo</li><ol><li>bar</ol><li>baz]</ol><p>extra", + [["defaultparagraphseparator","p"],["outdent",""]], + "<p>[foo</p><ol><li>bar</li></ol><p>baz]</p><p>extra</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<ol><li>[foo]<ol><li>bar</ol>baz</ol>", + [["defaultparagraphseparator","div"],["outdent",""]], + "<div>[foo]</div><ol><ol><li>bar</li></ol><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<ol><li>[foo]<ol><li>bar</ol>baz</ol>", + [["defaultparagraphseparator","p"],["outdent",""]], + "<p>[foo]</p><ol><ol><li>bar</li></ol><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo<ol><li>[bar]</ol>baz</ol>", + [["outdent",""]], + "<ol><li>foo</li><li>[bar]</li><li>baz</li></ol>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo<ol><li>bar</ol>[baz]</ol>", + [["defaultparagraphseparator","div"],["outdent",""]], + "<ol><li>foo</li><ol><li>bar</li></ol></ol><div>[baz]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo<ol><li>bar</ol>[baz]</ol>", + [["defaultparagraphseparator","p"],["outdent",""]], + "<ol><li>foo</li><ol><li>bar</li></ol></ol><p>[baz]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<ol><li>[foo<ol><li>bar]</ol>baz</ol>", + [["defaultparagraphseparator","div"],["outdent",""]], + "<div>[foo</div><ol><li>bar]</li><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<ol><li>[foo<ol><li>bar]</ol>baz</ol>", + [["defaultparagraphseparator","p"],["outdent",""]], + "<p>[foo</p><ol><li>bar]</li><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["foo<ol start=5><li>[bar]</ol>baz", + [["defaultparagraphseparator","div"],["outdent",""]], + "foo<div>[bar]</div>baz", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["foo<ol start=5><li>[bar]</ol>baz", + [["defaultparagraphseparator","p"],["outdent",""]], + "foo<p>[bar]</p>baz", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["foo<ol id=abc><li>[bar]</ol>baz", + [["defaultparagraphseparator","div"],["outdent",""]], + "foo<div id=\"abc\"><div>[bar]</div></div>baz", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["foo<ol id=abc><li>[bar]</ol>baz", + [["defaultparagraphseparator","p"],["outdent",""]], + "foo<div id=\"abc\"><p>[bar]</p></div>baz", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["foo<ol style=color:blue><li>[bar]</ol>baz", + [["defaultparagraphseparator","div"],["outdent",""]], + "foo<div style=\"color:rgb(0, 0, 255)\"><div>[bar]</div></div>baz", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["foo<ol style=color:blue><li>[bar]</ol>baz", + [["defaultparagraphseparator","p"],["outdent",""]], + "foo<div style=\"color:rgb(0, 0, 255)\"><p>[bar]</p></div>baz", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["foo<ol><li value=5>[bar]</ol>baz", + [["defaultparagraphseparator","div"],["outdent",""]], + "foo<div value=\"5\">[bar]</div>baz", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["foo<ol><li value=5>[bar]</ol>baz", + [["defaultparagraphseparator","p"],["outdent",""]], + "foo<p value=\"5\">[bar]</p>baz", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["foo<ol><li id=abc>[bar]</ol>baz", + [["defaultparagraphseparator","div"],["outdent",""]], + "foo<div id=\"abc\">[bar]</div>baz", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["foo<ol><li id=abc>[bar]</ol>baz", + [["defaultparagraphseparator","p"],["outdent",""]], + "foo<p id=\"abc\">[bar]</p>baz", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["foo<ol><li style=color:blue>[bar]</ol>baz", + [["defaultparagraphseparator","div"],["outdent",""]], + "foo<div style=\"color:rgb(0, 0, 255)\">[bar]</div>baz", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["foo<ol><li style=color:blue>[bar]</ol>baz", + [["defaultparagraphseparator","p"],["outdent",""]], + "foo<p style=\"color:rgb(0, 0, 255)\">[bar]</p>baz", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo</li><ol><li value=5>[bar]</ol></ol>", + [["outdent",""]], + "<ol><li>foo</li><li value=\"5\">[bar]</li></ol>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<ul><li>foo</li><ol><li value=5>[bar]</ol></ul>", + [["outdent",""]], + "<ul><li>foo</li><li value=\"5\">[bar]</li></ul>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo</li><ol start=5><li>[bar]</ol><li>baz</ol>", + [["outdent",""]], + "<ol><li>foo</li><li>[bar]</li><li>baz</li></ol>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo</li><ol id=abc><li>[bar]</ol><li>baz</ol>", + [["outdent",""]], + "<ol><li>foo</li><li>[bar]</li><li>baz</li></ol>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo</li><ol style=color:blue><li>[bar]</ol><li>baz</ol>", + [["stylewithcss","true"],["outdent",""]], + "<ol><li>foo</li><li><span style=\"color:rgb(0, 0, 255)\">[bar]</span></li><li>baz</li></ol>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo</li><ol style=color:blue><li>[bar]</ol><li>baz</ol>", + [["stylewithcss","false"],["outdent",""]], + "<ol><li>foo</li><li><font color=\"#0000ff\">[bar]</font></li><li>baz</li></ol>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo</li><ol style=text-indent:1em><li>[bar]</ol><li>baz</ol>", + [["stylewithcss","true"],["outdent",""]], + "<ol><li>foo</li><li>[bar]</li><li>baz</li></ol>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo</li><ol style=text-indent:1em><li>[bar]</ol><li>baz</ol>", + [["stylewithcss","false"],["outdent",""]], + "<ol><li>foo</li><li>[bar]</li><li>baz</li></ol>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo</li><ol start=5><li>[bar<li>baz]</ol><li>quz</ol>", + [["outdent",""]], + "<ol><li>foo</li><li>[bar</li><li>baz]</li><li>quz</li></ol>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo</li><ol id=abc><li>[bar<li>baz]</ol><li>quz</ol>", + [["outdent",""]], + "<ol><li>foo</li><li>[bar</li><li>baz]</li><li>quz</li></ol>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo</li><ol style=color:blue><li>[bar<li>baz]</ol><li>quz</ol>", + [["stylewithcss","true"],["outdent",""]], + "<ol><li>foo</li><li><span style=\"color:rgb(0, 0, 255)\">[bar</span></li><li><span style=\"color:rgb(0, 0, 255)\">baz]</span></li><li>quz</li></ol>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo</li><ol style=color:blue><li>[bar<li>baz]</ol><li>quz</ol>", + [["stylewithcss","false"],["outdent",""]], + "<ol><li>foo</li><li><font color=\"#0000ff\">[bar</font></li><li><font color=\"#0000ff\">baz]</font></li><li>quz</li></ol>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo</li><ol style=text-indent:1em><li>[bar<li>baz]</ol><li>quz</ol>", + [["stylewithcss","true"],["outdent",""]], + "<ol><li>foo</li><li>[bar</li><li>baz]</li><li>quz</li></ol>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"outdent":[false,false,"",false,false,""]}], +["<ol><li>foo</li><ol style=text-indent:1em><li>[bar<li>baz]</ol><li>quz</ol>", + [["stylewithcss","false"],["outdent",""]], + "<ol><li>foo</li><li>[bar</li><li>baz]</li><li>quz</li></ol>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"outdent":[false,false,"",false,false,""]}], +["<blockquote><ol><li>[foo]</ol></blockquote><p>extra", + [["outdent",""]], + "<ol><li>[foo]</li></ol><p>extra</p>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<blockquote>foo<ol><li>[bar]</ol>baz</blockquote><p>extra", + [["outdent",""]], + "<blockquote>foo</blockquote><ol><li>[bar]</li></ol><blockquote>baz</blockquote><p>extra</p>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<blockquote><ol><li>foo</li><ol><li>[bar]</ol><li>baz</ol></blockquote><p>extra", + [["outdent",""]], + "<blockquote><ol><li>foo</li><li>[bar]</li><li>baz</li></ol></blockquote><p>extra</p>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<ol><li><h1>[foo]</h1></ol>", + [["outdent",""]], + "<h1>[foo]</h1>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<ol><li><xmp>[foo]</xmp></li></ol>", + [["outdent",""]], + "<xmp>[foo]</xmp>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<blockquote><ol><li>foo<div><ol><li>[bar]</ol></div><li>baz</ol></blockquote>", + [["defaultparagraphseparator","div"],["outdent",""]], + "<blockquote><ol><li>foo</li><li>[bar]</li><li>baz</li></ol></blockquote>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<blockquote><ol><li>foo<div><ol><li>[bar]</ol></div><li>baz</ol></blockquote>", + [["defaultparagraphseparator","p"],["outdent",""]], + "<blockquote><ol><li>foo</li><li>[bar]</li><li>baz</li></ol></blockquote>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<blockquote> <p>[foo]</p></blockquote>", + [["outdent",""]], + " <p>[foo]</p>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<blockquote><p>[foo]</p> </blockquote>", + [["outdent",""]], + "<p>[foo]</p> ", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<blockquote> <p>[foo]</p> </blockquote>", + [["outdent",""]], + " <p>[foo]</p> ", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<ol> <li>[foo]</li></ol>", + [["defaultparagraphseparator","div"],["outdent",""]], + " <div>[foo]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<ol> <li>[foo]</li></ol>", + [["defaultparagraphseparator","p"],["outdent",""]], + " <p>[foo]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<ol><li>[foo]</li> </ol>", + [["defaultparagraphseparator","div"],["outdent",""]], + "<div>[foo]</div> ", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<ol><li>[foo]</li> </ol>", + [["defaultparagraphseparator","p"],["outdent",""]], + "<p>[foo]</p> ", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<ol> <li>[foo]</li> </ol>", + [["defaultparagraphseparator","div"],["outdent",""]], + " <div>[foo]</div> ", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<ol> <li>[foo]</li> </ol>", + [["defaultparagraphseparator","p"],["outdent",""]], + " <p>[foo]</p> ", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<ul> <li>[foo]</li></ul>", + [["defaultparagraphseparator","div"],["outdent",""]], + " <div>[foo]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<ul> <li>[foo]</li></ul>", + [["defaultparagraphseparator","p"],["outdent",""]], + " <p>[foo]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<ul><li>[foo]</li> </ul>", + [["defaultparagraphseparator","div"],["outdent",""]], + "<div>[foo]</div> ", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<ul><li>[foo]</li> </ul>", + [["defaultparagraphseparator","p"],["outdent",""]], + "<p>[foo]</p> ", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<ul> <li>[foo]</li> </ul>", + [["defaultparagraphseparator","div"],["outdent",""]], + " <div>[foo]</div> ", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<ul> <li>[foo]</li> </ul>", + [["defaultparagraphseparator","p"],["outdent",""]], + " <p>[foo]</p> ", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<blockquote> <p>[foo]</p> <p>bar</p> <p>baz</p></blockquote>", + [["outdent",""]], + " <p>[foo]</p><blockquote> <p>bar</p> <p>baz</p></blockquote>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<blockquote> <p>foo</p> <p>[bar]</p> <p>baz</p></blockquote>", + [["outdent",""]], + "<blockquote> <p>foo</p> </blockquote><p>[bar]</p><blockquote> <p>baz</p></blockquote>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<blockquote> <p>foo</p> <p>bar</p> <p>[baz]</p></blockquote>", + [["outdent",""]], + "<blockquote> <p>foo</p> <p>bar</p> </blockquote><p>[baz]</p>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<ol> <li>[foo]</li> <li>bar</li> <li>baz</li></ol>", + [["defaultparagraphseparator","div"],["outdent",""]], + " <div>[foo]</div> <ol><li>bar</li> <li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<ol> <li>[foo]</li> <li>bar</li> <li>baz</li></ol>", + [["defaultparagraphseparator","p"],["outdent",""]], + " <p>[foo]</p> <ol><li>bar</li> <li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<ol> <li>foo</li> <li>[bar]</li> <li>baz</li></ol>", + [["defaultparagraphseparator","div"],["outdent",""]], + "<ol> <li>foo</li></ol> <div>[bar]</div> <ol><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<ol> <li>foo</li> <li>[bar]</li> <li>baz</li></ol>", + [["defaultparagraphseparator","p"],["outdent",""]], + "<ol> <li>foo</li></ol> <p>[bar]</p> <ol><li>baz</li></ol>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<ol> <li>foo</li> <li>bar</li> <li>[baz]</li></ol>", + [["defaultparagraphseparator","div"],["outdent",""]], + "<ol> <li>foo</li> <li>bar</li></ol> <div>[baz]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<ol> <li>foo</li> <li>bar</li> <li>[baz]</li></ol>", + [["defaultparagraphseparator","p"],["outdent",""]], + "<ol> <li>foo</li> <li>bar</li></ol> <p>[baz]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<ul> <li>[foo]</li> <li>bar</li> <li>baz</li></ul>", + [["defaultparagraphseparator","div"],["outdent",""]], + " <div>[foo]</div> <ul><li>bar</li> <li>baz</li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<ul> <li>[foo]</li> <li>bar</li> <li>baz</li></ul>", + [["defaultparagraphseparator","p"],["outdent",""]], + " <p>[foo]</p> <ul><li>bar</li> <li>baz</li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<ul> <li>foo</li> <li>[bar]</li> <li>baz</li></ul>", + [["defaultparagraphseparator","div"],["outdent",""]], + "<ul> <li>foo</li></ul> <div>[bar]</div> <ul><li>baz</li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<ul> <li>foo</li> <li>[bar]</li> <li>baz</li></ul>", + [["defaultparagraphseparator","p"],["outdent",""]], + "<ul> <li>foo</li></ul> <p>[bar]</p> <ul><li>baz</li></ul>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<ul> <li>foo</li> <li>bar</li> <li>[baz]</li></ul>", + [["defaultparagraphseparator","div"],["outdent",""]], + "<ul> <li>foo</li> <li>bar</li></ul> <div>[baz]</div>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<ul> <li>foo</li> <li>bar</li> <li>[baz]</li></ul>", + [["defaultparagraphseparator","p"],["outdent",""]], + "<ul> <li>foo</li> <li>bar</li></ul> <p>[baz]</p>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<ol><li>[]a<table><tr><td><br></table></ol>", + [["defaultparagraphseparator","div"],["outdent",""]], + "<div>[]a</div><table><tbody><tr><td><br></td></tr></tbody></table>", + [true,true], + {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"outdent":[false,false,"",false,false,""]}], +["<ol><li>[]a<table><tr><td><br></table></ol>", + [["defaultparagraphseparator","p"],["outdent",""]], + "<p>[]a</p><table><tbody><tr><td><br></td></tr></tbody></table>", + [true,true], + {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"outdent":[false,false,"",false,false,""]}], +["<blockquote><span>foo<br>[bar]</span></blockquote>", + [["outdent",""]], + "<blockquote>foo</blockquote><span>[bar]</span>", + [true], + {"outdent":[false,false,"",false,false,""]}], +["<ul><ul><li><span style=\"color:rgb(255, 0, 0)\">[]foo</span></li></ul></ul>", + [["outdent",""]], + "<ul><li><span style=\"color:rgb(255, 0, 0)\">[]foo</span></li></ul>", + [true], + {"outdent":[false,false,"",false,false,""]}] +] diff --git a/testing/web-platform/tests/editing/data/removeformat.js b/testing/web-platform/tests/editing/data/removeformat.js new file mode 100644 index 0000000000..db5c055083 --- /dev/null +++ b/testing/web-platform/tests/editing/data/removeformat.js @@ -0,0 +1,733 @@ +// For documentation of the format, see README in this directory. +var browserTests = [ +["foo[]bar", + [["removeformat",""]], + "foo[]bar", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["<span>foo</span>{}<span>bar</span>", + [["removeformat",""]], + "<span>foo</span>{}<span>bar</span>", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["<span>foo[</span><span>]bar</span>", + [["removeformat",""]], + "<span>foo[</span><span>]bar</span>", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["[foo<b>bar</b>baz]", + [["stylewithcss","true"],["removeformat",""]], + "[foobarbaz]", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"removeformat":[false,false,"",false,false,""]}], +["[foo<b>bar</b>baz]", + [["stylewithcss","false"],["removeformat",""]], + "[foobarbaz]", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"removeformat":[false,false,"",false,false,""]}], +["foo[<b>bar</b>baz]", + [["stylewithcss","true"],["removeformat",""]], + "foo[barbaz]", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"removeformat":[false,false,"",false,false,""]}], +["foo[<b>bar</b>baz]", + [["stylewithcss","false"],["removeformat",""]], + "foo[barbaz]", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"removeformat":[false,false,"",false,false,""]}], +["foo[<b>bar</b>]baz", + [["stylewithcss","true"],["removeformat",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"removeformat":[false,false,"",false,false,""]}], +["foo[<b>bar</b>]baz", + [["stylewithcss","false"],["removeformat",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"removeformat":[false,false,"",false,false,""]}], +["foo<b>[bar]</b>baz", + [["stylewithcss","true"],["removeformat",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"removeformat":[false,false,"",false,false,""]}], +["foo<b>[bar]</b>baz", + [["stylewithcss","false"],["removeformat",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"removeformat":[false,false,"",false,false,""]}], +["foo<b>b[a]r</b>baz", + [["stylewithcss","true"],["removeformat",""]], + "foo<b>b</b>[a]<b>r</b>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"removeformat":[false,false,"",false,false,""]}], +["foo<b>b[a]r</b>baz", + [["stylewithcss","false"],["removeformat",""]], + "foo<b>b</b>[a]<b>r</b>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"removeformat":[false,false,"",false,false,""]}], +["[foo<span style=\"font-weight: bold\">bar</span>baz]", + [["stylewithcss","true"],["removeformat",""]], + "[foobarbaz]", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"removeformat":[false,false,"",false,false,""]}], +["[foo<span style=\"font-weight: bold\">bar</span>baz]", + [["stylewithcss","false"],["removeformat",""]], + "[foobarbaz]", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"removeformat":[false,false,"",false,false,""]}], +["[foo<span style=\"display: none\">bar</span>baz]", + [["stylewithcss","true"],["removeformat",""]], + "[foobarbaz]", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"removeformat":[false,false,"",false,false,""]}], +["[foo<span style=\"display: none\">bar</span>baz]", + [["stylewithcss","false"],["removeformat",""]], + "[foobarbaz]", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"removeformat":[false,false,"",false,false,""]}], +["[foo<span style=\"display: none; font-weight: bold\">bar</span>baz]", + [["stylewithcss","true"],["removeformat",""]], + "[foobarbaz]", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"removeformat":[false,false,"",false,false,""]}], +["[foo<span style=\"display: none; font-weight: bold\">bar</span>baz]", + [["stylewithcss","false"],["removeformat",""]], + "[foobarbaz]", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"removeformat":[false,false,"",false,false,""]}], +["foo<span style=\"font-weight: bold\">b[a]r</span>baz", + [["stylewithcss","true"],["removeformat",""]], + "foo<span style=\"font-weight:bold\">b</span>[a]<span style=\"font-weight:bold\">r</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"removeformat":[false,false,"",false,false,""]}], +["foo<span style=\"font-weight: bold\">b[a]r</span>baz", + [["stylewithcss","false"],["removeformat",""]], + "foo<span style=\"font-weight:bold\">b</span>[a]<span style=\"font-weight:bold\">r</span>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"removeformat":[false,false,"",false,false,""]}], +["foo<span style=\"display: none\">b[a]r</span>baz", + [["stylewithcss","true"],["removeformat",""]], + "foo<span style=\"display:none\">b</span>[a]<span style=\"display:none\">r</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"removeformat":[false,false,"",false,false,""]}], +["foo<span style=\"display: none\">b[a]r</span>baz", + [["stylewithcss","false"],["removeformat",""]], + "foo<span style=\"display:none\">b</span>[a]<span style=\"display:none\">r</span>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"removeformat":[false,false,"",false,false,""]}], +["foo<span style=\"display: none; font-weight: bold\">b[a]r</span>baz", + [["stylewithcss","true"],["removeformat",""]], + "foo<span style=\"display:none; font-weight:bold\">b</span>[a]<span style=\"display:none; font-weight:bold\">r</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"removeformat":[false,false,"",false,false,""]}], +["foo<span style=\"display: none; font-weight: bold\">b[a]r</span>baz", + [["stylewithcss","false"],["removeformat",""]], + "foo<span style=\"display:none; font-weight:bold\">b</span>[a]<span style=\"display:none; font-weight:bold\">r</span>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"removeformat":[false,false,"",false,false,""]}], +["[foo<span style=\"font-variant: small-caps\">bar</span>baz]", + [["stylewithcss","true"],["removeformat",""]], + "[foobarbaz]", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"removeformat":[false,false,"",false,false,""]}], +["[foo<span style=\"font-variant: small-caps\">bar</span>baz]", + [["stylewithcss","false"],["removeformat",""]], + "[foobarbaz]", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"removeformat":[false,false,"",false,false,""]}], +["foo<span style=\"font-variant: small-caps\">b[a]r</span>baz", + [["stylewithcss","true"],["removeformat",""]], + "foo<span style=\"font-variant:small-caps\">b</span>[a]<span style=\"font-variant:small-caps\">r</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"removeformat":[false,false,"",false,false,""]}], +["foo<span style=\"font-variant: small-caps\">b[a]r</span>baz", + [["stylewithcss","false"],["removeformat",""]], + "foo<span style=\"font-variant:small-caps\">b</span>[a]<span style=\"font-variant:small-caps\">r</span>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"removeformat":[false,false,"",false,false,""]}], +["[foo<b id=foo>bar</b>baz]", + [["stylewithcss","true"],["removeformat",""]], + "[foobarbaz]", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"removeformat":[false,false,"",false,false,""]}], +["[foo<b id=foo>bar</b>baz]", + [["stylewithcss","false"],["removeformat",""]], + "[foobarbaz]", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"removeformat":[false,false,"",false,false,""]}], +["foo<b id=foo>b[a]r</b>baz", + [["stylewithcss","true"],["removeformat",""]], + "foo<b id=\"foo\">b</b>[a]<b>r</b>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"removeformat":[false,false,"",false,false,""]}], +["foo<b id=foo>b[a]r</b>baz", + [["stylewithcss","false"],["removeformat",""]], + "foo<b id=\"foo\">b</b>[a]<b>r</b>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"removeformat":[false,false,"",false,false,""]}], +["[foo<a>bar</a>baz]", + [["removeformat",""]], + "[foo<a>bar</a>baz]", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["foo<a>b[a]r</a>baz", + [["removeformat",""]], + "foo<a>b[a]r</a>baz", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["[foo<a href=foo>bar</a>baz]", + [["removeformat",""]], + "[foo<a href=\"foo\">bar</a>baz]", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["foo<a href=foo>b[a]r</a>baz", + [["removeformat",""]], + "foo<a href=\"foo\">b[a]r</a>baz", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["[foo<abbr>bar</abbr>baz]", + [["removeformat",""]], + "[foobarbaz]", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["foo<abbr>b[a]r</abbr>baz", + [["removeformat",""]], + "foo<abbr>b</abbr>[a]<abbr>r</abbr>baz", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["[foo<acronym>bar</acronym>baz]", + [["removeformat",""]], + "[foobarbaz]", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["foo<acronym>b[a]r</acronym>baz", + [["removeformat",""]], + "foo<acronym>b</acronym>[a]<acronym>r</acronym>baz", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["[foo<bdi dir=rtl>bar</bdi>baz]", + [["removeformat",""]], + "[foobarbaz]", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["foo<bdi dir=rtl>b[a]r</bdi>baz", + [["removeformat",""]], + "foo<bdi dir=\"rtl\">b</bdi>[a]<bdi dir=\"rtl\">r</bdi>baz", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["[foo<bdo dir=rtl>bar</bdo>baz]", + [["removeformat",""]], + "[foobarbaz]", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["foo<bdo dir=rtl>b[a]r</bdo>baz", + [["removeformat",""]], + "foo<bdo dir=\"rtl\">b</bdo>[a]<bdo dir=\"rtl\">r</bdo>baz", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["[foo<big>bar</big>baz]", + [["removeformat",""]], + "[foobarbaz]", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["foo<big>b[a]r</big>baz", + [["removeformat",""]], + "foo<big>b</big>[a]<big>r</big>baz", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["[foo<blink>bar</blink>baz]", + [["removeformat",""]], + "[foobarbaz]", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["foo<blink>b[a]r</blink>baz", + [["removeformat",""]], + "foo<blink>b</blink>[a]<blink>r</blink>baz", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["[foo<cite>bar</cite>baz]", + [["removeformat",""]], + "[foobarbaz]", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["foo<cite>b[a]r</cite>baz", + [["removeformat",""]], + "foo<cite>b</cite>[a]<cite>r</cite>baz", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["[foo<code>bar</code>baz]", + [["removeformat",""]], + "[foobarbaz]", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["foo<code>b[a]r</code>baz", + [["removeformat",""]], + "foo<code>b</code>[a]<code>r</code>baz", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["[foo<del>bar</del>baz]", + [["removeformat",""]], + "[foo<del>bar</del>baz]", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["foo<del>b[a]r</del>baz", + [["removeformat",""]], + "foo<del>b[a]r</del>baz", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["[foo<dfn>bar</dfn>baz]", + [["removeformat",""]], + "[foobarbaz]", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["foo<dfn>b[a]r</dfn>baz", + [["removeformat",""]], + "foo<dfn>b</dfn>[a]<dfn>r</dfn>baz", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["[foo<em>bar</em>baz]", + [["removeformat",""]], + "[foobarbaz]", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["foo<em>b[a]r</em>baz", + [["removeformat",""]], + "foo<em>b</em>[a]<em>r</em>baz", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["[foo<font>bar</font>baz]", + [["stylewithcss","true"],["removeformat",""]], + "[foobarbaz]", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"removeformat":[false,false,"",false,false,""]}], +["[foo<font>bar</font>baz]", + [["stylewithcss","false"],["removeformat",""]], + "[foobarbaz]", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"removeformat":[false,false,"",false,false,""]}], +["foo<font>b[a]r</font>baz", + [["stylewithcss","true"],["removeformat",""]], + "foo<font>b</font>[a]<font>r</font>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"removeformat":[false,false,"",false,false,""]}], +["foo<font>b[a]r</font>baz", + [["stylewithcss","false"],["removeformat",""]], + "foo<font>b</font>[a]<font>r</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"removeformat":[false,false,"",false,false,""]}], +["[foo<font color=blue>bar</font>baz]", + [["stylewithcss","true"],["removeformat",""]], + "[foobarbaz]", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"removeformat":[false,false,"",false,false,""]}], +["[foo<font color=blue>bar</font>baz]", + [["stylewithcss","false"],["removeformat",""]], + "[foobarbaz]", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"removeformat":[false,false,"",false,false,""]}], +["foo<font color=blue>b[a]r</font>baz", + [["stylewithcss","true"],["removeformat",""]], + "foo<font color=\"blue\">b</font>[a]<font color=\"blue\">r</font>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"removeformat":[false,false,"",false,false,""]}], +["foo<font color=blue>b[a]r</font>baz", + [["stylewithcss","false"],["removeformat",""]], + "foo<font color=\"blue\">b</font>[a]<font color=\"blue\">r</font>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"removeformat":[false,false,"",false,false,""]}], +["[foo<i>bar</i>baz]", + [["stylewithcss","true"],["removeformat",""]], + "[foobarbaz]", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"removeformat":[false,false,"",false,false,""]}], +["[foo<i>bar</i>baz]", + [["stylewithcss","false"],["removeformat",""]], + "[foobarbaz]", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"removeformat":[false,false,"",false,false,""]}], +["foo<i>b[a]r</i>baz", + [["stylewithcss","true"],["removeformat",""]], + "foo<i>b</i>[a]<i>r</i>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"removeformat":[false,false,"",false,false,""]}], +["foo<i>b[a]r</i>baz", + [["stylewithcss","false"],["removeformat",""]], + "foo<i>b</i>[a]<i>r</i>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"removeformat":[false,false,"",false,false,""]}], +["[foo<ins>bar</ins>baz]", + [["removeformat",""]], + "[foobarbaz]", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["foo<ins>b[a]r</ins>baz", + [["removeformat",""]], + "foo<ins>b</ins>[a]<ins>r</ins>baz", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["[foo<kbd>bar</kbd>baz]", + [["removeformat",""]], + "[foobarbaz]", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["foo<kbd>b[a]r</kbd>baz", + [["removeformat",""]], + "foo<kbd>b</kbd>[a]<kbd>r</kbd>baz", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["[foo<mark>bar</mark>baz]", + [["removeformat",""]], + "[foobarbaz]", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["foo<mark>b[a]r</mark>baz", + [["removeformat",""]], + "foo<mark>b</mark>[a]<mark>r</mark>baz", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["[foo<nobr>bar</nobr>baz]", + [["removeformat",""]], + "[foobarbaz]", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["foo<nobr>b[a]r</nobr>baz", + [["removeformat",""]], + "foo<nobr>b</nobr>[a]<nobr>r</nobr>baz", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["[foo<q>bar</q>baz]", + [["removeformat",""]], + "[foobarbaz]", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["foo<q>b[a]r</q>baz", + [["removeformat",""]], + "foo<q>b</q>[a]<q>r</q>baz", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["[foo<samp>bar</samp>baz]", + [["removeformat",""]], + "[foobarbaz]", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["foo<samp>b[a]r</samp>baz", + [["removeformat",""]], + "foo<samp>b</samp>[a]<samp>r</samp>baz", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["[foo<s>bar</s>baz]", + [["stylewithcss","true"],["removeformat",""]], + "[foobarbaz]", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"removeformat":[false,false,"",false,false,""]}], +["[foo<s>bar</s>baz]", + [["stylewithcss","false"],["removeformat",""]], + "[foobarbaz]", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"removeformat":[false,false,"",false,false,""]}], +["foo<s>b[a]r</s>baz", + [["stylewithcss","true"],["removeformat",""]], + "foo<s>b</s>[a]<s>r</s>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"removeformat":[false,false,"",false,false,""]}], +["foo<s>b[a]r</s>baz", + [["stylewithcss","false"],["removeformat",""]], + "foo<s>b</s>[a]<s>r</s>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"removeformat":[false,false,"",false,false,""]}], +["[foo<small>bar</small>baz]", + [["removeformat",""]], + "[foobarbaz]", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["foo<small>b[a]r</small>baz", + [["removeformat",""]], + "foo<small>b</small>[a]<small>r</small>baz", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["[foo<span>bar</span>baz]", + [["removeformat",""]], + "[foobarbaz]", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["foo<span>b[a]r</span>baz", + [["removeformat",""]], + "foo<span>b</span>[a]<span>r</span>baz", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["[foo<strike>bar</strike>baz]", + [["stylewithcss","true"],["removeformat",""]], + "[foobarbaz]", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"removeformat":[false,false,"",false,false,""]}], +["[foo<strike>bar</strike>baz]", + [["stylewithcss","false"],["removeformat",""]], + "[foobarbaz]", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"removeformat":[false,false,"",false,false,""]}], +["foo<strike>b[a]r</strike>baz", + [["stylewithcss","true"],["removeformat",""]], + "foo<strike>b</strike>[a]<strike>r</strike>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"removeformat":[false,false,"",false,false,""]}], +["foo<strike>b[a]r</strike>baz", + [["stylewithcss","false"],["removeformat",""]], + "foo<strike>b</strike>[a]<strike>r</strike>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"removeformat":[false,false,"",false,false,""]}], +["[foo<strong>bar</strong>baz]", + [["removeformat",""]], + "[foobarbaz]", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["foo<strong>b[a]r</strong>baz", + [["removeformat",""]], + "foo<strong>b</strong>[a]<strong>r</strong>baz", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["[foo<sub>bar</sub>baz]", + [["stylewithcss","true"],["removeformat",""]], + "[foobarbaz]", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"removeformat":[false,false,"",false,false,""]}], +["[foo<sub>bar</sub>baz]", + [["stylewithcss","false"],["removeformat",""]], + "[foobarbaz]", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"removeformat":[false,false,"",false,false,""]}], +["foo<sub>b[a]r</sub>baz", + [["stylewithcss","true"],["removeformat",""]], + "foo<sub>b</sub>[a]<sub>r</sub>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"removeformat":[false,false,"",false,false,""]}], +["foo<sub>b[a]r</sub>baz", + [["stylewithcss","false"],["removeformat",""]], + "foo<sub>b</sub>[a]<sub>r</sub>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"removeformat":[false,false,"",false,false,""]}], +["[foo<sup>bar</sup>baz]", + [["stylewithcss","true"],["removeformat",""]], + "[foobarbaz]", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"removeformat":[false,false,"",false,false,""]}], +["[foo<sup>bar</sup>baz]", + [["stylewithcss","false"],["removeformat",""]], + "[foobarbaz]", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"removeformat":[false,false,"",false,false,""]}], +["foo<sup>b[a]r</sup>baz", + [["stylewithcss","true"],["removeformat",""]], + "foo<sup>b</sup>[a]<sup>r</sup>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"removeformat":[false,false,"",false,false,""]}], +["foo<sup>b[a]r</sup>baz", + [["stylewithcss","false"],["removeformat",""]], + "foo<sup>b</sup>[a]<sup>r</sup>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"removeformat":[false,false,"",false,false,""]}], +["[foo<tt>bar</tt>baz]", + [["removeformat",""]], + "[foobarbaz]", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["foo<tt>b[a]r</tt>baz", + [["removeformat",""]], + "foo<tt>b</tt>[a]<tt>r</tt>baz", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["[foo<u>bar</u>baz]", + [["stylewithcss","true"],["removeformat",""]], + "[foobarbaz]", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"removeformat":[false,false,"",false,false,""]}], +["[foo<u>bar</u>baz]", + [["stylewithcss","false"],["removeformat",""]], + "[foobarbaz]", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"removeformat":[false,false,"",false,false,""]}], +["foo<u>b[a]r</u>baz", + [["stylewithcss","true"],["removeformat",""]], + "foo<u>b</u>[a]<u>r</u>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"removeformat":[false,false,"",false,false,""]}], +["foo<u>b[a]r</u>baz", + [["stylewithcss","false"],["removeformat",""]], + "foo<u>b</u>[a]<u>r</u>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"removeformat":[false,false,"",false,false,""]}], +["[foo<var>bar</var>baz]", + [["removeformat",""]], + "[foobarbaz]", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["foo<var>b[a]r</var>baz", + [["removeformat",""]], + "foo<var>b</var>[a]<var>r</var>baz", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["[foo<br>bar]", + [["removeformat",""]], + "[foo<br>bar]", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["[foo<hr>bar]", + [["removeformat",""]], + "[foo<hr>bar]", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["[foo<wbr>bar]", + [["removeformat",""]], + "[foo<wbr>bar]", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["[foo<img>bar]", + [["removeformat",""]], + "[foo<img>bar]", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["[foo<img src=abc>bar]", + [["removeformat",""]], + "[foo<img src=\"abc\">bar]", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["[foo<video></video>bar]", + [["removeformat",""]], + "[foo<video></video>bar]", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["[foo<video src=abc></video>bar]", + [["removeformat",""]], + "[foo<video src=\"abc\"></video>bar]", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["[foo<svg><circle fill=blue r=20 cx=20 cy=20 /></svg>bar]", + [["removeformat",""]], + "[foo<svg><circle fill=\"blue\" r=\"20\" cx=\"20\" cy=\"20\"></circle></svg>bar]", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["[foo<nonexistentelement>bar</nonexistentelement>baz]", + [["removeformat",""]], + "[foo<nonexistentelement>bar</nonexistentelement>baz]", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["foo<nonexistentelement>b[a]r</nonexistentelement>baz", + [["removeformat",""]], + "foo<nonexistentelement>b[a]r</nonexistentelement>baz", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["[foo<nonexistentelement style=\"display: block\">bar</nonexistentelement>baz]", + [["removeformat",""]], + "[foo<nonexistentelement style=\"display:block\">bar</nonexistentelement>baz]", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["foo<nonexistentelement style=\"display: block\">b[a]r</nonexistentelement>baz", + [["removeformat",""]], + "foo<nonexistentelement style=\"display:block\">b[a]r</nonexistentelement>baz", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["[foo<span id=foo>bar</span>baz]", + [["removeformat",""]], + "[foobarbaz]", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["foo<span id=foo>b[a]r</span>baz", + [["removeformat",""]], + "foo<span id=\"foo\">b</span>[a]<span>r</span>baz", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["[foo<span class=foo>bar</span>baz]", + [["removeformat",""]], + "[foobarbaz]", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["foo<span class=foo>b[a]r</span>baz", + [["removeformat",""]], + "foo<span class=\"foo\">b</span>[a]<span class=\"foo\">r</span>baz", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["[foo<b style=\"font-weight: normal\">bar</b>baz]", + [["stylewithcss","true"],["removeformat",""]], + "[foobarbaz]", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"removeformat":[false,false,"",false,false,""]}], +["[foo<b style=\"font-weight: normal\">bar</b>baz]", + [["stylewithcss","false"],["removeformat",""]], + "[foobarbaz]", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"removeformat":[false,false,"",false,false,""]}], +["foo<b style=\"font-weight: normal\">b[a]r</b>baz", + [["stylewithcss","true"],["removeformat",""]], + "foo<b style=\"font-weight:normal\">b</b>[a]<b style=\"font-weight:normal\">r</b>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"removeformat":[false,false,"",false,false,""]}], +["foo<b style=\"font-weight: normal\">b[a]r</b>baz", + [["stylewithcss","false"],["removeformat",""]], + "foo<b style=\"font-weight:normal\">b</b>[a]<b style=\"font-weight:normal\">r</b>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"removeformat":[false,false,"",false,false,""]}], +["<p style=\"background-color: aqua\">foo[bar]baz</p>", + [["removeformat",""]], + "<p style=\"background-color:rgb(0, 255, 255)\">foo[bar]baz</p>", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["<p><span style=\"background-color: aqua\">foo[bar]baz</span></p>", + [["stylewithcss","true"],["removeformat",""]], + "<p><span style=\"background-color:rgb(0, 255, 255)\">foo</span>[bar]<span style=\"background-color:rgb(0, 255, 255)\">baz</span></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"removeformat":[false,false,"",false,false,""]}], +["<p><span style=\"background-color: aqua\">foo[bar]baz</span></p>", + [["stylewithcss","false"],["removeformat",""]], + "<p><span style=\"background-color:rgb(0, 255, 255)\">foo</span>[bar]<span style=\"background-color:rgb(0, 255, 255)\">baz</span></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"removeformat":[false,false,"",false,false,""]}], +["<p style=\"font-weight: bold\">foo[bar]baz</p>", + [["stylewithcss","true"],["removeformat",""]], + "<p><span style=\"font-weight:bold\">foo</span>[bar]<span style=\"font-weight:bold\">baz</span></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"removeformat":[false,false,"",false,false,""]}], +["<p style=\"font-weight: bold\">foo[bar]baz</p>", + [["stylewithcss","false"],["removeformat",""]], + "<p><b>foo</b>[bar]<b>baz</b></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"removeformat":[false,false,"",false,false,""]}], +["<b><p style=\"font-weight: bold\">foo[bar]baz</p></b>", + [["stylewithcss","true"],["removeformat",""]], + "<p><span style=\"font-weight:bold\">foo</span>[bar]<span style=\"font-weight:bold\">baz</span></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"removeformat":[false,false,"",false,false,""]}], +["<b><p style=\"font-weight: bold\">foo[bar]baz</p></b>", + [["stylewithcss","false"],["removeformat",""]], + "<p><b>foo</b>[bar]<b>baz</b></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"removeformat":[false,false,"",false,false,""]}], +["<p style=\"font-variant: small-caps\">foo[bar]baz</p>", + [["removeformat",""]], + "<p style=\"font-variant:small-caps\">foo[bar]baz</p>", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["{<p style=\"font-variant: small-caps\">foobarbaz</p>}", + [["removeformat",""]], + "{<p style=\"font-variant:small-caps\">foobarbaz</p>}", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["<p style=\"text-indent: 2em\">foo[bar]baz</p>", + [["removeformat",""]], + "<p style=\"text-indent:2em\">foo[bar]baz</p>", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["{<p style=\"text-indent: 2em\">foobarbaz</p>}", + [["removeformat",""]], + "{<p style=\"text-indent:2em\">foobarbaz</p>}", + [true], + {"removeformat":[false,false,"",false,false,""]}], +["<table data-start=0 data-end=1><tr><td><b>foo</b></table>", + [["stylewithcss","true"],["removeformat",""]], + "<table>{<tbody><tr><td>foo</td></tr></tbody>}</table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"removeformat":[false,false,"",false,false,""]}], +["<table data-start=0 data-end=1><tr><td><b>foo</b></table>", + [["stylewithcss","false"],["removeformat",""]], + "<table>{<tbody><tr><td>foo</td></tr></tbody>}</table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"removeformat":[false,false,"",false,false,""]}] +] diff --git a/testing/web-platform/tests/editing/data/strikethrough.js b/testing/web-platform/tests/editing/data/strikethrough.js new file mode 100644 index 0000000000..db26555700 --- /dev/null +++ b/testing/web-platform/tests/editing/data/strikethrough.js @@ -0,0 +1,771 @@ +// For documentation of the format, see README in this directory. +var browserTests = [ +["foo[]bar", + [["strikethrough",""]], + "foo[]bar", + [true], + {"strikethrough":[false,false,"",false,true,""]}], +["<p>[foo</p> <p>bar]</p>", + [["stylewithcss","true"],["strikethrough",""]], + "<p><span style=\"text-decoration:line-through\">[foo</span></p> <p><span style=\"text-decoration:line-through\">bar]</span></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,false,"",false,true,""]}], +["<p>[foo</p> <p>bar]</p>", + [["stylewithcss","false"],["strikethrough",""]], + "<p><strike>[foo</strike></p> <p><strike>bar]</strike></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,false,"",false,true,""]}], +// The first <span> should be styled with text-decoration, then, it becomes a +// good container for the following text node and the other <span>. +["<span>[foo</span> <span>bar]</span>", + [["stylewithcss","true"],["strikethrough",""]], + "<span style=\"text-decoration:line-through\"><span>foo</span> <span>bar</span></span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,false,"",false,true,""]}], +["<span>[foo</span> <span>bar]</span>", + [["stylewithcss","false"],["strikethrough",""]], + "<strike><span>[foo</span> <span>bar]</span></strike>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,false,"",false,true,""]}], +// Entire the content of the first <p> and the last <p> should be wrapped in +// new <span> elements, and in the middle <p>, the <span> element should be +// styled but the invisible text nodes should be ignored. +["<p>[foo</p><p> <span>bar</span> </p><p>baz]</p>", + [["stylewithcss","true"],["strikethrough",""]], + "<p><span style=\"text-decoration:line-through\">[foo</span></p><p> <span style=\"text-decoration:line-through\">bar</span> </p><p><span style=\"text-decoration:line-through\">baz</span></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,false,"",false,true,""]}], +["<p>[foo</p><p> <span>bar</span> </p><p>baz]</p>", + [["stylewithcss","false"],["strikethrough",""]], + "<p><strike>[foo</strike></p><p> <strike><span>bar</span></strike> </p><p><strike>baz]</strike></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,false,"",false,true,""]}], +["<p>[foo<p><br><p>bar]", + [["stylewithcss","true"],["strikethrough",""]], + "<p><span style=\"text-decoration:line-through\">[foo</span></p><p><span style=\"text-decoration:line-through\"><br></span></p><p><span style=\"text-decoration:line-through\">bar]</span></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,false,"",false,true,""]}], +["<p>[foo<p><br><p>bar]", + [["stylewithcss","false"],["strikethrough",""]], + "<p><strike>[foo</strike></p><p><strike><br></strike></p><p><strike>bar]</strike></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,false,"",false,true,""]}], +["<b>foo[]bar</b>", + [["strikethrough",""]], + "<b>foo[]bar</b>", + [true], + {"strikethrough":[false,false,"",false,true,""]}], +["<i>foo[]bar</i>", + [["strikethrough",""]], + "<i>foo[]bar</i>", + [true], + {"strikethrough":[false,false,"",false,true,""]}], +["<span>foo</span>{}<span>bar</span>", + [["strikethrough",""]], + "<span>foo</span>{}<span>bar</span>", + [true], + {"strikethrough":[false,false,"",false,true,""]}], +["<span>foo[</span><span>]bar</span>", + [["strikethrough",""]], + "<span>foo[</span><span>]bar</span>", + [true], + {"strikethrough":[false,false,"",false,true,""]}], +["foo[bar]baz", + [["stylewithcss","true"],["strikethrough",""]], + "foo<span style=\"text-decoration:line-through\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,false,"",false,true,""]}], +["foo[bar]baz", + [["stylewithcss","false"],["strikethrough",""]], + "foo<strike>[bar]</strike>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,false,"",false,true,""]}], +["foo[bar<b>baz]qoz</b>quz", + [["stylewithcss","true"],["strikethrough",""]], + "foo<span style=\"text-decoration:line-through\">[bar</span><b><span style=\"text-decoration:line-through\">baz]</span>qoz</b>quz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,false,"",false,true,""]}], +["foo[bar<b>baz]qoz</b>quz", + [["stylewithcss","false"],["strikethrough",""]], + "foo<strike>[bar</strike><b><strike>baz]</strike>qoz</b>quz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,false,"",false,true,""]}], +["foo[bar<i>baz]qoz</i>quz", + [["stylewithcss","true"],["strikethrough",""]], + "foo<span style=\"text-decoration:line-through\">[bar</span><i><span style=\"text-decoration:line-through\">baz]</span>qoz</i>quz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,false,"",false,true,""]}], +["foo[bar<i>baz]qoz</i>quz", + [["stylewithcss","false"],["strikethrough",""]], + "foo<strike>[bar</strike><i><strike>baz]</strike>qoz</i>quz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,false,"",false,true,""]}], +["{<p><p> <p>foo</p>}", + [["stylewithcss","true"],["strikethrough",""]], + "{<p></p><p> </p><p><span style=\"text-decoration:line-through\">foo</span></p>}", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,false,"",false,true,""]}], +["{<p><p> <p>foo</p>}", + [["stylewithcss","false"],["strikethrough",""]], + "{<p></p><p> </p><p><strike>foo</strike></p>}", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,false,"",false,true,""]}], +["<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>", + [["stylewithcss","true"],["strikethrough",""]], + "<table><tbody><tr><td>foo</td><td>b<span style=\"text-decoration:line-through\">[a]</span>r</td><td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,false,"",false,true,""]}], +["<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>", + [["stylewithcss","false"],["strikethrough",""]], + "<table><tbody><tr><td>foo</td><td>b<strike>[a]</strike>r</td><td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,false,"",false,true,""]}], +["<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table>", + [["stylewithcss","true"],["strikethrough",""]], + "<table><tbody><tr><td>foo</td>{<td><span style=\"text-decoration:line-through\">bar</span></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,false,"",false,true,""]}], +["<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table>", + [["stylewithcss","false"],["strikethrough",""]], + "<table><tbody><tr><td>foo</td>{<td><strike>bar</strike></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,false,"",false,true,""]}], +["<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table>", + [["stylewithcss","true"],["strikethrough",""]], + "<table><tbody><tr>{<td><span style=\"text-decoration:line-through\">foo</span></td><td><span style=\"text-decoration:line-through\">bar</span></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,false,"",false,true,""]}], +["<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table>", + [["stylewithcss","false"],["strikethrough",""]], + "<table><tbody><tr>{<td><strike>foo</strike></td><td><strike>bar</strike></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,false,"",false,true,""]}], +["<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>", + [["stylewithcss","true"],["strikethrough",""]], + "<table><tbody>{<tr><td><span style=\"text-decoration:line-through\">foo</span></td><td><span style=\"text-decoration:line-through\">bar</span></td><td><span style=\"text-decoration:line-through\">baz</span></td></tr>}</tbody></table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,false,"",false,true,""]}], +["<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>", + [["stylewithcss","false"],["strikethrough",""]], + "<table><tbody>{<tr><td><strike>foo</strike></td><td><strike>bar</strike></td><td><strike>baz</strike></td></tr>}</tbody></table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,false,"",false,true,""]}], +["<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>", + [["stylewithcss","true"],["strikethrough",""]], + "<table>{<tbody><tr><td><span style=\"text-decoration:line-through\">foo</span></td><td><span style=\"text-decoration:line-through\">bar</span></td><td><span style=\"text-decoration:line-through\">baz</span></td></tr></tbody>}</table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,false,"",false,true,""]}], +["<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>", + [["stylewithcss","false"],["strikethrough",""]], + "<table>{<tbody><tr><td><strike>foo</strike></td><td><strike>bar</strike></td><td><strike>baz</strike></td></tr></tbody>}</table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,false,"",false,true,""]}], +["{<table><tr><td>foo<td>bar<td>baz</table>}", + [["stylewithcss","true"],["strikethrough",""]], + "{<table><tbody><tr><td><span style=\"text-decoration:line-through\">foo</span></td><td><span style=\"text-decoration:line-through\">bar</span></td><td><span style=\"text-decoration:line-through\">baz</span></td></tr></tbody></table>}", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,false,"",false,true,""]}], +["{<table><tr><td>foo<td>bar<td>baz</table>}", + [["stylewithcss","false"],["strikethrough",""]], + "{<table><tbody><tr><td><strike>foo</strike></td><td><strike>bar</strike></td><td><strike>baz</strike></td></tr></tbody></table>}", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,false,"",false,true,""]}], +// <u> is just representing underline style. Therefore, browsers should not +// keep it. Instead, it should be replaced with new <span> and set its +// text-decoration to line-through (requested style) and underline (default +// style of <u>). +["foo<u>[bar]</u>baz", + [["stylewithcss","true"],["strikethrough",""]], + "foo<span style=\"text-decoration:underline line-through\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,false,"",false,true,""]}], +["foo<u>[bar]</u>baz", + [["stylewithcss","false"],["strikethrough",""]], + "foo<u><strike>[bar]</strike></u>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,false,"",false,true,""]}], +// The <span> which is a container of the range has text-decoration style. +// Therefore, it should be updated rather than creating new element. +["foo<span style=\"text-decoration: underline\">[bar]</span>baz", + [["stylewithcss","true"],["strikethrough",""]], + "foo<span style=\"text-decoration:underline line-through\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,false,"",false,true,""]}], +["foo<span style=\"text-decoration: underline\">[bar]</span>baz", + [["stylewithcss","false"],["strikethrough",""]], + "foo<strike><span style=\"text-decoration:underline\">[bar]</span></strike>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,false,"",false,true,""]}], +["<u>foo[bar]baz</u>", + [["stylewithcss","true"],["strikethrough",""]], + "<u>foo<span style=\"text-decoration:line-through\">[bar]</span>baz</u>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,false,"",false,true,""]}], +["<u>foo[bar]baz</u>", + [["stylewithcss","false"],["strikethrough",""]], + "<u>foo<strike>[bar]</strike>baz</u>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,false,"",false,true,""]}], +["<u>foo[b<span style=\"color:blue\">ar]ba</span>z</u>", + [["stylewithcss","true"],["strikethrough",""]], + "<u>foo<span style=\"text-decoration:line-through\">[b</span><span style=\"color:rgb(0, 0, 255)\"><span style=\"text-decoration:line-through\">ar]</span>ba</span>z</u>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,false,"",false,true,""]}], +["<u>foo[b<span style=\"color:blue\">ar]ba</span>z</u>", + [["stylewithcss","false"],["strikethrough",""]], + "<u>foo<strike>[b</strike><span style=\"color:rgb(0, 0, 255)\"><strike>ar]</strike>ba</span>z</u>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,false,"",false,true,""]}], +["<u>foo[b<span style=\"color:blue\" id=foo>ar]ba</span>z</u>", + [["stylewithcss","true"],["strikethrough",""]], + "<u>foo<span style=\"text-decoration:line-through\">[b</span><span style=\"color:rgb(0, 0, 255)\" id=\"foo\"><span style=\"text-decoration:line-through\">ar]</span>ba</span>z</u>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,false,"",false,true,""]}], +["<u>foo[b<span style=\"color:blue\" id=foo>ar]ba</span>z</u>", + [["stylewithcss","false"],["strikethrough",""]], + "<u>foo<strike>[b</strike><span style=\"color:rgb(0, 0, 255)\" id=\"foo\"><strike>ar]</strike>ba</span>z</u>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,false,"",false,true,""]}], +["<u>foo[b<span style=\"font-size:3em\">ar]ba</span>z</u>", + [["stylewithcss","true"],["strikethrough",""]], + "<u>foo<span style=\"text-decoration:line-through\">[b</span><span style=\"font-size:3em\"><span style=\"text-decoration:line-through\">ar]</span>ba</span>z</u>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,false,"",false,true,""]}], +["<u>foo[b<span style=\"font-size:3em\">ar]ba</span>z</u>", + [["stylewithcss","false"],["strikethrough",""]], + "<u>foo<strike>[b</strike><span style=\"font-size:3em\"><strike>ar]</strike>ba</span>z</u>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,false,"",false,true,""]}], +["<u>foo[b<i>ar]ba</i>z</u>", + [["stylewithcss","true"],["strikethrough",""]], + "<u>foo<span style=\"text-decoration:line-through\">[b</span><i><span style=\"text-decoration:line-through\">ar]</span>ba</i>z</u>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,false,"",false,true,""]}], +["<u>foo[b<i>ar]ba</i>z</u>", + [["stylewithcss","false"],["strikethrough",""]], + "<u>foo<strike>[b</strike><i><strike>ar]</strike>ba</i>z</u>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,false,"",false,true,""]}], +["<p style=\"text-decoration: underline\">foo[bar]baz</p>", + [["stylewithcss","true"],["strikethrough",""]], + "<p style=\"text-decoration:underline\">foo<span style=\"text-decoration:line-through\">[bar]</span>baz</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,false,"",false,true,""]}], +["<p style=\"text-decoration: underline\">foo[bar]baz</p>", + [["stylewithcss","false"],["strikethrough",""]], + "<p style=\"text-decoration:underline\">foo<strike>[bar]</strike>baz</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,false,"",false,true,""]}], +["foo<span style=\"text-decoration: line-through\">[bar]</span>baz", + [["stylewithcss","true"],["strikethrough",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,true,"",false,false,""]}], +["foo<span style=\"text-decoration: line-through\">[bar]</span>baz", + [["stylewithcss","false"],["strikethrough",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,true,"",false,false,""]}], +// Should not replace existing <s> with <strike>/<span> when removing the style +// partially. +["<s>foo[bar]baz</s>", + [["stylewithcss","true"],["strikethrough",""]], + "<s>foo</s>[bar]<s>baz</s>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,true,"",false,false,""]}], +["<s>foo[bar]baz</s>", + [["stylewithcss","false"],["strikethrough",""]], + "<s>foo</s>[bar]<s>baz</s>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,true,"",false,false,""]}], +["<s>foo[b<span style=\"color:blue\">ar]ba</span>z</s>", + [["stylewithcss","true"],["strikethrough",""]], + "<s>foo</s>b<span style=\"color:rgb(0, 0, 255)\">ar<span style=\"text-decoration-line:line-through\">ba</span></span><s>z</s>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,true,"",false,false,""]}], +["<s>foo[b<span style=\"color:blue\">ar]ba</span>z</s>", + [["stylewithcss","false"],["strikethrough",""]], + "<s>foo</s>b<span style=\"color:rgb(0, 0, 255)\">ar<strike>ba</strike></span><s>z</s>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,true,"",false,false,""]}], +["<s>foo[b<span style=\"color:blue\" id=foo>ar]ba</span>z</s>", + [["stylewithcss","true"],["strikethrough",""]], + "<s>foo</s>b<span style=\"color:rgb(0, 0, 255)\" id=\"foo\">ar<span style=\"text-decoration-line:line-through\">ba</span></span><s>z</s>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,true,"",false,false,""]}], +["<s>foo[b<span style=\"color:blue\" id=foo>ar]ba</span>z</s>", + [["stylewithcss","false"],["strikethrough",""]], + "<s>foo</s>b<span style=\"color:rgb(0, 0, 255)\" id=\"foo\">ar<strike>ba</strike></span><s>z</s>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,true,"",false,false,""]}], +["<s>foo[b<span style=\"font-size:3em\">ar]ba</span>z</s>", + [["stylewithcss","true"],["strikethrough",""]], + "<s>foo</s>b<span style=\"font-size:3em\">ar<span style=\"text-decoration-line:line-through\">ba</span></span><s>z</s>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,true,"",false,false,""]}], +["<s>foo[b<span style=\"font-size:3em\">ar]ba</span>z</s>", + [["stylewithcss","false"],["strikethrough",""]], + "<s>foo</s>b<span style=\"font-size:3em\">ar<strike>ba</strike></span><s>z</s>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,true,"",false,false,""]}], +["<s>foo[b<i>ar]ba</i>z</s>", + [["stylewithcss","true"],["strikethrough",""]], + "<s>foo</s>b<i>ar<span style=\"text-decoration-line:line-through\">ba</span></i><s>z</s>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,true,"",false,false,""]}], +["<s>foo[b<i>ar]ba</i>z</s>", + [["stylewithcss","false"],["strikethrough",""]], + "<s>foo</s>b<i>ar<strike>ba</strike></i><s>z</s>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,true,"",false,false,""]}], +["foo<strike>[bar]</strike>baz", + [["stylewithcss","true"],["strikethrough",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,true,"",false,false,""]}], +["foo<strike>[bar]</strike>baz", + [["stylewithcss","false"],["strikethrough",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,true,"",false,false,""]}], +["<strike>foo[bar]baz</strike>", + [["stylewithcss","true"],["strikethrough",""]], + "<span style=\"text-decoration:line-through\">foo</span>[bar]<span style=\"text-decoration:line-through\">baz</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,true,"",false,false,""]}], +["<strike>foo[bar]baz</strike>", + [["stylewithcss","false"],["strikethrough",""]], + "<strike>foo</strike>[bar]<strike>baz</strike>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,true,"",false,false,""]}], +["<strike>foo[b<span style=\"color:blue\">ar]ba</span>z</strike>", + [["stylewithcss","true"],["strikethrough",""]], + "<span style=\"text-decoration:line-through\">foo</span>[b<span style=\"color:rgb(0, 0, 255)\">ar]<span style=\"text-decoration:line-through\">ba</span></span><span style=\"text-decoration:line-through\">z</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,true,"",false,false,""]}], +["<strike>foo[b<span style=\"color:blue\">ar]ba</span>z</strike>", + [["stylewithcss","false"],["strikethrough",""]], + "<strike>foo</strike>[b<span style=\"color:rgb(0, 0, 255)\">ar]<strike>ba</strike></span><strike>z</strike>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,true,"",false,false,""]}], +["<strike>foo[b<span style=\"color:blue\" id=foo>ar]ba</span>z</strike>", + [["stylewithcss","true"],["strikethrough",""]], + "<span style=\"text-decoration:line-through\">foo</span>[b<span style=\"color:rgb(0, 0, 255)\" id=\"foo\">ar]<span style=\"text-decoration:line-through\">ba</span></span><span style=\"text-decoration:line-through\">z</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,true,"",false,false,""]}], +["<strike>foo[b<span style=\"color:blue\" id=foo>ar]ba</span>z</strike>", + [["stylewithcss","false"],["strikethrough",""]], + "<strike>foo</strike>[b<span style=\"color:rgb(0, 0, 255)\" id=\"foo\">ar]<strike>ba</strike></span><strike>z</strike>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,true,"",false,false,""]}], +["<strike>foo[b<span style=\"font-size:3em\">ar]ba</span>z</strike>", + [["stylewithcss","true"],["strikethrough",""]], + "<span style=\"text-decoration:line-through\">foo</span>[b<span style=\"font-size:3em\">ar]<span style=\"text-decoration:line-through\">ba</span></span><span style=\"text-decoration:line-through\">z</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,true,"",false,false,""]}], +["<strike>foo[b<span style=\"font-size:3em\">ar]ba</span>z</strike>", + [["stylewithcss","false"],["strikethrough",""]], + "<strike>foo</strike>[b<span style=\"font-size:3em\">ar]<strike>ba</strike></span><strike>z</strike>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,true,"",false,false,""]}], +["<strike>foo[b<i>ar]ba</i>z</strike>", + [["stylewithcss","true"],["strikethrough",""]], + "<span style=\"text-decoration:line-through\">foo</span>[b<i>ar]<span style=\"text-decoration:line-through\">ba</span></i><span style=\"text-decoration:line-through\">z</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,true,"",false,false,""]}], +["<strike>foo[b<i>ar]ba</i>z</strike>", + [["stylewithcss","false"],["strikethrough",""]], + "<strike>foo</strike>[b<i>ar]<strike>ba</strike></i><strike>z</strike>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,true,"",false,false,""]}], +// Should set text-decoration of <ins> because it has underline style by +// default and it is not only representing it, thus, replacing it with <span> +// changes the meaning. +["foo<ins>[bar]</ins>baz", + [["stylewithcss","true"],["strikethrough",""]], + "foo<ins style=\"text-decoration:underline line-through\">[bar]</ins>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,false,"",false,true,""]}], +["foo<ins>[bar]</ins>baz", + [["stylewithcss","false"],["strikethrough",""]], + "foo<ins><strike>[bar]</strike></ins>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,false,"",false,true,""]}], +["<ins>foo[bar]baz</ins>", + [["stylewithcss","true"],["strikethrough",""]], + "<ins>foo<span style=\"text-decoration:line-through\">[bar]</span>baz</ins>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,false,"",false,true,""]}], +["<ins>foo[bar]baz</ins>", + [["stylewithcss","false"],["strikethrough",""]], + "<ins>foo<strike>[bar]</strike>baz</ins>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,false,"",false,true,""]}], +["<ins>foo[b<span style=\"color:blue\">ar]ba</span>z</ins>", + [["stylewithcss","true"],["strikethrough",""]], + "<ins>foo<span style=\"text-decoration:line-through\">[b</span><span style=\"color:rgb(0, 0, 255)\"><span style=\"text-decoration:line-through\">ar]</span>ba</span>z</ins>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,false,"",false,true,""]}], +["<ins>foo[b<span style=\"color:blue\">ar]ba</span>z</ins>", + [["stylewithcss","false"],["strikethrough",""]], + "<ins>foo<strike>[b</strike><span style=\"color:rgb(0, 0, 255)\"><strike>ar]</strike>ba</span>z</ins>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,false,"",false,true,""]}], +["<ins>foo[b<span style=\"color:blue\" id=foo>ar]ba</span>z</ins>", + [["stylewithcss","true"],["strikethrough",""]], + "<ins>foo<span style=\"text-decoration:line-through\">[b</span><span style=\"color:rgb(0, 0, 255)\" id=\"foo\"><span style=\"text-decoration:line-through\">ar]</span>ba</span>z</ins>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,false,"",false,true,""]}], +["<ins>foo[b<span style=\"color:blue\" id=foo>ar]ba</span>z</ins>", + [["stylewithcss","false"],["strikethrough",""]], + "<ins>foo<strike>[b</strike><span style=\"color:rgb(0, 0, 255)\" id=\"foo\"><strike>ar]</strike>ba</span>z</ins>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,false,"",false,true,""]}], +["<ins>foo[b<span style=\"font-size:3em\">ar]ba</span>z</ins>", + [["stylewithcss","true"],["strikethrough",""]], + "<ins>foo<span style=\"text-decoration:line-through\">[b</span><span style=\"font-size:3em\"><span style=\"text-decoration:line-through\">ar]</span>ba</span>z</ins>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,false,"",false,true,""]}], +["<ins>foo[b<span style=\"font-size:3em\">ar]ba</span>z</ins>", + [["stylewithcss","false"],["strikethrough",""]], + "<ins>foo<strike>[b</strike><span style=\"font-size:3em\"><strike>ar]</strike>ba</span>z</ins>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,false,"",false,true,""]}], +["<ins>foo[b<i>ar]ba</i>z</ins>", + [["stylewithcss","true"],["strikethrough",""]], + "<ins>foo<span style=\"text-decoration:line-through\">[b</span><i><span style=\"text-decoration:line-through\">ar]</span>ba</i>z</ins>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,false,"",false,true,""]}], +["<ins>foo[b<i>ar]ba</i>z</ins>", + [["stylewithcss","false"],["strikethrough",""]], + "<ins>foo<strike>[b</strike><i><strike>ar]</strike>ba</i>z</ins>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,false,"",false,true,""]}], +["foo<del>[bar]</del>baz", + [["strikethrough",""]], + "foo<del>[bar]</del>baz", + [true], + {"strikethrough":[false,true,"",false,true,""]}], +["<del>foo[bar]baz</del>", + [["strikethrough",""]], + "<del>foo[bar]baz</del>", + [true], + {"strikethrough":[false,true,"",false,true,""]}], +["<del>foo[b<span style=\"color:blue\">ar]ba</span>z</del>", + [["strikethrough",""]], + "<del>foo[b<span style=\"color:rgb(0, 0, 255)\">ar]ba</span>z</del>", + [true], + {"strikethrough":[false,true,"",false,true,""]}], +["<del>foo[b<span style=\"color:blue\" id=foo>ar]ba</span>z</del>", + [["strikethrough",""]], + "<del>foo[b<span style=\"color:rgb(0, 0, 255)\" id=\"foo\">ar]ba</span>z</del>", + [true], + {"strikethrough":[false,true,"",false,true,""]}], +["<del>foo[b<span style=\"font-size:3em\">ar]ba</span>z</del>", + [["strikethrough",""]], + "<del>foo[b<span style=\"font-size:3em\">ar]ba</span>z</del>", + [true], + {"strikethrough":[false,true,"",false,true,""]}], +["<del>foo[b<i>ar]ba</i>z</del>", + [["strikethrough",""]], + "<del>foo[b<i>ar]ba</i>z</del>", + [true], + {"strikethrough":[false,true,"",false,true,""]}], +["foo<span style=\"text-decoration: underline line-through\">[bar]</span>baz", + [["strikethrough",""]], + "foo<span style=\"text-decoration:underline\">[bar]</span>baz", + [true], + {"strikethrough":[false,true,"",false,false,""]}], +["foo<span style=\"text-decoration: underline line-through\">b[a]r</span>baz", + [["stylewithcss","true"],["strikethrough",""]], + "foo<span style=\"text-decoration:underline\"><span style=\"text-decoration:line-through\">b</span>[a]<span style=\"text-decoration:line-through\">r</span></span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,true,"",false,false,""]}], +["foo<span style=\"text-decoration: underline line-through\">b[a]r</span>baz", + [["stylewithcss","false"],["strikethrough",""]], + "foo<span style=\"text-decoration:underline\"><strike>b</strike>[a]<strike>r</strike></span>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,true,"",false,false,""]}], +// <s> should be replaced with <strike> or <span> element. +["foo<s style=\"text-decoration: underline\">[bar]</s>baz", + [["stylewithcss","true"],["strikethrough",""]], + "foo<span style=\"text-decoration-line:underline line-through\">bar</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,false,"",false,true,""]}], +["foo<s style=\"text-decoration: underline\">[bar]</s>baz", + [["stylewithcss","false"],["strikethrough",""]], + "foo<u><strike>bar</strike></u>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,false,"",false,true,""]}], +["foo<s style=\"text-decoration: underline\">b[a]r</s>baz", + [["stylewithcss","true"],["strikethrough",""]], + "foo<s style=\"text-decoration:underline\">b</s><span style=\"text-decoration-line:underline line-through\">a</span><s style=\"text-decoration:underline\">r</s>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,false,"",false,true,""]}], +["foo<s style=\"text-decoration: underline\">b[a]r</s>baz", + [["stylewithcss","false"],["strikethrough",""]], + "foo<s style=\"text-decoration:underline\">b</s><u><strike>a</strike></u><s style=\"text-decoration:underline\">r</s>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,false,"",false,true,""]}], +["foo<u style=\"text-decoration: line-through\">[bar]</u>baz", + [["stylewithcss","true"],["strikethrough",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,true,"",false,false,""]}], +["foo<u style=\"text-decoration: line-through\">[bar]</u>baz", + [["stylewithcss","false"],["strikethrough",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,true,"",false,false,""]}], +["foo<u style=\"text-decoration: line-through\">b[a]r</u>baz", + [["stylewithcss","true"],["strikethrough",""]], + "foo<span style=\"text-decoration:line-through\">b</span>[a]<span style=\"text-decoration:line-through\">r</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,true,"",false,false,""]}], +["foo<u style=\"text-decoration: line-through\">b[a]r</u>baz", + [["stylewithcss","false"],["strikethrough",""]], + "foo<strike>b</strike>[a]<strike>r</strike>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,true,"",false,false,""]}], +["foo<s style=\"text-decoration: overline\">[bar]</s>baz", + [["stylewithcss","true"],["strikethrough",""]], + "foo<span style=\"text-decoration-line:overline line-through\">bar</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,false,"",false,true,""]}], +["foo<s style=\"text-decoration: overline\">[bar]</s>baz", + [["stylewithcss","false"],["strikethrough",""]], + "foo<span style=\"text-decoration-line:overline\"><strike>bar</strike></span>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,false,"",false,true,""]}], +["foo<s style=\"text-decoration: overline\">b[a]r</s>baz", + [["stylewithcss","true"],["strikethrough",""]], + "foo<s style=\"text-decoration:overline\">b</s><span style=\"text-decoration-line:overline line-through\">a</span><s style=\"text-decoration:overline\">r</s>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,false,"",false,true,""]}], +["foo<s style=\"text-decoration: overline\">b[a]r</s>baz", + [["stylewithcss","false"],["strikethrough",""]], + "foo<s style=\"text-decoration:overline\">b</s><span style=\"text-decoration-line:overline\"><strike>a</strike></span><s style=\"text-decoration:overline\">r</s>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,false,"",false,true,""]}], +// Should replace <u> with new <span> and set its `text-decoration` to +// line-though (for applying the requested style) and overline (which was +// specified to the <u>). Note that underline was removed by the +// text-decoration setting. Therefore, it should not appear. +["foo<u style=\"text-decoration: overline\">[bar]</u>baz", + [["stylewithcss","true"],["strikethrough",""]], + "foo<span style=\"text-decoration:overline line-through\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,false,"",false,true,""]}], +["foo<u style=\"text-decoration: overline\">[bar]</u>baz", + [["stylewithcss","false"],["strikethrough",""]], + "foo<strike><u style=\"text-decoration:overline\">[bar]</u></strike>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,false,"",false,true,""]}], +["foo<u style=\"text-decoration: overline\">b[a]r</u>baz", + [["stylewithcss","true"],["strikethrough",""]], + "foo<u style=\"text-decoration:overline\">b<span style=\"text-decoration:line-through\">[a]</span>r</u>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,false,"",false,true,""]}], +["foo<u style=\"text-decoration: overline\">b[a]r</u>baz", + [["stylewithcss","false"],["strikethrough",""]], + "foo<u style=\"text-decoration:overline\">b<strike>[a]</strike>r</u>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,false,"",false,true,""]}], +["<p style=\"text-decoration: line-through\">foo[bar]baz</p>", + [["stylewithcss","true"],["strikethrough",""]], + "<p><span style=\"text-decoration:line-through\">foo</span>[bar]<span style=\"text-decoration:line-through\">baz</span></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,true,"",false,false,""]}], +["<p style=\"text-decoration: line-through\">foo[bar]baz</p>", + [["stylewithcss","false"],["strikethrough",""]], + "<p><strike>foo</strike>[bar]<strike>baz</strike></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,true,"",false,false,""]}], +["<p style=\"text-decoration: overline\">foo[bar]baz</p>", + [["stylewithcss","true"],["strikethrough",""]], + "<p style=\"text-decoration:overline\">foo<span style=\"text-decoration:line-through\">[bar]</span>baz</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,false,"",false,true,""]}], +["<p style=\"text-decoration: overline\">foo[bar]baz</p>", + [["stylewithcss","false"],["strikethrough",""]], + "<p style=\"text-decoration:overline\">foo<strike>[bar]</strike>baz</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,false,"",false,true,""]}], +["foo<span class=\"underline\">[bar]</span>baz", + [["stylewithcss","true"],["strikethrough",""]], + "foo<span class=\"underline\" style=\"text-decoration:line-through\">bar</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,false,"",false,true,""]}], +["foo<span class=\"underline\">[bar]</span>baz", + [["stylewithcss","false"],["strikethrough",""]], + "foo<span class=\"underline\"><strike>[bar]</strike></span>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,false,"",false,true,""]}], +["foo<span class=\"underline\">b[a]r</span>baz", + [["stylewithcss","true"],["strikethrough",""]], + "foo<span class=\"underline\">b<span style=\"text-decoration:line-through\">[a]</span>r</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,false,"",false,true,""]}], +["foo<span class=\"underline\">b[a]r</span>baz", + [["stylewithcss","false"],["strikethrough",""]], + "foo<span class=\"underline\">b<strike>[a]</strike>r</span>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,false,"",false,true,""]}], +["foo<span class=\"line-through\">[bar]</span>baz", + [["strikethrough",""]], + "foo<span class=\"line-through\">[bar]</span>baz", + [true], + {"strikethrough":[false,true,"",false,true,""]}], +["foo<span class=\"line-through\">b[a]r</span>baz", + [["strikethrough",""]], + "foo<span class=\"line-through\">b[a]r</span>baz", + [true], + {"strikethrough":[false,true,"",false,true,""]}], +["foo<span class=\"underline-and-line-through\">[bar]</span>baz", + [["strikethrough",""]], + "foo<span class=\"underline-and-line-through\">[bar]</span>baz", + [true], + {"strikethrough":[false,true,"",false,true,""]}], +["foo<span class=\"underline-and-line-through\">b[a]r</span>baz", + [["strikethrough",""]], + "foo<span class=\"underline-and-line-through\">b[a]r</span>baz", + [true], + {"strikethrough":[false,true,"",false,true,""]}], +// Should wrap in new <strike> only when it's not wrapped in <s> +["fo[o<s>b]ar</s>baz", + [["strikethrough",""]], + "fo<strike>o</strike><s>bar</s>baz", + [true], + {"strikethrough":[true,false,"",false,true,""]}], +["foo<s>ba[r</s>b]az", + [["strikethrough",""]], + "foo<s>ba</s>rbaz", + [true], + {"strikethrough":[true,false,"",false,true,""]}], +["fo[o<s>bar</s>b]az", + [["stylewithcss","true"],["strikethrough",""]], + "fo<span style=\"text-decoration-line:line-through\">obarb</span>az", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[true,false,"",false,true,""]}], +["fo[o<s>bar</s>b]az", + [["stylewithcss","false"],["strikethrough",""]], + "fo<strike>obarb</strike>az", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[true,false,"",false,true,""]}], +["foo[<s>b]ar</s>baz", + [["stylewithcss","true"],["strikethrough",""]], + "foo[b]<s>ar</s>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,true,"",false,false,""]}], +["foo[<s>b]ar</s>baz", + [["stylewithcss","false"],["strikethrough",""]], + "foo[b]<s>ar</s>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,true,"",false,false,""]}], +["foo<s>ba[r</s>]baz", + [["stylewithcss","true"],["strikethrough",""]], + "foo<s>ba</s>[r]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,true,"",false,false,""]}], +["foo<s>ba[r</s>]baz", + [["stylewithcss","false"],["strikethrough",""]], + "foo<s>ba</s>[r]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,true,"",false,false,""]}], +["foo[<s>bar</s>]baz", + [["stylewithcss","true"],["strikethrough",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,true,"",false,false,""]}], +["foo[<s>bar</s>]baz", + [["stylewithcss","false"],["strikethrough",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,true,"",false,false,""]}], +["foo<s>[bar]</s>baz", + [["stylewithcss","true"],["strikethrough",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,true,"",false,false,""]}], +["foo<s>[bar]</s>baz", + [["stylewithcss","false"],["strikethrough",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,true,"",false,false,""]}], +["foo{<s>bar</s>}baz", + [["stylewithcss","true"],["strikethrough",""]], + "foo{bar}baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,true,"",false,false,""]}], +["foo{<s>bar</s>}baz", + [["stylewithcss","false"],["strikethrough",""]], + "foo{bar}baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,true,"",false,false,""]}], +["fo[o<span style=text-decoration:line-through>b]ar</span>baz", + [["strikethrough",""]], + "fo<strike>o</strike><s>bar</s>baz", + [true], + {"strikethrough":[true,false,"",false,true,""]}], +["<strike>fo[o</strike><s>b]ar</s>", + [["stylewithcss","true"],["strikethrough",""]], + "<strike>fo</strike>[ob]<s>ar</s>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,true,"",false,false,""]}], +["<strike>fo[o</strike><s>b]ar</s>", + [["stylewithcss","false"],["strikethrough",""]], + "<strike>fo</strike>[ob]<s>ar</s>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,true,"",false,false,""]}], +["<s>fo[o</s><del>b]ar</del>", + [["stylewithcss","true"],["strikethrough",""]], + "<s>fo</s>[o<del>b]ar</del>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"strikethrough":[false,true,"",true,false,""]}], +["<s>fo[o</s><del>b]ar</del>", + [["stylewithcss","false"],["strikethrough",""]], + "<s>fo</s>[o<del>b]ar</del>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"strikethrough":[false,true,"",true,false,""]}], + + +// Tests to remove only strikethrough from existing text-decoration +["abc<span style=\"text-decoration:line-through overline underline\">[def]</span>ghi", + [["stylewithcss","true"],["strikethrough",""]], + ["abc<span style=\"text-decoration:underline overline\">[def]</span>ghi", + "abc<span style=\"text-decoration-line:underline overline\">[def]</span>ghi"], + [true,true], + {}], + +// blink, text-decoration-color and text-decoration-style values should be +// dropped. This rule is odd because executing "underline" command causes +// the data loss, but for now, the compatibility between browsers is more +// important. Once you want/need to change the behavior of a browser, you +// should file a spec issue first. +// And these tests allows the difference between text-decoration vs. +// text-decoration-line because these tests want to check the data loss. +["abc<span style=\"text-decoration:blink overline underline\">[def]</span>ghi", + [["stylewithcss","true"],["strikethrough",""]], + ["abc<span style=\"text-decoration:underline overline line-through\">[def]</span>ghi", + "abc<span style=\"text-decoration-line:underline overline line-through\">[def]</span>ghi"], + [true,true], + {}], +["abc<span style=\"text-decoration:underline blue dotted\">[def]</span>ghi", + [["stylewithcss","true"],["strikethrough",""]], + ["abc<span style=\"text-decoration:underline line-through\">[def]</span>ghi", + "abc<span style=\"text-decoration-line:underline line-through\">[def]</span>ghi"], + [true,true], + {}], +["abc<span style=\"text-decoration:blink line-through underline overline\">[def]</span>ghi", + [["stylewithcss","true"],["strikethrough",""]], + ["abc<span style=\"text-decoration:underline overline\">[def]</span>ghi", + "abc<span style=\"text-decoration-line:underline overline\">[def]</span>ghi"], + [true,true], + {}], +["abc<span style=\"text-decoration:underline line-through blue dotted\">[def]</span>ghi", + [["stylewithcss","true"],["strikethrough",""]], + ["abc<span style=\"text-decoration:underline\">[def]</span>ghi", + "abc<span style=\"text-decoration-line:underline\">[def]</span>ghi"], + [true,true], + {}], +] diff --git a/testing/web-platform/tests/editing/data/subscript.js b/testing/web-platform/tests/editing/data/subscript.js new file mode 100644 index 0000000000..4129f4f0e8 --- /dev/null +++ b/testing/web-platform/tests/editing/data/subscript.js @@ -0,0 +1,431 @@ +// For documentation of the format, see README in this directory. +var browserTests = [ +["foo[]bar", + [["subscript",""]], + "foo[]bar", + [true], + {"subscript":[false,false,"",false,true,""]}], +// <sub> should be used instead of <span style="text-align: sub"> because +// <sub> changes font-size too, thus, they are not equivalent. Additionally, +// even if specifying `font-size`, it'd be removed by the other commands. +// Therefore, it's hard to maintain <sub> only with CSS. +// See also <https://bugzilla.mozilla.org/show_bug.cgi?id=394304#c2>. +["<p>[foo</p> <p>bar]</p>", + [["stylewithcss","true"],["subscript",""]], + "<p><sub>[foo</sub></p> <p><sub>bar]</sub></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"subscript":[false,false,"",false,true,""]}], +["<p>[foo</p> <p>bar]</p>", + [["stylewithcss","false"],["subscript",""]], + "<p><sub>[foo</sub></p> <p><sub>bar]</sub></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"subscript":[false,false,"",false,true,""]}], +["<span>[foo</span> <span>bar]</span>", + [["stylewithcss","true"],["subscript",""]], + "<sub><span>[foo</span> <span>bar]</span></sub>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"subscript":[false,false,"",false,true,""]}], +["<span>[foo</span> <span>bar]</span>", + [["stylewithcss","false"],["subscript",""]], + "<sub><span>[foo</span> <span>bar]</span></sub>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"subscript":[false,false,"",false,true,""]}], +["<p>[foo</p><p> <span>bar</span> </p><p>baz]</p>", + [["stylewithcss","true"],["subscript",""]], + "<p><sub>[foo</sub></p><p> <sub><span>bar</span></sub> </p><p><sub>baz]</sub></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"subscript":[false,false,"",false,true,""]}], +["<p>[foo</p><p> <span>bar</span> </p><p>baz]</p>", + [["stylewithcss","false"],["subscript",""]], + "<p><sub>[foo</sub></p><p> <sub><span>bar</span></sub> </p><p><sub>baz]</sub></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"subscript":[false,false,"",false,true,""]}], +["<p>[foo<p><br><p>bar]", + [["stylewithcss","true"],["subscript",""]], + "<p><sub>[foo</sub></p><p><sub><br></sub></p><p><sub>bar]</sub></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"subscript":[false,false,"",false,true,""]}], +["<p>[foo<p><br><p>bar]", + [["stylewithcss","false"],["subscript",""]], + "<p><sub>[foo</sub></p><p><sub><br></sub></p><p><sub>bar]</sub></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"subscript":[false,false,"",false,true,""]}], +["<b>foo[]bar</b>", + [["subscript",""]], + "<b>foo[]bar</b>", + [true], + {"subscript":[false,false,"",false,true,""]}], +["<i>foo[]bar</i>", + [["subscript",""]], + "<i>foo[]bar</i>", + [true], + {"subscript":[false,false,"",false,true,""]}], +["<span>foo</span>{}<span>bar</span>", + [["subscript",""]], + "<span>foo</span>{}<span>bar</span>", + [true], + {"subscript":[false,false,"",false,true,""]}], +["<span>foo[</span><span>]bar</span>", + [["subscript",""]], + "<span>foo[</span><span>]bar</span>", + [true], + {"subscript":[false,false,"",false,true,""]}], +["foo[bar]baz", + [["stylewithcss","true"],["subscript",""]], + "foo<sub>[bar]</sub>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"subscript":[false,false,"",false,true,""]}], +["foo[bar]baz", + [["stylewithcss","false"],["subscript",""]], + "foo<sub>[bar]</sub>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"subscript":[false,false,"",false,true,""]}], +["foo[bar<b>baz]qoz</b>quz", + [["stylewithcss","true"],["subscript",""]], + "foo<sub>[bar</sub><b><sub>baz]</sub>qoz</b>quz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"subscript":[false,false,"",false,true,""]}], +["foo[bar<b>baz]qoz</b>quz", + [["stylewithcss","false"],["subscript",""]], + "foo<sub>[bar</sub><b><sub>baz]</sub>qoz</b>quz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"subscript":[false,false,"",false,true,""]}], +["foo[bar<i>baz]qoz</i>quz", + [["stylewithcss","true"],["subscript",""]], + "foo<sub>[bar</sub><i><sub>baz]</sub>qoz</i>quz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"subscript":[false,false,"",false,true,""]}], +["foo[bar<i>baz]qoz</i>quz", + [["stylewithcss","false"],["subscript",""]], + "foo<sub>[bar</sub><i><sub>baz]</sub>qoz</i>quz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"subscript":[false,false,"",false,true,""]}], +["{<p><p> <p>foo</p>}", + [["stylewithcss","true"],["subscript",""]], + "{<p></p><p> </p><p><sub>foo</sub></p>}", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"subscript":[false,false,"",false,true,""]}], +["{<p><p> <p>foo</p>}", + [["stylewithcss","false"],["subscript",""]], + "{<p></p><p> </p><p><sub>foo</sub></p>}", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"subscript":[false,false,"",false,true,""]}], +["<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>", + [["stylewithcss","true"],["subscript",""]], + "<table><tbody><tr><td>foo</td><td>b<sub>[a]</sub>r</td><td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"subscript":[false,false,"",false,true,""]}], +["<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>", + [["stylewithcss","false"],["subscript",""]], + "<table><tbody><tr><td>foo</td><td>b<sub>[a]</sub>r</td><td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"subscript":[false,false,"",false,true,""]}], +["<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table>", + [["stylewithcss","true"],["subscript",""]], + "<table><tbody><tr><td>foo</td>{<td><sub>bar</sub></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"subscript":[false,false,"",false,true,""]}], +["<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table>", + [["stylewithcss","false"],["subscript",""]], + "<table><tbody><tr><td>foo</td>{<td><sub>bar</sub></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"subscript":[false,false,"",false,true,""]}], +["<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table>", + [["stylewithcss","true"],["subscript",""]], + "<table><tbody><tr>{<td><sub>foo</sub></td><td><sub>bar</sub></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"subscript":[false,false,"",false,true,""]}], +["<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table>", + [["stylewithcss","false"],["subscript",""]], + "<table><tbody><tr>{<td><sub>foo</sub></td><td><sub>bar</sub></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"subscript":[false,false,"",false,true,""]}], +["<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>", + [["stylewithcss","true"],["subscript",""]], + "<table><tbody>{<tr><td><sub>foo</sub></td><td><sub>bar</sub></td><td><sub>baz</sub></td></tr>}</tbody></table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"subscript":[false,false,"",false,true,""]}], +["<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>", + [["stylewithcss","false"],["subscript",""]], + "<table><tbody>{<tr><td><sub>foo</sub></td><td><sub>bar</sub></td><td><sub>baz</sub></td></tr>}</tbody></table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"subscript":[false,false,"",false,true,""]}], +["<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>", + [["stylewithcss","true"],["subscript",""]], + "<table>{<tbody><tr><td><sub>foo</sub></td><td><sub>bar</sub></td><td><sub>baz</sub></td></tr></tbody>}</table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"subscript":[false,false,"",false,true,""]}], +["<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>", + [["stylewithcss","false"],["subscript",""]], + "<table>{<tbody><tr><td><sub>foo</sub></td><td><sub>bar</sub></td><td><sub>baz</sub></td></tr></tbody>}</table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"subscript":[false,false,"",false,true,""]}], +["{<table><tr><td>foo<td>bar<td>baz</table>}", + [["stylewithcss","true"],["subscript",""]], + "{<table><tbody><tr><td><sub>foo</sub></td><td><sub>bar</sub></td><td><sub>baz</sub></td></tr></tbody></table>}", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"subscript":[false,false,"",false,true,""]}], +["{<table><tr><td>foo<td>bar<td>baz</table>}", + [["stylewithcss","false"],["subscript",""]], + "{<table><tbody><tr><td><sub>foo</sub></td><td><sub>bar</sub></td><td><sub>baz</sub></td></tr></tbody></table>}", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"subscript":[false,false,"",false,true,""]}], +["foo<sub>b[a]r</sub>baz", + [["stylewithcss","true"],["subscript",""]], + "foo<sub>b</sub>[a]<sub>r</sub>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"subscript":[false,true,"",false,false,""]}], +["foo<sub>b[a]r</sub>baz", + [["stylewithcss","false"],["subscript",""]], + "foo<sub>b</sub>[a]<sub>r</sub>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"subscript":[false,true,"",false,false,""]}], +["foo<sup>[bar]</sup>baz", + [["stylewithcss","true"],["subscript",""]], + "foo<sub>[bar]</sub>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"subscript":[false,false,"",false,true,""]}], +["foo<sup>[bar]</sup>baz", + [["stylewithcss","false"],["subscript",""]], + "foo<sub>[bar]</sub>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"subscript":[false,false,"",false,true,""]}], +["foo<sup>b[a]r</sup>baz", + [["stylewithcss","true"],["subscript",""]], + "foo<sup>b</sup><sub>[a]</sub><sup>r</sup>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"subscript":[false,false,"",false,true,""]}], +["foo<sup>b[a]r</sup>baz", + [["stylewithcss","false"],["subscript",""]], + "foo<sup>b</sup><sub>[a]</sub><sup>r</sup>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"subscript":[false,false,"",false,true,""]}], +// Although <sub> is not equivalent to `vertical-align: sub` as mentioned above, +// they are obviously conflict. Therefore, `vertical-align` style of ancestor +// and descendants elements of selection should be removed to make <sub> work. +["foo<span style=vertical-align:sub>[bar]</span>baz", + [["stylewithcss","true"],["subscript",""]], + "foo<sub>[bar]</sub>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"subscript":[false,false,"",false,true,""]}], +["foo<span style=vertical-align:sub>[bar]</span>baz", + [["stylewithcss","false"],["subscript",""]], + "foo<sub>[bar]</sub>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"subscript":[false,false,"",false,true,""]}], +["foo<span style=vertical-align:super>[bar]</span>baz", + [["stylewithcss","true"],["subscript",""]], + "foo<sub>[bar]</sub>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"subscript":[false,false,"",false,true,""]}], +["foo<span style=vertical-align:super>[bar]</span>baz", + [["stylewithcss","false"],["subscript",""]], + "foo<sub>[bar]</sub>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"subscript":[false,false,"",false,true,""]}], +["foo<sub><sub>[bar]</sub></sub>baz", + [["stylewithcss","true"],["subscript",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"subscript":[false,true,"",false,false,""]}], +["foo<sub><sub>[bar]</sub></sub>baz", + [["stylewithcss","false"],["subscript",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"subscript":[false,true,"",false,false,""]}], +["foo<sub><sub>b[a]r</sub></sub>baz", + [["subscript",""]], + "foo<sub>b</sub>[a]<sub>r</sub>baz", + [true], + {"subscript":[false,true,"",false,false,""]}], +["foo<sub>b<sub>[a]</sub>r</sub>baz", + [["subscript",""]], + "foo<sub>b</sub>[a]<sub>r</sub>baz", + [true], + {"subscript":[false,true,"",false,false,""]}], +["foo<sup><sup>[bar]</sup></sup>baz", + [["stylewithcss","true"],["subscript",""]], + "foo<sub>[bar]</sub>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"subscript":[false,false,"",false,true,""]}], +["foo<sup><sup>[bar]</sup></sup>baz", + [["stylewithcss","false"],["subscript",""]], + "foo<sub>[bar]</sub>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"subscript":[false,false,"",false,true,""]}], +["foo<sup><sup>b[a]r</sup></sup>baz", + [["stylewithcss","true"],["subscript",""]], + "foo<sup>b</sup><sub>[a]</sub><sup>r</sup>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"subscript":[false,false,"",false,true,""]}], +["foo<sup><sup>b[a]r</sup></sup>baz", + [["stylewithcss","false"],["subscript",""]], + "foo<sup>b</sup><sub>[a]</sub><sup>r</sup>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"subscript":[false,false,"",false,true,""]}], +["foo<sup>b<sup>[a]</sup>r</sup>baz", + [["stylewithcss","true"],["subscript",""]], + "foo<sup>b</sup><sub>[a]</sub><sup>r</sup>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"subscript":[false,false,"",false,true,""]}], +["foo<sup>b<sup>[a]</sup>r</sup>baz", + [["stylewithcss","false"],["subscript",""]], + "foo<sup>b</sup><sub>[a]</sub><sup>r</sup>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"subscript":[false,false,"",false,true,""]}], +["foo<sub><sup>[bar]</sup></sub>baz", + [["stylewithcss","true"],["subscript",""]], + "foo<sub>[bar]</sub>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"subscript":[true,false,"",false,true,""]}], +["foo<sub><sup>[bar]</sup></sub>baz", + [["stylewithcss","false"],["subscript",""]], + "foo<sub>[bar]</sub>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"subscript":[true,false,"",false,true,""]}], +["foo<sub><sup>b[a]r</sup></sub>baz", + [["stylewithcss","true"],["subscript",""]], + "foo<sup>b</sup><sub>[a]</sub><sup>r</sup>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"subscript":[true,false,"",false,true,""]}], +["foo<sub><sup>b[a]r</sup></sub>baz", + [["stylewithcss","false"],["subscript",""]], + "foo<sup>b</sup><sub>[a]</sub><sup>r</sup>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"subscript":[true,false,"",false,true,""]}], +["foo<sub>b<sup>[a]</sup>r</sub>baz", + [["stylewithcss","true"],["subscript",""]], + "foo<sub>b[a]r</sub>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"subscript":[true,false,"",false,true,""]}], +["foo<sub>b<sup>[a]</sup>r</sub>baz", + [["stylewithcss","false"],["subscript",""]], + "foo<sub>b[a]r</sub>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"subscript":[true,false,"",false,true,""]}], +["foo<sup><sub>[bar]</sub></sup>baz", + [["stylewithcss","true"],["subscript",""]], + "foo<sub>[bar]</sub>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"subscript":[true,false,"",false,true,""]}], +["foo<sup><sub>[bar]</sub></sup>baz", + [["stylewithcss","false"],["subscript",""]], + "foo<sub>[bar]</sub>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"subscript":[true,false,"",false,true,""]}], +["foo<sup><sub>b[a]r</sub></sup>baz", + [["stylewithcss","true"],["subscript",""]], + "foo<sub>b[a]r</sub>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"subscript":[true,false,"",false,true,""]}], +["foo<sup><sub>b[a]r</sub></sup>baz", + [["stylewithcss","false"],["subscript",""]], + "foo<sub>b[a]r</sub>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"subscript":[true,false,"",false,true,""]}], +["foo<sup>b<sub>[a]</sub>r</sup>baz", + [["stylewithcss","true"],["subscript",""]], + "foo<sup>b</sup><sub>[a]</sub><sup>r</sup>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"subscript":[true,false,"",false,true,""]}], +["foo<sup>b<sub>[a]</sub>r</sup>baz", + [["stylewithcss","false"],["subscript",""]], + "foo<sup>b</sup><sub>[a]</sub><sup>r</sup>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"subscript":[true,false,"",false,true,""]}], +["fo[o<sub>b]ar</sub>baz", + [["subscript",""]], + "fo<sub>[ob]ar</sub>baz", + [true], + {"subscript":[true,false,"",false,true,""]}], +["foo<sub>ba[r</sub>b]az", + [["subscript",""]], + "foo<sub>ba[rb]</sub>az", + [true], + {"subscript":[true,false,"",false,true,""]}], +["fo[o<sub>bar</sub>b]az", + [["subscript",""]], + "fo<sub>[obarb]</sub>az", + [true], + {"subscript":[true,false,"",false,true,""]}], +["foo[<sub>b]ar</sub>baz", + [["subscript",""]], + "foo[b]<sub>ar</sub>baz", + [true], + {"subscript":[false,true,"",false,false,""]}], +["foo<sub>ba[r</sub>]baz", + [["subscript",""]], + "foo<sub>ba</sub>[r]baz", + [true], + {"subscript":[false,true,"",false,false,""]}], +["foo[<sub>bar</sub>]baz", + [["stylewithcss","true"],["subscript",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"subscript":[false,true,"",false,false,""]}], +["foo[<sub>bar</sub>]baz", + [["stylewithcss","false"],["subscript",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"subscript":[false,true,"",false,false,""]}], +["foo<sub>[bar]</sub>baz", + [["stylewithcss","true"],["subscript",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"subscript":[false,true,"",false,false,""]}], +["foo<sub>[bar]</sub>baz", + [["stylewithcss","false"],["subscript",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"subscript":[false,true,"",false,false,""]}], +["foo{<sub>bar</sub>}baz", + [["stylewithcss","true"],["subscript",""]], + "foo{bar}baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"subscript":[false,true,"",false,false,""]}], +["foo{<sub>bar</sub>}baz", + [["stylewithcss","false"],["subscript",""]], + "foo{bar}baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"subscript":[false,true,"",false,false,""]}], +// The selected text not in <sub> should be moved into the existing <sub>. +["<sub>fo[o</sub><sup>b]ar</sup>", + [["subscript",""]], + "<sub>fo[ob]</sub><sup>ar</sup>", + [true], + {"subscript":[true,false,"",false,true,""]}], +// In the following cases, the vertical-align style in the range should be +// removed first, then, apply <sub>. +["<sub>fo[o</sub><span style=vertical-align:sub>b]ar</span>", + [["stylewithcss","true"],["subscript",""]], + "<sub>fo[ob]</sub><span style=\"vertical-align:sub\">ar</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"subscript":[true,false,"",false,true,""]}], +["<sub>fo[o</sub><span style=vertical-align:sub>b]ar</span>", + [["stylewithcss","false"],["subscript",""]], + "<sub>fo[ob]</sub><span style=\"vertical-align:sub\">ar</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"subscript":[true,false,"",false,true,""]}], +["<sub>fo[o</sub><span style=vertical-align:top>b]ar</span>", + [["stylewithcss","true"],["subscript",""]], + "<sub>fo[ob]</sub><span style=\"vertical-align:top\">ar</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"subscript":[true,false,"",false,true,""]}], +["<sub>fo[o</sub><span style=vertical-align:top>b]ar</span>", + [["stylewithcss","false"],["subscript",""]], + "<sub>fo[ob]</sub><span style=\"vertical-align:top\">ar</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"subscript":[true,false,"",false,true,""]}], +// Even if a vertical-align value is not related to <sub>/<sup>, it should be +// removed to make new <sub> work cleanly. +["foo<span style=vertical-align:top>[bar]</span>baz", + [["stylewithcss","true"],["subscript",""]], + "foo<sub>[bar]</sub>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"subscript":[false,false,"",false,true,""]}], +["foo<span style=vertical-align:top>[bar]</span>baz", + [["stylewithcss","false"],["subscript",""]], + "foo<sub>[bar]</sub>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"subscript":[false,false,"",false,true,""]}], +] diff --git a/testing/web-platform/tests/editing/data/superscript.js b/testing/web-platform/tests/editing/data/superscript.js new file mode 100644 index 0000000000..310f471a97 --- /dev/null +++ b/testing/web-platform/tests/editing/data/superscript.js @@ -0,0 +1,443 @@ +// For documentation of the format, see README in this directory. +var browserTests = [ +["foo[]bar", + [["superscript",""]], + "foo[]bar", + [true], + {"superscript":[false,false,"",false,true,""]}], +// <sup> should be used instead of <span style="text-align: super"> because +// <sup> changes font-size too, thus, they are not equivalent. Additionally, +// even if specifying `font-size`, it'd be removed by the other commands. +// Therefore, it's hard to maintain <sup> only with CSS. +// See also <https://bugzilla.mozilla.org/show_bug.cgi?id=394304#c2>. +["<p>[foo</p> <p>bar]</p>", + [["stylewithcss","true"],["superscript",""]], + "<p><sup>[foo</sup></p> <p><sup>bar]</sup></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"superscript":[false,false,"",false,true,""]}], +["<p>[foo</p> <p>bar]</p>", + [["stylewithcss","false"],["superscript",""]], + "<p><sup>[foo</sup></p> <p><sup>bar]</sup></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"superscript":[false,false,"",false,true,""]}], +["<span>[foo</span> <span>bar]</span>", + [["stylewithcss","true"],["superscript",""]], + "<sup><span>[foo</span> <span>bar]</span></sup>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"superscript":[false,false,"",false,true,""]}], +["<span>[foo</span> <span>bar]</span>", + [["stylewithcss","false"],["superscript",""]], + "<sup><span>[foo</span> <span>bar]</span></sup>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"superscript":[false,false,"",false,true,""]}], +["<p>[foo</p><p> <span>bar</span> </p><p>baz]</p>", + [["stylewithcss","true"],["superscript",""]], + "<p><sup>[foo</sup></p><p> <sup><span>bar</span></sup> </p><p><sup>baz]</sup></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"superscript":[false,false,"",false,true,""]}], +["<p>[foo</p><p> <span>bar</span> </p><p>baz]</p>", + [["stylewithcss","false"],["superscript",""]], + "<p><sup>[foo</sup></p><p> <sup><span>bar</span></sup> </p><p><sup>baz]</sup></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"superscript":[false,false,"",false,true,""]}], +["<p>[foo<p><br><p>bar]", + [["stylewithcss","true"],["superscript",""]], + "<p><sup>[foo</sup></p><p><sup><br></sup></p><p><sup>bar]</sup></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"superscript":[false,false,"",false,true,""]}], +["<p>[foo<p><br><p>bar]", + [["stylewithcss","false"],["superscript",""]], + "<p><sup>[foo</sup></p><p><sup><br></sup></p><p><sup>bar]</sup></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"superscript":[false,false,"",false,true,""]}], +["<b>foo[]bar</b>", + [["superscript",""]], + "<b>foo[]bar</b>", + [true], + {"superscript":[false,false,"",false,true,""]}], +["<i>foo[]bar</i>", + [["superscript",""]], + "<i>foo[]bar</i>", + [true], + {"superscript":[false,false,"",false,true,""]}], +["<span>foo</span>{}<span>bar</span>", + [["superscript",""]], + "<span>foo</span>{}<span>bar</span>", + [true], + {"superscript":[false,false,"",false,true,""]}], +["<span>foo[</span><span>]bar</span>", + [["superscript",""]], + "<span>foo[</span><span>]bar</span>", + [true], + {"superscript":[false,false,"",false,true,""]}], +["foo[bar]baz", + [["stylewithcss","true"],["superscript",""]], + "foo<sup>[bar]</sup>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"superscript":[false,false,"",false,true,""]}], +["foo[bar]baz", + [["stylewithcss","false"],["superscript",""]], + "foo<sup>[bar]</sup>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"superscript":[false,false,"",false,true,""]}], +["foo[bar<b>baz]qoz</b>quz", + [["stylewithcss","true"],["superscript",""]], + "foo<sup>[bar</sup><b><sup>baz]</sup>qoz</b>quz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"superscript":[false,false,"",false,true,""]}], +["foo[bar<b>baz]qoz</b>quz", + [["stylewithcss","false"],["superscript",""]], + "foo<sup>[bar</sup><b><sup>baz]</sup>qoz</b>quz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"superscript":[false,false,"",false,true,""]}], +["foo[bar<i>baz]qoz</i>quz", + [["stylewithcss","true"],["superscript",""]], + "foo<sup>[bar</sup><i><sup>baz]</sup>qoz</i>quz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"superscript":[false,false,"",false,true,""]}], +["foo[bar<i>baz]qoz</i>quz", + [["stylewithcss","false"],["superscript",""]], + "foo<sup>[bar</sup><i><sup>baz]</sup>qoz</i>quz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"superscript":[false,false,"",false,true,""]}], +["{<p><p> <p>foo</p>}", + [["stylewithcss","true"],["superscript",""]], + "{<p></p><p> </p><p><sup>foo</sup></p>}", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"superscript":[false,false,"",false,true,""]}], +["{<p><p> <p>foo</p>}", + [["stylewithcss","false"],["superscript",""]], + "{<p></p><p> </p><p><sup>foo</sup></p>}", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"superscript":[false,false,"",false,true,""]}], +["<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>", + [["stylewithcss","true"],["superscript",""]], + "<table><tbody><tr><td>foo</td><td>b<sup>[a]</sup>r</td><td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"superscript":[false,false,"",false,true,""]}], +["<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>", + [["stylewithcss","false"],["superscript",""]], + "<table><tbody><tr><td>foo</td><td>b<sup>[a]</sup>r</td><td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"superscript":[false,false,"",false,true,""]}], +["<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table>", + [["stylewithcss","true"],["superscript",""]], + "<table><tbody><tr><td>foo</td>{<td><sup>bar</sup></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"superscript":[false,false,"",false,true,""]}], +["<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table>", + [["stylewithcss","false"],["superscript",""]], + "<table><tbody><tr><td>foo</td>{<td><sup>bar</sup></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"superscript":[false,false,"",false,true,""]}], +["<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table>", + [["stylewithcss","true"],["superscript",""]], + "<table><tbody><tr>{<td><sup>foo</sup></td><td><sup>bar</sup></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"superscript":[false,false,"",false,true,""]}], +["<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table>", + [["stylewithcss","false"],["superscript",""]], + "<table><tbody><tr>{<td><sup>foo</sup></td><td><sup>bar</sup></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"superscript":[false,false,"",false,true,""]}], +["<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>", + [["stylewithcss","true"],["superscript",""]], + "<table><tbody>{<tr><td><sup>foo</sup></td><td><sup>bar</sup></td><td><sup>baz</sup></td></tr>}</tbody></table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"superscript":[false,false,"",false,true,""]}], +["<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>", + [["stylewithcss","false"],["superscript",""]], + "<table><tbody>{<tr><td><sup>foo</sup></td><td><sup>bar</sup></td><td><sup>baz</sup></td></tr>}</tbody></table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"superscript":[false,false,"",false,true,""]}], +["<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>", + [["stylewithcss","true"],["superscript",""]], + "<table>{<tbody><tr><td><sup>foo</sup></td><td><sup>bar</sup></td><td><sup>baz</sup></td></tr></tbody>}</table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"superscript":[false,false,"",false,true,""]}], +["<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>", + [["stylewithcss","false"],["superscript",""]], + "<table>{<tbody><tr><td><sup>foo</sup></td><td><sup>bar</sup></td><td><sup>baz</sup></td></tr></tbody>}</table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"superscript":[false,false,"",false,true,""]}], +["{<table><tr><td>foo<td>bar<td>baz</table>}", + [["stylewithcss","true"],["superscript",""]], + "{<table><tbody><tr><td><sup>foo</sup></td><td><sup>bar</sup></td><td><sup>baz</sup></td></tr></tbody></table>}", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"superscript":[false,false,"",false,true,""]}], +["{<table><tr><td>foo<td>bar<td>baz</table>}", + [["stylewithcss","false"],["superscript",""]], + "{<table><tbody><tr><td><sup>foo</sup></td><td><sup>bar</sup></td><td><sup>baz</sup></td></tr></tbody></table>}", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"superscript":[false,false,"",false,true,""]}], +["foo<sub>[bar]</sub>baz", + [["stylewithcss","true"],["superscript",""]], + "foo<sup>[bar]</sup>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"superscript":[false,false,"",false,true,""]}], +["foo<sub>[bar]</sub>baz", + [["stylewithcss","false"],["superscript",""]], + "foo<sup>[bar]</sup>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"superscript":[false,false,"",false,true,""]}], +["foo<sub>b[a]r</sub>baz", + [["stylewithcss","true"],["superscript",""]], + "foo<sub>b</sub><sup>[a]</sup><sub>r</sub>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"superscript":[false,false,"",false,true,""]}], +["foo<sub>b[a]r</sub>baz", + [["stylewithcss","false"],["superscript",""]], + "foo<sub>b</sub><sup>[a]</sup><sub>r</sub>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"superscript":[false,false,"",false,true,""]}], +["foo<sup>b[a]r</sup>baz", + [["stylewithcss","true"],["superscript",""]], + "foo<sup>b</sup>[a]<sup>r</sup>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"superscript":[false,true,"",false,false,""]}], +["foo<sup>b[a]r</sup>baz", + [["stylewithcss","false"],["superscript",""]], + "foo<sup>b</sup>[a]<sup>r</sup>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"superscript":[false,true,"",false,false,""]}], +// Although <sup> is not equivalent to `vertical-align: super` as mentioned +// above, they are obviously conflict. Therefore, `vertical-align` style of +// ancestor and descendants elements of selection should be removed to make +// <sup> work. +["foo<span style=vertical-align:sub>[bar]</span>baz", + [["stylewithcss","true"],["superscript",""]], + "foo<sup>[bar]</sup>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"superscript":[false,false,"",false,true,""]}], +["foo<span style=vertical-align:sub>[bar]</span>baz", + [["stylewithcss","false"],["superscript",""]], + "foo<sup>[bar]</sup>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"superscript":[false,false,"",false,true,""]}], +["foo<span style=vertical-align:super>[bar]</span>baz", + [["stylewithcss","true"],["superscript",""]], + "foo<sup>[bar]</sup>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"superscript":[false,false,"",false,true,""]}], +["foo<span style=vertical-align:super>[bar]</span>baz", + [["stylewithcss","false"],["superscript",""]], + "foo<sup>[bar]</sup>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"superscript":[false,false,"",false,true,""]}], +["foo<sub><sub>[bar]</sub></sub>baz", + [["stylewithcss","true"],["superscript",""]], + "foo<sup>[bar]</sup>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"superscript":[false,false,"",false,true,""]}], +["foo<sub><sub>[bar]</sub></sub>baz", + [["stylewithcss","false"],["superscript",""]], + "foo<sup>[bar]</sup>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"superscript":[false,false,"",false,true,""]}], +["foo<sub><sub>b[a]r</sub></sub>baz", + [["stylewithcss","true"],["superscript",""]], + "foo<sub>b</sub><sup>[a]</sup><sub>r</sub>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"superscript":[false,false,"",false,true,""]}], +["foo<sub><sub>b[a]r</sub></sub>baz", + [["stylewithcss","false"],["superscript",""]], + "foo<sub>b</sub><sup>[a]</sup><sub>r</sub>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"superscript":[false,false,"",false,true,""]}], +["foo<sub>b<sub>[a]</sub>r</sub>baz", + [["stylewithcss","true"],["superscript",""]], + "foo<sub>b</sub><sup>[a]</sup><sub>r</sub>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"superscript":[false,false,"",false,true,""]}], +["foo<sub>b<sub>[a]</sub>r</sub>baz", + [["stylewithcss","false"],["superscript",""]], + "foo<sub>b</sub><sup>[a]</sup><sub>r</sub>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"superscript":[false,false,"",false,true,""]}], +["foo<sup><sup>[bar]</sup></sup>baz", + [["stylewithcss","true"],["superscript",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"superscript":[false,true,"",false,false,""]}], +["foo<sup><sup>[bar]</sup></sup>baz", + [["stylewithcss","false"],["superscript",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"superscript":[false,true,"",false,false,""]}], +["foo<sup><sup>b[a]r</sup></sup>baz", + [["superscript",""]], + "foo<sup>b</sup>[a]<sup>r</sup>baz", + [true], + {"superscript":[false,true,"",false,false,""]}], +["foo<sup>b<sup>[a]</sup>r</sup>baz", + [["superscript",""]], + "foo<sup>b</sup>[a]<sup>r</sup>baz", + [true], + {"superscript":[false,true,"",false,false,""]}], +["foo<sub><sup>[bar]</sup></sub>baz", + [["stylewithcss","true"],["superscript",""]], + "foo<sup>[bar]</sup>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"superscript":[true,false,"",false,true,""]}], +["foo<sub><sup>[bar]</sup></sub>baz", + [["stylewithcss","false"],["superscript",""]], + "foo<sup>[bar]</sup>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"superscript":[true,false,"",false,true,""]}], +["foo<sub><sup>b[a]r</sup></sub>baz", + [["stylewithcss","true"],["superscript",""]], + "foo<sup>b[a]r</sup>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"superscript":[true,false,"",false,true,""]}], +["foo<sub><sup>b[a]r</sup></sub>baz", + [["stylewithcss","false"],["superscript",""]], + "foo<sup>b[a]r</sup>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"superscript":[true,false,"",false,true,""]}], +["foo<sub>b<sup>[a]</sup>r</sub>baz", + [["stylewithcss","true"],["superscript",""]], + "foo<sub>b</sub><sup>[a]</sup><sub>r</sub>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"superscript":[true,false,"",false,true,""]}], +["foo<sub>b<sup>[a]</sup>r</sub>baz", + [["stylewithcss","false"],["superscript",""]], + "foo<sub>b</sub><sup>[a]</sup><sub>r</sub>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"superscript":[true,false,"",false,true,""]}], +["foo<sup><sub>[bar]</sub></sup>baz", + [["stylewithcss","true"],["superscript",""]], + "foo<sup>[bar]</sup>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"superscript":[true,false,"",false,true,""]}], +["foo<sup><sub>[bar]</sub></sup>baz", + [["stylewithcss","false"],["superscript",""]], + "foo<sup>[bar]</sup>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"superscript":[true,false,"",false,true,""]}], +["foo<sup><sub>b[a]r</sub></sup>baz", + [["stylewithcss","true"],["superscript",""]], + "foo<sub>b</sub><sup>[a]</sup><sub>r</sub>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"superscript":[true,false,"",false,true,""]}], +["foo<sup><sub>b[a]r</sub></sup>baz", + [["stylewithcss","false"],["superscript",""]], + "foo<sub>b</sub><sup>[a]</sup><sub>r</sub>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"superscript":[true,false,"",false,true,""]}], +["foo<sup>b<sub>[a]</sub>r</sup>baz", + [["stylewithcss","true"],["superscript",""]], + "foo<sup>b[a]r</sup>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"superscript":[true,false,"",false,true,""]}], +["foo<sup>b<sub>[a]</sub>r</sup>baz", + [["stylewithcss","false"],["superscript",""]], + "foo<sup>b[a]r</sup>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"superscript":[true,false,"",false,true,""]}], +["fo[o<sup>b]ar</sup>baz", + [["superscript",""]], + "fo<sup>[ob]ar</sup>baz", + [true], + {"superscript":[true,false,"",false,true,""]}], +["foo<sup>ba[r</sup>b]az", + [["superscript",""]], + "foo<sup>ba[rb]</sup>az", + [true], + {"superscript":[true,false,"",false,true,""]}], +["fo[o<sup>bar</sup>b]az", + [["superscript",""]], + "fo<sup>[obarb]</sup>az", + [true], + {"superscript":[true,false,"",false,true,""]}], +["foo[<sup>b]ar</sup>baz", + [["superscript",""]], + "foo[b]<sup>ar</sup>baz", + [true], + {"superscript":[false,true,"",false,false,""]}], +["foo<sup>ba[r</sup>]baz", + [["superscript",""]], + "foo<sup>ba</sup>[r]baz", + [true], + {"superscript":[false,true,"",false,false,""]}], +["foo[<sup>bar</sup>]baz", + [["stylewithcss","true"],["superscript",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"superscript":[false,true,"",false,false,""]}], +["foo[<sup>bar</sup>]baz", + [["stylewithcss","false"],["superscript",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"superscript":[false,true,"",false,false,""]}], +["foo<sup>[bar]</sup>baz", + [["stylewithcss","true"],["superscript",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"superscript":[false,true,"",false,false,""]}], +["foo<sup>[bar]</sup>baz", + [["stylewithcss","false"],["superscript",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"superscript":[false,true,"",false,false,""]}], +["foo{<sup>bar</sup>}baz", + [["stylewithcss","true"],["superscript",""]], + "foo{bar}baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"superscript":[false,true,"",false,false,""]}], +["foo{<sup>bar</sup>}baz", + [["stylewithcss","false"],["superscript",""]], + "foo{bar}baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"superscript":[false,true,"",false,false,""]}], +// The selected text not in <sup> should be moved into the existing <sup>. +["<sup>fo[o</sup><sub>b]ar</sub>", + [["superscript",""]], + "<sup>fo[ob]</sup><sub>ar</sub>", + [true], + {"superscript":[true,false,"",false,true,""]}], +// In the following cases, the vertical-align style in the range should be +// removed first, then, apply <sup>. +["<sup>fo[o</sup><span style=vertical-align:super>b]ar</span>", + [["stylewithcss","true"],["superscript",""]], + "<sup>fo[ob]</sup><span style=\"vertical-align:super\">ar</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"superscript":[true,false,"",false,true,""]}], +["<sup>fo[o</sup><span style=vertical-align:super>b]ar</span>", + [["stylewithcss","false"],["superscript",""]], + "<sup>fo[ob]</sup><span style=\"vertical-align:super\">ar</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"superscript":[true,false,"",false,true,""]}], +["<sup>fo[o</sup><span style=vertical-align:bottom>b]ar</span>", + [["stylewithcss","true"],["superscript",""]], + "<sup>fo[ob]</sup><span style=\"vertical-align:bottom\">ar</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"superscript":[true,false,"",false,true,""]}], +["<sup>fo[o</sup><span style=vertical-align:bottom>b]ar</span>", + [["stylewithcss","false"],["superscript",""]], + "<sup>fo[ob]</sup><span style=\"vertical-align:bottom\">ar</span>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"superscript":[true,false,"",false,true,""]}], +// Even if a vertical-align value is not related to <sub>/<sup>, it should be +// removed to make new <sub> work cleanly. +["foo<span style=vertical-align:bottom>[bar]</span>baz", + [["stylewithcss","true"],["superscript",""]], + "foo<sup>[bar]</sup>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"superscript":[false,false,"",false,true,""]}], +["foo<span style=vertical-align:bottom>[bar]</span>baz", + [["stylewithcss","false"],["superscript",""]], + "foo<sup>[bar]</sup>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"superscript":[false,false,"",false,true,""]}], +// Remove <sup> when it becomes only having an invisible <br> element. +["foo<sup>[bar]<br></sup>", + [["stylewithcss","true"],["superscript",""]], + "foo[bar]<br>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"superscript":[false,true,"",false,false,""]}], +["foo<sup>[bar]<br></sup>", + [["stylewithcss","false"],["superscript",""]], + "foo[bar]<br>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"superscript":[false,true,"",false,false,""]}] +] diff --git a/testing/web-platform/tests/editing/data/underline.js b/testing/web-platform/tests/editing/data/underline.js new file mode 100644 index 0000000000..64fe0ac48b --- /dev/null +++ b/testing/web-platform/tests/editing/data/underline.js @@ -0,0 +1,763 @@ +// For documentation of the format, see README in this directory. +var browserTests = [ +["foo[]bar", + [["underline",""]], + "foo[]bar", + [true], + {"underline":[false,false,"",false,true,""]}], +["<p>[foo</p> <p>bar]</p>", + [["stylewithcss","true"],["underline",""]], + "<p><span style=\"text-decoration:underline\">[foo</span></p> <p><span style=\"text-decoration:underline\">bar]</span></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,false,"",false,true,""]}], +["<p>[foo</p> <p>bar]</p>", + [["stylewithcss","false"],["underline",""]], + "<p><u>[foo</u></p> <p><u>bar]</u></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,false,"",false,true,""]}], +["<span>[foo</span> <span>bar]</span>", + [["stylewithcss","true"],["underline",""]], + "<span style=\"text-decoration:underline\"><span>[foo</span> <span>bar]</span></span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,false,"",false,true,""]}], +["<span>[foo</span> <span>bar]</span>", + [["stylewithcss","false"],["underline",""]], + "<u><span>[foo</span> <span>bar]</span></u>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,false,"",false,true,""]}], +["<p>[foo</p><p> <span>bar</span> </p><p>baz]</p>", + [["stylewithcss","true"],["underline",""]], + "<p><span style=\"text-decoration:underline\">[foo</span></p><p> <span style=\"text-decoration:underline\">bar</span> </p><p><span style=\"text-decoration:underline\">baz</span></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,false,"",false,true,""]}], +["<p>[foo</p><p> <span>bar</span> </p><p>baz]</p>", + [["stylewithcss","false"],["underline",""]], + "<p><u>[foo</u></p><p> <u><span>bar</span></u> </p><p><u>baz]</u></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,false,"",false,true,""]}], +["<p>[foo<p><br><p>bar]", + [["stylewithcss","true"],["underline",""]], + "<p><span style=\"text-decoration:underline\">[foo</span></p><p><span style=\"text-decoration:underline\"><br></span></p><p><span style=\"text-decoration:underline\">bar]</span></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,false,"",false,true,""]}], +["<p>[foo<p><br><p>bar]", + [["stylewithcss","false"],["underline",""]], + "<p><u>[foo</u></p><p><u><br></u></p><p><u>bar]</u></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,false,"",false,true,""]}], +["<b>foo[]bar</b>", + [["underline",""]], + "<b>foo[]bar</b>", + [true], + {"underline":[false,false,"",false,true,""]}], +["<i>foo[]bar</i>", + [["underline",""]], + "<i>foo[]bar</i>", + [true], + {"underline":[false,false,"",false,true,""]}], +["<span>foo</span>{}<span>bar</span>", + [["underline",""]], + "<span>foo</span>{}<span>bar</span>", + [true], + {"underline":[false,false,"",false,true,""]}], +["<span>foo[</span><span>]bar</span>", + [["underline",""]], + "<span>foo[</span><span>]bar</span>", + [true], + {"underline":[false,false,"",false,true,""]}], +["foo[bar]baz", + [["stylewithcss","true"],["underline",""]], + "foo<span style=\"text-decoration:underline\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,false,"",false,true,""]}], +["foo[bar]baz", + [["stylewithcss","false"],["underline",""]], + "foo<u>[bar]</u>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,false,"",false,true,""]}], +["foo[bar<b>baz]qoz</b>quz", + [["stylewithcss","true"],["underline",""]], + "foo<span style=\"text-decoration:underline\">[bar</span><b><span style=\"text-decoration:underline\">baz]</span>qoz</b>quz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,false,"",false,true,""]}], +["foo[bar<b>baz]qoz</b>quz", + [["stylewithcss","false"],["underline",""]], + "foo<u>[bar</u><b><u>baz]</u>qoz</b>quz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,false,"",false,true,""]}], +["foo[bar<i>baz]qoz</i>quz", + [["stylewithcss","true"],["underline",""]], + "foo<span style=\"text-decoration:underline\">[bar</span><i><span style=\"text-decoration:underline\">baz]</span>qoz</i>quz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,false,"",false,true,""]}], +["foo[bar<i>baz]qoz</i>quz", + [["stylewithcss","false"],["underline",""]], + "foo<u>[bar</u><i><u>baz]</u>qoz</i>quz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,false,"",false,true,""]}], +["{<p><p> <p>foo</p>}", + [["stylewithcss","true"],["underline",""]], + "{<p></p><p> </p><p><span style=\"text-decoration:underline\">foo</span></p>}", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,false,"",false,true,""]}], +["{<p><p> <p>foo</p>}", + [["stylewithcss","false"],["underline",""]], + "{<p></p><p> </p><p><u>foo</u></p>}", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,false,"",false,true,""]}], +["<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>", + [["stylewithcss","true"],["underline",""]], + "<table><tbody><tr><td>foo</td><td>b<span style=\"text-decoration:underline\">[a]</span>r</td><td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,false,"",false,true,""]}], +["<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>", + [["stylewithcss","false"],["underline",""]], + "<table><tbody><tr><td>foo</td><td>b<u>[a]</u>r</td><td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,false,"",false,true,""]}], +["<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table>", + [["stylewithcss","true"],["underline",""]], + "<table><tbody><tr><td>foo</td>{<td><span style=\"text-decoration:underline\">bar</span></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,false,"",false,true,""]}], +["<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table>", + [["stylewithcss","false"],["underline",""]], + "<table><tbody><tr><td>foo</td>{<td><u>bar</u></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,false,"",false,true,""]}], +["<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table>", + [["stylewithcss","true"],["underline",""]], + "<table><tbody><tr>{<td><span style=\"text-decoration:underline\">foo</span></td><td><span style=\"text-decoration:underline\">bar</span></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,false,"",false,true,""]}], +["<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table>", + [["stylewithcss","false"],["underline",""]], + "<table><tbody><tr>{<td><u>foo</u></td><td><u>bar</u></td>}<td>baz</td></tr></tbody></table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,false,"",false,true,""]}], +["<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>", + [["stylewithcss","true"],["underline",""]], + "<table><tbody>{<tr><td><span style=\"text-decoration:underline\">foo</span></td><td><span style=\"text-decoration:underline\">bar</span></td><td><span style=\"text-decoration:underline\">baz</span></td></tr>}</tbody></table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,false,"",false,true,""]}], +["<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>", + [["stylewithcss","false"],["underline",""]], + "<table><tbody>{<tr><td><u>foo</u></td><td><u>bar</u></td><td><u>baz</u></td></tr>}</tbody></table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,false,"",false,true,""]}], +["<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>", + [["stylewithcss","true"],["underline",""]], + "<table>{<tbody><tr><td><span style=\"text-decoration:underline\">foo</span></td><td><span style=\"text-decoration:underline\">bar</span></td><td><span style=\"text-decoration:underline\">baz</span></td></tr></tbody>}</table>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,false,"",false,true,""]}], +["<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>", + [["stylewithcss","false"],["underline",""]], + "<table>{<tbody><tr><td><u>foo</u></td><td><u>bar</u></td><td><u>baz</u></td></tr></tbody>}</table>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,false,"",false,true,""]}], +["{<table><tr><td>foo<td>bar<td>baz</table>}", + [["stylewithcss","true"],["underline",""]], + "{<table><tbody><tr><td><span style=\"text-decoration:underline\">foo</span></td><td><span style=\"text-decoration:underline\">bar</span></td><td><span style=\"text-decoration:underline\">baz</span></td></tr></tbody></table>}", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,false,"",false,true,""]}], +["{<table><tr><td>foo<td>bar<td>baz</table>}", + [["stylewithcss","false"],["underline",""]], + "{<table><tbody><tr><td><u>foo</u></td><td><u>bar</u></td><td><u>baz</u></td></tr></tbody></table>}", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,false,"",false,true,""]}], +["foo<span style=\"text-decoration: underline\">[bar]</span>baz", + [["stylewithcss","true"],["underline",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,true,"",false,false,""]}], +["foo<span style=\"text-decoration: underline\">[bar]</span>baz", + [["stylewithcss","false"],["underline",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,true,"",false,false,""]}], +["<u>foo[bar]baz</u>", + [["stylewithcss","true"],["underline",""]], + "<span style=\"text-decoration:underline\">foo</span>[bar]<span style=\"text-decoration:underline\">baz</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,true,"",false,false,""]}], +["<u>foo[bar]baz</u>", + [["stylewithcss","false"],["underline",""]], + "<u>foo</u>[bar]<u>baz</u>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,true,"",false,false,""]}], +["<u>foo[b<span style=\"color:blue\">ar]ba</span>z</u>", + [["stylewithcss","true"],["underline",""]], + "<span style=\"text-decoration:underline\">foo</span>[b<span style=\"color:rgb(0, 0, 255)\">ar]<span style=\"text-decoration:underline\">ba</span></span><span style=\"text-decoration:underline\">z</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,true,"",false,false,""]}], +["<u>foo[b<span style=\"color:blue\">ar]ba</span>z</u>", + [["stylewithcss","false"],["underline",""]], + "<u>foo</u>[b<span style=\"color:rgb(0, 0, 255)\">ar]<u>ba</u></span><u>z</u>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,true,"",false,false,""]}], +["<u>foo[b<span style=\"color:blue\" id=foo>ar]ba</span>z</u>", + [["stylewithcss","true"],["underline",""]], + "<span style=\"text-decoration:underline\">foo</span>[b<span style=\"color:rgb(0, 0, 255)\" id=\"foo\">ar]<span style=\"text-decoration:underline\">ba</span></span><span style=\"text-decoration:underline\">z</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,true,"",false,false,""]}], +["<u>foo[b<span style=\"color:blue\" id=foo>ar]ba</span>z</u>", + [["stylewithcss","false"],["underline",""]], + "<u>foo</u>[b<span style=\"color:rgb(0, 0, 255)\" id=\"foo\">ar]<u>ba</u></span><u>z</u>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,true,"",false,false,""]}], +["<u>foo[b<span style=\"font-size:3em\">ar]ba</span>z</u>", + [["stylewithcss","true"],["underline",""]], + "<span style=\"text-decoration:underline\">foo</span>[b<span style=\"font-size:3em\">ar]<span style=\"text-decoration:underline\">ba</span></span><span style=\"text-decoration:underline\">z</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,true,"",false,false,""]}], +["<u>foo[b<span style=\"font-size:3em\">ar]ba</span>z</u>", + [["stylewithcss","false"],["underline",""]], + "<u>foo</u>[b<span style=\"font-size:3em\">ar]<u>ba</u></span><u>z</u>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,true,"",false,false,""]}], +["<u>foo[b<i>ar]ba</i>z</u>", + [["stylewithcss","true"],["underline",""]], + "<span style=\"text-decoration:underline\">foo</span>[b<i>ar]<span style=\"text-decoration:underline\">ba</span></i><span style=\"text-decoration:underline\">z</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,true,"",false,false,""]}], +["<u>foo[b<i>ar]ba</i>z</u>", + [["stylewithcss","false"],["underline",""]], + "<u>foo</u>[b<i>ar]<u>ba</u></i><u>z</u>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,true,"",false,false,""]}], +["<p style=\"text-decoration: underline\">foo[bar]baz</p>", + [["stylewithcss","true"],["underline",""]], + "<p><span style=\"text-decoration:underline\">foo</span>[bar]<span style=\"text-decoration:underline\">baz</span></p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,true,"",false,false,""]}], +["<p style=\"text-decoration: underline\">foo[bar]baz</p>", + [["stylewithcss","false"],["underline",""]], + "<p><u>foo</u>[bar]<u>baz</u></p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,true,"",false,false,""]}], +// <s> should be replaced with new <span> because it just represents line-though +// style, and should set its text-decoration to underline (requested style) and +// line-through (default style of <s>). +["foo<s>[bar]</s>baz", + [["stylewithcss","true"],["underline",""]], + "foo<span style=\"text-decoration:underline line-through\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,false,"",false,true,""]}], +["foo<s>[bar]</s>baz", + [["stylewithcss","false"],["underline",""]], + "foo<s><u>[bar]</u></s>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,false,"",false,true,""]}], +// Should update text-decoration declaration in the <span> which is a container +// of the range. +["foo<span style=\"text-decoration: line-through\">[bar]</span>baz", + [["stylewithcss","true"],["underline",""]], + "foo<span style=\"text-decoration:underline line-through\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,false,"",false,true,""]}], +["foo<span style=\"text-decoration: line-through\">[bar]</span>baz", + [["stylewithcss","false"],["underline",""]], + "foo<u><span style=\"text-decoration:line-through\">[bar]</span></u>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,false,"",false,true,""]}], +["<s>foo[bar]baz</s>", + [["stylewithcss","true"],["underline",""]], + "<s>foo<span style=\"text-decoration:underline\">[bar]</span>baz</s>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,false,"",false,true,""]}], +["<s>foo[bar]baz</s>", + [["stylewithcss","false"],["underline",""]], + "<s>foo<u>[bar]</u>baz</s>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,false,"",false,true,""]}], +["<s>foo[b<span style=\"color:blue\">ar]ba</span>z</s>", + [["stylewithcss","true"],["underline",""]], + "<s>foo<span style=\"text-decoration:underline\">[b</span><span style=\"color:rgb(0, 0, 255)\"><span style=\"text-decoration:underline\">ar]</span>ba</span>z</s>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,false,"",false,true,""]}], +["<s>foo[b<span style=\"color:blue\">ar]ba</span>z</s>", + [["stylewithcss","false"],["underline",""]], + "<s>foo<u>[b</u><span style=\"color:rgb(0, 0, 255)\"><u>ar]</u>ba</span>z</s>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,false,"",false,true,""]}], +["<s>foo[b<span style=\"color:blue\" id=foo>ar]ba</span>z</s>", + [["stylewithcss","true"],["underline",""]], + "<s>foo<span style=\"text-decoration:underline\">[b</span><span style=\"color:rgb(0, 0, 255)\" id=\"foo\"><span style=\"text-decoration:underline\">ar]</span>ba</span>z</s>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,false,"",false,true,""]}], +["<s>foo[b<span style=\"color:blue\" id=foo>ar]ba</span>z</s>", + [["stylewithcss","false"],["underline",""]], + "<s>foo<u>[b</u><span style=\"color:rgb(0, 0, 255)\" id=\"foo\"><u>ar]</u>ba</span>z</s>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,false,"",false,true,""]}], +["<s>foo[b<span style=\"font-size:3em\">ar]ba</span>z</s>", + [["stylewithcss","true"],["underline",""]], + "<s>foo<span style=\"text-decoration:underline\">[b</span><span style=\"font-size:3em\"><span style=\"text-decoration:underline\">ar]</span>ba</span>z</s>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,false,"",false,true,""]}], +["<s>foo[b<span style=\"font-size:3em\">ar]ba</span>z</s>", + [["stylewithcss","false"],["underline",""]], + "<s>foo<u>[b</u><span style=\"font-size:3em\"><u>ar]</u>ba</span>z</s>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,false,"",false,true,""]}], +["<s>foo[b<i>ar]ba</i>z</s>", + [["stylewithcss","true"],["underline",""]], + "<s>foo<span style=\"text-decoration:underline\">[b</span><i><span style=\"text-decoration:underline\">ar]</span>ba</i>z</s>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,false,"",false,true,""]}], +["<s>foo[b<i>ar]ba</i>z</s>", + [["stylewithcss","false"],["underline",""]], + "<s>foo<u>[b</u><i><u>ar]</u>ba</i>z</s>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,false,"",false,true,""]}], +["<p style=\"text-decoration: line-through\">foo[bar]baz</p>", + [["stylewithcss","true"],["underline",""]], + "<p style=\"text-decoration:line-through\">foo<span style=\"text-decoration:underline\">[bar]</span>baz</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,false,"",false,true,""]}], +["<p style=\"text-decoration: line-through\">foo[bar]baz</p>", + [["stylewithcss","false"],["underline",""]], + "<p style=\"text-decoration:line-through\">foo<u>[bar]</u>baz</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,false,"",false,true,""]}], +// Should replace <strike> with new <span> because <strike> is just representing +// line-through style, and set its text-decoration to underline (requested +// style) and line-though (default style of <strike>). +["foo<strike>[bar]</strike>baz", + [["stylewithcss","true"],["underline",""]], + "foo<span style=\"text-decoration:underline line-through\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,false,"",false,true,""]}], +["foo<strike>[bar]</strike>baz", + [["stylewithcss","false"],["underline",""]], + "foo<strike><u>[bar]</u></strike>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,false,"",false,true,""]}], +["<strike>foo[bar]baz</strike>", + [["stylewithcss","true"],["underline",""]], + "<strike>foo<span style=\"text-decoration:underline\">[bar]</span>baz</strike>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,false,"",false,true,""]}], +["<strike>foo[bar]baz</strike>", + [["stylewithcss","false"],["underline",""]], + "<strike>foo<u>[bar]</u>baz</strike>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,false,"",false,true,""]}], +["<strike>foo[b<span style=\"color:blue\">ar]ba</span>z</strike>", + [["stylewithcss","true"],["underline",""]], + "<strike>foo<span style=\"text-decoration:underline\">[b</span><span style=\"color:rgb(0, 0, 255)\"><span style=\"text-decoration:underline\">ar]</span>ba</span>z</strike>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,false,"",false,true,""]}], +["<strike>foo[b<span style=\"color:blue\">ar]ba</span>z</strike>", + [["stylewithcss","false"],["underline",""]], + "<strike>foo<u>[b</u><span style=\"color:rgb(0, 0, 255)\"><u>ar]</u>ba</span>z</strike>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,false,"",false,true,""]}], +["<strike>foo[b<span style=\"color:blue\" id=foo>ar]ba</span>z</strike>", + [["stylewithcss","true"],["underline",""]], + "<strike>foo<span style=\"text-decoration:underline\">[b</span><span style=\"color:rgb(0, 0, 255)\" id=\"foo\"><span style=\"text-decoration:underline\">ar]</span>ba</span>z</strike>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,false,"",false,true,""]}], +["<strike>foo[b<span style=\"color:blue\" id=foo>ar]ba</span>z</strike>", + [["stylewithcss","false"],["underline",""]], + "<strike>foo<u>[b</u><span style=\"color:rgb(0, 0, 255)\" id=\"foo\"><u>ar]</u>ba</span>z</strike>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,false,"",false,true,""]}], +["<strike>foo[b<span style=\"font-size:3em\">ar]ba</span>z</strike>", + [["stylewithcss","true"],["underline",""]], + "<strike>foo<span style=\"text-decoration:underline\">[b</span><span style=\"font-size:3em\"><span style=\"text-decoration:underline\">ar]</span>ba</span>z</strike>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,false,"",false,true,""]}], +["<strike>foo[b<span style=\"font-size:3em\">ar]ba</span>z</strike>", + [["stylewithcss","false"],["underline",""]], + "<strike>foo<u>[b</u><span style=\"font-size:3em\"><u>ar]</u>ba</span>z</strike>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,false,"",false,true,""]}], +["<strike>foo[b<i>ar]ba</i>z</strike>", + [["stylewithcss","true"],["underline",""]], + "<strike>foo<span style=\"text-decoration:underline\">[b</span><i><span style=\"text-decoration:underline\">ar]</span>ba</i>z</strike>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,false,"",false,true,""]}], +["<strike>foo[b<i>ar]ba</i>z</strike>", + [["stylewithcss","false"],["underline",""]], + "<strike>foo<u>[b</u><i><u>ar]</u>ba</i>z</strike>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,false,"",false,true,""]}], +["foo<ins>[bar]</ins>baz", + [["underline",""]], + "foo<ins>[bar]</ins>baz", + [true], + {"underline":[false,true,"",false,true,""]}], +["<ins>foo[bar]baz</ins>", + [["underline",""]], + "<ins>foo[bar]baz</ins>", + [true], + {"underline":[false,true,"",false,true,""]}], +["<ins>foo[b<span style=\"color:blue\">ar]ba</span>z</ins>", + [["underline",""]], + "<ins>foo[b<span style=\"color:rgb(0, 0, 255)\">ar]ba</span>z</ins>", + [true], + {"underline":[false,true,"",false,true,""]}], +["<ins>foo[b<span style=\"color:blue\" id=foo>ar]ba</span>z</ins>", + [["underline",""]], + "<ins>foo[b<span style=\"color:rgb(0, 0, 255)\" id=\"foo\">ar]ba</span>z</ins>", + [true], + {"underline":[false,true,"",false,true,""]}], +["<ins>foo[b<span style=\"font-size:3em\">ar]ba</span>z</ins>", + [["underline",""]], + "<ins>foo[b<span style=\"font-size:3em\">ar]ba</span>z</ins>", + [true], + {"underline":[false,true,"",false,true,""]}], +["<ins>foo[b<i>ar]ba</i>z</ins>", + [["underline",""]], + "<ins>foo[b<i>ar]ba</i>z</ins>", + [true], + {"underline":[false,true,"",false,true,""]}], +// Should set text-decoration of <del> because it has line-through style by +// default and it is not only representing it, thus, replacing it with <span> +// changes the meaning. +["foo<del>[bar]</del>baz", + [["stylewithcss","true"],["underline",""]], + "foo<del style=\"text-decoration:underline line-through\">[bar]</del>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,false,"",false,true,""]}], +["foo<del>[bar]</del>baz", + [["stylewithcss","false"],["underline",""]], + "foo<del><u>[bar]</u></del>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,false,"",false,true,""]}], +["<del>foo[bar]baz</del>", + [["stylewithcss","true"],["underline",""]], + "<del>foo<span style=\"text-decoration:underline\">[bar]</span>baz</del>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,false,"",false,true,""]}], +["<del>foo[bar]baz</del>", + [["stylewithcss","false"],["underline",""]], + "<del>foo<u>[bar]</u>baz</del>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,false,"",false,true,""]}], +["<del>foo[b<span style=\"color:blue\">ar]ba</span>z</del>", + [["stylewithcss","true"],["underline",""]], + "<del>foo<span style=\"text-decoration:underline\">[b</span><span style=\"color:rgb(0, 0, 255)\"><span style=\"text-decoration:underline\">ar]</span>ba</span>z</del>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,false,"",false,true,""]}], +["<del>foo[b<span style=\"color:blue\">ar]ba</span>z</del>", + [["stylewithcss","false"],["underline",""]], + "<del>foo<u>[b</u><span style=\"color:rgb(0, 0, 255)\"><u>ar]</u>ba</span>z</del>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,false,"",false,true,""]}], +["<del>foo[b<span style=\"color:blue\" id=foo>ar]ba</span>z</del>", + [["stylewithcss","true"],["underline",""]], + "<del>foo<span style=\"text-decoration:underline\">[b</span><span style=\"color:rgb(0, 0, 255)\" id=\"foo\"><span style=\"text-decoration:underline\">ar]</span>ba</span>z</del>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,false,"",false,true,""]}], +["<del>foo[b<span style=\"color:blue\" id=foo>ar]ba</span>z</del>", + [["stylewithcss","false"],["underline",""]], + "<del>foo<u>[b</u><span style=\"color:rgb(0, 0, 255)\" id=\"foo\"><u>ar]</u>ba</span>z</del>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,false,"",false,true,""]}], +["<del>foo[b<span style=\"font-size:3em\">ar]ba</span>z</del>", + [["stylewithcss","true"],["underline",""]], + "<del>foo<span style=\"text-decoration:underline\">[b</span><span style=\"font-size:3em\"><span style=\"text-decoration:underline\">ar]</span>ba</span>z</del>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,false,"",false,true,""]}], +["<del>foo[b<span style=\"font-size:3em\">ar]ba</span>z</del>", + [["stylewithcss","false"],["underline",""]], + "<del>foo<u>[b</u><span style=\"font-size:3em\"><u>ar]</u>ba</span>z</del>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,false,"",false,true,""]}], +["<del>foo[b<i>ar]ba</i>z</del>", + [["stylewithcss","true"],["underline",""]], + "<del>foo<span style=\"text-decoration:underline\">[b</span><i><span style=\"text-decoration:underline\">ar]</span>ba</i>z</del>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,false,"",false,true,""]}], +["<del>foo[b<i>ar]ba</i>z</del>", + [["stylewithcss","false"],["underline",""]], + "<del>foo<u>[b</u><i><u>ar]</u>ba</i>z</del>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,false,"",false,true,""]}], +["foo<span style=\"text-decoration: underline line-through\">[bar]</span>baz", + [["underline",""]], + "foo<span style=\"text-decoration:line-through\">[bar]</span>baz", + [true], + {"underline":[false,true,"",false,false,""]}], +["foo<span style=\"text-decoration: underline line-through\">b[a]r</span>baz", + [["stylewithcss","true"],["underline",""]], + "foo<span style=\"text-decoration:line-through\"><span style=\"text-decoration:underline\">b</span>[a]<span style=\"text-decoration:underline\">r</span></span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,true,"",false,false,""]}], +["foo<span style=\"text-decoration: underline line-through\">b[a]r</span>baz", + [["stylewithcss","false"],["underline",""]], + "foo<span style=\"text-decoration:line-through\"><u>b</u>[a]<u>r</u></span>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,true,"",false,false,""]}], +["foo<s style=\"text-decoration: underline\">[bar]</s>baz", + [["stylewithcss","true"],["underline",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,true,"",false,false,""]}], +["foo<s style=\"text-decoration: underline\">[bar]</s>baz", + [["stylewithcss","false"],["underline",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,true,"",false,false,""]}], +["foo<s style=\"text-decoration: underline\">b[a]r</s>baz", + [["stylewithcss","true"],["underline",""]], + "foo<span style=\"text-decoration:underline\">b</span>[a]<span style=\"text-decoration:underline\">r</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,true,"",false,false,""]}], +["foo<s style=\"text-decoration: underline\">b[a]r</s>baz", + [["stylewithcss","false"],["underline",""]], + "foo<u>b</u>[a]<u>r</u>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,true,"",false,false,""]}], +["foo<u style=\"text-decoration: line-through\">[bar]</u>baz", + [["stylewithcss","true"],["underline",""]], + "foo<span style=\"text-decoration:underline\"><u style=\"text-decoration:line-through\">[bar]</u></span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,false,"",false,true,""]}], +["foo<u style=\"text-decoration: line-through\">[bar]</u>baz", + [["stylewithcss","false"],["underline",""]], + "foo<u><u style=\"text-decoration:line-through\">[bar]</u></u>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,false,"",false,true,""]}], +["foo<u style=\"text-decoration: line-through\">b[a]r</u>baz", + [["stylewithcss","true"],["underline",""]], + "foo<u style=\"text-decoration:line-through\">b<span style=\"text-decoration:underline\">[a]</span>r</u>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,false,"",false,true,""]}], +["foo<u style=\"text-decoration: line-through\">b[a]r</u>baz", + [["stylewithcss","false"],["underline",""]], + "foo<u style=\"text-decoration:line-through\">b<u>[a]</u>r</u>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,false,"",false,true,""]}], +// Should replace <s> with new <span> and set its `text-decoration` to underline +// (for applying the requested style) and overline (which was specified to the +// <s>). Note that line-though was removed by the text-decoration setting. +// Therefore, it should not appear. +["foo<s style=\"text-decoration: overline\">[bar]</s>baz", + [["stylewithcss","true"],["underline",""]], + "foo<span style=\"text-decoration:underline overline\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,false,"",false,true,""]}], +["foo<s style=\"text-decoration: overline\">[bar]</s>baz", + [["stylewithcss","false"],["underline",""]], + "foo<u><s style=\"text-decoration:overline\">[bar]</s></u>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,false,"",false,true,""]}], +["foo<s style=\"text-decoration: overline\">b[a]r</s>baz", + [["stylewithcss","true"],["underline",""]], + "foo<s style=\"text-decoration:overline\">b<span style=\"text-decoration:underline\">[a]</span>r</s>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,false,"",false,true,""]}], +["foo<s style=\"text-decoration: overline\">b[a]r</s>baz", + [["stylewithcss","false"],["underline",""]], + "foo<s style=\"text-decoration:overline\">b<u>[a]</u>r</s>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,false,"",false,true,""]}], +["foo<u style=\"text-decoration: overline\">[bar]</u>baz", + [["stylewithcss","true"],["underline",""]], + "foo<span style=\"text-decoration:underline\"><u style=\"text-decoration:overline\">[bar]</u></span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,false,"",false,true,""]}], +["foo<u style=\"text-decoration: overline\">[bar]</u>baz", + [["stylewithcss","false"],["underline",""]], + "foo<u><u style=\"text-decoration:overline\">[bar]</u></u>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,false,"",false,true,""]}], +["foo<u style=\"text-decoration: overline\">b[a]r</u>baz", + [["stylewithcss","true"],["underline",""]], + "foo<u style=\"text-decoration:overline\">b<span style=\"text-decoration:underline\">[a]</span>r</u>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,false,"",false,true,""]}], +["foo<u style=\"text-decoration: overline\">b[a]r</u>baz", + [["stylewithcss","false"],["underline",""]], + "foo<u style=\"text-decoration:overline\">b<u>[a]</u>r</u>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,false,"",false,true,""]}], +["<p style=\"text-decoration: overline\">foo[bar]baz</p>", + [["stylewithcss","true"],["underline",""]], + "<p style=\"text-decoration:overline\">foo<span style=\"text-decoration:underline\">[bar]</span>baz</p>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,false,"",false,true,""]}], +["<p style=\"text-decoration: overline\">foo[bar]baz</p>", + [["stylewithcss","false"],["underline",""]], + "<p style=\"text-decoration:overline\">foo<u>[bar]</u>baz</p>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,false,"",false,true,""]}], +["foo<span class=\"underline\">[bar]</span>baz", + [["underline",""]], + "foo<span class=\"underline\">[bar]</span>baz", + [true], + {"underline":[false,true,"",false,true,""]}], +["foo<span class=\"underline\">b[a]r</span>baz", + [["underline",""]], + "foo<span class=\"underline\">b[a]r</span>baz", + [true], + {"underline":[false,true,"",false,true,""]}], +["foo<span class=\"line-through\">[bar]</span>baz", + [["stylewithcss","true"],["underline",""]], + "foo<span class=\"line-through\" style=\"text-decoration:underline\">[bar]</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,false,"",false,true,""]}], +["foo<span class=\"line-through\">[bar]</span>baz", + [["stylewithcss","false"],["underline",""]], + "foo<span class=\"line-through\"><u>[bar]</u></span>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,false,"",false,true,""]}], +["foo<span class=\"line-through\">b[a]r</span>baz", + [["stylewithcss","true"],["underline",""]], + "foo<span class=\"line-through\">b<span style=\"text-decoration:underline\">[a]</span>r</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,false,"",false,true,""]}], +["foo<span class=\"line-through\">b[a]r</span>baz", + [["stylewithcss","false"],["underline",""]], + "foo<span class=\"line-through\">b<u>[a]</u>r</span>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,false,"",false,true,""]}], +["foo<span class=\"underline-and-line-through\">[bar]</span>baz", + [["underline",""]], + "foo<span class=\"underline-and-line-through\">[bar]</span>baz", + [true], + {"underline":[false,true,"",false,true,""]}], +["foo<span class=\"underline-and-line-through\">b[a]r</span>baz", + [["underline",""]], + "foo<span class=\"underline-and-line-through\">b[a]r</span>baz", + [true], + {"underline":[false,true,"",false,true,""]}], +["fo[o<u>b]ar</u>baz", + [["underline",""]], + "fo<u>[ob]ar</u>baz", + [true], + {"underline":[true,false,"",false,true,""]}], +["foo<u>ba[r</u>b]az", + [["underline",""]], + "foo<u>ba[rb]</u>az", + [true], + {"underline":[true,false,"",false,true,""]}], +["fo[o<u>bar</u>b]az", + [["stylewithcss","true"],["underline",""]], + "fo<span style=\"text-decoration:underline\">[obarb]</span>az", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[true,false,"",false,true,""]}], +["fo[o<u>bar</u>b]az", + [["stylewithcss","false"],["underline",""]], + "fo<u>[obarb]</u>az", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[true,false,"",false,true,""]}], +["foo[<u>b]ar</u>baz", + [["stylewithcss","true"],["underline",""]], + "foo[b]<span style=\"text-decoration:underline\">ar</span>baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,true,"",false,false,""]}], +["foo[<u>b]ar</u>baz", + [["stylewithcss","false"],["underline",""]], + "foo[b]<u>ar</u>baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,true,"",false,false,""]}], +["foo<u>ba[r</u>]baz", + [["stylewithcss","true"],["underline",""]], + "foo<span style=\"text-decoration:underline\">ba</span>[r]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,true,"",false,false,""]}], +["foo<u>ba[r</u>]baz", + [["stylewithcss","false"],["underline",""]], + "foo<u>ba</u>[r]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,true,"",false,false,""]}], +["foo[<u>bar</u>]baz", + [["stylewithcss","true"],["underline",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,true,"",false,false,""]}], +["foo[<u>bar</u>]baz", + [["stylewithcss","false"],["underline",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,true,"",false,false,""]}], +["foo<u>[bar]</u>baz", + [["stylewithcss","true"],["underline",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,true,"",false,false,""]}], +["foo<u>[bar]</u>baz", + [["stylewithcss","false"],["underline",""]], + "foo[bar]baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,true,"",false,false,""]}], +["foo{<u>bar</u>}baz", + [["stylewithcss","true"],["underline",""]], + "foo{bar}baz", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,true,"",false,false,""]}], +["foo{<u>bar</u>}baz", + [["stylewithcss","false"],["underline",""]], + "foo{bar}baz", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,true,"",false,false,""]}], +["fo[o<span style=text-decoration:underline>b]ar</span>baz", + [["underline",""]], + "fo<span style=\"text-decoration:underline\">[ob]ar</span>baz", + [true], + {"underline":[true,false,"",false,true,""]}], +["<ins>fo[o</ins><u>b]ar</u>", + [["stylewithcss","true"],["underline",""]], + "<ins>fo[o</ins>b]<span style=\"text-decoration:underline\">ar</span>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,true,"",true,false,""]}], +["<ins>fo[o</ins><u>b]ar</u>", + [["stylewithcss","false"],["underline",""]], + "<ins>fo[o</ins>b]<u>ar</u>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,true,"",true,false,""]}], +["<u>fo[o</u><ins>b]ar</ins>", + [["stylewithcss","true"],["underline",""]], + "<span style=\"text-decoration:underline\">fo</span>[o<ins>b]ar</ins>", + [true,true], + {"stylewithcss":[false,false,"",false,true,""],"underline":[false,true,"",true,false,""]}], +["<u>fo[o</u><ins>b]ar</ins>", + [["stylewithcss","false"],["underline",""]], + "<u>fo</u>[o<ins>b]ar</ins>", + [true,true], + {"stylewithcss":[false,true,"",false,false,""],"underline":[false,true,"",true,false,""]}], + +// Tests to remove only underline from existing text-decoration +["abc<span style=\"text-decoration:line-through overline underline\">[def]</span>ghi", + [["stylewithcss","true"],["underline",""]], + ["abc<span style=\"text-decoration:overline line-through\">[def]</span>ghi", + "abc<span style=\"text-decoration-line:overline line-through\">[def]</span>ghi"], + [true,true], + {}], + +// blink, text-decoration-color and text-decoration-style values should be +// dropped. This rule is odd because executing "underline" command causes +// the data loss, but for now, the compatibility between browsers is more +// important. Once you want/need to change the behavior of a browser, you +// should file a spec issue first. +// And these tests allows the difference between text-decoration vs. +// text-decoration-line because these tests want to check the data loss. +["abc<span style=\"text-decoration:blink line-through overline\">[def]</span>ghi", + [["stylewithcss","true"],["underline",""]], + ["abc<span style=\"text-decoration:underline overline line-through\">[def]</span>ghi", + "abc<span style=\"text-decoration-line:underline overline line-through\">[def]</span>ghi"], + [true,true], + {}], +["abc<span style=\"text-decoration:line-through blue dotted\">[def]</span>ghi", + [["stylewithcss","true"],["underline",""]], + ["abc<span style=\"text-decoration:underline line-through\">[def]</span>ghi", + "abc<span style=\"text-decoration-line:underline line-through\">[def]</span>ghi"], + [true,true], + {}], +["abc<span style=\"text-decoration:blink line-through underline overline\">[def]</span>ghi", + [["stylewithcss","true"],["underline",""]], + ["abc<span style=\"text-decoration:overline line-through\">[def]</span>ghi", + "abc<span style=\"text-decoration-line:overline line-through\">[def]</span>ghi"], + [true,true], + {}], +["abc<span style=\"text-decoration:underline line-through blue dotted\">[def]</span>ghi", + [["stylewithcss","true"],["underline",""]], + ["abc<span style=\"text-decoration:line-through\">[def]</span>ghi", + "abc<span style=\"text-decoration-line:line-through\">[def]</span>ghi"], + [true,true], + {}], +]
\ No newline at end of file diff --git a/testing/web-platform/tests/editing/data/unlink.js b/testing/web-platform/tests/editing/data/unlink.js new file mode 100644 index 0000000000..b043adfd99 --- /dev/null +++ b/testing/web-platform/tests/editing/data/unlink.js @@ -0,0 +1,218 @@ +// For documentation of the format, see README in this directory. +var browserTests = [ +["foo[]bar", + [["unlink",""]], + "foo[]bar", + [true], + {"unlink":[false,false,"",false,false,""]}], +["<p>[foo</p> <p>bar]</p>", + [["unlink",""]], + "<p>[foo</p> <p>bar]</p>", + [true], + {"unlink":[false,false,"",false,false,""]}], +["<span>[foo</span> <span>bar]</span>", + [["unlink",""]], + "<span>[foo</span> <span>bar]</span>", + [true], + {"unlink":[false,false,"",false,false,""]}], +["<p>[foo</p><p> <span>bar</span> </p><p>baz]</p>", + [["unlink",""]], + "<p>[foo</p><p> <span>bar</span> </p><p>baz]</p>", + [true], + {"unlink":[false,false,"",false,false,""]}], +["<b>foo[]bar</b>", + [["unlink",""]], + "<b>foo[]bar</b>", + [true], + {"unlink":[false,false,"",false,false,""]}], +["<i>foo[]bar</i>", + [["unlink",""]], + "<i>foo[]bar</i>", + [true], + {"unlink":[false,false,"",false,false,""]}], +["<span>foo</span>{}<span>bar</span>", + [["unlink",""]], + "<span>foo</span>{}<span>bar</span>", + [true], + {"unlink":[false,false,"",false,false,""]}], +["<span>foo[</span><span>]bar</span>", + [["unlink",""]], + "<span>foo[</span><span>]bar</span>", + [true], + {"unlink":[false,false,"",false,false,""]}], +["foo[bar]baz", + [["unlink",""]], + "foo[bar]baz", + [true], + {"unlink":[false,false,"",false,false,""]}], +["foo[bar<b>baz]qoz</b>quz", + [["unlink",""]], + "foo[bar<b>baz]qoz</b>quz", + [true], + {"unlink":[false,false,"",false,false,""]}], +["foo[bar<i>baz]qoz</i>quz", + [["unlink",""]], + "foo[bar<i>baz]qoz</i>quz", + [true], + {"unlink":[false,false,"",false,false,""]}], +["{<p><p> <p>foo</p>}", + [["unlink",""]], + "{<p></p><p> </p><p>foo</p>}", + [true], + {"unlink":[false,false,"",false,false,""]}], +["<a href=http://www.google.com/>foo[bar]baz</a>", + [["unlink",""]], + "foo[bar]baz", + [true], + {"unlink":[false,false,"",false,false,""]}], +["<a href=http://www.google.com/>foo[barbaz</a>}", + [["unlink",""]], + "foo[barbaz}", + [true], + {"unlink":[false,false,"",false,false,""]}], +["{<a href=http://www.google.com/>foobar]baz</a>", + [["unlink",""]], + "{foobar]baz", + [true], + {"unlink":[false,false,"",false,false,""]}], +["{<a href=http://www.google.com/>foobarbaz</a>}", + [["unlink",""]], + "{foobarbaz}", + [true], + {"unlink":[false,false,"",false,false,""]}], +["<a href=http://www.google.com/>[foobarbaz]</a>", + [["unlink",""]], + "[foobarbaz]", + [true], + {"unlink":[false,false,"",false,false,""]}], +["foo<a href=http://www.google.com/>b[]ar</a>baz", + [["unlink",""]], + "foob[]arbaz", + [true], + {"unlink":[false,false,"",false,false,""]}], +["foo<a href=http://www.google.com/>[bar]</a>baz", + [["unlink",""]], + "foo[bar]baz", + [true], + {"unlink":[false,false,"",false,false,""]}], +["foo[<a href=http://www.google.com/>bar</a>]baz", + [["unlink",""]], + "foo[bar]baz", + [true], + {"unlink":[false,false,"",false,false,""]}], +["foo<a href=http://www.google.com/>[bar</a>baz]", + [["unlink",""]], + "foo[barbaz]", + [true], + {"unlink":[false,false,"",false,false,""]}], +["[foo<a href=http://www.google.com/>bar]</a>baz", + [["unlink",""]], + "[foobar]baz", + [true], + {"unlink":[false,false,"",false,false,""]}], +["[foo<a href=http://www.google.com/>bar</a>baz]", + [["unlink",""]], + "[foobarbaz]", + [true], + {"unlink":[false,false,"",false,false,""]}], +["<a id=foo href=http://www.google.com/>foobar[]baz</a>", + [["unlink",""]], + "<a id=\"foo\">foobar[]baz</a>", + [true], + {"unlink":[false,false,"",false,false,""]}], +["<a id=foo href=http://www.google.com/>foo[bar]baz</a>", + [["unlink",""]], + "<a id=\"foo\">foo[bar]baz</a>", + [true], + {"unlink":[false,false,"",false,false,""]}], +["<a id=foo href=http://www.google.com/>[foobarbaz]</a>", + [["unlink",""]], + "<a id=\"foo\">[foobarbaz]</a>", + [true], + {"unlink":[false,false,"",false,false,""]}], +["foo<a id=foo href=http://www.google.com/>[bar]</a>baz", + [["unlink",""]], + "foo<a id=\"foo\">[bar]</a>baz", + [true], + {"unlink":[false,false,"",false,false,""]}], +["foo[<a id=foo href=http://www.google.com/>bar</a>]baz", + [["unlink",""]], + "foo[<a id=\"foo\">bar</a>]baz", + [true], + {"unlink":[false,false,"",false,false,""]}], +["[foo<a id=foo href=http://www.google.com/>bar</a>baz]", + [["unlink",""]], + "[foo<a id=\"foo\">bar</a>baz]", + [true], + {"unlink":[false,false,"",false,false,""]}], +["<a name=foo>foobar[]baz</a>", + [["unlink",""]], + "<a name=\"foo\">foobar[]baz</a>", + [true], + {"unlink":[false,false,"",false,false,""]}], +["<a name=foo>foo[bar]baz</a>", + [["unlink",""]], + "<a name=\"foo\">foo[bar]baz</a>", + [true], + {"unlink":[false,false,"",false,false,""]}], +["<a name=foo>[foobarbaz]</a>", + [["unlink",""]], + "<a name=\"foo\">[foobarbaz]</a>", + [true], + {"unlink":[false,false,"",false,false,""]}], +["foo<a name=foo>[bar]</a>baz", + [["unlink",""]], + "foo<a name=\"foo\">[bar]</a>baz", + [true], + {"unlink":[false,false,"",false,false,""]}], +["foo[<a name=foo>bar</a>]baz", + [["unlink",""]], + "foo[<a name=\"foo\">bar</a>]baz", + [true], + {"unlink":[false,false,"",false,false,""]}], +["[foo<a name=foo>bar</a>baz]", + [["unlink",""]], + "[foo<a name=\"foo\">bar</a>baz]", + [true], + {"unlink":[false,false,"",false,false,""]}], +["[foo<a href=https://example.com class=bold>bar</a>baz]", + [["stylewithcss", "false"], ["unlink",""]], + "foobarbaz", + [true, true], + {"unlink":[false,false,"",false,false,""]}], +["foo<a href=https://example.com class=bold>[bar]</a>baz", + [["stylewithcss", "false"], ["unlink",""]], + "foobarbaz", + [true, true], + {"unlink":[false,false,"",false,false,""]}], +["[foo<a href=https://example.com class=bold>bar</a>baz]", + [["stylewithcss", "true"], ["unlink",""]], + "foobarbaz", + [true, true], + {"unlink":[false,false,"",false,false,""]}], +["foo<a href=https://example.com class=bold>[bar]</a>baz", + [["stylewithcss", "true"], ["unlink",""]], + "foobarbaz", + [true, true], + {"unlink":[false,false,"",false,false,""]}], +["[foo<a href=https://example.com style=font-weight:bold>bar</a>baz]", + [["stylewithcss", "false"], ["unlink",""]], + "foo<b>bar</b>baz", + [true, true], + {"unlink":[false,false,"",false,false,""]}], +["foo<a href=https://example.com style=font-weight:bold>[bar]</a>baz", + [["stylewithcss", "false"], ["unlink",""]], + "foo<b>bar</b>baz", + [true, true], + {"unlink":[false,false,"",false,false,""]}], +["[foo<a href=https://example.com style=font-weight:bold>bar</a>baz]", + [["stylewithcss", "true"], ["unlink",""]], + "foo<span style=\"font-weight:bold\">bar</span>baz", + [true, true], + {"unlink":[false,false,"",false,false,""]}], +["foo<a href=https://example.com style=font-weight:bold>[bar]</a>baz", + [["stylewithcss", "true"], ["unlink",""]], + "foo<span style=\"font-weight:bold\">bar</span>baz", + [true, true], + {"unlink":[false,false,"",false,false,""]}], +] diff --git a/testing/web-platform/tests/editing/edit-context/edit-context-basics.tentative.html b/testing/web-platform/tests/editing/edit-context/edit-context-basics.tentative.html new file mode 100644 index 0000000000..78b6824921 --- /dev/null +++ b/testing/web-platform/tests/editing/edit-context/edit-context-basics.tentative.html @@ -0,0 +1,196 @@ +<!DOCTYPE html> +<html> +<head> +<title>EditContext: The HTMLElement.editContext property</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src='../../html/resources/common.js'></script> +</head> +<body> + <div id="test"></div> + <div id="contenteditableDiv" contenteditable></div> + <script> + test(function() { + const editContextDict = { + text: "Hello world", + selectionStart: 11, + selectionEnd: 11 + }; + const editContext = new EditContext(editContextDict); + assert_not_equals(editContext, null); + // Verify all the members of the EditContext + assert_equals(editContext.text, "Hello world"); + assert_equals(editContext.selectionStart, 11); + assert_equals(editContext.selectionEnd, 11); + }, 'Testing EditContext Dictionary Init'); + + test(function() { + contenteditableDiv.editContext = new EditContext(); + contenteditableDiv.editContext = null; + contenteditableDiv.focus(); + assert_equals(document.activeElement, contenteditableDiv); + }, 'A contenteditable element should remain editable after attaching and detaching EditContext.'); + + test(function() { + const editContext = new EditContext(); + assert_not_equals(editContext, null); + + const disconnected_div = document.createElement("DIV"); + assert_equals(disconnected_div.editContext, null); + + disconnected_div.editContext = editContext; + assert_equals(disconnected_div.editContext, editContext); + assert_equals(editContext.attachedElements().length, 1); + assert_equals(editContext.attachedElements()[0], disconnected_div); + }, 'EditContext can be associated with an element that is not in the tree.'); + + test(function() { + const editContext = new EditContext(); + assert_not_equals(editContext, null); + + const div = document.createElement("DIV"); + assert_equals(div.editContext, null); + + document.body.appendChild(div); + div.editContext = editContext; + assert_equals(div.editContext, editContext); + assert_equals(editContext.attachedElements().length, 1); + assert_equals(editContext.attachedElements()[0], div); + + document.body.removeChild(div); + assert_equals(div.editContext, editContext); + assert_equals(editContext.attachedElements().length, 1); + assert_equals(editContext.attachedElements()[0], div); + }, 'If an element is removed from the tree, the associated EditContext remains connected to the element.'); + + test(function() { + const editContext = new EditContext(); + + const div_parent = document.createElement("DIV"); + const div_child = document.createElement("DIV"); + document.body.appendChild(div_parent); + div_parent.appendChild(div_child); + + div_child.editContext = editContext; + assert_equals(div_child.editContext, editContext); + assert_equals(div_parent.editContext, null); + assert_equals(editContext.attachedElements().length, 1); + assert_equals(editContext.attachedElements()[0], div_child); + + document.body.removeChild(div_parent); + assert_equals(div_child.editContext, editContext); + assert_equals(editContext.attachedElements().length, 1); + assert_equals(editContext.attachedElements()[0], div_child); + }, 'If an element\'s ancestor is removed from tree, the associated EditContext remains connected to the element.'); + + test(function() { + const editContext = new EditContext(); + const test = document.getElementById("test"); + + test.editContext = editContext; + + assert_equals(test.editContext, editContext); + assert_equals(editContext.attachedElements().length, 1); + assert_equals(editContext.attachedElements()[0], test); + + test.editContext = null; + + assert_equals(editContext.attachedElements().length, 0); + }, '.attachedElements() should return associated element'); + + test(function() { + const editContext = new EditContext(); + assert_not_equals(editContext, null); + editContext.updateText(0, 3, "foo"); + assert_equals(editContext.text, "foo"); + const test = document.getElementById('test'); + // Update the layout of the |EditContext| + var viewRect = test.getBoundingClientRect(); + viewRect.x = viewRect.left; + viewRect.y = viewRect.top; + var caretRect = test.getBoundingClientRect(); + caretRect.x = caretRect.left; + caretRect.y = 2.2 * caretRect.top; + caretRect.width = 1; + editContext.updateSelection(0, 0); + assert_equals(editContext.selectionStart, 0); + assert_equals(editContext.selectionEnd, 0); + editContext.updateSelection(1, 0); + assert_equals(editContext.selectionStart, 1); + assert_equals(editContext.selectionEnd, 0); + editContext.updateSelection(0, 1); + assert_equals(editContext.selectionStart, 0); + assert_equals(editContext.selectionEnd, 1); + editContext.updateSelection(1, 1); + assert_equals(editContext.selectionStart, 1); + assert_equals(editContext.selectionEnd, 1); + editContext.updateControlBounds(viewRect); + editContext.updateSelectionBounds(caretRect); + editContext.updateCharacterBounds(0, [caretRect]); + + assert_throws_js(TypeError, function() { editContext.updateControlBounds(42); }); + assert_throws_js(TypeError, function() { editContext.updateSelectionBounds(42); }); + assert_throws_js(TypeError, function() { editContext.updateControlBounds(undefined); }); + assert_throws_js(TypeError, function() { editContext.updateSelectionBounds(undefined); }); + assert_throws_js(TypeError, function() { editContext.updateCharacterBounds(0); }); + assert_throws_js(TypeError, function() { editContext.updateCharacterBounds([caretRect]); }); + assert_throws_js(TypeError, function() { editContext.updateCharacterBounds(0, caretRect); }); + assert_throws_js(TypeError, function() { editContext.updateCharacterBounds(0, 42); }); + assert_throws_js(TypeError, function() { editContext.updateCharacterBounds(0, undefined); }); + assert_throws_js(TypeError, function() { editContext.updateCharacterBounds(0, [undefined]); }); + + viewRect.x = viewRect.y = viewRect.width = viewRect.height = undefined; + editContext.updateControlBounds(viewRect); + editContext.updateSelectionBounds(viewRect); + editContext.updateCharacterBounds(0, [viewRect]); + }, 'Testing EditContext update text, selection and layout'); + + test(function() { + const editContext = new EditContext(); + const test = document.getElementById('test'); + var rect1 = DOMRect.fromRect({x:0, y:1, width:100, height:200}); + var rect2 = DOMRect.fromRect({x:2, y:3, width:300, height:400}); + var rectArray = [rect1, rect2]; + var rangeStart = 2; + editContext.updateCharacterBounds(rangeStart, rectArray); + assert_equals(editContext.characterBoundsRangeStart, 2); + + var actualRectArray = editContext.characterBounds(); + assert_equals(actualRectArray.length, 2); + assert_equals(actualRectArray[0].x, 0); + assert_equals(actualRectArray[0].y, 1); + assert_equals(actualRectArray[0].width, 100); + assert_equals(actualRectArray[0].height, 200); + rect2.x=100; + assert_equals(actualRectArray[1].x, 2); // the cached value shouldn't change. + assert_equals(actualRectArray[1].y, 3); + assert_equals(actualRectArray[1].width, 300); + assert_equals(actualRectArray[1].height, 400); + }, 'updateCharacterBounds(), characterBounds(), and characterBoundsRangeStart should work properly'); + + // The behavior in this test case is not well-defined in the spec. + // See https://github.com/w3c/edit-context/issues/88 + // test(function() { + // const editContext = new EditContext(); + // assert_not_equals(editContext, null); + // editContext.updateText(0, 3, "foo"); + // assert_equals(editContext.text, "foo"); + // assert_throws_dom("IndexSizeError", function() { editContext.updateSelection(10, 0); }); + // assert_equals(editContext.selectionStart, 0); + // assert_equals(editContext.selectionEnd, 0); + // assert_throws_dom("IndexSizeError", function() { editContext.updateText(10, 1, "h"); }); + // assert_equals(editContext.text, "foo"); + // }, 'Testing EditContext update text and selection with invalid values'); + + test(function() { + const editContext = new EditContext(); + assert_not_equals(editContext, null); + editContext.updateText(0, 3, "foo"); + assert_equals(editContext.text, "foo"); + editContext.updateSelection(3, 0); + assert_equals(editContext.selectionStart, 3); + assert_equals(editContext.selectionEnd, 0); + }, 'EditContext should allow a backwards selection'); + </script> +</body> +</html> diff --git a/testing/web-platform/tests/editing/edit-context/edit-context-execCommand.tentative.https.html b/testing/web-platform/tests/editing/edit-context/edit-context-execCommand.tentative.https.html new file mode 100644 index 0000000000..daa9df3cce --- /dev/null +++ b/testing/web-platform/tests/editing/edit-context/edit-context-execCommand.tentative.https.html @@ -0,0 +1,111 @@ +<!DOCTYPE html> +<html> +<head> +<title>EditContext: document.execCommand</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="../../clipboard-apis/resources/user-activation.js"></script> +</head> +<body> + <script> + promise_test(async function() { + const editContext = new EditContext(); + const test = document.createElement("div"); + document.body.appendChild(test); + let firedTextUpdate = false; + editContext.addEventListener("textupdate", e => { + firedTextUpdate = true; + }); + test.editContext = editContext; + test.focus(); + + assert_true(document.queryCommandSupported("inserttext"), "'inserttext' should be supported regardless of focus position"); + assert_false(document.queryCommandEnabled("inserttext"), "'inserttext' should not be supported in EditContext"); + + document.execCommand("inserttext", false, "a"); + assert_equals(test.innerHTML, "", "DOM should not be updated from execCommand('inserttext')"); + assert_false(firedTextUpdate, "textupdate should not fire for to execCommand('inserttext')"); + test.remove(); + }, 'document.execCommand("inserttext") should not change the DOM or fire textupdate'); + + promise_test(async function() { + const editContext = new EditContext(); + const test = document.createElement("div"); + test.innerHTML = "abc"; + document.body.appendChild(test); + let firedTextUpdate = false; + editContext.addEventListener("textupdate", e => { + firedTextUpdate = true; + }); + test.editContext = editContext; + test.focus(); + + assert_true(document.queryCommandSupported("bold"), "'bold' should be supported regardless of focus position"); + assert_false(document.queryCommandEnabled("bold"), "'bold' should not be supported in EditContext"); + + document.execCommand("bold"); + assert_equals(test.innerHTML, "abc", "DOM should not be updated from execCommand('bold')"); + assert_false(firedTextUpdate, "textupdate should not fire for execCommand('bold')"); + test.remove(); + }, 'document.execCommand("bold") should not change the DOM or fire textupdate'); + + promise_test(async function() { + const editContext = new EditContext(); + const test = document.createElement("div"); + test.innerHTML = "<b>ab</b>c"; + document.body.appendChild(test); + let firedTextUpdate = false; + editContext.addEventListener("textupdate", e => { + firedTextUpdate = true; + }); + test.editContext = editContext; + const selection = window.getSelection(); + selection.setBaseAndExtent(test.firstChild.firstChild, 0, test.firstChild.firstChild, 1); + + assert_false(document.queryCommandState("bold"), "queryCommandState should always return false in EditContext"); + assert_equals(document.queryCommandValue("bold"), "false", "queryCommandValue should always return 'false' in EditContext for commands that return booleans"); + assert_equals(document.queryCommandValue("forecolor"), "", "queryCommandValue should always return empty string in EditContext for commands that return strings"); + + selection.setBaseAndExtent(test.firstChild.firstChild, 1, test.lastChild, 1); + assert_false(document.queryCommandIndeterm("bold"), "'queryCommandInterm should always return false in EditContext"); + + test.remove(); + }, 'queryCommandState, queryCommandvalue, and queryCommandInterm should always return false'); + + promise_test(async function() { + const editContext = new EditContext(); + const test = document.createElement("div"); + test.innerHTML = "abc"; + document.body.appendChild(test); + let firedTextUpdate = false; + editContext.addEventListener("textupdate", e => { + firedTextUpdate = true; + }); + test.editContext = editContext; + test.focus(); + + const selection = window.getSelection(); + selection.setBaseAndExtent(test.firstChild, 0, test.firstChild, 1); + + await test_driver.set_permission({name: 'clipboard-read'}, 'granted'); + assert_true(document.execCommand("copy"), "'copy' always returns true regardless of whether it did anything"); + await waitForUserActivation(); + let clipboardText = await navigator.clipboard.readText(); + assert_equals(clipboardText, "a", "'copy' should work in EditContext"); + + selection.setBaseAndExtent(test.firstChild, 1, test.firstChild, 2); + + assert_true(document.execCommand("cut"), "'cut' always returns true regardless of whether it did anything"); + assert_equals(test.innerHTML, "abc", "DOM should not be updated from execCommand('cut')"); + await waitForUserActivation(); + clipboardText = await navigator.clipboard.readText(); + assert_equals(clipboardText, "a", "Failed 'cut' should not change clipboard"); + + test.remove(); + }, 'document.execCommand("copy") should work but document.execCommand("cut") should not change the DOM or the clipboard'); + </script> +</body> +</html> diff --git a/testing/web-platform/tests/editing/edit-context/edit-context-inheritability.tentative.html b/testing/web-platform/tests/editing/edit-context/edit-context-inheritability.tentative.html new file mode 100644 index 0000000000..59c553d966 --- /dev/null +++ b/testing/web-platform/tests/editing/edit-context/edit-context-inheritability.tentative.html @@ -0,0 +1,182 @@ +<!DOCTYPE html> +<html> +<head> +<title>EditContext: Inherited Editability</title> +<meta name="author" title="Dan Clark" href="mailto:daniec@microsoft.com"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +</head> +<body> + <div id="edit-context-top-0">Text in EditContext-associated element, should be editable</div> + + <div id="edit-context-top-1"> + <div id="default-1"> + Element child of EditContext, should be editable + </div> + </div> + + <div id="edit-context-top-2"> + <div id="noteditable-2" contenteditable="false"> + <div id="editable-in-noteditable-2" contenteditable=""> + This is a contenteditable="" child of contenteditable="false" parent. + This node should be editable. It should be the target of beforeinput/input events when the user edits here. + The grandparent node #edit-context-0 should not be the target of beforeinput/input events, + and the EditContext should not receive + textupdate events + </div> + </div> + </div> + + <div id="edit-context-top-3"> + <div id="noteditable-3" contenteditable="false"> + <div id="editable-in-noteditable-3" contenteditable=""> + <div id="contenteditable-in-contenteditable-3" contenteditable=""> + This is an contenteditable="" child of a contenteditable="". Since this is the child of an + editable element, when the user types here, it's the parent contenteditable="" that gets + input/beforeinput events, and this doesn't. Basically the child contenteditable="" attribute + is a no-op. + </div> + </div> + </div> + </div> + + <div id="edit-context-top-4"> + <div id="noteditable-4" contenteditable="false"> + <div id="edit-context-in-noteditable-4"> + This is an EditContext child of contenteditable="false" parent. + This node should be editable, and this EditContext (but not the + grandparent EditContext) should get events, since there is an + intermediate non-editable parent. + </div> + </div> + </div> + + <div id="edit-context-top-5"> + <div id="contenteditable-in-ec-5" contenteditable=""> + This is a contenteditable="" child of EditContext. + It inherits editability from the parent and it should not be the target of beforeinput/input events. + Setting contenteditable="" on this node is basically a no-op. + </div> + </div> + + <div id="edit-context-top-6"> + <input id="input-in-ec-6" value="Input in EditContext. Events are fired against this element, and not against any parent EditContext."> + </div> + + <div id="edit-context-top-7"> + <div id="edit-context-in-ec-7"> + EditContext child of EditContext. When user types here, + events are fired only against the parent EditContext, not this one. + Since the parent element was editable, the EditContext association is basically a no-op. + </div> + </div> + +<script> + const event_log = []; + + const editContextElements = document.querySelectorAll("div[id^='edit-context-']"); + editContextElements.forEach((element) => { + element.editContext = new EditContext(); + }); + + const divs = Array.from(document.querySelectorAll("div")); + const inputs = Array.from(document.querySelectorAll("input")); + const eventTargets = divs.concat(inputs); + eventTargets.forEach((element) => { + element.addEventListener("beforeinput", (e) => { + if (element == e.target) { + event_log.push(`beforeinput: ${element.id}`); + } + }); + + element.addEventListener("input", (e) => { + if (element === e.target) { + event_log.push(`input: ${element.id}`); + } + }); + + if (element.editContext) { + element.editContext.addEventListener("textupdate", () => { + event_log.push(`textupdate: ${element.id}`); + }); + } + }); + + promise_test(async () => { + event_log.length = 0; + + const input_target = document.querySelector("#edit-context-top-0"); + await test_driver.click(input_target); + await test_driver.send_keys(input_target, "a"); + assert_array_equals(event_log, ["beforeinput: edit-context-top-0", "textupdate: edit-context-top-0"]); + }, 'Check that element with EditContext is editable and gets events'); + + promise_test(async () => { + event_log.length = 0; + + const input_target = document.querySelector("#default-1"); + await test_driver.click(input_target); + await test_driver.send_keys(input_target, "a"); + assert_array_equals(event_log, ["beforeinput: edit-context-top-1", "textupdate: edit-context-top-1"]); + }, 'Check that child of EditContext is editable and the parent EditContext gets the events'); + + promise_test(async () => { + event_log.length = 0; + + const input_target = document.querySelector("#editable-in-noteditable-2"); + await test_driver.click(input_target); + await test_driver.send_keys(input_target, "a"); + assert_array_equals(event_log, ["beforeinput: editable-in-noteditable-2", "input: editable-in-noteditable-2"]); + }, 'Check that a contenteditable child of a contenteditable="false" is editable'); + + promise_test(async () => { + event_log.length = 0; + + const input_target = document.querySelector("#contenteditable-in-contenteditable-3"); + await test_driver.click(input_target); + await test_driver.send_keys(input_target, "a"); + assert_array_equals(event_log, ["beforeinput: editable-in-noteditable-3", "input: editable-in-noteditable-3"]); + }, 'Check that a contenteditable child of a contenteditable is editable, but the parent contenteditable gets the events'); + + promise_test(async () => { + event_log.length = 0; + + const input_target = document.querySelector("#edit-context-in-noteditable-4"); + await test_driver.click(input_target); + await test_driver.send_keys(input_target, "a"); + assert_array_equals(event_log, ["beforeinput: edit-context-in-noteditable-4", "textupdate: edit-context-in-noteditable-4"]); + }, 'Check that an EditContext child of a contenteditable="false" parent is editable and gets events'); + + promise_test(async () => { + event_log.length = 0; + + const input_target = document.querySelector("#contenteditable-in-ec-5"); + await test_driver.click(input_target); + await test_driver.send_keys(input_target, "a"); + assert_array_equals(event_log, ["beforeinput: edit-context-top-5", "textupdate: edit-context-top-5"]); + }, 'Check that an contenteditable child of an EditContext is editable, but the EditContext gets the events'); + + promise_test(async () => { + event_log.length = 0; + + const input_target = document.querySelector("#input-in-ec-6"); + await test_driver.click(input_target); + await test_driver.send_keys(input_target, "a"); + assert_array_equals(event_log, ["beforeinput: input-in-ec-6", "input: input-in-ec-6"]); + }, 'Check that an input element in an EditContext is the event target for beforeinput/input'); + + promise_test(async () => { + event_log.length = 0; + + const input_target = document.querySelector("#edit-context-in-ec-7"); + await test_driver.click(input_target); + await test_driver.send_keys(input_target, "a"); + assert_array_equals(event_log, ["beforeinput: edit-context-top-7", "textupdate: edit-context-top-7"]); + }, 'Check that for an EditContext child of an EditContext, the parent is the one that gets the events'); + +</script> +</body> +</html> diff --git a/testing/web-platform/tests/editing/edit-context/edit-context-input.tentative.html b/testing/web-platform/tests/editing/edit-context/edit-context-input.tentative.html new file mode 100644 index 0000000000..762ec59547 --- /dev/null +++ b/testing/web-platform/tests/editing/edit-context/edit-context-input.tentative.html @@ -0,0 +1,249 @@ +<!DOCTYPE html> +<html> +<head> +<title>EditContext: The HTMLElement.editContext property</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +</head> +<body> + <script> + const kBackspaceKey = "\uE003"; + const kDeleteKey = "\uE017"; + + async function testBasicTestInput(element) { + const editContext = new EditContext(); + let textForView = ""; + document.body.appendChild(element); + let beforeInputType = null; + let beforeInputTargetRanges = null; + element.addEventListener("beforeinput", e => { + beforeInputType = e.inputType; + beforeInputTargetRanges = e.getTargetRanges().map( + staticRange => [staticRange.startOffset, staticRange.endOffset]); + }); + editContext.addEventListener("textupdate", e => { + textForView = `${textForView.substring(0, e.updateRangeStart)}${e.text}${textForView.substring(e.updateRangeEnd)}`; + }); + element.editContext = editContext; + element.focus(); + await test_driver.send_keys(element, 'a'); + assert_equals(editContext.text, "a"); + assert_equals(textForView, "a"); + assert_equals(beforeInputType, "insertText"); + if (element instanceof HTMLCanvasElement) { + // DOM selection doesn't work inside <canvas>, so events + // in <canvas> can't have target ranges. + assert_equals(beforeInputTargetRanges.length, 0); + } else { + assert_equals(beforeInputTargetRanges.length, 1); + assert_array_equals(beforeInputTargetRanges[0], [0, 0]); + } + + element.remove(); + } + + promise_test(testBasicTestInput.bind(null, document.createElement("div")), "Basic text input with div"); + promise_test(testBasicTestInput.bind(null, document.createElement("canvas")), "Basic text input with canvas"); + + async function testBasicTestInputWithExistingSelection(element) { + const editContext = new EditContext(); + let textForView = ""; + document.body.appendChild(element); + editContext.addEventListener("textupdate", e => { + textForView = `${textForView.substring(0, e.updateRangeStart)}${e.text}${textForView.substring(e.updateRangeEnd)}`; + }); + element.editContext = editContext; + element.focus(); + + editContext.updateText(0, 0, "abcd"); + textForView = "abcd"; + assert_equals(editContext.text, "abcd"); + editContext.updateSelection(2, 3); + await test_driver.send_keys(element, 'Z'); + assert_equals(editContext.text, "abZd"); + assert_equals(textForView, "abZd"); + + editContext.updateSelection(2, 1); + await test_driver.send_keys(element, 'Y'); + assert_equals(editContext.text, "aYZd"); + assert_equals(textForView, "aYZd"); + + element.remove(); + } + + promise_test(testBasicTestInputWithExistingSelection.bind(null, document.createElement("div")), "Text insertion with non-collapsed selection with div"); + promise_test(testBasicTestInputWithExistingSelection.bind(null, document.createElement("canvas")), "Text insertion with non-collapsed selection with canvas"); + + promise_test(async function() { + const editContext = new EditContext(); + assert_not_equals(editContext, null); + const test = document.createElement("div"); + document.body.appendChild(test); + test.editContext = editContext; + test.focus(); + await test_driver.send_keys(test, 'a'); + assert_equals(test.innerHTML, ""); + test.remove(); + }, 'EditContext should disable DOM mutation'); + + promise_test(async function() { + const editContext = new EditContext(); + assert_not_equals(editContext, null); + const test = document.createElement("div"); + document.body.appendChild(test); + test.focus(); + test.editContext = editContext; + test.addEventListener("beforeinput", e => { + if (e.inputType === "insertText") { + e.preventDefault(); + } + }); + await test_driver.send_keys(test, 'a'); + assert_equals(editContext.text, ""); + test.remove(); + }, 'beforeInput(insertText) should be cancelable'); + + promise_test(async () => { + let div = document.createElement("div"); + document.body.appendChild(div); + let divText = "Hello World"; + div.innerText = divText; + div.editContext = new EditContext(); + div.focus(); + let got_before_input_event = false; + div.addEventListener("beforeinput", e => { + got_before_input_event = true; + }); + let got_textupdate_event = false; + div.editContext.addEventListener("textupdate", e => { + got_textupdate_event = true; + }); + + div.editContext = null; + await test_driver.send_keys(div, "a"); + + assert_false(got_textupdate_event, "Shouldn't have received textupdate event after editContext was detached"); + assert_false(got_before_input_event, "Shouldn't have received beforeinput event after editContext was detached"); + + div.remove(); + }, "EditContext should not receive events after being detached from element"); + + async function testBackspaceAndDelete(element) { + const editContext = new EditContext(); + let textForView = "hello there"; + document.body.appendChild(element); + let beforeInputType = null; + let beforeInputTargetRanges = null; + element.addEventListener("beforeinput", e => { + beforeInputType = e.inputType; + beforeInputTargetRanges = e.getTargetRanges().map( + staticRange => [staticRange.startOffset, staticRange.endOffset]); + }); + let textUpdateSelection = null; + editContext.addEventListener("textupdate", e => { + textUpdateSelection = [e.selectionStart, e.selectionEnd]; + textForView = `${textForView.substring(0, e.updateRangeStart)}${e.text}${textForView.substring(e.updateRangeEnd)}`; + }); + element.editContext = editContext; + editContext.updateText(0, 11, "hello there"); + editContext.updateSelection(10, 10); + const selection = window.getSelection(); + + await test_driver.send_keys(element, kBackspaceKey); + assert_equals(textForView, "hello thee"); + assert_array_equals(textUpdateSelection, [9, 9]); + assert_equals(beforeInputType, "deleteContentBackward"); + assert_equals(beforeInputTargetRanges.length, 0, "Backspace should not have a target range in EditContext"); + + await test_driver.send_keys(element, kDeleteKey); + assert_equals(textForView, "hello the"); + assert_array_equals(textUpdateSelection, [9, 9]); + assert_equals(beforeInputType, "deleteContentForward"); + assert_equals(beforeInputTargetRanges.length, 0, "Delete should not have a target range in EditContext"); + element.remove(); + } + + promise_test(testBackspaceAndDelete.bind(null, document.createElement("div")), "Backspace and delete in EditContext with div"); + promise_test(testBackspaceAndDelete.bind(null, document.createElement("canvas")) , "Backspace and delete in EditContext with canvas"); + + async function testBackspaceAndDeleteWithExistingSelection(element) { + const editContext = new EditContext(); + let textForView = "hello there"; + document.body.appendChild(element); + let beforeInputType = null; + let beforeInputTargetRanges = null; + element.addEventListener("beforeinput", e => { + beforeInputType = e.inputType; + beforeInputTargetRanges = e.getTargetRanges().map( + staticRange => [staticRange.startOffset, staticRange.endOffset]); + }); + let textUpdateSelection = null; + editContext.addEventListener("textupdate", e => { + textUpdateSelection = [e.selectionStart, e.selectionEnd]; + textForView = `${textForView.substring(0, e.updateRangeStart)}${e.text}${textForView.substring(e.updateRangeEnd)}`; + }); + element.editContext = editContext; + const initialText = "abcdefghijklmnopqrstuvwxyz"; + editContext.updateText(0, initialText.length, initialText); + textForView = initialText; + element.focus(); + + editContext.updateSelection(3, 6); + await test_driver.send_keys(element, kBackspaceKey); + assert_equals(editContext.text, "abcghijklmnopqrstuvwxyz"); + assert_equals(textForView, "abcghijklmnopqrstuvwxyz"); + assert_array_equals(textUpdateSelection, [3, 3]); + assert_equals(beforeInputType, "deleteContentBackward"); + assert_equals(beforeInputTargetRanges.length, 0, "Backspace should not have a target range in EditContext"); + + editContext.updateSelection(3, 6); + await test_driver.send_keys(element, kDeleteKey); + assert_equals(editContext.text, "abcjklmnopqrstuvwxyz"); + assert_equals(textForView, "abcjklmnopqrstuvwxyz"); + assert_array_equals(textUpdateSelection, [3, 3]); + assert_equals(beforeInputType, "deleteContentForward"); + assert_equals(beforeInputTargetRanges.length, 0, "Delete should not have a target range in EditContext"); + + editContext.updateSelection(6, 3); + await test_driver.send_keys(element, kBackspaceKey); + assert_equals(editContext.text, "abcmnopqrstuvwxyz"); + assert_equals(textForView, "abcmnopqrstuvwxyz"); + assert_array_equals(textUpdateSelection, [3, 3]); + assert_equals(beforeInputType, "deleteContentBackward"); + assert_equals(beforeInputTargetRanges.length, 0, "Backspace should not have a target range in EditContext"); + + editContext.updateSelection(6, 3); + await test_driver.send_keys(element, kDeleteKey); + assert_equals(editContext.text, "abcpqrstuvwxyz"); + assert_equals(textForView, "abcpqrstuvwxyz"); + assert_array_equals(textUpdateSelection, [3, 3]); + assert_equals(beforeInputType, "deleteContentForward"); + assert_equals(beforeInputTargetRanges.length, 0, "Delete should not have a target range in EditContext"); + + element.remove(); + } + + promise_test(testBackspaceAndDeleteWithExistingSelection.bind(null, document.createElement("div")), "Backspace and delete with existing selection with div"); + promise_test(testBackspaceAndDeleteWithExistingSelection.bind(null, document.createElement("canvas")) , "Backspace and delete with existing selection with canvas"); + + promise_test(async function() { + const iframe = document.createElement("iframe"); + document.body.appendChild(iframe); + const editContext = new EditContext(); + iframe.contentDocument.body.editContext = editContext; + iframe.contentDocument.body.focus(); + let got_textupdate_event = false; + editContext.addEventListener("textupdate", e => { + got_textupdate_event = true; + }); + await test_driver.send_keys(iframe.contentDocument.body, "a"); + assert_equals(iframe.contentDocument.body.innerHTML, "", "EditContext should disable DOM modification in iframe."); + assert_true(got_textupdate_event, "Input in iframe EditContext should trigger textupdate event"); + iframe.remove(); + }, 'EditContext constructed outside iframe can be used in iframe'); + </script> +</body> +</html> diff --git a/testing/web-platform/tests/editing/edit-context/edit-context-property.tentative.html b/testing/web-platform/tests/editing/edit-context/edit-context-property.tentative.html new file mode 100644 index 0000000000..c63d5f8cf6 --- /dev/null +++ b/testing/web-platform/tests/editing/edit-context/edit-context-property.tentative.html @@ -0,0 +1,90 @@ +<!DOCTYPE html> +<html> +<head> +<title>EditContext: The HTMLElement.editContext property</title> +<meta name="author" title="Dan Clark" href="mailto:daniec@microsoft.com"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src='../../html/resources/common.js'></script> +</head> +<body> +<script> + +test(function () { + assert_true('editContext' in HTMLElement.prototype, 'Element.prototype.editContext must exist'); + assert_equals(typeof(document.createElement('div').editContext), 'object', 'An instance of div must have editContext which is an object'); +}, 'Check the existence of HTMLElement.editContext'); + +test(function () { + assert_false('editContext' in Node.prototype, 'Node.prototype.editContext must not exist'); + assert_false('editContext' in Element.prototype, 'Element.prototype.editContext must not exist'); + assert_false('editContext' in CharacterData.prototype, 'CharacterData.prototype.editContext must not exist'); + assert_false('editContext' in Comment.prototype, 'Comment.prototype.editContext must not exist'); + assert_equals(typeof(document.createComment('').editContext), 'undefined', 'An instance of comment must not have editContext'); + assert_false('editContext' in Document.prototype, 'Document.prototype.editContext must not exist'); + assert_equals(typeof(document.editContext), 'undefined', 'An instance of document must not have editContext which is a function'); + assert_false('editContext' in DocumentFragment.prototype, 'DocumentFragment.prototype.editContext must not exist'); + assert_equals(typeof((new DOMParser()).parseFromString('', 'text/html').editContext), 'undefined', 'An instance of document must not have editContext which is a function'); + assert_false('editContext' in Text.prototype, 'Text.prototype.editContext must not exist'); + assert_equals(typeof(document.createTextNode('').editContext), 'undefined', 'An instance of text node must not have editContext'); +}, 'Nodes other than Element should not have editContext'); + +test(function () { + assert_throws_js(TypeError, function () { + document.createElement('div').editContext = "hello"; + }, 'editContext must throw a TypeError when set to a string'); + + assert_throws_js(TypeError, function () { + document.createElement('div').editContext = 42; + }, 'editContext must throw a TypeError when set to a number'); + + assert_throws_js(TypeError, function () { + document.createElement('div').editContext = document.createElement('span'); + }, 'editContext must throw a TypeError when set to a node'); +}, 'HTMLElement.editContext must throw a TypeError if set to something other than an EditContext'); + +test(function () { + const EDIT_CONTEXT_ALLOWED_ELEMENTS = HTML5_SHADOW_ALLOWED_ELEMENTS.concat(['canvas']); + for (const elementName of EDIT_CONTEXT_ALLOWED_ELEMENTS) { + const element = document.createElement(elementName); + const ec = new EditContext(); + element.editContext = ec; + assert_equals(element.editContext, ec, 'Getting HTMLElement.editContext should yield the same EditContext instance'); + } +}, 'HTMLElement.editContext can be set on the shadow root elements plus canvas.'); + +test(function () { + // EditContext shares all of the shadow root disallowed elements except for canvas. + const EDIT_CONTEXT_DISALLOWED_ELEMENTS = HTML5_SHADOW_DISALLOWED_ELEMENTS.toSpliced(HTML5_SHADOW_DISALLOWED_ELEMENTS.indexOf('canvas'), 1); + for (const elementName of EDIT_CONTEXT_DISALLOWED_ELEMENTS) { + const element = document.createElement(elementName); + const ec = new EditContext(); + assert_throws_dom('NotSupportedError', () => { + element.editContext = ec; + }, `Setting editContext on <${elementName}> must throw.`); + assert_equals(element.editContext, null); + } +}, 'Setting HTMLElement.editContext must throw a NotSupportedError for disallowed elements'); + +test(function () { + const element1 = document.createElement('div'); + const element2 = document.createElement('div'); + const editContext1 = new EditContext(); + const editContext2 = new EditContext(); + element1.editContext = editContext1; + assert_throws_dom('NotSupportedError', () => { + element2.editContext = editContext1; + }, `TypeError should be thrown when author attempts to associate an EditContext with a second element`); + assert_equals(element1.editContext, editContext1, "element1 association should not have changed"); + assert_equals(element2.editContext, null, "element2 association should not have changed"); + + element1.editContext = editContext2; + assert_equals(element1.editContext, editContext2, "Association can be switched directly to second EditConext"); + + element1.editContext = editContext2; + assert_equals(element1.editContext, editContext2, "Assigning to the same EditContext again is a no-op"); +}, 'An EditContext can only be associated with one element at a time'); + +</script> +</body> +</html> diff --git a/testing/web-platform/tests/editing/event.html b/testing/web-platform/tests/editing/event.html new file mode 100644 index 0000000000..16d640be21 --- /dev/null +++ b/testing/web-platform/tests/editing/event.html @@ -0,0 +1,224 @@ +<!doctype html> +<title>Editing event tests</title> +<style>body { font-family: serif }</style> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<div id=test></div> +<div id=log></div> +<script> +"use strict"; + +var div = document.querySelector("#test"); +add_completion_callback(function() { div.parentNode.removeChild(div) }); + +function copyEvent(e) { + var ret = {}; + ret.original = e; + ["type", "target", "currentTarget", "eventPhase", "bubbles", "cancelable", + "defaultPrevented", "isTrusted", "command", "value"].forEach(function(k) { + ret[k] = e[k]; + }); + return ret; +} + +var tests = [ + { + name: "Simple editable div", + html: "<div contenteditable>foo<b>bar</b>baz</div>", + initRange: function(range) { + range.setStart(div.querySelector("b").firstChild, 0); + range.setEnd(div.querySelector("b"), 1); + }, + target: function() { return div.firstChild }, + command: "bold", + value: "", + }, + { + name: "Editable b", + html: "foo<b contenteditable>bar</b>baz", + initRange: function(range) { + range.setStart(div.querySelector("b").firstChild, 0); + range.setEnd(div.querySelector("b"), 1); + }, + target: function() { return div.querySelector("b") }, + command: "bold", + value: "", + }, + { + name: "No editable content", + html: "foo<b>bar</b>baz", + initRange: function(range) { + range.setStart(div.querySelector("b").firstChild, 0); + range.setEnd(div.querySelector("b"), 1); + }, + target: function() { return null }, + command: "bold", + value: "", + }, + { + name: "Partially-selected editable content", + html: "foo<b contenteditable>bar</b>baz", + initRange: function(range) { + range.setStart(div.querySelector("b").firstChild, 0); + range.setEnd(div, 3); + }, + target: function() { return null }, + command: "bold", + value: "", + }, + { + name: "Selection spans two editing hosts", + html: "<div contenteditable>foo</div><div contenteditable>bar</div>", + initRange: function(range) { + range.setStart(div.querySelector("div").firstChild, 2); + range.setEnd(div.querySelector("div + div").firstChild, 1); + }, + target: function() { return null }, + command: "bold", + value: "", + }, + { + name: "Selection includes two editing hosts", + html: "foo<div contenteditable>bar</div>baz<div contenteditable>quz</div>qoz", + initRange: function(range) { + range.setStart(div.firstChild, 2); + range.setEnd(div.lastChild, 1); + }, + target: function() { return null }, + command: "bold", + value: "", + }, + { + name: "Changing selection from handler", + html: "<div contenteditable>foo</div><div contenteditable>bar</div>", + initRange: function(range) { + range.setStart(div.querySelector("div").firstChild, 0); + range.setEnd(div.querySelector("div").firstChild, 3); + }, + target: function() { return div.firstChild }, + finalTarget: function() { return div.lastChild }, + command: "bold", + value: "", + }, +]; + +var commandTests = { + backColor: ["green"], + createLink: ["http://www.w3.org/community/editing/"], + fontName: ["serif", "Helvetica"], + fontSize: ["6", "15px"], + foreColor: ["green"], + hiliteColor: ["green"], + italic: [], + removeFormat: [], + strikeThrough: [], + subscript: [], + superscript: [], + underline: [], + unlink: [], + delete: [], + formatBlock: ["p"], + forwardDelete: [], + indent: [], + insertHorizontalRule: ["id"], + insertHTML: ["<b>hi</b>"], + insertImage: ["../images/green.png"], + insertLineBreak: [], + insertOrderedList: [], + insertParagraph: [], + insertText: ["abc"], + insertUnorderedList: [], + justifyCenter: [], + justifyFull: [], + justifyLeft: [], + justifyRight: [], + outdent: [], + redo: [], + selectAll: [], + styleWithCSS: [], + undo: [], + useCSS: [], +}; + +Object.keys(commandTests).forEach(function(command) { + commandTests[command] = ["", "quasit"].concat(commandTests[command]); + commandTests[command].forEach(function(value) { + tests.push({ + name: "Command " + command + ", value " + format_value(value), + html: "<div contenteditable>foo<b>bar</b>baz</div>", + initRange: function(range) { + range.setStart(div.querySelector("b").firstChild, 0); + range.setEnd(div.querySelector("b"), 1); + }, + target: function() { + return ["redo", "selectAll", "styleWithCSS", "undo", "useCSS"] + .indexOf(command) == -1 ? div.firstChild : null; + }, + command: command, + value: value, + }); + }); +}); + +tests.forEach(function(obj) { + // Kill all event handlers first + var newDiv = div.cloneNode(false); + div.parentNode.insertBefore(newDiv, div); + div.parentNode.removeChild(div); + div = newDiv; + + div.innerHTML = obj.html; + + var originalContents = div.cloneNode(true); + + getSelection().removeAllRanges(); + var range = document.createRange(); + obj.initRange(range); + getSelection().addRange(range); + + var target = obj.target(); + var finalTarget = "finalTarget" in obj ? obj.finalTarget() : target; + var command = obj.command; + var value = obj.value; + + var inputEvents = []; + div.addEventListener("input", function(e) { inputEvents.push(copyEvent(e)) }); + + var exception = null; + try { + document.execCommand(command, false, value); + } catch(e) { + exception = e; + } + + test(function() { + assert_equals(exception, null, "Unexpected exception"); + }, obj.name + ": execCommand() must not throw"); + + test(function() { + assert_equals(inputEvents.length, target ? 1 : 0, + "number of input events fired"); + if (!target) { + assert_true(originalContents.isEqualNode(div), + "div contents must not be changed"); + return; + } + var e = inputEvents[0]; + assert_equals(e.type, "input", "event.type"); + assert_equals(e.target, finalTarget, "event.target"); + assert_equals(e.currentTarget, div, "event.currentTarget"); + assert_equals(e.eventPhase, Event.BUBBLING_PHASE, "event.eventPhase"); + assert_equals(e.bubbles, true, "event.bubbles"); + assert_equals(e.cancelable, false, "event.cancelable"); + assert_equals(e.defaultPrevented, false, "event.defaultPrevented"); + assert_own_property(window, "InputEvent", + "window.InputEvent must exist"); + assert_equals(Object.getPrototypeOf(e.original), InputEvent.prototype, + "event prototype"); + assert_equals(e.isTrusted, true, "event.isTrusted"); + }, obj.name + ": input event"); +}); + +// Thanks, Gecko. +document.body.bgColor = ""; +</script> diff --git a/testing/web-platform/tests/editing/include/editor-test-utils.js b/testing/web-platform/tests/editing/include/editor-test-utils.js new file mode 100644 index 0000000000..24527d4a79 --- /dev/null +++ b/testing/web-platform/tests/editing/include/editor-test-utils.js @@ -0,0 +1,419 @@ +/** + * EditorTestUtils is a helper utilities to test HTML editor. This can be + * instantiated per an editing host. If you test `designMode`, the editing + * host should be the <body> element. + * Note that if you want to use sendKey in a sub-document, you need to include + * testdriver.js (and related files) from the sub-document before creating this. + */ +class EditorTestUtils { + kShift = "\uE008"; + kMeta = "\uE03d"; + kControl = "\uE009"; + kAlt = "\uE00A"; + + editingHost; + + constructor(aEditingHost, aHarnessWindow = window) { + this.editingHost = aEditingHost; + if (aHarnessWindow != this.window && this.window.test_driver) { + this.window.test_driver.set_test_context(aHarnessWindow); + } + } + + get document() { + return this.editingHost.ownerDocument; + } + get window() { + return this.document.defaultView; + } + get selection() { + return this.window.getSelection(); + } + + sendKey(key, modifier) { + if (!modifier) { + return this.window.test_driver.send_keys(this.editingHost, key) + .catch(() => { + return new this.window.test_driver.Actions() + .keyDown(key) + .keyUp(key) + .send(); + }); + } + return new this.window.test_driver.Actions() + .keyDown(modifier) + .keyDown(key) + .keyUp(key) + .keyUp(modifier) + .send(); + } + + sendDeleteKey(modifier) { + const kDeleteKey = "\uE017"; + return this.sendKey(kDeleteKey, modifier); + } + + sendBackspaceKey(modifier) { + const kBackspaceKey = "\uE003"; + return this.sendKey(kBackspaceKey, modifier); + } + + sendArrowLeftKey(modifier) { + const kArrowLeft = "\uE012"; + return this.sendKey(kArrowLeft, modifier); + } + + sendArrowRightKey(modifier) { + const kArrowRight = "\uE014"; + return this.sendKey(kArrowRight, modifier); + } + + sendHomeKey(modifier) { + const kHome = "\uE011"; + return this.sendKey(kHome, modifier); + } + + sendEndKey(modifier) { + const kEnd = "\uE010"; + return this.sendKey(kEnd, modifier); + } + + sendEnterKey(modifier) { + const kEnter = "\uE007"; + return this.sendKey(kEnter, modifier); + } + + sendSelectAllShortcutKey() { + return this.sendKey( + "a", + this.window.navigator.platform.includes("Mac") + ? this.kMeta + : this.kControl + ); + } + + // Similar to `setupDiv` in editing/include/tests.js, this method sets + // innerHTML value of this.editingHost, and sets multiple selection ranges + // specified with the markers. + // - `[` specifies start boundary in a text node + // - `{` specifies start boundary before a node + // - `]` specifies end boundary in a text node + // - `}` specifies end boundary after a node + // + // options can have following fields: + // - selection: how to set selection, "addRange" (default), + // "setBaseAndExtent", "setBaseAndExtent-reverse". + setupEditingHost(innerHTMLWithRangeMarkers, options = {}) { + if (!options.selection) { + options.selection = "addRange"; + } + const startBoundaries = innerHTMLWithRangeMarkers.match(/\{|\[/g) || []; + const endBoundaries = innerHTMLWithRangeMarkers.match(/\}|\]/g) || []; + if (startBoundaries.length !== endBoundaries.length) { + throw "Should match number of open/close markers"; + } + + this.editingHost.innerHTML = innerHTMLWithRangeMarkers; + this.editingHost.focus(); + + if (startBoundaries.length === 0) { + // Don't remove the range for now since some tests may assume that + // setting innerHTML does not remove all selection ranges. + return; + } + + let getNextRangeAndDeleteMarker = startNode => { + let getNextLeafNode = node => { + let inclusiveDeepestFirstChildNode = container => { + while (container.firstChild) { + container = container.firstChild; + } + return container; + }; + if (node.hasChildNodes()) { + return inclusiveDeepestFirstChildNode(node); + } + if (node === this.editingHost) { + return null; + } + if (node.nextSibling) { + return inclusiveDeepestFirstChildNode(node.nextSibling); + } + let nextSibling = (child => { + for ( + let parent = child.parentElement; + parent && parent != this.editingHost; + parent = parent.parentElement + ) { + if (parent.nextSibling) { + return parent.nextSibling; + } + } + return null; + })(node); + if (!nextSibling) { + return null; + } + return inclusiveDeepestFirstChildNode(nextSibling); + }; + let scanMarkerInTextNode = (textNode, offset) => { + return /[\{\[\]\}]/.exec(textNode.data.substr(offset)); + }; + let startMarker = ((startContainer, startOffset) => { + let scanStartMakerInTextNode = (textNode, offset) => { + let scanResult = scanMarkerInTextNode(textNode, offset); + if (scanResult === null) { + return null; + } + if (scanResult[0] === "}" || scanResult[0] === "]") { + throw "An end marker is found before a start marker"; + } + return { + marker: scanResult[0], + container: textNode, + offset: scanResult.index + offset, + }; + }; + if (startContainer.nodeType === Node.TEXT_NODE) { + let scanResult = scanStartMakerInTextNode( + startContainer, + startOffset + ); + if (scanResult !== null) { + return scanResult; + } + } + let nextNode = startContainer; + while ((nextNode = getNextLeafNode(nextNode))) { + if (nextNode.nodeType === Node.TEXT_NODE) { + let scanResult = scanStartMakerInTextNode(nextNode, 0); + if (scanResult !== null) { + return scanResult; + } + continue; + } + } + return null; + })(startNode, 0); + if (startMarker === null) { + return null; + } + let endMarker = ((startContainer, startOffset) => { + let scanEndMarkerInTextNode = (textNode, offset) => { + let scanResult = scanMarkerInTextNode(textNode, offset); + if (scanResult === null) { + return null; + } + if (scanResult[0] === "{" || scanResult[0] === "[") { + throw "A start marker is found before an end marker"; + } + return { + marker: scanResult[0], + container: textNode, + offset: scanResult.index + offset, + }; + }; + if (startContainer.nodeType === Node.TEXT_NODE) { + let scanResult = scanEndMarkerInTextNode(startContainer, startOffset); + if (scanResult !== null) { + return scanResult; + } + } + let nextNode = startContainer; + while ((nextNode = getNextLeafNode(nextNode))) { + if (nextNode.nodeType === Node.TEXT_NODE) { + let scanResult = scanEndMarkerInTextNode(nextNode, 0); + if (scanResult !== null) { + return scanResult; + } + continue; + } + } + return null; + })(startMarker.container, startMarker.offset + 1); + if (endMarker === null) { + throw "Found an open marker, but not found corresponding close marker"; + } + let indexOfContainer = (container, child) => { + let offset = 0; + for (let node = container.firstChild; node; node = node.nextSibling) { + if (node == child) { + return offset; + } + offset++; + } + throw "child must be a child node of container"; + }; + let deleteFoundMarkers = () => { + let removeNode = node => { + let container = node.parentElement; + let offset = indexOfContainer(container, node); + node.remove(); + return { container, offset }; + }; + if (startMarker.container == endMarker.container) { + // If the text node becomes empty, remove it and set collapsed range + // to the position where there is the text node. + if (startMarker.container.length === 2) { + if (!/[\[\{][\]\}]/.test(startMarker.container.data)) { + throw `Unexpected text node (data: "${startMarker.container.data}")`; + } + let { container, offset } = removeNode(startMarker.container); + startMarker.container = endMarker.container = container; + startMarker.offset = endMarker.offset = offset; + startMarker.marker = endMarker.marker = ""; + return; + } + startMarker.container.data = `${startMarker.container.data.substring( + 0, + startMarker.offset + )}${startMarker.container.data.substring( + startMarker.offset + 1, + endMarker.offset + )}${startMarker.container.data.substring(endMarker.offset + 1)}`; + if (startMarker.offset >= startMarker.container.length) { + startMarker.offset = endMarker.offset = + startMarker.container.length; + return; + } + endMarker.offset--; // remove the start marker's length + if (endMarker.offset > endMarker.container.length) { + endMarker.offset = endMarker.container.length; + } + return; + } + if (startMarker.container.length === 1) { + let { container, offset } = removeNode(startMarker.container); + startMarker.container = container; + startMarker.offset = offset; + startMarker.marker = ""; + } else { + startMarker.container.data = `${startMarker.container.data.substring( + 0, + startMarker.offset + )}${startMarker.container.data.substring(startMarker.offset + 1)}`; + } + if (endMarker.container.length === 1) { + let { container, offset } = removeNode(endMarker.container); + endMarker.container = container; + endMarker.offset = offset; + endMarker.marker = ""; + } else { + endMarker.container.data = `${endMarker.container.data.substring( + 0, + endMarker.offset + )}${endMarker.container.data.substring(endMarker.offset + 1)}`; + } + }; + deleteFoundMarkers(); + + let handleNodeSelectMarker = () => { + if (startMarker.marker === "{") { + if (startMarker.offset === 0) { + // The range start with the text node. + let container = startMarker.container.parentElement; + startMarker.offset = indexOfContainer( + container, + startMarker.container + ); + startMarker.container = container; + } else if (startMarker.offset === startMarker.container.data.length) { + // The range start after the text node. + let container = startMarker.container.parentElement; + startMarker.offset = + indexOfContainer(container, startMarker.container) + 1; + startMarker.container = container; + } else { + throw 'Start marker "{" is allowed start or end of a text node'; + } + } + if (endMarker.marker === "}") { + if (endMarker.offset === 0) { + // The range ends before the text node. + let container = endMarker.container.parentElement; + endMarker.offset = indexOfContainer(container, endMarker.container); + endMarker.container = container; + } else if (endMarker.offset === endMarker.container.data.length) { + // The range ends with the text node. + let container = endMarker.container.parentElement; + endMarker.offset = + indexOfContainer(container, endMarker.container) + 1; + endMarker.container = container; + } else { + throw 'End marker "}" is allowed start or end of a text node'; + } + } + }; + handleNodeSelectMarker(); + + let range = document.createRange(); + range.setStart(startMarker.container, startMarker.offset); + range.setEnd(endMarker.container, endMarker.offset); + return range; + }; + + let ranges = []; + for ( + let range = getNextRangeAndDeleteMarker(this.editingHost.firstChild); + range; + range = getNextRangeAndDeleteMarker(range.endContainer) + ) { + ranges.push(range); + } + + if (options.selection != "addRange" && ranges.length > 1) { + throw `Failed due to invalid selection option, ${options.selection}, for multiple selection ranges`; + } + + this.selection.removeAllRanges(); + for (const range of ranges) { + if (options.selection == "addRange") { + this.selection.addRange(range); + } else if (options.selection == "setBaseAndExtent") { + this.selection.setBaseAndExtent( + range.startContainer, + range.startOffset, + range.endContainer, + range.endOffset + ); + } else if (options.selection == "setBaseAndExtent-reverse") { + this.selection.setBaseAndExtent( + range.endContainer, + range.endOffset, + range.startContainer, + range.startOffset + ); + } else { + throw `Failed due to invalid selection option, ${options.selection}`; + } + } + + if (this.selection.rangeCount != ranges.length) { + throw `Failed to set selection to the given ranges whose length is ${ranges.length}, but only ${this.selection.rangeCount} ranges are added`; + } + } + + // Originated from normalizeSerializedStyle in include/tests.js + normalizeStyleAttributeValues() { + for (const element of Array.from( + this.editingHost.querySelectorAll("[style]") + )) { + element.setAttribute( + "style", + element + .getAttribute("style") + // Random spacing differences + .replace(/; ?$/, "") + .replace(/: /g, ":") + // Gecko likes "transparent" + .replace(/transparent/g, "rgba(0, 0, 0, 0)") + // WebKit likes to look overly precise + .replace(/, 0.496094\)/g, ", 0.5)") + // Gecko converts anything with full alpha to "transparent" which + // then becomes "rgba(0, 0, 0, 0)", so we have to make other + // browsers match + .replace(/rgba\([0-9]+, [0-9]+, [0-9]+, 0\)/g, "rgba(0, 0, 0, 0)") + ); + } + } +} diff --git a/testing/web-platform/tests/editing/include/implementation.js b/testing/web-platform/tests/editing/include/implementation.js new file mode 100644 index 0000000000..44a7afd82d --- /dev/null +++ b/testing/web-platform/tests/editing/include/implementation.js @@ -0,0 +1,8526 @@ +"use strict"; + +var htmlNamespace = "http://www.w3.org/1999/xhtml"; + +var cssStylingFlag = false; + +var defaultSingleLineContainerName = "div"; + +// This is bad :( +var globalRange = null; + +// Commands are stored in a dictionary where we call their actions and such +var commands = {}; + +/////////////////////////////////////////////////////////////////////////////// +////////////////////////////// Utility functions ////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +//@{ + +function nextNode(node) { + if (node.hasChildNodes()) { + return node.firstChild; + } + return nextNodeDescendants(node); +} + +function previousNode(node) { + if (node.previousSibling) { + node = node.previousSibling; + while (node.hasChildNodes()) { + node = node.lastChild; + } + return node; + } + if (node.parentNode + && node.parentNode.nodeType == Node.ELEMENT_NODE) { + return node.parentNode; + } + return null; +} + +function nextNodeDescendants(node) { + while (node && !node.nextSibling) { + node = node.parentNode; + } + if (!node) { + return null; + } + return node.nextSibling; +} + +/** + * Returns true if ancestor is an ancestor of descendant, false otherwise. + */ +function isAncestor(ancestor, descendant) { + return ancestor + && descendant + && Boolean(ancestor.compareDocumentPosition(descendant) & Node.DOCUMENT_POSITION_CONTAINED_BY); +} + +/** + * Returns true if ancestor is an ancestor of or equal to descendant, false + * otherwise. + */ +function isAncestorContainer(ancestor, descendant) { + return (ancestor || descendant) + && (ancestor == descendant || isAncestor(ancestor, descendant)); +} + +/** + * Returns true if descendant is a descendant of ancestor, false otherwise. + */ +function isDescendant(descendant, ancestor) { + return ancestor + && descendant + && Boolean(ancestor.compareDocumentPosition(descendant) & Node.DOCUMENT_POSITION_CONTAINED_BY); +} + +/** + * Returns true if node1 is before node2 in tree order, false otherwise. + */ +function isBefore(node1, node2) { + return Boolean(node1.compareDocumentPosition(node2) & Node.DOCUMENT_POSITION_FOLLOWING); +} + +/** + * Returns true if node1 is after node2 in tree order, false otherwise. + */ +function isAfter(node1, node2) { + return Boolean(node1.compareDocumentPosition(node2) & Node.DOCUMENT_POSITION_PRECEDING); +} + +function getAncestors(node) { + var ancestors = []; + while (node.parentNode) { + ancestors.unshift(node.parentNode); + node = node.parentNode; + } + return ancestors; +} + +function getInclusiveAncestors(node) { + return getAncestors(node).concat(node); +} + +function getDescendants(node) { + var descendants = []; + var stop = nextNodeDescendants(node); + while ((node = nextNode(node)) + && node != stop) { + descendants.push(node); + } + return descendants; +} + +function getInclusiveDescendants(node) { + return [node].concat(getDescendants(node)); +} + +function convertProperty(property) { + // Special-case for now + var map = { + "fontFamily": "font-family", + "fontSize": "font-size", + "fontStyle": "font-style", + "fontWeight": "font-weight", + "textDecoration": "text-decoration", + }; + if (typeof map[property] != "undefined") { + return map[property]; + } + + return property; +} + +// Return the <font size=X> value for the given CSS size, or undefined if there +// is none. +function cssSizeToLegacy(cssVal) { + return { + "x-small": 1, + "small": 2, + "medium": 3, + "large": 4, + "x-large": 5, + "xx-large": 6, + "xxx-large": 7 + }[cssVal]; +} + +// Return the CSS size given a legacy size. +function legacySizeToCss(legacyVal) { + return { + 1: "x-small", + 2: "small", + 3: "medium", + 4: "large", + 5: "x-large", + 6: "xx-large", + 7: "xxx-large", + }[legacyVal]; +} + +// Opera 11 puts HTML elements in the null namespace, it seems. +function isHtmlNamespace(ns) { + return ns === null + || ns === htmlNamespace; +} + +// "the directionality" from HTML. I don't bother caring about non-HTML +// elements. +// +// "The directionality of an element is either 'ltr' or 'rtl', and is +// determined as per the first appropriate set of steps from the following +// list:" +function getDirectionality(element) { + // "If the element's dir attribute is in the ltr state + // The directionality of the element is 'ltr'." + if (element.dir == "ltr") { + return "ltr"; + } + + // "If the element's dir attribute is in the rtl state + // The directionality of the element is 'rtl'." + if (element.dir == "rtl") { + return "rtl"; + } + + // "If the element's dir attribute is in the auto state + // "If the element is a bdi element and the dir attribute is not in a + // defined state (i.e. it is not present or has an invalid value) + // [lots of complicated stuff] + // + // Skip this, since no browser implements it anyway. + + // "If the element is a root element and the dir attribute is not in a + // defined state (i.e. it is not present or has an invalid value) + // The directionality of the element is 'ltr'." + if (!isHtmlElement(element.parentNode)) { + return "ltr"; + } + + // "If the element has a parent element and the dir attribute is not in a + // defined state (i.e. it is not present or has an invalid value) + // The directionality of the element is the same as the element's + // parent element's directionality." + return getDirectionality(element.parentNode); +} + +//@} + +/////////////////////////////////////////////////////////////////////////////// +///////////////////////////// DOM Range functions ///////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +//@{ + +function getNodeIndex(node) { + var ret = 0; + while (node.previousSibling) { + ret++; + node = node.previousSibling; + } + return ret; +} + +// "The length of a Node node is the following, depending on node: +// +// ProcessingInstruction +// DocumentType +// Always 0. +// Text +// Comment +// node's length. +// Any other node +// node's childNodes's length." +function getNodeLength(node) { + switch (node.nodeType) { + case Node.PROCESSING_INSTRUCTION_NODE: + case Node.DOCUMENT_TYPE_NODE: + return 0; + + case Node.TEXT_NODE: + case Node.COMMENT_NODE: + return node.length; + + default: + return node.childNodes.length; + } +} + +/** + * The position of two boundary points relative to one another, as defined by + * DOM Range. + */ +function getPosition(nodeA, offsetA, nodeB, offsetB) { + // "If node A is the same as node B, return equal if offset A equals offset + // B, before if offset A is less than offset B, and after if offset A is + // greater than offset B." + if (nodeA == nodeB) { + if (offsetA == offsetB) { + return "equal"; + } + if (offsetA < offsetB) { + return "before"; + } + if (offsetA > offsetB) { + return "after"; + } + } + + // "If node A is after node B in tree order, compute the position of (node + // B, offset B) relative to (node A, offset A). If it is before, return + // after. If it is after, return before." + if (nodeB.compareDocumentPosition(nodeA) & Node.DOCUMENT_POSITION_FOLLOWING) { + var pos = getPosition(nodeB, offsetB, nodeA, offsetA); + if (pos == "before") { + return "after"; + } + if (pos == "after") { + return "before"; + } + } + + // "If node A is an ancestor of node B:" + if (nodeB.compareDocumentPosition(nodeA) & Node.DOCUMENT_POSITION_CONTAINS) { + // "Let child equal node B." + var child = nodeB; + + // "While child is not a child of node A, set child to its parent." + while (child.parentNode != nodeA) { + child = child.parentNode; + } + + // "If the index of child is less than offset A, return after." + if (getNodeIndex(child) < offsetA) { + return "after"; + } + } + + // "Return before." + return "before"; +} + +/** + * Returns the furthest ancestor of a Node as defined by DOM Range. + */ +function getFurthestAncestor(node) { + var root = node; + while (root.parentNode != null) { + root = root.parentNode; + } + return root; +} + +/** + * "contained" as defined by DOM Range: "A Node node is contained in a range + * range if node's furthest ancestor is the same as range's root, and (node, 0) + * is after range's start, and (node, length of node) is before range's end." + */ +function isContained(node, range) { + var pos1 = getPosition(node, 0, range.startContainer, range.startOffset); + var pos2 = getPosition(node, getNodeLength(node), range.endContainer, range.endOffset); + + return getFurthestAncestor(node) == getFurthestAncestor(range.startContainer) + && pos1 == "after" + && pos2 == "before"; +} + +/** + * Return all nodes contained in range that the provided function returns true + * for, omitting any with an ancestor already being returned. + */ +function getContainedNodes(range, condition) { + if (typeof condition == "undefined") { + condition = function() { return true }; + } + var node = range.startContainer; + if (node.hasChildNodes() + && range.startOffset < node.childNodes.length) { + // A child is contained + node = node.childNodes[range.startOffset]; + } else if (range.startOffset == getNodeLength(node)) { + // No descendant can be contained + node = nextNodeDescendants(node); + } else { + // No children; this node at least can't be contained + node = nextNode(node); + } + + var stop = range.endContainer; + if (stop.hasChildNodes() + && range.endOffset < stop.childNodes.length) { + // The node after the last contained node is a child + stop = stop.childNodes[range.endOffset]; + } else { + // This node and/or some of its children might be contained + stop = nextNodeDescendants(stop); + } + + var nodeList = []; + while (isBefore(node, stop)) { + if (isContained(node, range) + && condition(node)) { + nodeList.push(node); + node = nextNodeDescendants(node); + continue; + } + node = nextNode(node); + } + return nodeList; +} + +/** + * As above, but includes nodes with an ancestor that's already been returned. + */ +function getAllContainedNodes(range, condition) { + if (typeof condition == "undefined") { + condition = function() { return true }; + } + var node = range.startContainer; + if (node.hasChildNodes() + && range.startOffset < node.childNodes.length) { + // A child is contained + node = node.childNodes[range.startOffset]; + } else if (range.startOffset == getNodeLength(node)) { + // No descendant can be contained + node = nextNodeDescendants(node); + } else { + // No children; this node at least can't be contained + node = nextNode(node); + } + + var stop = range.endContainer; + if (stop.hasChildNodes() + && range.endOffset < stop.childNodes.length) { + // The node after the last contained node is a child + stop = stop.childNodes[range.endOffset]; + } else { + // This node and/or some of its children might be contained + stop = nextNodeDescendants(stop); + } + + var nodeList = []; + while (isBefore(node, stop)) { + if (isContained(node, range) + && condition(node)) { + nodeList.push(node); + } + node = nextNode(node); + } + return nodeList; +} + +// Returns either null, or something of the form rgb(x, y, z), or something of +// the form rgb(x, y, z, w) with w != 0. +function normalizeColor(color) { + if (color.toLowerCase() == "currentcolor") { + return null; + } + + if (normalizeColor.resultCache === undefined) { + normalizeColor.resultCache = {}; + } + + if (normalizeColor.resultCache[color] !== undefined) { + return normalizeColor.resultCache[color]; + } + + var originalColor = color; + + var outerSpan = document.createElement("span"); + document.body.appendChild(outerSpan); + outerSpan.style.color = "black"; + + var innerSpan = document.createElement("span"); + outerSpan.appendChild(innerSpan); + innerSpan.style.color = color; + color = getComputedStyle(innerSpan).color; + + if (color == "rgb(0, 0, 0)") { + // Maybe it's really black, maybe it's invalid. + outerSpan.color = "white"; + color = getComputedStyle(innerSpan).color; + if (color != "rgb(0, 0, 0)") { + return normalizeColor.resultCache[originalColor] = null; + } + } + + document.body.removeChild(outerSpan); + + // I rely on the fact that browsers generally provide consistent syntax for + // getComputedStyle(), although it's not standardized. There are only + // three exceptions I found: + if (/^rgba\([0-9]+, [0-9]+, [0-9]+, 1\)$/.test(color)) { + // IE10PP2 seems to do this sometimes. + return normalizeColor.resultCache[originalColor] = + color.replace("rgba", "rgb").replace(", 1)", ")"); + } + if (color == "transparent") { + // IE10PP2, Firefox 7.0a2, and Opera 11.50 all return "transparent" if + // the specified value is "transparent". + return normalizeColor.resultCache[originalColor] = + "rgba(0, 0, 0, 0)"; + } + // Chrome 15 dev adds way too many significant figures. This isn't a full + // fix, it just fixes one case that comes up in tests. + color = color.replace(/, 0.496094\)$/, ", 0.5)"); + return normalizeColor.resultCache[originalColor] = color; +} + +// Returns either null, or something of the form #xxxxxx. +function parseSimpleColor(color) { + color = normalizeColor(color); + var matches = /^rgb\(([0-9]+), ([0-9]+), ([0-9]+)\)$/.exec(color); + if (matches) { + return "#" + + parseInt(matches[1]).toString(16).replace(/^.$/, "0$&") + + parseInt(matches[2]).toString(16).replace(/^.$/, "0$&") + + parseInt(matches[3]).toString(16).replace(/^.$/, "0$&"); + } + return null; +} + +//@} + +////////////////////////////////////////////////////////////////////////////// +/////////////////////////// Edit command functions /////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////// +///// Methods of the HTMLDocument interface ///// +///////////////////////////////////////////////// +//@{ + +var executionStackDepth = 0; + +// Helper function for common behavior. +function editCommandMethod(command, range, callback) { + // Set up our global range magic, but only if we're the outermost function + if (executionStackDepth == 0 && typeof range != "undefined") { + globalRange = range; + } else if (executionStackDepth == 0) { + globalRange = null; + globalRange = getActiveRange(); + } + + executionStackDepth++; + try { + var ret = callback(); + } catch(e) { + executionStackDepth--; + throw e; + } + executionStackDepth--; + return ret; +} + +function myExecCommand(command, showUi, value, range) { + // "All of these methods must treat their command argument ASCII + // case-insensitively." + command = command.toLowerCase(); + + // "If only one argument was provided, let show UI be false." + // + // If range was passed, I can't actually detect how many args were passed + // . . . + if (arguments.length == 1 + || (arguments.length >=4 && typeof showUi == "undefined")) { + showUi = false; + } + + // "If only one or two arguments were provided, let value be the empty + // string." + if (arguments.length <= 2 + || (arguments.length >=4 && typeof value == "undefined")) { + value = ""; + } + + return editCommandMethod(command, range, (function(command, showUi, value) { return function() { + // "If command is not supported or not enabled, return false." + if (!(command in commands) || !myQueryCommandEnabled(command)) { + return false; + } + + // "Take the action for command, passing value to the instructions as an + // argument." + var ret = commands[command].action(value); + + // Check for bugs + if (ret !== true && ret !== false) { + throw "execCommand() didn't return true or false: " + ret; + } + + // "If the previous step returned false, return false." + if (ret === false) { + return false; + } + + // "Return true." + return true; + }})(command, showUi, value)); +} + +function myQueryCommandEnabled(command, range) { + // "All of these methods must treat their command argument ASCII + // case-insensitively." + command = command.toLowerCase(); + + return editCommandMethod(command, range, (function(command) { return function() { + // "Return true if command is both supported and enabled, false + // otherwise." + if (!(command in commands)) { + return false; + } + + // "Among commands defined in this specification, those listed in + // Miscellaneous commands are always enabled, except for the cut + // command and the paste command. The other commands defined here are + // enabled if the active range is not null, its start node is either + // editable or an editing host, its end node is either editable or an + // editing host, and there is some editing host that is an inclusive + // ancestor of both its start node and its end node." + return ["copy", "defaultparagraphseparator", "selectall", "stylewithcss", + "usecss"].indexOf(command) != -1 + || ( + getActiveRange() !== null + && (isEditable(getActiveRange().startContainer) || isEditingHost(getActiveRange().startContainer)) + && (isEditable(getActiveRange().endContainer) || isEditingHost(getActiveRange().endContainer)) + && (getInclusiveAncestors(getActiveRange().commonAncestorContainer).some(isEditingHost)) + ); + }})(command)); +} + +function myQueryCommandIndeterm(command, range) { + // "All of these methods must treat their command argument ASCII + // case-insensitively." + command = command.toLowerCase(); + + return editCommandMethod(command, range, (function(command) { return function() { + // "If command is not supported or has no indeterminacy, return false." + if (!(command in commands) || !("indeterm" in commands[command])) { + return false; + } + + // "Return true if command is indeterminate, otherwise false." + return commands[command].indeterm(); + }})(command)); +} + +function myQueryCommandState(command, range) { + // "All of these methods must treat their command argument ASCII + // case-insensitively." + command = command.toLowerCase(); + + return editCommandMethod(command, range, (function(command) { return function() { + // "If command is not supported or has no state, return false." + if (!(command in commands) || !("state" in commands[command])) { + return false; + } + + // "If the state override for command is set, return it." + if (typeof getStateOverride(command) != "undefined") { + return getStateOverride(command); + } + + // "Return true if command's state is true, otherwise false." + return commands[command].state(); + }})(command)); +} + +// "When the queryCommandSupported(command) method on the HTMLDocument +// interface is invoked, the user agent must return true if command is +// supported, and false otherwise." +function myQueryCommandSupported(command) { + // "All of these methods must treat their command argument ASCII + // case-insensitively." + command = command.toLowerCase(); + + return command in commands; +} + +function myQueryCommandValue(command, range) { + // "All of these methods must treat their command argument ASCII + // case-insensitively." + command = command.toLowerCase(); + + return editCommandMethod(command, range, function() { + // "If command is not supported or has no value, return the empty string." + if (!(command in commands) || !("value" in commands[command])) { + return ""; + } + + // "If command is "fontSize" and its value override is set, convert the + // value override to an integer number of pixels and return the legacy + // font size for the result." + if (command == "fontsize" + && getValueOverride("fontsize") !== undefined) { + return getLegacyFontSize(getValueOverride("fontsize")); + } + + // "If the value override for command is set, return it." + if (typeof getValueOverride(command) != "undefined") { + return getValueOverride(command); + } + + // "Return command's value." + return commands[command].value(); + }); +} +//@} + +////////////////////////////// +///// Common definitions ///// +////////////////////////////// +//@{ + +// "An HTML element is an Element whose namespace is the HTML namespace." +// +// I allow an extra argument to more easily check whether something is a +// particular HTML element, like isHtmlElement(node, "OL"). It accepts arrays +// too, like isHtmlElement(node, ["OL", "UL"]) to check if it's an ol or ul. +function isHtmlElement(node, tags) { + if (typeof tags == "string") { + tags = [tags]; + } + if (typeof tags == "object") { + tags = tags.map(function(tag) { return tag.toUpperCase() }); + } + return node + && node.nodeType == Node.ELEMENT_NODE + && isHtmlNamespace(node.namespaceURI) + && (typeof tags == "undefined" || tags.indexOf(node.tagName) != -1); +} + +// "A prohibited paragraph child name is "address", "article", "aside", +// "blockquote", "caption", "center", "col", "colgroup", "dd", "details", +// "dir", "div", "dl", "dt", "fieldset", "figcaption", "figure", "footer", +// "form", "h1", "h2", "h3", "h4", "h5", "h6", "header", "hgroup", "hr", "li", +// "listing", "menu", "nav", "ol", "p", "plaintext", "pre", "section", +// "summary", "table", "tbody", "td", "tfoot", "th", "thead", "tr", "ul", or +// "xmp"." +var prohibitedParagraphChildNames = ["address", "article", "aside", + "blockquote", "caption", "center", "col", "colgroup", "dd", "details", + "dir", "div", "dl", "dt", "fieldset", "figcaption", "figure", "footer", + "form", "h1", "h2", "h3", "h4", "h5", "h6", "header", "hgroup", "hr", "li", + "listing", "menu", "nav", "ol", "p", "plaintext", "pre", "section", + "summary", "table", "tbody", "td", "tfoot", "th", "thead", "tr", "ul", + "xmp"]; + +// "A prohibited paragraph child is an HTML element whose local name is a +// prohibited paragraph child name." +function isProhibitedParagraphChild(node) { + return isHtmlElement(node, prohibitedParagraphChildNames); +} + +// "A block node is either an Element whose "display" property does not have +// resolved value "inline" or "inline-block" or "inline-table" or "none", or a +// Document, or a DocumentFragment." +function isBlockNode(node) { + return node + && ((node.nodeType == Node.ELEMENT_NODE && ["inline", "inline-block", "inline-table", "none"].indexOf(getComputedStyle(node).display) == -1) + || node.nodeType == Node.DOCUMENT_NODE + || node.nodeType == Node.DOCUMENT_FRAGMENT_NODE); +} + +// "An inline node is a node that is not a block node." +function isInlineNode(node) { + return node && !isBlockNode(node); +} + +// "An editing host is a node that is either an HTML element with a +// contenteditable attribute set to the true state, or the HTML element child +// of a Document whose designMode is enabled." +function isEditingHost(node) { + return node + && isHtmlElement(node) + && (node.contentEditable == "true" + || (node.parentNode + && node.parentNode.nodeType == Node.DOCUMENT_NODE + && node.parentNode.designMode == "on")); +} + +// "Something is editable if it is a node; it is not an editing host; it does +// not have a contenteditable attribute set to the false state; its parent is +// an editing host or editable; and either it is an HTML element, or it is an +// svg or math element, or it is not an Element and its parent is an HTML +// element." +function isEditable(node) { + return node + && !isEditingHost(node) + && (node.nodeType != Node.ELEMENT_NODE || node.contentEditable != "false") + && (isEditingHost(node.parentNode) || isEditable(node.parentNode)) + && (isHtmlElement(node) + || (node.nodeType == Node.ELEMENT_NODE && node.namespaceURI == "http://www.w3.org/2000/svg" && node.localName == "svg") + || (node.nodeType == Node.ELEMENT_NODE && node.namespaceURI == "http://www.w3.org/1998/Math/MathML" && node.localName == "math") + || (node.nodeType != Node.ELEMENT_NODE && isHtmlElement(node.parentNode))); +} + +// Helper function, not defined in the spec +function hasEditableDescendants(node) { + for (var i = 0; i < node.childNodes.length; i++) { + if (isEditable(node.childNodes[i]) + || hasEditableDescendants(node.childNodes[i])) { + return true; + } + } + return false; +} + +// "The editing host of node is null if node is neither editable nor an editing +// host; node itself, if node is an editing host; or the nearest ancestor of +// node that is an editing host, if node is editable." +function getEditingHostOf(node) { + if (isEditingHost(node)) { + return node; + } else if (isEditable(node)) { + var ancestor = node.parentNode; + while (!isEditingHost(ancestor)) { + ancestor = ancestor.parentNode; + } + return ancestor; + } else { + return null; + } +} + +// "Two nodes are in the same editing host if the editing host of the first is +// non-null and the same as the editing host of the second." +function inSameEditingHost(node1, node2) { + return getEditingHostOf(node1) + && getEditingHostOf(node1) == getEditingHostOf(node2); +} + +// "A collapsed line break is a br that begins a line box which has nothing +// else in it, and therefore has zero height." +function isCollapsedLineBreak(br) { + if (!isHtmlElement(br, "br")) { + return false; + } + + // Add a zwsp after it and see if that changes the height of the nearest + // non-inline parent. Note: this is not actually reliable, because the + // parent might have a fixed height or something. + var ref = br.parentNode; + while (getComputedStyle(ref).display == "inline") { + ref = ref.parentNode; + } + var refStyle = ref.hasAttribute("style") ? ref.getAttribute("style") : null; + ref.style.height = "auto"; + ref.style.maxHeight = "none"; + ref.style.minHeight = "0"; + var space = document.createTextNode("\u200b"); + var origHeight = ref.offsetHeight; + if (origHeight == 0) { + throw "isCollapsedLineBreak: original height is zero, bug?"; + } + br.parentNode.insertBefore(space, br.nextSibling); + var finalHeight = ref.offsetHeight; + space.parentNode.removeChild(space); + if (refStyle === null) { + // Without the setAttribute() line, removeAttribute() doesn't work in + // Chrome 14 dev. I have no idea why. + ref.setAttribute("style", ""); + ref.removeAttribute("style"); + } else { + ref.setAttribute("style", refStyle); + } + + // Allow some leeway in case the zwsp didn't create a whole new line, but + // only made an existing line slightly higher. Firefox 6.0a2 shows this + // behavior when the first line is bold. + return origHeight < finalHeight - 5; +} + +// "An extraneous line break is a br that has no visual effect, in that +// removing it from the DOM would not change layout, except that a br that is +// the sole child of an li is not extraneous." +// +// FIXME: This doesn't work in IE, since IE ignores display: none in +// contenteditable. +function isExtraneousLineBreak(br) { + if (!isHtmlElement(br, "br")) { + return false; + } + + if (isHtmlElement(br.parentNode, "li") + && br.parentNode.childNodes.length == 1) { + return false; + } + + // Make the line break disappear and see if that changes the block's + // height. Yes, this is an absurd hack. We have to reset height etc. on + // the reference node because otherwise its height won't change if it's not + // auto. + var ref = br.parentNode; + while (getComputedStyle(ref).display == "inline") { + ref = ref.parentNode; + } + var refStyle = ref.hasAttribute("style") ? ref.getAttribute("style") : null; + ref.style.height = "auto"; + ref.style.maxHeight = "none"; + ref.style.minHeight = "0"; + var brStyle = br.hasAttribute("style") ? br.getAttribute("style") : null; + var origHeight = ref.offsetHeight; + if (origHeight == 0) { + throw "isExtraneousLineBreak: original height is zero, bug?"; + } + br.setAttribute("style", "display:none"); + var finalHeight = ref.offsetHeight; + if (refStyle === null) { + // Without the setAttribute() line, removeAttribute() doesn't work in + // Chrome 14 dev. I have no idea why. + ref.setAttribute("style", ""); + ref.removeAttribute("style"); + } else { + ref.setAttribute("style", refStyle); + } + if (brStyle === null) { + br.removeAttribute("style"); + } else { + br.setAttribute("style", brStyle); + } + + return origHeight == finalHeight; +} + +// "A whitespace node is either a Text node whose data is the empty string; or +// a Text node whose data consists only of one or more tabs (0x0009), line +// feeds (0x000A), carriage returns (0x000D), and/or spaces (0x0020), and whose +// parent is an Element whose resolved value for "white-space" is "normal" or +// "nowrap"; or a Text node whose data consists only of one or more tabs +// (0x0009), carriage returns (0x000D), and/or spaces (0x0020), and whose +// parent is an Element whose resolved value for "white-space" is "pre-line"." +function isWhitespaceNode(node) { + return node + && node.nodeType == Node.TEXT_NODE + && (node.data == "" + || ( + /^[\t\n\r ]+$/.test(node.data) + && node.parentNode + && node.parentNode.nodeType == Node.ELEMENT_NODE + && ["normal", "nowrap"].indexOf(getComputedStyle(node.parentNode).whiteSpace) != -1 + ) || ( + /^[\t\r ]+$/.test(node.data) + && node.parentNode + && node.parentNode.nodeType == Node.ELEMENT_NODE + && getComputedStyle(node.parentNode).whiteSpace == "pre-line" + )); +} + +// "node is a collapsed whitespace node if the following algorithm returns +// true:" +function isCollapsedWhitespaceNode(node) { + // "If node is not a whitespace node, return false." + if (!isWhitespaceNode(node)) { + return false; + } + + // "If node's data is the empty string, return true." + if (node.data == "") { + return true; + } + + // "Let ancestor be node's parent." + var ancestor = node.parentNode; + + // "If ancestor is null, return true." + if (!ancestor) { + return true; + } + + // "If the "display" property of some ancestor of node has resolved value + // "none", return true." + if (getAncestors(node).some(function(ancestor) { + return ancestor.nodeType == Node.ELEMENT_NODE + && getComputedStyle(ancestor).display == "none"; + })) { + return true; + } + + // "While ancestor is not a block node and its parent is not null, set + // ancestor to its parent." + while (!isBlockNode(ancestor) + && ancestor.parentNode) { + ancestor = ancestor.parentNode; + } + + // "Let reference be node." + var reference = node; + + // "While reference is a descendant of ancestor:" + while (reference != ancestor) { + // "Let reference be the node before it in tree order." + reference = previousNode(reference); + + // "If reference is a block node or a br, return true." + if (isBlockNode(reference) + || isHtmlElement(reference, "br")) { + return true; + } + + // "If reference is a Text node that is not a whitespace node, or is an + // img, break from this loop." + if ((reference.nodeType == Node.TEXT_NODE && !isWhitespaceNode(reference)) + || isHtmlElement(reference, "img")) { + break; + } + } + + // "Let reference be node." + reference = node; + + // "While reference is a descendant of ancestor:" + var stop = nextNodeDescendants(ancestor); + while (reference != stop) { + // "Let reference be the node after it in tree order, or null if there + // is no such node." + reference = nextNode(reference); + + // "If reference is a block node or a br, return true." + if (isBlockNode(reference) + || isHtmlElement(reference, "br")) { + return true; + } + + // "If reference is a Text node that is not a whitespace node, or is an + // img, break from this loop." + if ((reference && reference.nodeType == Node.TEXT_NODE && !isWhitespaceNode(reference)) + || isHtmlElement(reference, "img")) { + break; + } + } + + // "Return false." + return false; +} + +// "Something is visible if it is a node that either is a block node, or a Text +// node that is not a collapsed whitespace node, or an img, or a br that is not +// an extraneous line break, or any node with a visible descendant; excluding +// any node with an ancestor container Element whose "display" property has +// resolved value "none"." +function isVisible(node) { + if (!node) { + return false; + } + + if (getAncestors(node).concat(node) + .filter(function(node) { return node.nodeType == Node.ELEMENT_NODE }) + .some(function(node) { return getComputedStyle(node).display == "none" })) { + return false; + } + + if (isBlockNode(node) + || (node.nodeType == Node.TEXT_NODE && !isCollapsedWhitespaceNode(node)) + || isHtmlElement(node, "img") + || (isHtmlElement(node, "br") && !isExtraneousLineBreak(node))) { + return true; + } + + for (var i = 0; i < node.childNodes.length; i++) { + if (isVisible(node.childNodes[i])) { + return true; + } + } + + return false; +} + +// "Something is invisible if it is a node that is not visible." +function isInvisible(node) { + return node && !isVisible(node); +} + +// "A collapsed block prop is either a collapsed line break that is not an +// extraneous line break, or an Element that is an inline node and whose +// children are all either invisible or collapsed block props and that has at +// least one child that is a collapsed block prop." +function isCollapsedBlockProp(node) { + if (isCollapsedLineBreak(node) + && !isExtraneousLineBreak(node)) { + return true; + } + + if (!isInlineNode(node) + || node.nodeType != Node.ELEMENT_NODE) { + return false; + } + + var hasCollapsedBlockPropChild = false; + for (var i = 0; i < node.childNodes.length; i++) { + if (!isInvisible(node.childNodes[i]) + && !isCollapsedBlockProp(node.childNodes[i])) { + return false; + } + if (isCollapsedBlockProp(node.childNodes[i])) { + hasCollapsedBlockPropChild = true; + } + } + + return hasCollapsedBlockPropChild; +} + +// "The active range is the range of the selection given by calling +// getSelection() on the context object. (Thus the active range may be null.)" +// +// We cheat and return globalRange if that's defined. We also ensure that the +// active range meets the requirements that selection boundary points are +// supposed to meet, i.e., that the nodes are both Text or Element nodes that +// descend from a Document. +function getActiveRange() { + var ret; + if (globalRange) { + ret = globalRange; + } else if (getSelection().rangeCount) { + ret = getSelection().getRangeAt(0); + } else { + return null; + } + if ([Node.TEXT_NODE, Node.ELEMENT_NODE].indexOf(ret.startContainer.nodeType) == -1 + || [Node.TEXT_NODE, Node.ELEMENT_NODE].indexOf(ret.endContainer.nodeType) == -1 + || !ret.startContainer.ownerDocument + || !ret.endContainer.ownerDocument + || !isDescendant(ret.startContainer, ret.startContainer.ownerDocument) + || !isDescendant(ret.endContainer, ret.endContainer.ownerDocument)) { + throw "Invalid active range; test bug?"; + } + return ret; +} + +// "For some commands, each HTMLDocument must have a boolean state override +// and/or a string value override. These do not change the command's state or +// value, but change the way some algorithms behave, as specified in those +// algorithms' definitions. Initially, both must be unset for every command. +// Whenever the number of ranges in the Selection changes to something +// different, and whenever a boundary point of the range at a given index in +// the Selection changes to something different, the state override and value +// override must be unset for every command." +// +// We implement this crudely by using setters and getters. To verify that the +// selection hasn't changed, we copy the active range and just check the +// endpoints match. This isn't really correct, but it's good enough for us. +// Unset state/value overrides are undefined. We put everything in a function +// so no one can access anything except via the provided functions, since +// otherwise callers might mistakenly use outdated overrides (if the selection +// has changed). +var getStateOverride, setStateOverride, unsetStateOverride, + getValueOverride, setValueOverride, unsetValueOverride; +(function() { + var stateOverrides = {}; + var valueOverrides = {}; + var storedRange = null; + + function resetOverrides() { + if (!storedRange + || storedRange.startContainer != getActiveRange().startContainer + || storedRange.endContainer != getActiveRange().endContainer + || storedRange.startOffset != getActiveRange().startOffset + || storedRange.endOffset != getActiveRange().endOffset) { + stateOverrides = {}; + valueOverrides = {}; + storedRange = getActiveRange().cloneRange(); + } + } + + getStateOverride = function(command) { + resetOverrides(); + return stateOverrides[command]; + }; + + setStateOverride = function(command, newState) { + resetOverrides(); + stateOverrides[command] = newState; + }; + + unsetStateOverride = function(command) { + resetOverrides(); + delete stateOverrides[command]; + } + + getValueOverride = function(command) { + resetOverrides(); + return valueOverrides[command]; + } + + // "The value override for the backColor command must be the same as the + // value override for the hiliteColor command, such that setting one sets + // the other to the same thing and unsetting one unsets the other." + setValueOverride = function(command, newValue) { + resetOverrides(); + valueOverrides[command] = newValue; + if (command == "backcolor") { + valueOverrides.hilitecolor = newValue; + } else if (command == "hilitecolor") { + valueOverrides.backcolor = newValue; + } + } + + unsetValueOverride = function(command) { + resetOverrides(); + delete valueOverrides[command]; + if (command == "backcolor") { + delete valueOverrides.hilitecolor; + } else if (command == "hilitecolor") { + delete valueOverrides.backcolor; + } + } +})(); + +//@} + +///////////////////////////// +///// Common algorithms ///// +///////////////////////////// + +///// Assorted common algorithms ///// +//@{ + +// Magic array of extra ranges whose endpoints we want to preserve. +var extraRanges = []; + +function movePreservingRanges(node, newParent, newIndex) { + // For convenience, I allow newIndex to be -1 to mean "insert at the end". + if (newIndex == -1) { + newIndex = newParent.childNodes.length; + } + + // "When the user agent is to move a Node to a new location, preserving + // ranges, it must remove the Node from its original parent (if any), then + // insert it in the new location. In doing so, however, it must ignore the + // regular range mutation rules, and instead follow these rules:" + + // "Let node be the moved Node, old parent and old index be the old parent + // (which may be null) and index, and new parent and new index be the new + // parent and index." + var oldParent = node.parentNode; + var oldIndex = getNodeIndex(node); + + // We preserve the global range object, the ranges in the selection, and + // any range that's in the extraRanges array. Any other ranges won't get + // updated, because we have no references to them. + var ranges = [globalRange].concat(extraRanges); + for (var i = 0; i < getSelection().rangeCount; i++) { + ranges.push(getSelection().getRangeAt(i)); + } + var boundaryPoints = []; + ranges.forEach(function(range) { + boundaryPoints.push([range.startContainer, range.startOffset]); + boundaryPoints.push([range.endContainer, range.endOffset]); + }); + + boundaryPoints.forEach(function(boundaryPoint) { + // "If a boundary point's node is the same as or a descendant of node, + // leave it unchanged, so it moves to the new location." + // + // No modifications necessary. + + // "If a boundary point's node is new parent and its offset is greater + // than new index, add one to its offset." + if (boundaryPoint[0] == newParent + && boundaryPoint[1] > newIndex) { + boundaryPoint[1]++; + } + + // "If a boundary point's node is old parent and its offset is old index or + // old index + 1, set its node to new parent and add new index − old index + // to its offset." + if (boundaryPoint[0] == oldParent + && (boundaryPoint[1] == oldIndex + || boundaryPoint[1] == oldIndex + 1)) { + boundaryPoint[0] = newParent; + boundaryPoint[1] += newIndex - oldIndex; + } + + // "If a boundary point's node is old parent and its offset is greater than + // old index + 1, subtract one from its offset." + if (boundaryPoint[0] == oldParent + && boundaryPoint[1] > oldIndex + 1) { + boundaryPoint[1]--; + } + }); + + // Now actually move it and preserve the ranges. + if (newParent.childNodes.length == newIndex) { + newParent.appendChild(node); + } else { + newParent.insertBefore(node, newParent.childNodes[newIndex]); + } + + globalRange.setStart(boundaryPoints[0][0], boundaryPoints[0][1]); + globalRange.setEnd(boundaryPoints[1][0], boundaryPoints[1][1]); + + for (var i = 0; i < extraRanges.length; i++) { + extraRanges[i].setStart(boundaryPoints[2*i + 2][0], boundaryPoints[2*i + 2][1]); + extraRanges[i].setEnd(boundaryPoints[2*i + 3][0], boundaryPoints[2*i + 3][1]); + } + + getSelection().removeAllRanges(); + for (var i = 1 + extraRanges.length; i < ranges.length; i++) { + var newRange = document.createRange(); + newRange.setStart(boundaryPoints[2*i][0], boundaryPoints[2*i][1]); + newRange.setEnd(boundaryPoints[2*i + 1][0], boundaryPoints[2*i + 1][1]); + getSelection().addRange(newRange); + } +} + +function setTagName(element, newName) { + // "If element is an HTML element with local name equal to new name, return + // element." + if (isHtmlElement(element, newName.toUpperCase())) { + return element; + } + + // "If element's parent is null, return element." + if (!element.parentNode) { + return element; + } + + // "Let replacement element be the result of calling createElement(new + // name) on the ownerDocument of element." + var replacementElement = element.ownerDocument.createElement(newName); + + // "Insert replacement element into element's parent immediately before + // element." + element.parentNode.insertBefore(replacementElement, element); + + // "Copy all attributes of element to replacement element, in order." + for (var i = 0; i < element.attributes.length; i++) { + replacementElement.setAttributeNS(element.attributes[i].namespaceURI, element.attributes[i].name, element.attributes[i].value); + } + + // "While element has children, append the first child of element as the + // last child of replacement element, preserving ranges." + while (element.childNodes.length) { + movePreservingRanges(element.firstChild, replacementElement, replacementElement.childNodes.length); + } + + // "Remove element from its parent." + element.parentNode.removeChild(element); + + // "Return replacement element." + return replacementElement; +} + +function removeExtraneousLineBreaksBefore(node) { + // "Let ref be the previousSibling of node." + var ref = node.previousSibling; + + // "If ref is null, abort these steps." + if (!ref) { + return; + } + + // "While ref has children, set ref to its lastChild." + while (ref.hasChildNodes()) { + ref = ref.lastChild; + } + + // "While ref is invisible but not an extraneous line break, and ref does + // not equal node's parent, set ref to the node before it in tree order." + while (isInvisible(ref) + && !isExtraneousLineBreak(ref) + && ref != node.parentNode) { + ref = previousNode(ref); + } + + // "If ref is an editable extraneous line break, remove it from its + // parent." + if (isEditable(ref) + && isExtraneousLineBreak(ref)) { + ref.parentNode.removeChild(ref); + } +} + +function removeExtraneousLineBreaksAtTheEndOf(node) { + // "Let ref be node." + var ref = node; + + // "While ref has children, set ref to its lastChild." + while (ref.hasChildNodes()) { + ref = ref.lastChild; + } + + // "While ref is invisible but not an extraneous line break, and ref does + // not equal node, set ref to the node before it in tree order." + while (isInvisible(ref) + && !isExtraneousLineBreak(ref) + && ref != node) { + ref = previousNode(ref); + } + + // "If ref is an editable extraneous line break:" + if (isEditable(ref) + && isExtraneousLineBreak(ref)) { + // "While ref's parent is editable and invisible, set ref to its + // parent." + while (isEditable(ref.parentNode) + && isInvisible(ref.parentNode)) { + ref = ref.parentNode; + } + + // "Remove ref from its parent." + ref.parentNode.removeChild(ref); + } +} + +// "To remove extraneous line breaks from a node, first remove extraneous line +// breaks before it, then remove extraneous line breaks at the end of it." +function removeExtraneousLineBreaksFrom(node) { + removeExtraneousLineBreaksBefore(node); + removeExtraneousLineBreaksAtTheEndOf(node); +} + +//@} +///// Wrapping a list of nodes ///// +//@{ + +function wrap(nodeList, siblingCriteria, newParentInstructions) { + // "If not provided, sibling criteria returns false and new parent + // instructions returns null." + if (typeof siblingCriteria == "undefined") { + siblingCriteria = function() { return false }; + } + if (typeof newParentInstructions == "undefined") { + newParentInstructions = function() { return null }; + } + + // "If every member of node list is invisible, and none is a br, return + // null and abort these steps." + if (nodeList.every(isInvisible) + && !nodeList.some(function(node) { return isHtmlElement(node, "br") })) { + return null; + } + + // "If node list's first member's parent is null, return null and abort + // these steps." + if (!nodeList[0].parentNode) { + return null; + } + + // "If node list's last member is an inline node that's not a br, and node + // list's last member's nextSibling is a br, append that br to node list." + if (isInlineNode(nodeList[nodeList.length - 1]) + && !isHtmlElement(nodeList[nodeList.length - 1], "br") + && isHtmlElement(nodeList[nodeList.length - 1].nextSibling, "br")) { + nodeList.push(nodeList[nodeList.length - 1].nextSibling); + } + + // "While node list's first member's previousSibling is invisible, prepend + // it to node list." + while (isInvisible(nodeList[0].previousSibling)) { + nodeList.unshift(nodeList[0].previousSibling); + } + + // "While node list's last member's nextSibling is invisible, append it to + // node list." + while (isInvisible(nodeList[nodeList.length - 1].nextSibling)) { + nodeList.push(nodeList[nodeList.length - 1].nextSibling); + } + + // "If the previousSibling of the first member of node list is editable and + // running sibling criteria on it returns true, let new parent be the + // previousSibling of the first member of node list." + var newParent; + if (isEditable(nodeList[0].previousSibling) + && siblingCriteria(nodeList[0].previousSibling)) { + newParent = nodeList[0].previousSibling; + + // "Otherwise, if the nextSibling of the last member of node list is + // editable and running sibling criteria on it returns true, let new parent + // be the nextSibling of the last member of node list." + } else if (isEditable(nodeList[nodeList.length - 1].nextSibling) + && siblingCriteria(nodeList[nodeList.length - 1].nextSibling)) { + newParent = nodeList[nodeList.length - 1].nextSibling; + + // "Otherwise, run new parent instructions, and let new parent be the + // result." + } else { + newParent = newParentInstructions(); + } + + // "If new parent is null, abort these steps and return null." + if (!newParent) { + return null; + } + + // "If new parent's parent is null:" + if (!newParent.parentNode) { + // "Insert new parent into the parent of the first member of node list + // immediately before the first member of node list." + nodeList[0].parentNode.insertBefore(newParent, nodeList[0]); + + // "If any range has a boundary point with node equal to the parent of + // new parent and offset equal to the index of new parent, add one to + // that boundary point's offset." + // + // Only try to fix the global range. + if (globalRange.startContainer == newParent.parentNode + && globalRange.startOffset == getNodeIndex(newParent)) { + globalRange.setStart(globalRange.startContainer, globalRange.startOffset + 1); + } + if (globalRange.endContainer == newParent.parentNode + && globalRange.endOffset == getNodeIndex(newParent)) { + globalRange.setEnd(globalRange.endContainer, globalRange.endOffset + 1); + } + } + + // "Let original parent be the parent of the first member of node list." + var originalParent = nodeList[0].parentNode; + + // "If new parent is before the first member of node list in tree order:" + if (isBefore(newParent, nodeList[0])) { + // "If new parent is not an inline node, but the last visible child of + // new parent and the first visible member of node list are both inline + // nodes, and the last child of new parent is not a br, call + // createElement("br") on the ownerDocument of new parent and append + // the result as the last child of new parent." + if (!isInlineNode(newParent) + && isInlineNode([].filter.call(newParent.childNodes, isVisible).slice(-1)[0]) + && isInlineNode(nodeList.filter(isVisible)[0]) + && !isHtmlElement(newParent.lastChild, "BR")) { + newParent.appendChild(newParent.ownerDocument.createElement("br")); + } + + // "For each node in node list, append node as the last child of new + // parent, preserving ranges." + for (var i = 0; i < nodeList.length; i++) { + movePreservingRanges(nodeList[i], newParent, -1); + } + + // "Otherwise:" + } else { + // "If new parent is not an inline node, but the first visible child of + // new parent and the last visible member of node list are both inline + // nodes, and the last member of node list is not a br, call + // createElement("br") on the ownerDocument of new parent and insert + // the result as the first child of new parent." + if (!isInlineNode(newParent) + && isInlineNode([].filter.call(newParent.childNodes, isVisible)[0]) + && isInlineNode(nodeList.filter(isVisible).slice(-1)[0]) + && !isHtmlElement(nodeList[nodeList.length - 1], "BR")) { + newParent.insertBefore(newParent.ownerDocument.createElement("br"), newParent.firstChild); + } + + // "For each node in node list, in reverse order, insert node as the + // first child of new parent, preserving ranges." + for (var i = nodeList.length - 1; i >= 0; i--) { + movePreservingRanges(nodeList[i], newParent, 0); + } + } + + // "If original parent is editable and has no children, remove it from its + // parent." + if (isEditable(originalParent) && !originalParent.hasChildNodes()) { + originalParent.parentNode.removeChild(originalParent); + } + + // "If new parent's nextSibling is editable and running sibling criteria on + // it returns true:" + if (isEditable(newParent.nextSibling) + && siblingCriteria(newParent.nextSibling)) { + // "If new parent is not an inline node, but new parent's last child + // and new parent's nextSibling's first child are both inline nodes, + // and new parent's last child is not a br, call createElement("br") on + // the ownerDocument of new parent and append the result as the last + // child of new parent." + if (!isInlineNode(newParent) + && isInlineNode(newParent.lastChild) + && isInlineNode(newParent.nextSibling.firstChild) + && !isHtmlElement(newParent.lastChild, "BR")) { + newParent.appendChild(newParent.ownerDocument.createElement("br")); + } + + // "While new parent's nextSibling has children, append its first child + // as the last child of new parent, preserving ranges." + while (newParent.nextSibling.hasChildNodes()) { + movePreservingRanges(newParent.nextSibling.firstChild, newParent, -1); + } + + // "Remove new parent's nextSibling from its parent." + newParent.parentNode.removeChild(newParent.nextSibling); + } + + // "Remove extraneous line breaks from new parent." + removeExtraneousLineBreaksFrom(newParent); + + // "Return new parent." + return newParent; +} + + +//@} +///// Allowed children ///// +//@{ + +// "A name of an element with inline contents is "a", "abbr", "b", "bdi", +// "bdo", "cite", "code", "dfn", "em", "h1", "h2", "h3", "h4", "h5", "h6", "i", +// "kbd", "mark", "p", "pre", "q", "rp", "rt", "ruby", "s", "samp", "small", +// "span", "strong", "sub", "sup", "u", "var", "acronym", "listing", "strike", +// "xmp", "big", "blink", "font", "marquee", "nobr", or "tt"." +var namesOfElementsWithInlineContents = ["a", "abbr", "b", "bdi", "bdo", + "cite", "code", "dfn", "em", "h1", "h2", "h3", "h4", "h5", "h6", "i", + "kbd", "mark", "p", "pre", "q", "rp", "rt", "ruby", "s", "samp", "small", + "span", "strong", "sub", "sup", "u", "var", "acronym", "listing", "strike", + "xmp", "big", "blink", "font", "marquee", "nobr", "tt"]; + +// "An element with inline contents is an HTML element whose local name is a +// name of an element with inline contents." +function isElementWithInlineContents(node) { + return isHtmlElement(node, namesOfElementsWithInlineContents); +} + +function isAllowedChild(child, parent_) { + // "If parent is "colgroup", "table", "tbody", "tfoot", "thead", "tr", or + // an HTML element with local name equal to one of those, and child is a + // Text node whose data does not consist solely of space characters, return + // false." + if ((["colgroup", "table", "tbody", "tfoot", "thead", "tr"].indexOf(parent_) != -1 + || isHtmlElement(parent_, ["colgroup", "table", "tbody", "tfoot", "thead", "tr"])) + && typeof child == "object" + && child.nodeType == Node.TEXT_NODE + && !/^[ \t\n\f\r]*$/.test(child.data)) { + return false; + } + + // "If parent is "script", "style", "plaintext", or "xmp", or an HTML + // element with local name equal to one of those, and child is not a Text + // node, return false." + if ((["script", "style", "plaintext", "xmp"].indexOf(parent_) != -1 + || isHtmlElement(parent_, ["script", "style", "plaintext", "xmp"])) + && (typeof child != "object" || child.nodeType != Node.TEXT_NODE)) { + return false; + } + + // "If child is a Document, DocumentFragment, or DocumentType, return + // false." + if (typeof child == "object" + && (child.nodeType == Node.DOCUMENT_NODE + || child.nodeType == Node.DOCUMENT_FRAGMENT_NODE + || child.nodeType == Node.DOCUMENT_TYPE_NODE)) { + return false; + } + + // "If child is an HTML element, set child to the local name of child." + if (isHtmlElement(child)) { + child = child.tagName.toLowerCase(); + } + + // "If child is not a string, return true." + if (typeof child != "string") { + return true; + } + + // "If parent is an HTML element:" + if (isHtmlElement(parent_)) { + // "If child is "a", and parent or some ancestor of parent is an a, + // return false." + // + // "If child is a prohibited paragraph child name and parent or some + // ancestor of parent is an element with inline contents, return + // false." + // + // "If child is "h1", "h2", "h3", "h4", "h5", or "h6", and parent or + // some ancestor of parent is an HTML element with local name "h1", + // "h2", "h3", "h4", "h5", or "h6", return false." + var ancestor = parent_; + while (ancestor) { + if (child == "a" && isHtmlElement(ancestor, "a")) { + return false; + } + if (prohibitedParagraphChildNames.indexOf(child) != -1 + && isElementWithInlineContents(ancestor)) { + return false; + } + if (/^h[1-6]$/.test(child) + && isHtmlElement(ancestor) + && /^H[1-6]$/.test(ancestor.tagName)) { + return false; + } + ancestor = ancestor.parentNode; + } + + // "Let parent be the local name of parent." + parent_ = parent_.tagName.toLowerCase(); + } + + // "If parent is an Element or DocumentFragment, return true." + if (typeof parent_ == "object" + && (parent_.nodeType == Node.ELEMENT_NODE + || parent_.nodeType == Node.DOCUMENT_FRAGMENT_NODE)) { + return true; + } + + // "If parent is not a string, return false." + if (typeof parent_ != "string") { + return false; + } + + // "If parent is on the left-hand side of an entry on the following list, + // then return true if child is listed on the right-hand side of that + // entry, and false otherwise." + switch (parent_) { + case "colgroup": + return child == "col"; + case "table": + return ["caption", "col", "colgroup", "tbody", "td", "tfoot", "th", "thead", "tr"].indexOf(child) != -1; + case "tbody": + case "thead": + case "tfoot": + return ["td", "th", "tr"].indexOf(child) != -1; + case "tr": + return ["td", "th"].indexOf(child) != -1; + case "dl": + return ["dt", "dd"].indexOf(child) != -1; + case "dir": + case "ol": + case "ul": + return ["dir", "li", "ol", "ul"].indexOf(child) != -1; + case "hgroup": + return /^h[1-6]$/.test(child); + } + + // "If child is "body", "caption", "col", "colgroup", "frame", "frameset", + // "head", "html", "tbody", "td", "tfoot", "th", "thead", or "tr", return + // false." + if (["body", "caption", "col", "colgroup", "frame", "frameset", "head", + "html", "tbody", "td", "tfoot", "th", "thead", "tr"].indexOf(child) != -1) { + return false; + } + + // "If child is "dd" or "dt" and parent is not "dl", return false." + if (["dd", "dt"].indexOf(child) != -1 + && parent_ != "dl") { + return false; + } + + // "If child is "li" and parent is not "ol" or "ul", return false." + if (child == "li" + && parent_ != "ol" + && parent_ != "ul") { + return false; + } + + // "If parent is on the left-hand side of an entry on the following list + // and child is listed on the right-hand side of that entry, return false." + var table = [ + [["a"], ["a"]], + [["dd", "dt"], ["dd", "dt"]], + [["h1", "h2", "h3", "h4", "h5", "h6"], ["h1", "h2", "h3", "h4", "h5", "h6"]], + [["li"], ["li"]], + [["nobr"], ["nobr"]], + [namesOfElementsWithInlineContents, prohibitedParagraphChildNames], + [["td", "th"], ["caption", "col", "colgroup", "tbody", "td", "tfoot", "th", "thead", "tr"]], + ]; + for (var i = 0; i < table.length; i++) { + if (table[i][0].indexOf(parent_) != -1 + && table[i][1].indexOf(child) != -1) { + return false; + } + } + + // "Return true." + return true; +} + + +//@} + +////////////////////////////////////// +///// Inline formatting commands ///// +////////////////////////////////////// + +///// Inline formatting command definitions ///// +//@{ + +// "A node node is effectively contained in a range range if range is not +// collapsed, and at least one of the following holds:" +function isEffectivelyContained(node, range) { + if (range.collapsed) { + return false; + } + + // "node is contained in range." + if (isContained(node, range)) { + return true; + } + + // "node is range's start node, it is a Text node, and its length is + // different from range's start offset." + if (node == range.startContainer + && node.nodeType == Node.TEXT_NODE + && getNodeLength(node) != range.startOffset) { + return true; + } + + // "node is range's end node, it is a Text node, and range's end offset is + // not 0." + if (node == range.endContainer + && node.nodeType == Node.TEXT_NODE + && range.endOffset != 0) { + return true; + } + + // "node has at least one child; and all its children are effectively + // contained in range; and either range's start node is not a descendant of + // node or is not a Text node or range's start offset is zero; and either + // range's end node is not a descendant of node or is not a Text node or + // range's end offset is its end node's length." + if (node.hasChildNodes() + && [].every.call(node.childNodes, function(child) { return isEffectivelyContained(child, range) }) + && (!isDescendant(range.startContainer, node) + || range.startContainer.nodeType != Node.TEXT_NODE + || range.startOffset == 0) + && (!isDescendant(range.endContainer, node) + || range.endContainer.nodeType != Node.TEXT_NODE + || range.endOffset == getNodeLength(range.endContainer))) { + return true; + } + + return false; +} + +// Like get(All)ContainedNodes(), but for effectively contained nodes. +function getEffectivelyContainedNodes(range, condition) { + if (typeof condition == "undefined") { + condition = function() { return true }; + } + var node = range.startContainer; + while (isEffectivelyContained(node.parentNode, range)) { + node = node.parentNode; + } + + var stop = nextNodeDescendants(range.endContainer); + + var nodeList = []; + while (isBefore(node, stop)) { + if (isEffectivelyContained(node, range) + && condition(node)) { + nodeList.push(node); + node = nextNodeDescendants(node); + continue; + } + node = nextNode(node); + } + return nodeList; +} + +function getAllEffectivelyContainedNodes(range, condition) { + if (typeof condition == "undefined") { + condition = function() { return true }; + } + var node = range.startContainer; + while (isEffectivelyContained(node.parentNode, range)) { + node = node.parentNode; + } + + var stop = nextNodeDescendants(range.endContainer); + + var nodeList = []; + while (isBefore(node, stop)) { + if (isEffectivelyContained(node, range) + && condition(node)) { + nodeList.push(node); + } + node = nextNode(node); + } + return nodeList; +} + +// "A modifiable element is a b, em, i, s, span, strong, sub, sup, or u element +// with no attributes except possibly style; or a font element with no +// attributes except possibly style, color, face, and/or size; or an a element +// with no attributes except possibly style and/or href." +function isModifiableElement(node) { + if (!isHtmlElement(node)) { + return false; + } + + if (["B", "EM", "I", "S", "SPAN", "STRIKE", "STRONG", "SUB", "SUP", "U"].indexOf(node.tagName) != -1) { + if (node.attributes.length == 0) { + return true; + } + + if (node.attributes.length == 1 + && node.hasAttribute("style")) { + return true; + } + } + + if (node.tagName == "FONT" || node.tagName == "A") { + var numAttrs = node.attributes.length; + + if (node.hasAttribute("style")) { + numAttrs--; + } + + if (node.tagName == "FONT") { + if (node.hasAttribute("color")) { + numAttrs--; + } + + if (node.hasAttribute("face")) { + numAttrs--; + } + + if (node.hasAttribute("size")) { + numAttrs--; + } + } + + if (node.tagName == "A" + && node.hasAttribute("href")) { + numAttrs--; + } + + if (numAttrs == 0) { + return true; + } + } + + return false; +} + +function isSimpleModifiableElement(node) { + // "A simple modifiable element is an HTML element for which at least one + // of the following holds:" + if (!isHtmlElement(node)) { + return false; + } + + // Only these elements can possibly be a simple modifiable element. + if (["A", "B", "EM", "FONT", "I", "S", "SPAN", "STRIKE", "STRONG", "SUB", "SUP", "U"].indexOf(node.tagName) == -1) { + return false; + } + + // "It is an a, b, em, font, i, s, span, strike, strong, sub, sup, or u + // element with no attributes." + if (node.attributes.length == 0) { + return true; + } + + // If it's got more than one attribute, everything after this fails. + if (node.attributes.length > 1) { + return false; + } + + // "It is an a, b, em, font, i, s, span, strike, strong, sub, sup, or u + // element with exactly one attribute, which is style, which sets no CSS + // properties (including invalid or unrecognized properties)." + // + // Not gonna try for invalid or unrecognized. + if (node.hasAttribute("style") + && node.style.length == 0) { + return true; + } + + // "It is an a element with exactly one attribute, which is href." + if (node.tagName == "A" + && node.hasAttribute("href")) { + return true; + } + + // "It is a font element with exactly one attribute, which is either color, + // face, or size." + if (node.tagName == "FONT" + && (node.hasAttribute("color") + || node.hasAttribute("face") + || node.hasAttribute("size") + )) { + return true; + } + + // "It is a b or strong element with exactly one attribute, which is style, + // and the style attribute sets exactly one CSS property (including invalid + // or unrecognized properties), which is "font-weight"." + if ((node.tagName == "B" || node.tagName == "STRONG") + && node.hasAttribute("style") + && node.style.length == 1 + && node.style.fontWeight != "") { + return true; + } + + // "It is an i or em element with exactly one attribute, which is style, + // and the style attribute sets exactly one CSS property (including invalid + // or unrecognized properties), which is "font-style"." + if ((node.tagName == "I" || node.tagName == "EM") + && node.hasAttribute("style") + && node.style.length == 1 + && node.style.fontStyle != "") { + return true; + } + + // "It is an a, font, or span element with exactly one attribute, which is + // style, and the style attribute sets exactly one CSS property (including + // invalid or unrecognized properties), and that property is not + // "text-decoration"." + if ((node.tagName == "A" || node.tagName == "FONT" || node.tagName == "SPAN") + && node.hasAttribute("style") + && node.style.length == 1 + && node.style.textDecoration == "") { + return true; + } + + // "It is an a, font, s, span, strike, or u element with exactly one + // attribute, which is style, and the style attribute sets exactly one CSS + // property (including invalid or unrecognized properties), which is + // "text-decoration", which is set to "line-through" or "underline" or + // "overline" or "none"." + // + // The weird extra node.style.length check is for Firefox, which as of + // 8.0a2 has annoying and weird behavior here. + if (["A", "FONT", "S", "SPAN", "STRIKE", "U"].indexOf(node.tagName) != -1 + && node.hasAttribute("style") + && (node.style.length == 1 + || (node.style.length == 4 + && "MozTextBlink" in node.style + && "MozTextDecorationColor" in node.style + && "MozTextDecorationLine" in node.style + && "MozTextDecorationStyle" in node.style) + || (node.style.length == 4 + && "MozTextBlink" in node.style + && "textDecorationColor" in node.style + && "textDecorationLine" in node.style + && "textDecorationStyle" in node.style) + ) + && (node.style.textDecoration == "line-through" + || node.style.textDecoration == "underline" + || node.style.textDecoration == "overline" + || node.style.textDecoration == "none")) { + return true; + } + + return false; +} + +// "A formattable node is an editable visible node that is either a Text node, +// an img, or a br." +function isFormattableNode(node) { + return isEditable(node) + && isVisible(node) + && (node.nodeType == Node.TEXT_NODE + || isHtmlElement(node, ["img", "br"])); +} + +// "Two quantities are equivalent values for a command if either both are null, +// or both are strings and they're equal and the command does not define any +// equivalent values, or both are strings and the command defines equivalent +// values and they match the definition." +function areEquivalentValues(command, val1, val2) { + if (val1 === null && val2 === null) { + return true; + } + + if (typeof val1 == "string" + && typeof val2 == "string" + && val1 == val2 + && !("equivalentValues" in commands[command])) { + return true; + } + + if (typeof val1 == "string" + && typeof val2 == "string" + && "equivalentValues" in commands[command] + && commands[command].equivalentValues(val1, val2)) { + return true; + } + + return false; +} + +// "Two quantities are loosely equivalent values for a command if either they +// are equivalent values for the command, or if the command is the fontSize +// command; one of the quantities is one of "x-small", "small", "medium", +// "large", "x-large", "xx-large", or "xxx-large"; and the other quantity is +// the resolved value of "font-size" on a font element whose size attribute has +// the corresponding value set ("1" through "7" respectively)." +function areLooselyEquivalentValues(command, val1, val2) { + if (areEquivalentValues(command, val1, val2)) { + return true; + } + + if (command != "fontsize" + || typeof val1 != "string" + || typeof val2 != "string") { + return false; + } + + // Static variables in JavaScript? + var callee = areLooselyEquivalentValues; + if (callee.sizeMap === undefined) { + callee.sizeMap = {}; + var font = document.createElement("font"); + document.body.appendChild(font); + ["x-small", "small", "medium", "large", "x-large", "xx-large", + "xxx-large"].forEach(function(keyword) { + font.size = cssSizeToLegacy(keyword); + callee.sizeMap[keyword] = getComputedStyle(font).fontSize; + }); + document.body.removeChild(font); + } + + return val1 === callee.sizeMap[val2] + || val2 === callee.sizeMap[val1]; +} + +//@} +///// Assorted inline formatting command algorithms ///// +//@{ + +function getEffectiveCommandValue(node, command) { + // "If neither node nor its parent is an Element, return null." + if (node.nodeType != Node.ELEMENT_NODE + && (!node.parentNode || node.parentNode.nodeType != Node.ELEMENT_NODE)) { + return null; + } + + // "If node is not an Element, return the effective command value of its + // parent for command." + if (node.nodeType != Node.ELEMENT_NODE) { + return getEffectiveCommandValue(node.parentNode, command); + } + + // "If command is "createLink" or "unlink":" + if (command == "createlink" || command == "unlink") { + // "While node is not null, and is not an a element that has an href + // attribute, set node to its parent." + while (node + && (!isHtmlElement(node) + || node.tagName != "A" + || !node.hasAttribute("href"))) { + node = node.parentNode; + } + + // "If node is null, return null." + if (!node) { + return null; + } + + // "Return the value of node's href attribute." + return node.getAttribute("href"); + } + + // "If command is "backColor" or "hiliteColor":" + if (command == "backcolor" + || command == "hilitecolor") { + // "While the resolved value of "background-color" on node is any + // fully transparent value, and node's parent is an Element, set + // node to its parent." + // + // Another lame hack to avoid flawed APIs. + while ((getComputedStyle(node).backgroundColor == "rgba(0, 0, 0, 0)" + || getComputedStyle(node).backgroundColor === "" + || getComputedStyle(node).backgroundColor == "transparent") + && node.parentNode + && node.parentNode.nodeType == Node.ELEMENT_NODE) { + node = node.parentNode; + } + + // "Return the resolved value of "background-color" for node." + return getComputedStyle(node).backgroundColor; + } + + // "If command is "subscript" or "superscript":" + if (command == "subscript" || command == "superscript") { + // "Let affected by subscript and affected by superscript be two + // boolean variables, both initially false." + var affectedBySubscript = false; + var affectedBySuperscript = false; + + // "While node is an inline node:" + while (isInlineNode(node)) { + var verticalAlign = getComputedStyle(node).verticalAlign; + + // "If node is a sub, set affected by subscript to true." + if (isHtmlElement(node, "sub")) { + affectedBySubscript = true; + // "Otherwise, if node is a sup, set affected by superscript to + // true." + } else if (isHtmlElement(node, "sup")) { + affectedBySuperscript = true; + } + + // "Set node to its parent." + node = node.parentNode; + } + + // "If affected by subscript and affected by superscript are both true, + // return the string "mixed"." + if (affectedBySubscript && affectedBySuperscript) { + return "mixed"; + } + + // "If affected by subscript is true, return "subscript"." + if (affectedBySubscript) { + return "subscript"; + } + + // "If affected by superscript is true, return "superscript"." + if (affectedBySuperscript) { + return "superscript"; + } + + // "Return null." + return null; + } + + // "If command is "strikethrough", and the "text-decoration" property of + // node or any of its ancestors has resolved value containing + // "line-through", return "line-through". Otherwise, return null." + if (command == "strikethrough") { + do { + if (getComputedStyle(node).textDecoration.indexOf("line-through") != -1) { + return "line-through"; + } + node = node.parentNode; + } while (node && node.nodeType == Node.ELEMENT_NODE); + return null; + } + + // "If command is "underline", and the "text-decoration" property of node + // or any of its ancestors has resolved value containing "underline", + // return "underline". Otherwise, return null." + if (command == "underline") { + do { + if (getComputedStyle(node).textDecoration.indexOf("underline") != -1) { + return "underline"; + } + node = node.parentNode; + } while (node && node.nodeType == Node.ELEMENT_NODE); + return null; + } + + if (!("relevantCssProperty" in commands[command])) { + throw "Bug: no relevantCssProperty for " + command + " in getEffectiveCommandValue"; + } + + // "Return the resolved value for node of the relevant CSS property for + // command." + return getComputedStyle(node)[commands[command].relevantCssProperty]; +} + +function getSpecifiedCommandValue(element, command) { + // "If command is "backColor" or "hiliteColor" and element's display + // property does not have resolved value "inline", return null." + if ((command == "backcolor" || command == "hilitecolor") + && getComputedStyle(element).display != "inline") { + return null; + } + + // "If command is "createLink" or "unlink":" + if (command == "createlink" || command == "unlink") { + // "If element is an a element and has an href attribute, return the + // value of that attribute." + if (isHtmlElement(element) + && element.tagName == "A" + && element.hasAttribute("href")) { + return element.getAttribute("href"); + } + + // "Return null." + return null; + } + + // "If command is "subscript" or "superscript":" + if (command == "subscript" || command == "superscript") { + // "If element is a sup, return "superscript"." + if (isHtmlElement(element, "sup")) { + return "superscript"; + } + + // "If element is a sub, return "subscript"." + if (isHtmlElement(element, "sub")) { + return "subscript"; + } + + // "Return null." + return null; + } + + // "If command is "strikethrough", and element has a style attribute set, + // and that attribute sets "text-decoration":" + if (command == "strikethrough" + && element.style.textDecoration != "") { + // "If element's style attribute sets "text-decoration" to a value + // containing "line-through", return "line-through"." + if (element.style.textDecoration.indexOf("line-through") != -1) { + return "line-through"; + } + + // "Return null." + return null; + } + + // "If command is "strikethrough" and element is a s or strike element, + // return "line-through"." + if (command == "strikethrough" + && isHtmlElement(element, ["S", "STRIKE"])) { + return "line-through"; + } + + // "If command is "underline", and element has a style attribute set, and + // that attribute sets "text-decoration":" + if (command == "underline" + && element.style.textDecoration != "") { + // "If element's style attribute sets "text-decoration" to a value + // containing "underline", return "underline"." + if (element.style.textDecoration.indexOf("underline") != -1) { + return "underline"; + } + + // "Return null." + return null; + } + + // "If command is "underline" and element is a u element, return + // "underline"." + if (command == "underline" + && isHtmlElement(element, "U")) { + return "underline"; + } + + // "Let property be the relevant CSS property for command." + var property = commands[command].relevantCssProperty; + + // "If property is null, return null." + if (property === null) { + return null; + } + + // "If element has a style attribute set, and that attribute has the + // effect of setting property, return the value that it sets property to." + if (element.style[property] != "") { + return element.style[property]; + } + + // "If element is a font element that has an attribute whose effect is + // to create a presentational hint for property, return the value that the + // hint sets property to. (For a size of 7, this will be the non-CSS value + // "xxx-large".)" + if (isHtmlNamespace(element.namespaceURI) + && element.tagName == "FONT") { + if (property == "color" && element.hasAttribute("color")) { + return element.color; + } + if (property == "fontFamily" && element.hasAttribute("face")) { + return element.face; + } + if (property == "fontSize" && element.hasAttribute("size")) { + // This is not even close to correct in general. + var size = parseInt(element.size); + if (size < 1) { + size = 1; + } + if (size > 7) { + size = 7; + } + return { + 1: "x-small", + 2: "small", + 3: "medium", + 4: "large", + 5: "x-large", + 6: "xx-large", + 7: "xxx-large" + }[size]; + } + } + + // "If element is in the following list, and property is equal to the + // CSS property name listed for it, return the string listed for it." + // + // A list follows, whose meaning is copied here. + if (property == "fontWeight" + && (element.tagName == "B" || element.tagName == "STRONG")) { + return "bold"; + } + if (property == "fontStyle" + && (element.tagName == "I" || element.tagName == "EM")) { + return "italic"; + } + + // "Return null." + return null; +} + +function reorderModifiableDescendants(node, command, newValue) { + // "Let candidate equal node." + var candidate = node; + + // "While candidate is a modifiable element, and candidate has exactly one + // child, and that child is also a modifiable element, and candidate is not + // a simple modifiable element or candidate's specified command value for + // command is not equivalent to new value, set candidate to its child." + while (isModifiableElement(candidate) + && candidate.childNodes.length == 1 + && isModifiableElement(candidate.firstChild) + && (!isSimpleModifiableElement(candidate) + || !areEquivalentValues(command, getSpecifiedCommandValue(candidate, command), newValue))) { + candidate = candidate.firstChild; + } + + // "If candidate is node, or is not a simple modifiable element, or its + // specified command value is not equivalent to new value, or its effective + // command value is not loosely equivalent to new value, abort these + // steps." + if (candidate == node + || !isSimpleModifiableElement(candidate) + || !areEquivalentValues(command, getSpecifiedCommandValue(candidate, command), newValue) + || !areLooselyEquivalentValues(command, getEffectiveCommandValue(candidate, command), newValue)) { + return; + } + + // "While candidate has children, insert the first child of candidate into + // candidate's parent immediately before candidate, preserving ranges." + while (candidate.hasChildNodes()) { + movePreservingRanges(candidate.firstChild, candidate.parentNode, getNodeIndex(candidate)); + } + + // "Insert candidate into node's parent immediately after node." + node.parentNode.insertBefore(candidate, node.nextSibling); + + // "Append the node as the last child of candidate, preserving ranges." + movePreservingRanges(node, candidate, -1); +} + +function recordValues(nodeList) { + // "Let values be a list of (node, command, specified command value) + // triples, initially empty." + var values = []; + + // "For each node in node list, for each command in the list "subscript", + // "bold", "fontName", "fontSize", "foreColor", "hiliteColor", "italic", + // "strikethrough", and "underline" in that order:" + nodeList.forEach(function(node) { + ["subscript", "bold", "fontname", "fontsize", "forecolor", + "hilitecolor", "italic", "strikethrough", "underline"].forEach(function(command) { + // "Let ancestor equal node." + var ancestor = node; + + // "If ancestor is not an Element, set it to its parent." + if (ancestor.nodeType != Node.ELEMENT_NODE) { + ancestor = ancestor.parentNode; + } + + // "While ancestor is an Element and its specified command value + // for command is null, set it to its parent." + while (ancestor + && ancestor.nodeType == Node.ELEMENT_NODE + && getSpecifiedCommandValue(ancestor, command) === null) { + ancestor = ancestor.parentNode; + } + + // "If ancestor is an Element, add (node, command, ancestor's + // specified command value for command) to values. Otherwise add + // (node, command, null) to values." + if (ancestor && ancestor.nodeType == Node.ELEMENT_NODE) { + values.push([node, command, getSpecifiedCommandValue(ancestor, command)]); + } else { + values.push([node, command, null]); + } + }); + }); + + // "Return values." + return values; +} + +function restoreValues(values) { + // "For each (node, command, value) triple in values:" + values.forEach(function(triple) { + var node = triple[0]; + var command = triple[1]; + var value = triple[2]; + + // "Let ancestor equal node." + var ancestor = node; + + // "If ancestor is not an Element, set it to its parent." + if (!ancestor || ancestor.nodeType != Node.ELEMENT_NODE) { + ancestor = ancestor.parentNode; + } + + // "While ancestor is an Element and its specified command value for + // command is null, set it to its parent." + while (ancestor + && ancestor.nodeType == Node.ELEMENT_NODE + && getSpecifiedCommandValue(ancestor, command) === null) { + ancestor = ancestor.parentNode; + } + + // "If value is null and ancestor is an Element, push down values on + // node for command, with new value null." + if (value === null + && ancestor + && ancestor.nodeType == Node.ELEMENT_NODE) { + pushDownValues(node, command, null); + + // "Otherwise, if ancestor is an Element and its specified command + // value for command is not equivalent to value, or if ancestor is not + // an Element and value is not null, force the value of command to + // value on node." + } else if ((ancestor + && ancestor.nodeType == Node.ELEMENT_NODE + && !areEquivalentValues(command, getSpecifiedCommandValue(ancestor, command), value)) + || ((!ancestor || ancestor.nodeType != Node.ELEMENT_NODE) + && value !== null)) { + forceValue(node, command, value); + } + }); +} + + +//@} +///// Clearing an element's value ///// +//@{ + +function clearValue(element, command) { + // "If element is not editable, return the empty list." + if (!isEditable(element)) { + return []; + } + + // "If element's specified command value for command is null, return the + // empty list." + if (getSpecifiedCommandValue(element, command) === null) { + return []; + } + + // "If element is a simple modifiable element:" + if (isSimpleModifiableElement(element)) { + // "Let children be the children of element." + var children = Array.prototype.slice.call(element.childNodes); + + // "For each child in children, insert child into element's parent + // immediately before element, preserving ranges." + for (var i = 0; i < children.length; i++) { + movePreservingRanges(children[i], element.parentNode, getNodeIndex(element)); + } + + // "Remove element from its parent." + element.parentNode.removeChild(element); + + // "Return children." + return children; + } + + // "If command is "strikethrough", and element has a style attribute that + // sets "text-decoration" to some value containing "line-through", delete + // "line-through" from the value." + if (command == "strikethrough" + && element.style.textDecoration.indexOf("line-through") != -1) { + if (element.style.textDecoration == "line-through") { + element.style.textDecoration = ""; + } else { + element.style.textDecoration = element.style.textDecoration.replace("line-through", ""); + } + if (element.getAttribute("style") == "") { + element.removeAttribute("style"); + } + } + + // "If command is "underline", and element has a style attribute that sets + // "text-decoration" to some value containing "underline", delete + // "underline" from the value." + if (command == "underline" + && element.style.textDecoration.indexOf("underline") != -1) { + if (element.style.textDecoration == "underline") { + element.style.textDecoration = ""; + } else { + element.style.textDecoration = element.style.textDecoration.replace("underline", ""); + } + if (element.getAttribute("style") == "") { + element.removeAttribute("style"); + } + } + + // "If the relevant CSS property for command is not null, unset the CSS + // property property of element." + if (commands[command].relevantCssProperty !== null) { + element.style[commands[command].relevantCssProperty] = ''; + if (element.getAttribute("style") == "") { + element.removeAttribute("style"); + } + } + + // "If element is a font element:" + if (isHtmlNamespace(element.namespaceURI) && element.tagName == "FONT") { + // "If command is "foreColor", unset element's color attribute, if set." + if (command == "forecolor") { + element.removeAttribute("color"); + } + + // "If command is "fontName", unset element's face attribute, if set." + if (command == "fontname") { + element.removeAttribute("face"); + } + + // "If command is "fontSize", unset element's size attribute, if set." + if (command == "fontsize") { + element.removeAttribute("size"); + } + } + + // "If element is an a element and command is "createLink" or "unlink", + // unset the href property of element." + if (isHtmlElement(element, "A") + && (command == "createlink" || command == "unlink")) { + element.removeAttribute("href"); + } + + // "If element's specified command value for command is null, return the + // empty list." + if (getSpecifiedCommandValue(element, command) === null) { + return []; + } + + // "Set the tag name of element to "span", and return the one-node list + // consisting of the result." + return [setTagName(element, "span")]; +} + + +//@} +///// Pushing down values ///// +//@{ + +function pushDownValues(node, command, newValue) { + // "If node's parent is not an Element, abort this algorithm." + if (!node.parentNode + || node.parentNode.nodeType != Node.ELEMENT_NODE) { + return; + } + + // "If the effective command value of command is loosely equivalent to new + // value on node, abort this algorithm." + if (areLooselyEquivalentValues(command, getEffectiveCommandValue(node, command), newValue)) { + return; + } + + // "Let current ancestor be node's parent." + var currentAncestor = node.parentNode; + + // "Let ancestor list be a list of Nodes, initially empty." + var ancestorList = []; + + // "While current ancestor is an editable Element and the effective command + // value of command is not loosely equivalent to new value on it, append + // current ancestor to ancestor list, then set current ancestor to its + // parent." + while (isEditable(currentAncestor) + && currentAncestor.nodeType == Node.ELEMENT_NODE + && !areLooselyEquivalentValues(command, getEffectiveCommandValue(currentAncestor, command), newValue)) { + ancestorList.push(currentAncestor); + currentAncestor = currentAncestor.parentNode; + } + + // "If ancestor list is empty, abort this algorithm." + if (!ancestorList.length) { + return; + } + + // "Let propagated value be the specified command value of command on the + // last member of ancestor list." + var propagatedValue = getSpecifiedCommandValue(ancestorList[ancestorList.length - 1], command); + + // "If propagated value is null and is not equal to new value, abort this + // algorithm." + if (propagatedValue === null && propagatedValue != newValue) { + return; + } + + // "If the effective command value for the parent of the last member of + // ancestor list is not loosely equivalent to new value, and new value is + // not null, abort this algorithm." + if (newValue !== null + && !areLooselyEquivalentValues(command, getEffectiveCommandValue(ancestorList[ancestorList.length - 1].parentNode, command), newValue)) { + return; + } + + // "While ancestor list is not empty:" + while (ancestorList.length) { + // "Let current ancestor be the last member of ancestor list." + // "Remove the last member from ancestor list." + var currentAncestor = ancestorList.pop(); + + // "If the specified command value of current ancestor for command is + // not null, set propagated value to that value." + if (getSpecifiedCommandValue(currentAncestor, command) !== null) { + propagatedValue = getSpecifiedCommandValue(currentAncestor, command); + } + + // "Let children be the children of current ancestor." + var children = Array.prototype.slice.call(currentAncestor.childNodes); + + // "If the specified command value of current ancestor for command is + // not null, clear the value of current ancestor." + if (getSpecifiedCommandValue(currentAncestor, command) !== null) { + clearValue(currentAncestor, command); + } + + // "For every child in children:" + for (var i = 0; i < children.length; i++) { + var child = children[i]; + + // "If child is node, continue with the next child." + if (child == node) { + continue; + } + + // "If child is an Element whose specified command value for + // command is neither null nor equivalent to propagated value, + // continue with the next child." + if (child.nodeType == Node.ELEMENT_NODE + && getSpecifiedCommandValue(child, command) !== null + && !areEquivalentValues(command, propagatedValue, getSpecifiedCommandValue(child, command))) { + continue; + } + + // "If child is the last member of ancestor list, continue with the + // next child." + if (child == ancestorList[ancestorList.length - 1]) { + continue; + } + + // "Force the value of child, with command as in this algorithm + // and new value equal to propagated value." + forceValue(child, command, propagatedValue); + } + } +} + + +//@} +///// Forcing the value of a node ///// +//@{ + +function forceValue(node, command, newValue) { + // "If node's parent is null, abort this algorithm." + if (!node.parentNode) { + return; + } + + // "If new value is null, abort this algorithm." + if (newValue === null) { + return; + } + + // "If node is an allowed child of "span":" + if (isAllowedChild(node, "span")) { + // "Reorder modifiable descendants of node's previousSibling." + reorderModifiableDescendants(node.previousSibling, command, newValue); + + // "Reorder modifiable descendants of node's nextSibling." + reorderModifiableDescendants(node.nextSibling, command, newValue); + + // "Wrap the one-node list consisting of node, with sibling criteria + // returning true for a simple modifiable element whose specified + // command value is equivalent to new value and whose effective command + // value is loosely equivalent to new value and false otherwise, and + // with new parent instructions returning null." + wrap([node], + function(node) { + return isSimpleModifiableElement(node) + && areEquivalentValues(command, getSpecifiedCommandValue(node, command), newValue) + && areLooselyEquivalentValues(command, getEffectiveCommandValue(node, command), newValue); + }, + function() { return null } + ); + } + + // "If node is invisible, abort this algorithm." + if (isInvisible(node)) { + return; + } + + // "If the effective command value of command is loosely equivalent to new + // value on node, abort this algorithm." + if (areLooselyEquivalentValues(command, getEffectiveCommandValue(node, command), newValue)) { + return; + } + + // "If node is not an allowed child of "span":" + if (!isAllowedChild(node, "span")) { + // "Let children be all children of node, omitting any that are + // Elements whose specified command value for command is neither null + // nor equivalent to new value." + var children = []; + for (var i = 0; i < node.childNodes.length; i++) { + if (node.childNodes[i].nodeType == Node.ELEMENT_NODE) { + var specifiedValue = getSpecifiedCommandValue(node.childNodes[i], command); + + if (specifiedValue !== null + && !areEquivalentValues(command, newValue, specifiedValue)) { + continue; + } + } + children.push(node.childNodes[i]); + } + + // "Force the value of each Node in children, with command and new + // value as in this invocation of the algorithm." + for (var i = 0; i < children.length; i++) { + forceValue(children[i], command, newValue); + } + + // "Abort this algorithm." + return; + } + + // "If the effective command value of command is loosely equivalent to new + // value on node, abort this algorithm." + if (areLooselyEquivalentValues(command, getEffectiveCommandValue(node, command), newValue)) { + return; + } + + // "Let new parent be null." + var newParent = null; + + // "If the CSS styling flag is false:" + if (!cssStylingFlag) { + // "If command is "bold" and new value is "bold", let new parent be the + // result of calling createElement("b") on the ownerDocument of node." + if (command == "bold" && (newValue == "bold" || newValue == "700")) { + newParent = node.ownerDocument.createElement("b"); + } + + // "If command is "italic" and new value is "italic", let new parent be + // the result of calling createElement("i") on the ownerDocument of + // node." + if (command == "italic" && newValue == "italic") { + newParent = node.ownerDocument.createElement("i"); + } + + // "If command is "strikethrough" and new value is "line-through", let + // new parent be the result of calling createElement("s") on the + // ownerDocument of node." + if (command == "strikethrough" && newValue == "line-through") { + newParent = node.ownerDocument.createElement("s"); + } + + // "If command is "underline" and new value is "underline", let new + // parent be the result of calling createElement("u") on the + // ownerDocument of node." + if (command == "underline" && newValue == "underline") { + newParent = node.ownerDocument.createElement("u"); + } + + // "If command is "foreColor", and new value is fully opaque with red, + // green, and blue components in the range 0 to 255:" + if (command == "forecolor" && parseSimpleColor(newValue)) { + // "Let new parent be the result of calling createElement("font") + // on the ownerDocument of node." + newParent = node.ownerDocument.createElement("font"); + + // "Set the color attribute of new parent to the result of applying + // the rules for serializing simple color values to new value + // (interpreted as a simple color)." + newParent.setAttribute("color", parseSimpleColor(newValue)); + } + + // "If command is "fontName", let new parent be the result of calling + // createElement("font") on the ownerDocument of node, then set the + // face attribute of new parent to new value." + if (command == "fontname") { + newParent = node.ownerDocument.createElement("font"); + newParent.face = newValue; + } + } + + // "If command is "createLink" or "unlink":" + if (command == "createlink" || command == "unlink") { + // "Let new parent be the result of calling createElement("a") on the + // ownerDocument of node." + newParent = node.ownerDocument.createElement("a"); + + // "Set the href attribute of new parent to new value." + newParent.setAttribute("href", newValue); + + // "Let ancestor be node's parent." + var ancestor = node.parentNode; + + // "While ancestor is not null:" + while (ancestor) { + // "If ancestor is an a, set the tag name of ancestor to "span", + // and let ancestor be the result." + if (isHtmlElement(ancestor, "A")) { + ancestor = setTagName(ancestor, "span"); + } + + // "Set ancestor to its parent." + ancestor = ancestor.parentNode; + } + } + + // "If command is "fontSize"; and new value is one of "x-small", "small", + // "medium", "large", "x-large", "xx-large", or "xxx-large"; and either the + // CSS styling flag is false, or new value is "xxx-large": let new parent + // be the result of calling createElement("font") on the ownerDocument of + // node, then set the size attribute of new parent to the number from the + // following table based on new value: [table omitted]" + if (command == "fontsize" + && ["x-small", "small", "medium", "large", "x-large", "xx-large", "xxx-large"].indexOf(newValue) != -1 + && (!cssStylingFlag || newValue == "xxx-large")) { + newParent = node.ownerDocument.createElement("font"); + newParent.size = cssSizeToLegacy(newValue); + } + + // "If command is "subscript" or "superscript" and new value is + // "subscript", let new parent be the result of calling + // createElement("sub") on the ownerDocument of node." + if ((command == "subscript" || command == "superscript") + && newValue == "subscript") { + newParent = node.ownerDocument.createElement("sub"); + } + + // "If command is "subscript" or "superscript" and new value is + // "superscript", let new parent be the result of calling + // createElement("sup") on the ownerDocument of node." + if ((command == "subscript" || command == "superscript") + && newValue == "superscript") { + newParent = node.ownerDocument.createElement("sup"); + } + + // "If new parent is null, let new parent be the result of calling + // createElement("span") on the ownerDocument of node." + if (!newParent) { + newParent = node.ownerDocument.createElement("span"); + } + + // "Insert new parent in node's parent before node." + node.parentNode.insertBefore(newParent, node); + + // "If the effective command value of command for new parent is not loosely + // equivalent to new value, and the relevant CSS property for command is + // not null, set that CSS property of new parent to new value (if the new + // value would be valid)." + var property = commands[command].relevantCssProperty; + if (property !== null + && !areLooselyEquivalentValues(command, getEffectiveCommandValue(newParent, command), newValue)) { + newParent.style[property] = newValue; + } + + // "If command is "strikethrough", and new value is "line-through", and the + // effective command value of "strikethrough" for new parent is not + // "line-through", set the "text-decoration" property of new parent to + // "line-through"." + if (command == "strikethrough" + && newValue == "line-through" + && getEffectiveCommandValue(newParent, "strikethrough") != "line-through") { + newParent.style.textDecoration = "line-through"; + } + + // "If command is "underline", and new value is "underline", and the + // effective command value of "underline" for new parent is not + // "underline", set the "text-decoration" property of new parent to + // "underline"." + if (command == "underline" + && newValue == "underline" + && getEffectiveCommandValue(newParent, "underline") != "underline") { + newParent.style.textDecoration = "underline"; + } + + // "Append node to new parent as its last child, preserving ranges." + movePreservingRanges(node, newParent, newParent.childNodes.length); + + // "If node is an Element and the effective command value of command for + // node is not loosely equivalent to new value:" + if (node.nodeType == Node.ELEMENT_NODE + && !areEquivalentValues(command, getEffectiveCommandValue(node, command), newValue)) { + // "Insert node into the parent of new parent before new parent, + // preserving ranges." + movePreservingRanges(node, newParent.parentNode, getNodeIndex(newParent)); + + // "Remove new parent from its parent." + newParent.parentNode.removeChild(newParent); + + // "Let children be all children of node, omitting any that are + // Elements whose specified command value for command is neither null + // nor equivalent to new value." + var children = []; + for (var i = 0; i < node.childNodes.length; i++) { + if (node.childNodes[i].nodeType == Node.ELEMENT_NODE) { + var specifiedValue = getSpecifiedCommandValue(node.childNodes[i], command); + + if (specifiedValue !== null + && !areEquivalentValues(command, newValue, specifiedValue)) { + continue; + } + } + children.push(node.childNodes[i]); + } + + // "Force the value of each Node in children, with command and new + // value as in this invocation of the algorithm." + for (var i = 0; i < children.length; i++) { + forceValue(children[i], command, newValue); + } + } +} + + +//@} +///// Setting the selection's value ///// +//@{ + +function setSelectionValue(command, newValue) { + // "If there is no formattable node effectively contained in the active + // range:" + if (!getAllEffectivelyContainedNodes(getActiveRange()) + .some(isFormattableNode)) { + // "If command has inline command activated values, set the state + // override to true if new value is among them and false if it's not." + if ("inlineCommandActivatedValues" in commands[command]) { + setStateOverride(command, commands[command].inlineCommandActivatedValues + .indexOf(newValue) != -1); + } + + // "If command is "subscript", unset the state override for + // "superscript"." + if (command == "subscript") { + unsetStateOverride("superscript"); + } + + // "If command is "superscript", unset the state override for + // "subscript"." + if (command == "superscript") { + unsetStateOverride("subscript"); + } + + // "If new value is null, unset the value override (if any)." + if (newValue === null) { + unsetValueOverride(command); + + // "Otherwise, if command is "createLink" or it has a value specified, + // set the value override to new value." + } else if (command == "createlink" || "value" in commands[command]) { + setValueOverride(command, newValue); + } + + // "Abort these steps." + return; + } + + // "If the active range's start node is an editable Text node, and its + // start offset is neither zero nor its start node's length, call + // splitText() on the active range's start node, with argument equal to the + // active range's start offset. Then set the active range's start node to + // the result, and its start offset to zero." + if (isEditable(getActiveRange().startContainer) + && getActiveRange().startContainer.nodeType == Node.TEXT_NODE + && getActiveRange().startOffset != 0 + && getActiveRange().startOffset != getNodeLength(getActiveRange().startContainer)) { + // Account for browsers not following range mutation rules + var newActiveRange = document.createRange(); + var newNode; + if (getActiveRange().startContainer == getActiveRange().endContainer) { + var newEndOffset = getActiveRange().endOffset - getActiveRange().startOffset; + newNode = getActiveRange().startContainer.splitText(getActiveRange().startOffset); + newActiveRange.setEnd(newNode, newEndOffset); + getActiveRange().setEnd(newNode, newEndOffset); + } else { + newNode = getActiveRange().startContainer.splitText(getActiveRange().startOffset); + } + newActiveRange.setStart(newNode, 0); + getSelection().removeAllRanges(); + getSelection().addRange(newActiveRange); + + getActiveRange().setStart(newNode, 0); + } + + // "If the active range's end node is an editable Text node, and its end + // offset is neither zero nor its end node's length, call splitText() on + // the active range's end node, with argument equal to the active range's + // end offset." + if (isEditable(getActiveRange().endContainer) + && getActiveRange().endContainer.nodeType == Node.TEXT_NODE + && getActiveRange().endOffset != 0 + && getActiveRange().endOffset != getNodeLength(getActiveRange().endContainer)) { + // IE seems to mutate the range incorrectly here, so we need correction + // here as well. The active range will be temporarily in orphaned + // nodes, so calling getActiveRange() after splitText() but before + // fixing the range will throw an exception. + var activeRange = getActiveRange(); + var newStart = [activeRange.startContainer, activeRange.startOffset]; + var newEnd = [activeRange.endContainer, activeRange.endOffset]; + activeRange.endContainer.splitText(activeRange.endOffset); + activeRange.setStart(newStart[0], newStart[1]); + activeRange.setEnd(newEnd[0], newEnd[1]); + + getSelection().removeAllRanges(); + getSelection().addRange(activeRange); + } + + // "Let element list be all editable Elements effectively contained in the + // active range. + // + // "For each element in element list, clear the value of element." + getAllEffectivelyContainedNodes(getActiveRange(), function(node) { + return isEditable(node) && node.nodeType == Node.ELEMENT_NODE; + }).forEach(function(element) { + clearValue(element, command); + }); + + // "Let node list be all editable nodes effectively contained in the active + // range. + // + // "For each node in node list:" + getAllEffectivelyContainedNodes(getActiveRange(), isEditable).forEach(function(node) { + // "Push down values on node." + pushDownValues(node, command, newValue); + + // "If node is an allowed child of span, force the value of node." + if (isAllowedChild(node, "span")) { + forceValue(node, command, newValue); + } + }); +} + + +//@} +///// The backColor command ///// +//@{ +commands.backcolor = { + // Copy-pasted, same as hiliteColor + action: function(value) { + // Action is further copy-pasted, same as foreColor + + // "If value is not a valid CSS color, prepend "#" to it." + // + // "If value is still not a valid CSS color, or if it is currentColor, + // return false." + // + // Cheap hack for testing, no attempt to be comprehensive. + if (/^([0-9a-fA-F]{3}){1,2}$/.test(value)) { + value = "#" + value; + } + if (!/^(rgba?|hsla?)\(.*\)$/.test(value) + && !parseSimpleColor(value) + && value.toLowerCase() != "transparent") { + return false; + } + + // "Set the selection's value to value." + setSelectionValue("backcolor", value); + + // "Return true." + return true; + }, standardInlineValueCommand: true, relevantCssProperty: "backgroundColor", + equivalentValues: function(val1, val2) { + // "Either both strings are valid CSS colors and have the same red, + // green, blue, and alpha components, or neither string is a valid CSS + // color." + return normalizeColor(val1) === normalizeColor(val2); + }, +}; + +//@} +///// The bold command ///// +//@{ +commands.bold = { + action: function() { + // "If queryCommandState("bold") returns true, set the selection's + // value to "normal". Otherwise set the selection's value to "bold". + // Either way, return true." + if (myQueryCommandState("bold")) { + setSelectionValue("bold", "normal"); + } else { + setSelectionValue("bold", "bold"); + } + return true; + }, inlineCommandActivatedValues: ["bold", "600", "700", "800", "900"], + relevantCssProperty: "fontWeight", + equivalentValues: function(val1, val2) { + // "Either the two strings are equal, or one is "bold" and the other is + // "700", or one is "normal" and the other is "400"." + return val1 == val2 + || (val1 == "bold" && val2 == "700") + || (val1 == "700" && val2 == "bold") + || (val1 == "normal" && val2 == "400") + || (val1 == "400" && val2 == "normal"); + }, +}; + +//@} +///// The createLink command ///// +//@{ +commands.createlink = { + action: function(value) { + // "If value is the empty string, return false." + if (value === "") { + return false; + } + + // "For each editable a element that has an href attribute and is an + // ancestor of some node effectively contained in the active range, set + // that a element's href attribute to value." + // + // TODO: We don't actually do this in tree order, not that it matters + // unless you're spying with mutation events. + getAllEffectivelyContainedNodes(getActiveRange()).forEach(function(node) { + getAncestors(node).forEach(function(ancestor) { + if (isEditable(ancestor) + && isHtmlElement(ancestor, "a") + && ancestor.hasAttribute("href")) { + ancestor.setAttribute("href", value); + } + }); + }); + + // "Set the selection's value to value." + setSelectionValue("createlink", value); + + // "Return true." + return true; + } +}; + +//@} +///// The fontName command ///// +//@{ +commands.fontname = { + action: function(value) { + // "Set the selection's value to value, then return true." + setSelectionValue("fontname", value); + return true; + }, standardInlineValueCommand: true, relevantCssProperty: "fontFamily" +}; + +//@} +///// The fontSize command ///// +//@{ + +// Helper function for fontSize's action plus queryOutputHelper. It's just the +// middle of fontSize's action, ripped out into its own function. Returns null +// if the size is invalid. +function normalizeFontSize(value) { + // "Strip leading and trailing whitespace from value." + // + // Cheap hack, not following the actual algorithm. + value = value.trim(); + + // "If value is not a valid floating point number, and would not be a valid + // floating point number if a single leading "+" character were stripped, + // return false." + if (!/^[-+]?[0-9]+(\.[0-9]+)?([eE][-+]?[0-9]+)?$/.test(value)) { + return null; + } + + var mode; + + // "If the first character of value is "+", delete the character and let + // mode be "relative-plus"." + if (value[0] == "+") { + value = value.slice(1); + mode = "relative-plus"; + // "Otherwise, if the first character of value is "-", delete the character + // and let mode be "relative-minus"." + } else if (value[0] == "-") { + value = value.slice(1); + mode = "relative-minus"; + // "Otherwise, let mode be "absolute"." + } else { + mode = "absolute"; + } + + // "Apply the rules for parsing non-negative integers to value, and let + // number be the result." + // + // Another cheap hack. + var num = parseInt(value); + + // "If mode is "relative-plus", add three to number." + if (mode == "relative-plus") { + num += 3; + } + + // "If mode is "relative-minus", negate number, then add three to it." + if (mode == "relative-minus") { + num = 3 - num; + } + + // "If number is less than one, let number equal 1." + if (num < 1) { + num = 1; + } + + // "If number is greater than seven, let number equal 7." + if (num > 7) { + num = 7; + } + + // "Set value to the string here corresponding to number:" [table omitted] + value = { + 1: "x-small", + 2: "small", + 3: "medium", + 4: "large", + 5: "x-large", + 6: "xx-large", + 7: "xxx-large" + }[num]; + + return value; +} + +commands.fontsize = { + action: function(value) { + value = normalizeFontSize(value); + if (value === null) { + return false; + } + + // "Set the selection's value to value." + setSelectionValue("fontsize", value); + + // "Return true." + return true; + }, indeterm: function() { + // "True if among formattable nodes that are effectively contained in + // the active range, there are two that have distinct effective command + // values. Otherwise false." + return getAllEffectivelyContainedNodes(getActiveRange(), isFormattableNode) + .map(function(node) { + return getEffectiveCommandValue(node, "fontsize"); + }).filter(function(value, i, arr) { + return arr.slice(0, i).indexOf(value) == -1; + }).length >= 2; + }, value: function() { + // "If the active range is null, return the empty string." + if (!getActiveRange()) { + return ""; + } + + // "Let pixel size be the effective command value of the first + // formattable node that is effectively contained in the active range, + // or if there is no such node, the effective command value of the + // active range's start node, in either case interpreted as a number of + // pixels." + var node = getAllEffectivelyContainedNodes(getActiveRange(), isFormattableNode)[0]; + if (node === undefined) { + node = getActiveRange().startContainer; + } + var pixelSize = getEffectiveCommandValue(node, "fontsize"); + + // "Return the legacy font size for pixel size." + return getLegacyFontSize(pixelSize); + }, relevantCssProperty: "fontSize" +}; + +function getLegacyFontSize(size) { + if (getLegacyFontSize.resultCache === undefined) { + getLegacyFontSize.resultCache = {}; + } + + if (getLegacyFontSize.resultCache[size] !== undefined) { + return getLegacyFontSize.resultCache[size]; + } + + // For convenience in other places in my code, I handle all sizes, not just + // pixel sizes as the spec says. This means pixel sizes have to be passed + // in suffixed with "px", not as plain numbers. + if (normalizeFontSize(size) !== null) { + return getLegacyFontSize.resultCache[size] = cssSizeToLegacy(normalizeFontSize(size)); + } + + if (["x-small", "x-small", "small", "medium", "large", "x-large", "xx-large", "xxx-large"].indexOf(size) == -1 + && !/^[0-9]+(\.[0-9]+)?(cm|mm|in|pt|pc|px)$/.test(size)) { + // There is no sensible legacy size for things like "2em". + return getLegacyFontSize.resultCache[size] = null; + } + + var font = document.createElement("font"); + document.body.appendChild(font); + if (size == "xxx-large") { + font.size = 7; + } else { + font.style.fontSize = size; + } + var pixelSize = parseInt(getComputedStyle(font).fontSize); + document.body.removeChild(font); + + // "Let returned size be 1." + var returnedSize = 1; + + // "While returned size is less than 7:" + while (returnedSize < 7) { + // "Let lower bound be the resolved value of "font-size" in pixels + // of a font element whose size attribute is set to returned size." + var font = document.createElement("font"); + font.size = returnedSize; + document.body.appendChild(font); + var lowerBound = parseInt(getComputedStyle(font).fontSize); + + // "Let upper bound be the resolved value of "font-size" in pixels + // of a font element whose size attribute is set to one plus + // returned size." + font.size = 1 + returnedSize; + var upperBound = parseInt(getComputedStyle(font).fontSize); + document.body.removeChild(font); + + // "Let average be the average of upper bound and lower bound." + var average = (upperBound + lowerBound)/2; + + // "If pixel size is less than average, return the one-element + // string consisting of the digit returned size." + if (pixelSize < average) { + return getLegacyFontSize.resultCache[size] = String(returnedSize); + } + + // "Add one to returned size." + returnedSize++; + } + + // "Return "7"." + return getLegacyFontSize.resultCache[size] = "7"; +} + +//@} +///// The foreColor command ///// +//@{ +commands.forecolor = { + action: function(value) { + // Copy-pasted, same as backColor and hiliteColor + + // "If value is not a valid CSS color, prepend "#" to it." + // + // "If value is still not a valid CSS color, or if it is currentColor, + // return false." + // + // Cheap hack for testing, no attempt to be comprehensive. + if (/^([0-9a-fA-F]{3}){1,2}$/.test(value)) { + value = "#" + value; + } + if (!/^(rgba?|hsla?)\(.*\)$/.test(value) + && !parseSimpleColor(value) + && value.toLowerCase() != "transparent") { + return false; + } + + // "Set the selection's value to value." + setSelectionValue("forecolor", value); + + // "Return true." + return true; + }, standardInlineValueCommand: true, relevantCssProperty: "color", + equivalentValues: function(val1, val2) { + // "Either both strings are valid CSS colors and have the same red, + // green, blue, and alpha components, or neither string is a valid CSS + // color." + return normalizeColor(val1) === normalizeColor(val2); + }, +}; + +//@} +///// The hiliteColor command ///// +//@{ +commands.hilitecolor = { + // Copy-pasted, same as backColor + action: function(value) { + // Action is further copy-pasted, same as foreColor + + // "If value is not a valid CSS color, prepend "#" to it." + // + // "If value is still not a valid CSS color, or if it is currentColor, + // return false." + // + // Cheap hack for testing, no attempt to be comprehensive. + if (/^([0-9a-fA-F]{3}){1,2}$/.test(value)) { + value = "#" + value; + } + if (!/^(rgba?|hsla?)\(.*\)$/.test(value) + && !parseSimpleColor(value) + && value.toLowerCase() != "transparent") { + return false; + } + + // "Set the selection's value to value." + setSelectionValue("hilitecolor", value); + + // "Return true." + return true; + }, indeterm: function() { + // "True if among editable Text nodes that are effectively contained in + // the active range, there are two that have distinct effective command + // values. Otherwise false." + return getAllEffectivelyContainedNodes(getActiveRange(), function(node) { + return isEditable(node) && node.nodeType == Node.TEXT_NODE; + }).map(function(node) { + return getEffectiveCommandValue(node, "hilitecolor"); + }).filter(function(value, i, arr) { + return arr.slice(0, i).indexOf(value) == -1; + }).length >= 2; + }, standardInlineValueCommand: true, relevantCssProperty: "backgroundColor", + equivalentValues: function(val1, val2) { + // "Either both strings are valid CSS colors and have the same red, + // green, blue, and alpha components, or neither string is a valid CSS + // color." + return normalizeColor(val1) === normalizeColor(val2); + }, +}; + +//@} +///// The italic command ///// +//@{ +commands.italic = { + action: function() { + // "If queryCommandState("italic") returns true, set the selection's + // value to "normal". Otherwise set the selection's value to "italic". + // Either way, return true." + if (myQueryCommandState("italic")) { + setSelectionValue("italic", "normal"); + } else { + setSelectionValue("italic", "italic"); + } + return true; + }, inlineCommandActivatedValues: ["italic", "oblique"], + relevantCssProperty: "fontStyle" +}; + +//@} +///// The removeFormat command ///// +//@{ +commands.removeformat = { + action: function() { + // "A removeFormat candidate is an editable HTML element with local + // name "abbr", "acronym", "b", "bdi", "bdo", "big", "blink", "cite", + // "code", "dfn", "em", "font", "i", "ins", "kbd", "mark", "nobr", "q", + // "s", "samp", "small", "span", "strike", "strong", "sub", "sup", + // "tt", "u", or "var"." + function isRemoveFormatCandidate(node) { + return isEditable(node) + && isHtmlElement(node, ["abbr", "acronym", "b", "bdi", "bdo", + "big", "blink", "cite", "code", "dfn", "em", "font", "i", + "ins", "kbd", "mark", "nobr", "q", "s", "samp", "small", + "span", "strike", "strong", "sub", "sup", "tt", "u", "var"]); + } + + // "Let elements to remove be a list of every removeFormat candidate + // effectively contained in the active range." + var elementsToRemove = getAllEffectivelyContainedNodes(getActiveRange(), isRemoveFormatCandidate); + + // "For each element in elements to remove:" + elementsToRemove.forEach(function(element) { + // "While element has children, insert the first child of element + // into the parent of element immediately before element, + // preserving ranges." + while (element.hasChildNodes()) { + movePreservingRanges(element.firstChild, element.parentNode, getNodeIndex(element)); + } + + // "Remove element from its parent." + element.parentNode.removeChild(element); + }); + + // "If the active range's start node is an editable Text node, and its + // start offset is neither zero nor its start node's length, call + // splitText() on the active range's start node, with argument equal to + // the active range's start offset. Then set the active range's start + // node to the result, and its start offset to zero." + if (isEditable(getActiveRange().startContainer) + && getActiveRange().startContainer.nodeType == Node.TEXT_NODE + && getActiveRange().startOffset != 0 + && getActiveRange().startOffset != getNodeLength(getActiveRange().startContainer)) { + // Account for browsers not following range mutation rules + if (getActiveRange().startContainer == getActiveRange().endContainer) { + var newEnd = getActiveRange().endOffset - getActiveRange().startOffset; + var newNode = getActiveRange().startContainer.splitText(getActiveRange().startOffset); + getActiveRange().setStart(newNode, 0); + getActiveRange().setEnd(newNode, newEnd); + } else { + getActiveRange().setStart(getActiveRange().startContainer.splitText(getActiveRange().startOffset), 0); + } + } + + // "If the active range's end node is an editable Text node, and its + // end offset is neither zero nor its end node's length, call + // splitText() on the active range's end node, with argument equal to + // the active range's end offset." + if (isEditable(getActiveRange().endContainer) + && getActiveRange().endContainer.nodeType == Node.TEXT_NODE + && getActiveRange().endOffset != 0 + && getActiveRange().endOffset != getNodeLength(getActiveRange().endContainer)) { + // IE seems to mutate the range incorrectly here, so we need + // correction here as well. Have to be careful to set the range to + // something not including the text node so that getActiveRange() + // doesn't throw an exception due to a temporarily detached + // endpoint. + var newStart = [getActiveRange().startContainer, getActiveRange().startOffset]; + var newEnd = [getActiveRange().endContainer, getActiveRange().endOffset]; + getActiveRange().setEnd(document.documentElement, 0); + newEnd[0].splitText(newEnd[1]); + getActiveRange().setStart(newStart[0], newStart[1]); + getActiveRange().setEnd(newEnd[0], newEnd[1]); + } + + // "Let node list consist of all editable nodes effectively contained + // in the active range." + // + // "For each node in node list, while node's parent is a removeFormat + // candidate in the same editing host as node, split the parent of the + // one-node list consisting of node." + getAllEffectivelyContainedNodes(getActiveRange(), isEditable).forEach(function(node) { + while (isRemoveFormatCandidate(node.parentNode) + && inSameEditingHost(node.parentNode, node)) { + splitParent([node]); + } + }); + + // "For each of the entries in the following list, in the given order, + // set the selection's value to null, with command as given." + [ + "subscript", + "bold", + "fontname", + "fontsize", + "forecolor", + "hilitecolor", + "italic", + "strikethrough", + "underline", + ].forEach(function(command) { + setSelectionValue(command, null); + }); + + // "Return true." + return true; + } +}; + +//@} +///// The strikethrough command ///// +//@{ +commands.strikethrough = { + action: function() { + // "If queryCommandState("strikethrough") returns true, set the + // selection's value to null. Otherwise set the selection's value to + // "line-through". Either way, return true." + if (myQueryCommandState("strikethrough")) { + setSelectionValue("strikethrough", null); + } else { + setSelectionValue("strikethrough", "line-through"); + } + return true; + }, inlineCommandActivatedValues: ["line-through"] +}; + +//@} +///// The subscript command ///// +//@{ +commands.subscript = { + action: function() { + // "Call queryCommandState("subscript"), and let state be the result." + var state = myQueryCommandState("subscript"); + + // "Set the selection's value to null." + setSelectionValue("subscript", null); + + // "If state is false, set the selection's value to "subscript"." + if (!state) { + setSelectionValue("subscript", "subscript"); + } + + // "Return true." + return true; + }, indeterm: function() { + // "True if either among formattable nodes that are effectively + // contained in the active range, there is at least one with effective + // command value "subscript" and at least one with some other effective + // command value; or if there is some formattable node effectively + // contained in the active range with effective command value "mixed". + // Otherwise false." + var nodes = getAllEffectivelyContainedNodes(getActiveRange(), isFormattableNode); + return (nodes.some(function(node) { return getEffectiveCommandValue(node, "subscript") == "subscript" }) + && nodes.some(function(node) { return getEffectiveCommandValue(node, "subscript") != "subscript" })) + || nodes.some(function(node) { return getEffectiveCommandValue(node, "subscript") == "mixed" }); + }, inlineCommandActivatedValues: ["subscript"], +}; + +//@} +///// The superscript command ///// +//@{ +commands.superscript = { + action: function() { + // "Call queryCommandState("superscript"), and let state be the + // result." + var state = myQueryCommandState("superscript"); + + // "Set the selection's value to null." + setSelectionValue("superscript", null); + + // "If state is false, set the selection's value to "superscript"." + if (!state) { + setSelectionValue("superscript", "superscript"); + } + + // "Return true." + return true; + }, indeterm: function() { + // "True if either among formattable nodes that are effectively + // contained in the active range, there is at least one with effective + // command value "superscript" and at least one with some other + // effective command value; or if there is some formattable node + // effectively contained in the active range with effective command + // value "mixed". Otherwise false." + var nodes = getAllEffectivelyContainedNodes(getActiveRange(), isFormattableNode); + return (nodes.some(function(node) { return getEffectiveCommandValue(node, "superscript") == "superscript" }) + && nodes.some(function(node) { return getEffectiveCommandValue(node, "superscript") != "superscript" })) + || nodes.some(function(node) { return getEffectiveCommandValue(node, "superscript") == "mixed" }); + }, inlineCommandActivatedValues: ["superscript"], +}; + +//@} +///// The underline command ///// +//@{ +commands.underline = { + action: function() { + // "If queryCommandState("underline") returns true, set the selection's + // value to null. Otherwise set the selection's value to "underline". + // Either way, return true." + if (myQueryCommandState("underline")) { + setSelectionValue("underline", null); + } else { + setSelectionValue("underline", "underline"); + } + return true; + }, inlineCommandActivatedValues: ["underline"] +}; + +//@} +///// The unlink command ///// +//@{ +commands.unlink = { + action: function() { + // "Let hyperlinks be a list of every a element that has an href + // attribute and is contained in the active range or is an ancestor of + // one of its boundary points." + // + // As usual, take care to ensure it's tree order. The correctness of + // the following is left as an exercise for the reader. + var range = getActiveRange(); + var hyperlinks = []; + for ( + var node = range.startContainer; + node; + node = node.parentNode + ) { + if (isHtmlElement(node, "A") + && node.hasAttribute("href")) { + hyperlinks.unshift(node); + } + } + for ( + var node = range.startContainer; + node != nextNodeDescendants(range.endContainer); + node = nextNode(node) + ) { + if (isHtmlElement(node, "A") + && node.hasAttribute("href") + && (isContained(node, range) + || isAncestor(node, range.endContainer) + || node == range.endContainer)) { + hyperlinks.push(node); + } + } + + // "Clear the value of each member of hyperlinks." + for (var i = 0; i < hyperlinks.length; i++) { + clearValue(hyperlinks[i], "unlink"); + } + + // "Return true." + return true; + } +}; + +//@} + +///////////////////////////////////// +///// Block formatting commands ///// +///////////////////////////////////// + +///// Block formatting command definitions ///// +//@{ + +// "An indentation element is either a blockquote, or a div that has a style +// attribute that sets "margin" or some subproperty of it." +function isIndentationElement(node) { + if (!isHtmlElement(node)) { + return false; + } + + if (node.tagName == "BLOCKQUOTE") { + return true; + } + + if (node.tagName != "DIV") { + return false; + } + + for (var i = 0; i < node.style.length; i++) { + // Approximate check + if (/^(-[a-z]+-)?margin/.test(node.style[i])) { + return true; + } + } + + return false; +} + +// "A simple indentation element is an indentation element that has no +// attributes except possibly +// +// * "a style attribute that sets no properties other than "margin", +// "border", "padding", or subproperties of those; and/or +// * "a dir attribute." +function isSimpleIndentationElement(node) { + if (!isIndentationElement(node)) { + return false; + } + + for (var i = 0; i < node.attributes.length; i++) { + if (!isHtmlNamespace(node.attributes[i].namespaceURI) + || ["style", "dir"].indexOf(node.attributes[i].name) == -1) { + return false; + } + } + + for (var i = 0; i < node.style.length; i++) { + // This is approximate, but it works well enough for my purposes. + if (!/^(-[a-z]+-)?(margin|border|padding)/.test(node.style[i])) { + return false; + } + } + + return true; +} + +// "A non-list single-line container is an HTML element with local name +// "address", "div", "h1", "h2", "h3", "h4", "h5", "h6", "listing", "p", "pre", +// or "xmp"." +function isNonListSingleLineContainer(node) { + return isHtmlElement(node, ["address", "div", "h1", "h2", "h3", "h4", "h5", + "h6", "listing", "p", "pre", "xmp"]); +} + +// "A single-line container is either a non-list single-line container, or an +// HTML element with local name "li", "dt", or "dd"." +function isSingleLineContainer(node) { + return isNonListSingleLineContainer(node) + || isHtmlElement(node, ["li", "dt", "dd"]); +} + +function getBlockNodeOf(node) { + // "While node is an inline node, set node to its parent." + while (isInlineNode(node)) { + node = node.parentNode; + } + + // "Return node." + return node; +} + +//@} +///// Assorted block formatting command algorithms ///// +//@{ + +function fixDisallowedAncestors(node) { + // "If node is not editable, abort these steps." + if (!isEditable(node)) { + return; + } + + // "If node is not an allowed child of any of its ancestors in the same + // editing host:" + if (getAncestors(node).every(function(ancestor) { + return !inSameEditingHost(node, ancestor) + || !isAllowedChild(node, ancestor) + })) { + // "If node is a dd or dt, wrap the one-node list consisting of node, + // with sibling criteria returning true for any dl with no attributes + // and false otherwise, and new parent instructions returning the + // result of calling createElement("dl") on the context object. Then + // abort these steps." + if (isHtmlElement(node, ["dd", "dt"])) { + wrap([node], + function(sibling) { return isHtmlElement(sibling, "dl") && !sibling.attributes.length }, + function() { return document.createElement("dl") }); + return; + } + + // "If "p" is not an allowed child of the editing host of node, abort + // these steps." + if (!isAllowedChild("p", getEditingHostOf(node))) { + return; + } + + // "If node is not a prohibited paragraph child, abort these steps." + if (!isProhibitedParagraphChild(node)) { + return; + } + + // "Set the tag name of node to the default single-line container name, + // and let node be the result." + node = setTagName(node, defaultSingleLineContainerName); + + // "Fix disallowed ancestors of node." + fixDisallowedAncestors(node); + + // "Let children be node's children." + var children = [].slice.call(node.childNodes); + + // "For each child in children, if child is a prohibited paragraph + // child:" + children.filter(isProhibitedParagraphChild) + .forEach(function(child) { + // "Record the values of the one-node list consisting of child, and + // let values be the result." + var values = recordValues([child]); + + // "Split the parent of the one-node list consisting of child." + splitParent([child]); + + // "Restore the values from values." + restoreValues(values); + }); + + // "Abort these steps." + return; + } + + // "Record the values of the one-node list consisting of node, and let + // values be the result." + var values = recordValues([node]); + + // "While node is not an allowed child of its parent, split the parent of + // the one-node list consisting of node." + while (!isAllowedChild(node, node.parentNode)) { + splitParent([node]); + } + + // "Restore the values from values." + restoreValues(values); +} + +function normalizeSublists(item) { + // "If item is not an li or it is not editable or its parent is not + // editable, abort these steps." + if (!isHtmlElement(item, "LI") + || !isEditable(item) + || !isEditable(item.parentNode)) { + return; + } + + // "Let new item be null." + var newItem = null; + + // "While item has an ol or ul child:" + while ([].some.call(item.childNodes, function (node) { return isHtmlElement(node, ["OL", "UL"]) })) { + // "Let child be the last child of item." + var child = item.lastChild; + + // "If child is an ol or ul, or new item is null and child is a Text + // node whose data consists of zero of more space characters:" + if (isHtmlElement(child, ["OL", "UL"]) + || (!newItem && child.nodeType == Node.TEXT_NODE && /^[ \t\n\f\r]*$/.test(child.data))) { + // "Set new item to null." + newItem = null; + + // "Insert child into the parent of item immediately following + // item, preserving ranges." + movePreservingRanges(child, item.parentNode, 1 + getNodeIndex(item)); + + // "Otherwise:" + } else { + // "If new item is null, let new item be the result of calling + // createElement("li") on the ownerDocument of item, then insert + // new item into the parent of item immediately after item." + if (!newItem) { + newItem = item.ownerDocument.createElement("li"); + item.parentNode.insertBefore(newItem, item.nextSibling); + } + + // "Insert child into new item as its first child, preserving + // ranges." + movePreservingRanges(child, newItem, 0); + } + } +} + +function getSelectionListState() { + // "If the active range is null, return "none"." + if (!getActiveRange()) { + return "none"; + } + + // "Block-extend the active range, and let new range be the result." + var newRange = blockExtend(getActiveRange()); + + // "Let node list be a list of nodes, initially empty." + // + // "For each node contained in new range, append node to node list if the + // last member of node list (if any) is not an ancestor of node; node is + // editable; node is not an indentation element; and node is either an ol + // or ul, or the child of an ol or ul, or an allowed child of "li"." + var nodeList = getContainedNodes(newRange, function(node) { + return isEditable(node) + && !isIndentationElement(node) + && (isHtmlElement(node, ["ol", "ul"]) + || isHtmlElement(node.parentNode, ["ol", "ul"]) + || isAllowedChild(node, "li")); + }); + + // "If node list is empty, return "none"." + if (!nodeList.length) { + return "none"; + } + + // "If every member of node list is either an ol or the child of an ol or + // the child of an li child of an ol, and none is a ul or an ancestor of a + // ul, return "ol"." + if (nodeList.every(function(node) { + return isHtmlElement(node, "ol") + || isHtmlElement(node.parentNode, "ol") + || (isHtmlElement(node.parentNode, "li") && isHtmlElement(node.parentNode.parentNode, "ol")); + }) + && !nodeList.some(function(node) { return isHtmlElement(node, "ul") || ("querySelector" in node && node.querySelector("ul")) })) { + return "ol"; + } + + // "If every member of node list is either a ul or the child of a ul or the + // child of an li child of a ul, and none is an ol or an ancestor of an ol, + // return "ul"." + if (nodeList.every(function(node) { + return isHtmlElement(node, "ul") + || isHtmlElement(node.parentNode, "ul") + || (isHtmlElement(node.parentNode, "li") && isHtmlElement(node.parentNode.parentNode, "ul")); + }) + && !nodeList.some(function(node) { return isHtmlElement(node, "ol") || ("querySelector" in node && node.querySelector("ol")) })) { + return "ul"; + } + + var hasOl = nodeList.some(function(node) { + return isHtmlElement(node, "ol") + || isHtmlElement(node.parentNode, "ol") + || ("querySelector" in node && node.querySelector("ol")) + || (isHtmlElement(node.parentNode, "li") && isHtmlElement(node.parentNode.parentNode, "ol")); + }); + var hasUl = nodeList.some(function(node) { + return isHtmlElement(node, "ul") + || isHtmlElement(node.parentNode, "ul") + || ("querySelector" in node && node.querySelector("ul")) + || (isHtmlElement(node.parentNode, "li") && isHtmlElement(node.parentNode.parentNode, "ul")); + }); + // "If some member of node list is either an ol or the child or ancestor of + // an ol or the child of an li child of an ol, and some member of node list + // is either a ul or the child or ancestor of a ul or the child of an li + // child of a ul, return "mixed"." + if (hasOl && hasUl) { + return "mixed"; + } + + // "If some member of node list is either an ol or the child or ancestor of + // an ol or the child of an li child of an ol, return "mixed ol"." + if (hasOl) { + return "mixed ol"; + } + + // "If some member of node list is either a ul or the child or ancestor of + // a ul or the child of an li child of a ul, return "mixed ul"." + if (hasUl) { + return "mixed ul"; + } + + // "Return "none"." + return "none"; +} + +function getAlignmentValue(node) { + // "While node is neither null nor an Element, or it is an Element but its + // "display" property has resolved value "inline" or "none", set node to + // its parent." + while ((node && node.nodeType != Node.ELEMENT_NODE) + || (node.nodeType == Node.ELEMENT_NODE + && ["inline", "none"].indexOf(getComputedStyle(node).display) != -1)) { + node = node.parentNode; + } + + // "If node is not an Element, return "left"." + if (!node || node.nodeType != Node.ELEMENT_NODE) { + return "left"; + } + + var resolvedValue = getComputedStyle(node).textAlign + // Hack around browser non-standardness + .replace(/^-(moz|webkit)-/, "") + .replace(/^auto$/, "start"); + + // "If node's "text-align" property has resolved value "start", return + // "left" if the directionality of node is "ltr", "right" if it is "rtl"." + if (resolvedValue == "start") { + return getDirectionality(node) == "ltr" ? "left" : "right"; + } + + // "If node's "text-align" property has resolved value "end", return + // "right" if the directionality of node is "ltr", "left" if it is "rtl"." + if (resolvedValue == "end") { + return getDirectionality(node) == "ltr" ? "right" : "left"; + } + + // "If node's "text-align" property has resolved value "center", "justify", + // "left", or "right", return that value." + if (["center", "justify", "left", "right"].indexOf(resolvedValue) != -1) { + return resolvedValue; + } + + // "Return "left"." + return "left"; +} + +function getNextEquivalentPoint(node, offset) { + // "If node's length is zero, return null." + if (getNodeLength(node) == 0) { + return null; + } + + // "If offset is node's length, and node's parent is not null, and node is + // an inline node, return (node's parent, 1 + node's index)." + if (offset == getNodeLength(node) + && node.parentNode + && isInlineNode(node)) { + return [node.parentNode, 1 + getNodeIndex(node)]; + } + + // "If node has a child with index offset, and that child's length is not + // zero, and that child is an inline node, return (that child, 0)." + if (0 <= offset + && offset < node.childNodes.length + && getNodeLength(node.childNodes[offset]) != 0 + && isInlineNode(node.childNodes[offset])) { + return [node.childNodes[offset], 0]; + } + + // "Return null." + return null; +} + +function getPreviousEquivalentPoint(node, offset) { + // "If node's length is zero, return null." + if (getNodeLength(node) == 0) { + return null; + } + + // "If offset is 0, and node's parent is not null, and node is an inline + // node, return (node's parent, node's index)." + if (offset == 0 + && node.parentNode + && isInlineNode(node)) { + return [node.parentNode, getNodeIndex(node)]; + } + + // "If node has a child with index offset − 1, and that child's length is + // not zero, and that child is an inline node, return (that child, that + // child's length)." + if (0 <= offset - 1 + && offset - 1 < node.childNodes.length + && getNodeLength(node.childNodes[offset - 1]) != 0 + && isInlineNode(node.childNodes[offset - 1])) { + return [node.childNodes[offset - 1], getNodeLength(node.childNodes[offset - 1])]; + } + + // "Return null." + return null; +} + +function getFirstEquivalentPoint(node, offset) { + // "While (node, offset)'s previous equivalent point is not null, set + // (node, offset) to its previous equivalent point." + var prev; + while (prev = getPreviousEquivalentPoint(node, offset)) { + node = prev[0]; + offset = prev[1]; + } + + // "Return (node, offset)." + return [node, offset]; +} + +function getLastEquivalentPoint(node, offset) { + // "While (node, offset)'s next equivalent point is not null, set (node, + // offset) to its next equivalent point." + var next; + while (next = getNextEquivalentPoint(node, offset)) { + node = next[0]; + offset = next[1]; + } + + // "Return (node, offset)." + return [node, offset]; +} + +//@} +///// Block-extending a range ///// +//@{ + +// "A boundary point (node, offset) is a block start point if either node's +// parent is null and offset is zero; or node has a child with index offset − +// 1, and that child is either a visible block node or a visible br." +function isBlockStartPoint(node, offset) { + return (!node.parentNode && offset == 0) + || (0 <= offset - 1 + && offset - 1 < node.childNodes.length + && isVisible(node.childNodes[offset - 1]) + && (isBlockNode(node.childNodes[offset - 1]) + || isHtmlElement(node.childNodes[offset - 1], "br"))); +} + +// "A boundary point (node, offset) is a block end point if either node's +// parent is null and offset is node's length; or node has a child with index +// offset, and that child is a visible block node." +function isBlockEndPoint(node, offset) { + return (!node.parentNode && offset == getNodeLength(node)) + || (offset < node.childNodes.length + && isVisible(node.childNodes[offset]) + && isBlockNode(node.childNodes[offset])); +} + +// "A boundary point is a block boundary point if it is either a block start +// point or a block end point." +function isBlockBoundaryPoint(node, offset) { + return isBlockStartPoint(node, offset) + || isBlockEndPoint(node, offset); +} + +function blockExtend(range) { + // "Let start node, start offset, end node, and end offset be the start + // and end nodes and offsets of the range." + var startNode = range.startContainer; + var startOffset = range.startOffset; + var endNode = range.endContainer; + var endOffset = range.endOffset; + + // "If some ancestor container of start node is an li, set start offset to + // the index of the last such li in tree order, and set start node to that + // li's parent." + var liAncestors = getAncestors(startNode).concat(startNode) + .filter(function(ancestor) { return isHtmlElement(ancestor, "li") }) + .slice(-1); + if (liAncestors.length) { + startOffset = getNodeIndex(liAncestors[0]); + startNode = liAncestors[0].parentNode; + } + + // "If (start node, start offset) is not a block start point, repeat the + // following steps:" + if (!isBlockStartPoint(startNode, startOffset)) do { + // "If start offset is zero, set it to start node's index, then set + // start node to its parent." + if (startOffset == 0) { + startOffset = getNodeIndex(startNode); + startNode = startNode.parentNode; + + // "Otherwise, subtract one from start offset." + } else { + startOffset--; + } + + // "If (start node, start offset) is a block boundary point, break from + // this loop." + } while (!isBlockBoundaryPoint(startNode, startOffset)); + + // "While start offset is zero and start node's parent is not null, set + // start offset to start node's index, then set start node to its parent." + while (startOffset == 0 + && startNode.parentNode) { + startOffset = getNodeIndex(startNode); + startNode = startNode.parentNode; + } + + // "If some ancestor container of end node is an li, set end offset to one + // plus the index of the last such li in tree order, and set end node to + // that li's parent." + var liAncestors = getAncestors(endNode).concat(endNode) + .filter(function(ancestor) { return isHtmlElement(ancestor, "li") }) + .slice(-1); + if (liAncestors.length) { + endOffset = 1 + getNodeIndex(liAncestors[0]); + endNode = liAncestors[0].parentNode; + } + + // "If (end node, end offset) is not a block end point, repeat the + // following steps:" + if (!isBlockEndPoint(endNode, endOffset)) do { + // "If end offset is end node's length, set it to one plus end node's + // index, then set end node to its parent." + if (endOffset == getNodeLength(endNode)) { + endOffset = 1 + getNodeIndex(endNode); + endNode = endNode.parentNode; + + // "Otherwise, add one to end offset. + } else { + endOffset++; + } + + // "If (end node, end offset) is a block boundary point, break from + // this loop." + } while (!isBlockBoundaryPoint(endNode, endOffset)); + + // "While end offset is end node's length and end node's parent is not + // null, set end offset to one plus end node's index, then set end node to + // its parent." + while (endOffset == getNodeLength(endNode) + && endNode.parentNode) { + endOffset = 1 + getNodeIndex(endNode); + endNode = endNode.parentNode; + } + + // "Let new range be a new range whose start and end nodes and offsets + // are start node, start offset, end node, and end offset." + var newRange = startNode.ownerDocument.createRange(); + newRange.setStart(startNode, startOffset); + newRange.setEnd(endNode, endOffset); + + // "Return new range." + return newRange; +} + +function followsLineBreak(node) { + // "Let offset be zero." + var offset = 0; + + // "While (node, offset) is not a block boundary point:" + while (!isBlockBoundaryPoint(node, offset)) { + // "If node has a visible child with index offset minus one, return + // false." + if (0 <= offset - 1 + && offset - 1 < node.childNodes.length + && isVisible(node.childNodes[offset - 1])) { + return false; + } + + // "If offset is zero or node has no children, set offset to node's + // index, then set node to its parent." + if (offset == 0 + || !node.hasChildNodes()) { + offset = getNodeIndex(node); + node = node.parentNode; + + // "Otherwise, set node to its child with index offset minus one, then + // set offset to node's length." + } else { + node = node.childNodes[offset - 1]; + offset = getNodeLength(node); + } + } + + // "Return true." + return true; +} + +function precedesLineBreak(node) { + // "Let offset be node's length." + var offset = getNodeLength(node); + + // "While (node, offset) is not a block boundary point:" + while (!isBlockBoundaryPoint(node, offset)) { + // "If node has a visible child with index offset, return false." + if (offset < node.childNodes.length + && isVisible(node.childNodes[offset])) { + return false; + } + + // "If offset is node's length or node has no children, set offset to + // one plus node's index, then set node to its parent." + if (offset == getNodeLength(node) + || !node.hasChildNodes()) { + offset = 1 + getNodeIndex(node); + node = node.parentNode; + + // "Otherwise, set node to its child with index offset and set offset + // to zero." + } else { + node = node.childNodes[offset]; + offset = 0; + } + } + + // "Return true." + return true; +} + +//@} +///// Recording and restoring overrides ///// +//@{ + +function recordCurrentOverrides() { + // "Let overrides be a list of (string, string or boolean) ordered pairs, + // initially empty." + var overrides = []; + + // "If there is a value override for "createLink", add ("createLink", value + // override for "createLink") to overrides." + if (getValueOverride("createlink") !== undefined) { + overrides.push(["createlink", getValueOverride("createlink")]); + } + + // "For each command in the list "bold", "italic", "strikethrough", + // "subscript", "superscript", "underline", in order: if there is a state + // override for command, add (command, command's state override) to + // overrides." + ["bold", "italic", "strikethrough", "subscript", "superscript", + "underline"].forEach(function(command) { + if (getStateOverride(command) !== undefined) { + overrides.push([command, getStateOverride(command)]); + } + }); + + // "For each command in the list "fontName", "fontSize", "foreColor", + // "hiliteColor", in order: if there is a value override for command, add + // (command, command's value override) to overrides." + ["fontname", "fontsize", "forecolor", + "hilitecolor"].forEach(function(command) { + if (getValueOverride(command) !== undefined) { + overrides.push([command, getValueOverride(command)]); + } + }); + + // "Return overrides." + return overrides; +} + +function recordCurrentStatesAndValues() { + // "Let overrides be a list of (string, string or boolean) ordered pairs, + // initially empty." + var overrides = []; + + // "Let node be the first formattable node effectively contained in the + // active range, or null if there is none." + var node = getAllEffectivelyContainedNodes(getActiveRange()) + .filter(isFormattableNode)[0]; + + // "If node is null, return overrides." + if (!node) { + return overrides; + } + + // "Add ("createLink", node's effective command value for "createLink") to + // overrides." + overrides.push(["createlink", getEffectiveCommandValue(node, "createlink")]); + + // "For each command in the list "bold", "italic", "strikethrough", + // "subscript", "superscript", "underline", in order: if node's effective + // command value for command is one of its inline command activated values, + // add (command, true) to overrides, and otherwise add (command, false) to + // overrides." + ["bold", "italic", "strikethrough", "subscript", "superscript", + "underline"].forEach(function(command) { + if (commands[command].inlineCommandActivatedValues + .indexOf(getEffectiveCommandValue(node, command)) != -1) { + overrides.push([command, true]); + } else { + overrides.push([command, false]); + } + }); + + // "For each command in the list "fontName", "foreColor", "hiliteColor", in + // order: add (command, command's value) to overrides." + ["fontname", "fontsize", "forecolor", "hilitecolor"].forEach(function(command) { + overrides.push([command, commands[command].value()]); + }); + + // "Add ("fontSize", node's effective command value for "fontSize") to + // overrides." + overrides.push(["fontsize", getEffectiveCommandValue(node, "fontsize")]); + + // "Return overrides." + return overrides; +} + +function restoreStatesAndValues(overrides) { + // "Let node be the first formattable node effectively contained in the + // active range, or null if there is none." + var node = getAllEffectivelyContainedNodes(getActiveRange()) + .filter(isFormattableNode)[0]; + + // "If node is not null, then for each (command, override) pair in + // overrides, in order:" + if (node) { + for (var i = 0; i < overrides.length; i++) { + var command = overrides[i][0]; + var override = overrides[i][1]; + + // "If override is a boolean, and queryCommandState(command) + // returns something different from override, take the action for + // command, with value equal to the empty string." + if (typeof override == "boolean" + && myQueryCommandState(command) != override) { + commands[command].action(""); + + // "Otherwise, if override is a string, and command is neither + // "createLink" nor "fontSize", and queryCommandValue(command) + // returns something not equivalent to override, take the action + // for command, with value equal to override." + } else if (typeof override == "string" + && command != "createlink" + && command != "fontsize" + && !areEquivalentValues(command, myQueryCommandValue(command), override)) { + commands[command].action(override); + + // "Otherwise, if override is a string; and command is + // "createLink"; and either there is a value override for + // "createLink" that is not equal to override, or there is no value + // override for "createLink" and node's effective command value for + // "createLink" is not equal to override: take the action for + // "createLink", with value equal to override." + } else if (typeof override == "string" + && command == "createlink" + && ( + ( + getValueOverride("createlink") !== undefined + && getValueOverride("createlink") !== override + ) || ( + getValueOverride("createlink") === undefined + && getEffectiveCommandValue(node, "createlink") !== override + ) + )) { + commands.createlink.action(override); + + // "Otherwise, if override is a string; and command is "fontSize"; + // and either there is a value override for "fontSize" that is not + // equal to override, or there is no value override for "fontSize" + // and node's effective command value for "fontSize" is not loosely + // equivalent to override:" + } else if (typeof override == "string" + && command == "fontsize" + && ( + ( + getValueOverride("fontsize") !== undefined + && getValueOverride("fontsize") !== override + ) || ( + getValueOverride("fontsize") === undefined + && !areLooselyEquivalentValues(command, getEffectiveCommandValue(node, "fontsize"), override) + ) + )) { + // "Convert override to an integer number of pixels, and set + // override to the legacy font size for the result." + override = getLegacyFontSize(override); + + // "Take the action for "fontSize", with value equal to + // override." + commands.fontsize.action(override); + + // "Otherwise, continue this loop from the beginning." + } else { + continue; + } + + // "Set node to the first formattable node effectively contained in + // the active range, if there is one." + node = getAllEffectivelyContainedNodes(getActiveRange()) + .filter(isFormattableNode)[0] + || node; + } + + // "Otherwise, for each (command, override) pair in overrides, in order:" + } else { + for (var i = 0; i < overrides.length; i++) { + var command = overrides[i][0]; + var override = overrides[i][1]; + + // "If override is a boolean, set the state override for command to + // override." + if (typeof override == "boolean") { + setStateOverride(command, override); + } + + // "If override is a string, set the value override for command to + // override." + if (typeof override == "string") { + setValueOverride(command, override); + } + } + } +} + +//@} +///// Deleting the selection ///// +//@{ + +// The flags argument is a dictionary that can have blockMerging, +// stripWrappers, and/or direction as keys. +function deleteSelection(flags) { + if (flags === undefined) { + flags = {}; + } + + var blockMerging = "blockMerging" in flags ? Boolean(flags.blockMerging) : true; + var stripWrappers = "stripWrappers" in flags ? Boolean(flags.stripWrappers) : true; + var direction = "direction" in flags ? flags.direction : "forward"; + + // "If the active range is null, abort these steps and do nothing." + if (!getActiveRange()) { + return; + } + + // "Canonicalize whitespace at the active range's start." + canonicalizeWhitespace(getActiveRange().startContainer, getActiveRange().startOffset); + + // "Canonicalize whitespace at the active range's end." + canonicalizeWhitespace(getActiveRange().endContainer, getActiveRange().endOffset); + + // "Let (start node, start offset) be the last equivalent point for the + // active range's start." + var start = getLastEquivalentPoint(getActiveRange().startContainer, getActiveRange().startOffset); + var startNode = start[0]; + var startOffset = start[1]; + + // "Let (end node, end offset) be the first equivalent point for the active + // range's end." + var end = getFirstEquivalentPoint(getActiveRange().endContainer, getActiveRange().endOffset); + var endNode = end[0]; + var endOffset = end[1]; + + // "If (end node, end offset) is not after (start node, start offset):" + if (getPosition(endNode, endOffset, startNode, startOffset) !== "after") { + // "If direction is "forward", call collapseToStart() on the context + // object's Selection." + // + // Here and in a few other places, we check rangeCount to work around a + // WebKit bug: it will sometimes incorrectly remove ranges from the + // selection if nodes are removed, so collapseToStart() will throw. + // This will break everything if we're using an actual selection, but + // if getActiveRange() is really just returning globalRange and that's + // all we care about, it will work fine. I only add the extra check + // for errors I actually hit in testing. + if (direction == "forward") { + if (getSelection().rangeCount) { + getSelection().collapseToStart(); + } + getActiveRange().collapse(true); + + // "Otherwise, call collapseToEnd() on the context object's Selection." + } else { + getSelection().collapseToEnd(); + getActiveRange().collapse(false); + } + + // "Abort these steps." + return; + } + + // "If start node is a Text node and start offset is 0, set start offset to + // the index of start node, then set start node to its parent." + if (startNode.nodeType == Node.TEXT_NODE + && startOffset == 0) { + startOffset = getNodeIndex(startNode); + startNode = startNode.parentNode; + } + + // "If end node is a Text node and end offset is its length, set end offset + // to one plus the index of end node, then set end node to its parent." + if (endNode.nodeType == Node.TEXT_NODE + && endOffset == getNodeLength(endNode)) { + endOffset = 1 + getNodeIndex(endNode); + endNode = endNode.parentNode; + } + + // "Call collapse(start node, start offset) on the context object's + // Selection." + getSelection().collapse(startNode, startOffset); + getActiveRange().setStart(startNode, startOffset); + + // "Call extend(end node, end offset) on the context object's Selection." + getSelection().extend(endNode, endOffset); + getActiveRange().setEnd(endNode, endOffset); + + // "Let start block be the active range's start node." + var startBlock = getActiveRange().startContainer; + + // "While start block's parent is in the same editing host and start block + // is an inline node, set start block to its parent." + while (inSameEditingHost(startBlock, startBlock.parentNode) + && isInlineNode(startBlock)) { + startBlock = startBlock.parentNode; + } + + // "If start block is neither a block node nor an editing host, or "span" + // is not an allowed child of start block, or start block is a td or th, + // set start block to null." + if ((!isBlockNode(startBlock) && !isEditingHost(startBlock)) + || !isAllowedChild("span", startBlock) + || isHtmlElement(startBlock, ["td", "th"])) { + startBlock = null; + } + + // "Let end block be the active range's end node." + var endBlock = getActiveRange().endContainer; + + // "While end block's parent is in the same editing host and end block is + // an inline node, set end block to its parent." + while (inSameEditingHost(endBlock, endBlock.parentNode) + && isInlineNode(endBlock)) { + endBlock = endBlock.parentNode; + } + + // "If end block is neither a block node nor an editing host, or "span" is + // not an allowed child of end block, or end block is a td or th, set end + // block to null." + if ((!isBlockNode(endBlock) && !isEditingHost(endBlock)) + || !isAllowedChild("span", endBlock) + || isHtmlElement(endBlock, ["td", "th"])) { + endBlock = null; + } + + // "Record current states and values, and let overrides be the result." + var overrides = recordCurrentStatesAndValues(); + + // "If start node and end node are the same, and start node is an editable + // Text node:" + if (startNode == endNode + && isEditable(startNode) + && startNode.nodeType == Node.TEXT_NODE) { + // "Call deleteData(start offset, end offset − start offset) on start + // node." + startNode.deleteData(startOffset, endOffset - startOffset); + + // "Canonicalize whitespace at (start node, start offset), with fix + // collapsed space false." + canonicalizeWhitespace(startNode, startOffset, false); + + // "If direction is "forward", call collapseToStart() on the context + // object's Selection." + if (direction == "forward") { + if (getSelection().rangeCount) { + getSelection().collapseToStart(); + } + getActiveRange().collapse(true); + + // "Otherwise, call collapseToEnd() on the context object's Selection." + } else { + getSelection().collapseToEnd(); + getActiveRange().collapse(false); + } + + // "Restore states and values from overrides." + restoreStatesAndValues(overrides); + + // "Abort these steps." + return; + } + + // "If start node is an editable Text node, call deleteData() on it, with + // start offset as the first argument and (length of start node − start + // offset) as the second argument." + if (isEditable(startNode) + && startNode.nodeType == Node.TEXT_NODE) { + startNode.deleteData(startOffset, getNodeLength(startNode) - startOffset); + } + + // "Let node list be a list of nodes, initially empty." + // + // "For each node contained in the active range, append node to node list + // if the last member of node list (if any) is not an ancestor of node; + // node is editable; and node is not a thead, tbody, tfoot, tr, th, or td." + var nodeList = getContainedNodes(getActiveRange(), + function(node) { + return isEditable(node) + && !isHtmlElement(node, ["thead", "tbody", "tfoot", "tr", "th", "td"]); + } + ); + + // "For each node in node list:" + for (var i = 0; i < nodeList.length; i++) { + var node = nodeList[i]; + + // "Let parent be the parent of node." + var parent_ = node.parentNode; + + // "Remove node from parent." + parent_.removeChild(node); + + // "If the block node of parent has no visible children, and parent is + // editable or an editing host, call createElement("br") on the context + // object and append the result as the last child of parent." + if (![].some.call(getBlockNodeOf(parent_).childNodes, isVisible) + && (isEditable(parent_) || isEditingHost(parent_))) { + parent_.appendChild(document.createElement("br")); + } + + // "If strip wrappers is true or parent is not an ancestor container of + // start node, while parent is an editable inline node with length 0, + // let grandparent be the parent of parent, then remove parent from + // grandparent, then set parent to grandparent." + if (stripWrappers + || (!isAncestor(parent_, startNode) && parent_ != startNode)) { + while (isEditable(parent_) + && isInlineNode(parent_) + && getNodeLength(parent_) == 0) { + var grandparent = parent_.parentNode; + grandparent.removeChild(parent_); + parent_ = grandparent; + } + } + } + + // "If end node is an editable Text node, call deleteData(0, end offset) on + // it." + if (isEditable(endNode) + && endNode.nodeType == Node.TEXT_NODE) { + endNode.deleteData(0, endOffset); + } + + // "Canonicalize whitespace at the active range's start, with fix collapsed + // space false." + canonicalizeWhitespace(getActiveRange().startContainer, getActiveRange().startOffset, false); + + // "Canonicalize whitespace at the active range's end, with fix collapsed + // space false." + canonicalizeWhitespace(getActiveRange().endContainer, getActiveRange().endOffset, false); + + // "If block merging is false, or start block or end block is null, or + // start block is not in the same editing host as end block, or start block + // and end block are the same:" + if (!blockMerging + || !startBlock + || !endBlock + || !inSameEditingHost(startBlock, endBlock) + || startBlock == endBlock) { + // "If direction is "forward", call collapseToStart() on the context + // object's Selection." + if (direction == "forward") { + if (getSelection().rangeCount) { + getSelection().collapseToStart(); + } + getActiveRange().collapse(true); + + // "Otherwise, call collapseToEnd() on the context object's Selection." + } else { + if (getSelection().rangeCount) { + getSelection().collapseToEnd(); + } + getActiveRange().collapse(false); + } + + // "Restore states and values from overrides." + restoreStatesAndValues(overrides); + + // "Abort these steps." + return; + } + + // "If start block has one child, which is a collapsed block prop, remove + // its child from it." + if (startBlock.children.length == 1 + && isCollapsedBlockProp(startBlock.firstChild)) { + startBlock.removeChild(startBlock.firstChild); + } + + // "If start block is an ancestor of end block:" + if (isAncestor(startBlock, endBlock)) { + // "Let reference node be end block." + var referenceNode = endBlock; + + // "While reference node is not a child of start block, set reference + // node to its parent." + while (referenceNode.parentNode != startBlock) { + referenceNode = referenceNode.parentNode; + } + + // "Call collapse() on the context object's Selection, with first + // argument start block and second argument the index of reference + // node." + getSelection().collapse(startBlock, getNodeIndex(referenceNode)); + getActiveRange().setStart(startBlock, getNodeIndex(referenceNode)); + getActiveRange().collapse(true); + + // "If end block has no children:" + if (!endBlock.hasChildNodes()) { + // "While end block is editable and is the only child of its parent + // and is not a child of start block, let parent equal end block, + // then remove end block from parent, then set end block to + // parent." + while (isEditable(endBlock) + && endBlock.parentNode.childNodes.length == 1 + && endBlock.parentNode != startBlock) { + var parent_ = endBlock; + parent_.removeChild(endBlock); + endBlock = parent_; + } + + // "If end block is editable and is not an inline node, and its + // previousSibling and nextSibling are both inline nodes, call + // createElement("br") on the context object and insert it into end + // block's parent immediately after end block." + if (isEditable(endBlock) + && !isInlineNode(endBlock) + && isInlineNode(endBlock.previousSibling) + && isInlineNode(endBlock.nextSibling)) { + endBlock.parentNode.insertBefore(document.createElement("br"), endBlock.nextSibling); + } + + // "If end block is editable, remove it from its parent." + if (isEditable(endBlock)) { + endBlock.parentNode.removeChild(endBlock); + } + + // "Restore states and values from overrides." + restoreStatesAndValues(overrides); + + // "Abort these steps." + return; + } + + // "If end block's firstChild is not an inline node, restore states and + // values from overrides, then abort these steps." + if (!isInlineNode(endBlock.firstChild)) { + restoreStatesAndValues(overrides); + return; + } + + // "Let children be a list of nodes, initially empty." + var children = []; + + // "Append the first child of end block to children." + children.push(endBlock.firstChild); + + // "While children's last member is not a br, and children's last + // member's nextSibling is an inline node, append children's last + // member's nextSibling to children." + while (!isHtmlElement(children[children.length - 1], "br") + && isInlineNode(children[children.length - 1].nextSibling)) { + children.push(children[children.length - 1].nextSibling); + } + + // "Record the values of children, and let values be the result." + var values = recordValues(children); + + // "While children's first member's parent is not start block, split + // the parent of children." + while (children[0].parentNode != startBlock) { + splitParent(children); + } + + // "If children's first member's previousSibling is an editable br, + // remove that br from its parent." + if (isEditable(children[0].previousSibling) + && isHtmlElement(children[0].previousSibling, "br")) { + children[0].parentNode.removeChild(children[0].previousSibling); + } + + // "Otherwise, if start block is a descendant of end block:" + } else if (isDescendant(startBlock, endBlock)) { + // "Call collapse() on the context object's Selection, with first + // argument start block and second argument start block's length." + getSelection().collapse(startBlock, getNodeLength(startBlock)); + getActiveRange().setStart(startBlock, getNodeLength(startBlock)); + getActiveRange().collapse(true); + + // "Let reference node be start block." + var referenceNode = startBlock; + + // "While reference node is not a child of end block, set reference + // node to its parent." + while (referenceNode.parentNode != endBlock) { + referenceNode = referenceNode.parentNode; + } + + // "If reference node's nextSibling is an inline node and start block's + // lastChild is a br, remove start block's lastChild from it." + if (isInlineNode(referenceNode.nextSibling) + && isHtmlElement(startBlock.lastChild, "br")) { + startBlock.removeChild(startBlock.lastChild); + } + + // "Let nodes to move be a list of nodes, initially empty." + var nodesToMove = []; + + // "If reference node's nextSibling is neither null nor a block node, + // append it to nodes to move." + if (referenceNode.nextSibling + && !isBlockNode(referenceNode.nextSibling)) { + nodesToMove.push(referenceNode.nextSibling); + } + + // "While nodes to move is nonempty and its last member isn't a br and + // its last member's nextSibling is neither null nor a block node, + // append its last member's nextSibling to nodes to move." + if (nodesToMove.length + && !isHtmlElement(nodesToMove[nodesToMove.length - 1], "br") + && nodesToMove[nodesToMove.length - 1].nextSibling + && !isBlockNode(nodesToMove[nodesToMove.length - 1].nextSibling)) { + nodesToMove.push(nodesToMove[nodesToMove.length - 1].nextSibling); + } + + // "Record the values of nodes to move, and let values be the result." + var values = recordValues(nodesToMove); + + // "For each node in nodes to move, append node as the last child of + // start block, preserving ranges." + nodesToMove.forEach(function(node) { + movePreservingRanges(node, startBlock, -1); + }); + + // "Otherwise:" + } else { + // "Call collapse() on the context object's Selection, with first + // argument start block and second argument start block's length." + getSelection().collapse(startBlock, getNodeLength(startBlock)); + getActiveRange().setStart(startBlock, getNodeLength(startBlock)); + getActiveRange().collapse(true); + + // "If end block's firstChild is an inline node and start block's + // lastChild is a br, remove start block's lastChild from it." + if (isInlineNode(endBlock.firstChild) + && isHtmlElement(startBlock.lastChild, "br")) { + startBlock.removeChild(startBlock.lastChild); + } + + // "Record the values of end block's children, and let values be the + // result." + var values = recordValues([].slice.call(endBlock.childNodes)); + + // "While end block has children, append the first child of end block + // to start block, preserving ranges." + while (endBlock.hasChildNodes()) { + movePreservingRanges(endBlock.firstChild, startBlock, -1); + } + + // "While end block has no children, let parent be the parent of end + // block, then remove end block from parent, then set end block to + // parent." + while (!endBlock.hasChildNodes()) { + var parent_ = endBlock.parentNode; + parent_.removeChild(endBlock); + endBlock = parent_; + } + } + + // "Let ancestor be start block." + var ancestor = startBlock; + + // "While ancestor has an inclusive ancestor ol in the same editing host + // whose nextSibling is also an ol in the same editing host, or an + // inclusive ancestor ul in the same editing host whose nextSibling is also + // a ul in the same editing host:" + while (getInclusiveAncestors(ancestor).some(function(node) { + return inSameEditingHost(ancestor, node) + && ( + (isHtmlElement(node, "ol") && isHtmlElement(node.nextSibling, "ol")) + || (isHtmlElement(node, "ul") && isHtmlElement(node.nextSibling, "ul")) + ) && inSameEditingHost(ancestor, node.nextSibling); + })) { + // "While ancestor and its nextSibling are not both ols in the same + // editing host, and are also not both uls in the same editing host, + // set ancestor to its parent." + while (!( + isHtmlElement(ancestor, "ol") + && isHtmlElement(ancestor.nextSibling, "ol") + && inSameEditingHost(ancestor, ancestor.nextSibling) + ) && !( + isHtmlElement(ancestor, "ul") + && isHtmlElement(ancestor.nextSibling, "ul") + && inSameEditingHost(ancestor, ancestor.nextSibling) + )) { + ancestor = ancestor.parentNode; + } + + // "While ancestor's nextSibling has children, append ancestor's + // nextSibling's firstChild as the last child of ancestor, preserving + // ranges." + while (ancestor.nextSibling.hasChildNodes()) { + movePreservingRanges(ancestor.nextSibling.firstChild, ancestor, -1); + } + + // "Remove ancestor's nextSibling from its parent." + ancestor.parentNode.removeChild(ancestor.nextSibling); + } + + // "Restore the values from values." + restoreValues(values); + + // "If start block has no children, call createElement("br") on the context + // object and append the result as the last child of start block." + if (!startBlock.hasChildNodes()) { + startBlock.appendChild(document.createElement("br")); + } + + // "Remove extraneous line breaks at the end of start block." + removeExtraneousLineBreaksAtTheEndOf(startBlock); + + // "Restore states and values from overrides." + restoreStatesAndValues(overrides); +} + + +//@} +///// Splitting a node list's parent ///// +//@{ + +function splitParent(nodeList) { + // "Let original parent be the parent of the first member of node list." + var originalParent = nodeList[0].parentNode; + + // "If original parent is not editable or its parent is null, do nothing + // and abort these steps." + if (!isEditable(originalParent) + || !originalParent.parentNode) { + return; + } + + // "If the first child of original parent is in node list, remove + // extraneous line breaks before original parent." + if (nodeList.indexOf(originalParent.firstChild) != -1) { + removeExtraneousLineBreaksBefore(originalParent); + } + + // "If the first child of original parent is in node list, and original + // parent follows a line break, set follows line break to true. Otherwise, + // set follows line break to false." + var followsLineBreak_ = nodeList.indexOf(originalParent.firstChild) != -1 + && followsLineBreak(originalParent); + + // "If the last child of original parent is in node list, and original + // parent precedes a line break, set precedes line break to true. + // Otherwise, set precedes line break to false." + var precedesLineBreak_ = nodeList.indexOf(originalParent.lastChild) != -1 + && precedesLineBreak(originalParent); + + // "If the first child of original parent is not in node list, but its last + // child is:" + if (nodeList.indexOf(originalParent.firstChild) == -1 + && nodeList.indexOf(originalParent.lastChild) != -1) { + // "For each node in node list, in reverse order, insert node into the + // parent of original parent immediately after original parent, + // preserving ranges." + for (var i = nodeList.length - 1; i >= 0; i--) { + movePreservingRanges(nodeList[i], originalParent.parentNode, 1 + getNodeIndex(originalParent)); + } + + // "If precedes line break is true, and the last member of node list + // does not precede a line break, call createElement("br") on the + // context object and insert the result immediately after the last + // member of node list." + if (precedesLineBreak_ + && !precedesLineBreak(nodeList[nodeList.length - 1])) { + nodeList[nodeList.length - 1].parentNode.insertBefore(document.createElement("br"), nodeList[nodeList.length - 1].nextSibling); + } + + // "Remove extraneous line breaks at the end of original parent." + removeExtraneousLineBreaksAtTheEndOf(originalParent); + + // "Abort these steps." + return; + } + + // "If the first child of original parent is not in node list:" + if (nodeList.indexOf(originalParent.firstChild) == -1) { + // "Let cloned parent be the result of calling cloneNode(false) on + // original parent." + var clonedParent = originalParent.cloneNode(false); + + // "If original parent has an id attribute, unset it." + originalParent.removeAttribute("id"); + + // "Insert cloned parent into the parent of original parent immediately + // before original parent." + originalParent.parentNode.insertBefore(clonedParent, originalParent); + + // "While the previousSibling of the first member of node list is not + // null, append the first child of original parent as the last child of + // cloned parent, preserving ranges." + while (nodeList[0].previousSibling) { + movePreservingRanges(originalParent.firstChild, clonedParent, clonedParent.childNodes.length); + } + } + + // "For each node in node list, insert node into the parent of original + // parent immediately before original parent, preserving ranges." + for (var i = 0; i < nodeList.length; i++) { + movePreservingRanges(nodeList[i], originalParent.parentNode, getNodeIndex(originalParent)); + } + + // "If follows line break is true, and the first member of node list does + // not follow a line break, call createElement("br") on the context object + // and insert the result immediately before the first member of node list." + if (followsLineBreak_ + && !followsLineBreak(nodeList[0])) { + nodeList[0].parentNode.insertBefore(document.createElement("br"), nodeList[0]); + } + + // "If the last member of node list is an inline node other than a br, and + // the first child of original parent is a br, and original parent is not + // an inline node, remove the first child of original parent from original + // parent." + if (isInlineNode(nodeList[nodeList.length - 1]) + && !isHtmlElement(nodeList[nodeList.length - 1], "br") + && isHtmlElement(originalParent.firstChild, "br") + && !isInlineNode(originalParent)) { + originalParent.removeChild(originalParent.firstChild); + } + + // "If original parent has no children:" + if (!originalParent.hasChildNodes()) { + // "Remove original parent from its parent." + originalParent.parentNode.removeChild(originalParent); + + // "If precedes line break is true, and the last member of node list + // does not precede a line break, call createElement("br") on the + // context object and insert the result immediately after the last + // member of node list." + if (precedesLineBreak_ + && !precedesLineBreak(nodeList[nodeList.length - 1])) { + nodeList[nodeList.length - 1].parentNode.insertBefore(document.createElement("br"), nodeList[nodeList.length - 1].nextSibling); + } + + // "Otherwise, remove extraneous line breaks before original parent." + } else { + removeExtraneousLineBreaksBefore(originalParent); + } + + // "If node list's last member's nextSibling is null, but its parent is not + // null, remove extraneous line breaks at the end of node list's last + // member's parent." + if (!nodeList[nodeList.length - 1].nextSibling + && nodeList[nodeList.length - 1].parentNode) { + removeExtraneousLineBreaksAtTheEndOf(nodeList[nodeList.length - 1].parentNode); + } +} + +// "To remove a node node while preserving its descendants, split the parent of +// node's children if it has any. If it has no children, instead remove it from +// its parent." +function removePreservingDescendants(node) { + if (node.hasChildNodes()) { + splitParent([].slice.call(node.childNodes)); + } else { + node.parentNode.removeChild(node); + } +} + + +//@} +///// Canonical space sequences ///// +//@{ + +function canonicalSpaceSequence(n, nonBreakingStart, nonBreakingEnd) { + // "If n is zero, return the empty string." + if (n == 0) { + return ""; + } + + // "If n is one and both non-breaking start and non-breaking end are false, + // return a single space (U+0020)." + if (n == 1 && !nonBreakingStart && !nonBreakingEnd) { + return " "; + } + + // "If n is one, return a single non-breaking space (U+00A0)." + if (n == 1) { + return "\xa0"; + } + + // "Let buffer be the empty string." + var buffer = ""; + + // "If non-breaking start is true, let repeated pair be U+00A0 U+0020. + // Otherwise, let it be U+0020 U+00A0." + var repeatedPair; + if (nonBreakingStart) { + repeatedPair = "\xa0 "; + } else { + repeatedPair = " \xa0"; + } + + // "While n is greater than three, append repeated pair to buffer and + // subtract two from n." + while (n > 3) { + buffer += repeatedPair; + n -= 2; + } + + // "If n is three, append a three-element string to buffer depending on + // non-breaking start and non-breaking end:" + if (n == 3) { + buffer += + !nonBreakingStart && !nonBreakingEnd ? " \xa0 " + : nonBreakingStart && !nonBreakingEnd ? "\xa0\xa0 " + : !nonBreakingStart && nonBreakingEnd ? " \xa0\xa0" + : nonBreakingStart && nonBreakingEnd ? "\xa0 \xa0" + : "impossible"; + + // "Otherwise, append a two-element string to buffer depending on + // non-breaking start and non-breaking end:" + } else { + buffer += + !nonBreakingStart && !nonBreakingEnd ? "\xa0 " + : nonBreakingStart && !nonBreakingEnd ? "\xa0 " + : !nonBreakingStart && nonBreakingEnd ? " \xa0" + : nonBreakingStart && nonBreakingEnd ? "\xa0\xa0" + : "impossible"; + } + + // "Return buffer." + return buffer; +} + +function canonicalizeWhitespace(node, offset, fixCollapsedSpace) { + if (fixCollapsedSpace === undefined) { + // "an optional boolean argument fix collapsed space that defaults to + // true" + fixCollapsedSpace = true; + } + + // "If node is neither editable nor an editing host, abort these steps." + if (!isEditable(node) && !isEditingHost(node)) { + return; + } + + // "Let start node equal node and let start offset equal offset." + var startNode = node; + var startOffset = offset; + + // "Repeat the following steps:" + while (true) { + // "If start node has a child in the same editing host with index start + // offset minus one, set start node to that child, then set start + // offset to start node's length." + if (0 <= startOffset - 1 + && inSameEditingHost(startNode, startNode.childNodes[startOffset - 1])) { + startNode = startNode.childNodes[startOffset - 1]; + startOffset = getNodeLength(startNode); + + // "Otherwise, if start offset is zero and start node does not follow a + // line break and start node's parent is in the same editing host, set + // start offset to start node's index, then set start node to its + // parent." + } else if (startOffset == 0 + && !followsLineBreak(startNode) + && inSameEditingHost(startNode, startNode.parentNode)) { + startOffset = getNodeIndex(startNode); + startNode = startNode.parentNode; + + // "Otherwise, if start node is a Text node and its parent's resolved + // value for "white-space" is neither "pre" nor "pre-wrap" and start + // offset is not zero and the (start offset − 1)st element of start + // node's data is a space (0x0020) or non-breaking space (0x00A0), + // subtract one from start offset." + } else if (startNode.nodeType == Node.TEXT_NODE + && ["pre", "pre-wrap"].indexOf(getComputedStyle(startNode.parentNode).whiteSpace) == -1 + && startOffset != 0 + && /[ \xa0]/.test(startNode.data[startOffset - 1])) { + startOffset--; + + // "Otherwise, break from this loop." + } else { + break; + } + } + + // "Let end node equal start node and end offset equal start offset." + var endNode = startNode; + var endOffset = startOffset; + + // "Let length equal zero." + var length = 0; + + // "Let collapse spaces be true if start offset is zero and start node + // follows a line break, otherwise false." + var collapseSpaces = startOffset == 0 && followsLineBreak(startNode); + + // "Repeat the following steps:" + while (true) { + // "If end node has a child in the same editing host with index end + // offset, set end node to that child, then set end offset to zero." + if (endOffset < endNode.childNodes.length + && inSameEditingHost(endNode, endNode.childNodes[endOffset])) { + endNode = endNode.childNodes[endOffset]; + endOffset = 0; + + // "Otherwise, if end offset is end node's length and end node does not + // precede a line break and end node's parent is in the same editing + // host, set end offset to one plus end node's index, then set end node + // to its parent." + } else if (endOffset == getNodeLength(endNode) + && !precedesLineBreak(endNode) + && inSameEditingHost(endNode, endNode.parentNode)) { + endOffset = 1 + getNodeIndex(endNode); + endNode = endNode.parentNode; + + // "Otherwise, if end node is a Text node and its parent's resolved + // value for "white-space" is neither "pre" nor "pre-wrap" and end + // offset is not end node's length and the end offsetth element of + // end node's data is a space (0x0020) or non-breaking space (0x00A0):" + } else if (endNode.nodeType == Node.TEXT_NODE + && ["pre", "pre-wrap"].indexOf(getComputedStyle(endNode.parentNode).whiteSpace) == -1 + && endOffset != getNodeLength(endNode) + && /[ \xa0]/.test(endNode.data[endOffset])) { + // "If fix collapsed space is true, and collapse spaces is true, + // and the end offsetth code unit of end node's data is a space + // (0x0020): call deleteData(end offset, 1) on end node, then + // continue this loop from the beginning." + if (fixCollapsedSpace + && collapseSpaces + && " " == endNode.data[endOffset]) { + endNode.deleteData(endOffset, 1); + continue; + } + + // "Set collapse spaces to true if the end offsetth element of end + // node's data is a space (0x0020), false otherwise." + collapseSpaces = " " == endNode.data[endOffset]; + + // "Add one to end offset." + endOffset++; + + // "Add one to length." + length++; + + // "Otherwise, break from this loop." + } else { + break; + } + } + + // "If fix collapsed space is true, then while (start node, start offset) + // is before (end node, end offset):" + if (fixCollapsedSpace) { + while (getPosition(startNode, startOffset, endNode, endOffset) == "before") { + // "If end node has a child in the same editing host with index end + // offset − 1, set end node to that child, then set end offset to end + // node's length." + if (0 <= endOffset - 1 + && endOffset - 1 < endNode.childNodes.length + && inSameEditingHost(endNode, endNode.childNodes[endOffset - 1])) { + endNode = endNode.childNodes[endOffset - 1]; + endOffset = getNodeLength(endNode); + + // "Otherwise, if end offset is zero and end node's parent is in the + // same editing host, set end offset to end node's index, then set end + // node to its parent." + } else if (endOffset == 0 + && inSameEditingHost(endNode, endNode.parentNode)) { + endOffset = getNodeIndex(endNode); + endNode = endNode.parentNode; + + // "Otherwise, if end node is a Text node and its parent's resolved + // value for "white-space" is neither "pre" nor "pre-wrap" and end + // offset is end node's length and the last code unit of end node's + // data is a space (0x0020) and end node precedes a line break:" + } else if (endNode.nodeType == Node.TEXT_NODE + && ["pre", "pre-wrap"].indexOf(getComputedStyle(endNode.parentNode).whiteSpace) == -1 + && endOffset == getNodeLength(endNode) + && endNode.data[endNode.data.length - 1] == " " + && precedesLineBreak(endNode)) { + // "Subtract one from end offset." + endOffset--; + + // "Subtract one from length." + length--; + + // "Call deleteData(end offset, 1) on end node." + endNode.deleteData(endOffset, 1); + + // "Otherwise, break from this loop." + } else { + break; + } + } + } + + // "Let replacement whitespace be the canonical space sequence of length + // length. non-breaking start is true if start offset is zero and start + // node follows a line break, and false otherwise. non-breaking end is true + // if end offset is end node's length and end node precedes a line break, + // and false otherwise." + var replacementWhitespace = canonicalSpaceSequence(length, + startOffset == 0 && followsLineBreak(startNode), + endOffset == getNodeLength(endNode) && precedesLineBreak(endNode)); + + // "While (start node, start offset) is before (end node, end offset):" + while (getPosition(startNode, startOffset, endNode, endOffset) == "before") { + // "If start node has a child with index start offset, set start node + // to that child, then set start offset to zero." + if (startOffset < startNode.childNodes.length) { + startNode = startNode.childNodes[startOffset]; + startOffset = 0; + + // "Otherwise, if start node is not a Text node or if start offset is + // start node's length, set start offset to one plus start node's + // index, then set start node to its parent." + } else if (startNode.nodeType != Node.TEXT_NODE + || startOffset == getNodeLength(startNode)) { + startOffset = 1 + getNodeIndex(startNode); + startNode = startNode.parentNode; + + // "Otherwise:" + } else { + // "Remove the first element from replacement whitespace, and let + // element be that element." + var element = replacementWhitespace[0]; + replacementWhitespace = replacementWhitespace.slice(1); + + // "If element is not the same as the start offsetth element of + // start node's data:" + if (element != startNode.data[startOffset]) { + // "Call insertData(start offset, element) on start node." + startNode.insertData(startOffset, element); + + // "Call deleteData(start offset + 1, 1) on start node." + startNode.deleteData(startOffset + 1, 1); + } + + // "Add one to start offset." + startOffset++; + } + } +} + + +//@} +///// Indenting and outdenting ///// +//@{ + +function indentNodes(nodeList) { + // "If node list is empty, do nothing and abort these steps." + if (!nodeList.length) { + return; + } + + // "Let first node be the first member of node list." + var firstNode = nodeList[0]; + + // "If first node's parent is an ol or ul:" + if (isHtmlElement(firstNode.parentNode, ["OL", "UL"])) { + // "Let tag be the local name of the parent of first node." + var tag = firstNode.parentNode.tagName; + + // "Wrap node list, with sibling criteria returning true for an HTML + // element with local name tag and false otherwise, and new parent + // instructions returning the result of calling createElement(tag) on + // the ownerDocument of first node." + wrap(nodeList, + function(node) { return isHtmlElement(node, tag) }, + function() { return firstNode.ownerDocument.createElement(tag) }); + + // "Abort these steps." + return; + } + + // "Wrap node list, with sibling criteria returning true for a simple + // indentation element and false otherwise, and new parent instructions + // returning the result of calling createElement("blockquote") on the + // ownerDocument of first node. Let new parent be the result." + var newParent = wrap(nodeList, + function(node) { return isSimpleIndentationElement(node) }, + function() { return firstNode.ownerDocument.createElement("blockquote") }); + + // "Fix disallowed ancestors of new parent." + fixDisallowedAncestors(newParent); +} + +function outdentNode(node) { + // "If node is not editable, abort these steps." + if (!isEditable(node)) { + return; + } + + // "If node is a simple indentation element, remove node, preserving its + // descendants. Then abort these steps." + if (isSimpleIndentationElement(node)) { + removePreservingDescendants(node); + return; + } + + // "If node is an indentation element:" + if (isIndentationElement(node)) { + // "Unset the dir attribute of node, if any." + node.removeAttribute("dir"); + + // "Unset the margin, padding, and border CSS properties of node." + node.style.margin = ""; + node.style.padding = ""; + node.style.border = ""; + if (node.getAttribute("style") == "" + // Crazy WebKit bug: https://bugs.webkit.org/show_bug.cgi?id=68551 + || node.getAttribute("style") == "border-width: initial; border-color: initial; ") { + node.removeAttribute("style"); + } + + // "Set the tag name of node to "div"." + setTagName(node, "div"); + + // "Abort these steps." + return; + } + + // "Let current ancestor be node's parent." + var currentAncestor = node.parentNode; + + // "Let ancestor list be a list of nodes, initially empty." + var ancestorList = []; + + // "While current ancestor is an editable Element that is neither a simple + // indentation element nor an ol nor a ul, append current ancestor to + // ancestor list and then set current ancestor to its parent." + while (isEditable(currentAncestor) + && currentAncestor.nodeType == Node.ELEMENT_NODE + && !isSimpleIndentationElement(currentAncestor) + && !isHtmlElement(currentAncestor, ["ol", "ul"])) { + ancestorList.push(currentAncestor); + currentAncestor = currentAncestor.parentNode; + } + + // "If current ancestor is not an editable simple indentation element:" + if (!isEditable(currentAncestor) + || !isSimpleIndentationElement(currentAncestor)) { + // "Let current ancestor be node's parent." + currentAncestor = node.parentNode; + + // "Let ancestor list be the empty list." + ancestorList = []; + + // "While current ancestor is an editable Element that is neither an + // indentation element nor an ol nor a ul, append current ancestor to + // ancestor list and then set current ancestor to its parent." + while (isEditable(currentAncestor) + && currentAncestor.nodeType == Node.ELEMENT_NODE + && !isIndentationElement(currentAncestor) + && !isHtmlElement(currentAncestor, ["ol", "ul"])) { + ancestorList.push(currentAncestor); + currentAncestor = currentAncestor.parentNode; + } + } + + // "If node is an ol or ul and current ancestor is not an editable + // indentation element:" + if (isHtmlElement(node, ["OL", "UL"]) + && (!isEditable(currentAncestor) + || !isIndentationElement(currentAncestor))) { + // "Unset the reversed, start, and type attributes of node, if any are + // set." + node.removeAttribute("reversed"); + node.removeAttribute("start"); + node.removeAttribute("type"); + + // "Let children be the children of node." + var children = [].slice.call(node.childNodes); + + // "If node has attributes, and its parent is not an ol or ul, set the + // tag name of node to "div"." + if (node.attributes.length + && !isHtmlElement(node.parentNode, ["OL", "UL"])) { + setTagName(node, "div"); + + // "Otherwise:" + } else { + // "Record the values of node's children, and let values be the + // result." + var values = recordValues([].slice.call(node.childNodes)); + + // "Remove node, preserving its descendants." + removePreservingDescendants(node); + + // "Restore the values from values." + restoreValues(values); + } + + // "Fix disallowed ancestors of each member of children." + for (var i = 0; i < children.length; i++) { + fixDisallowedAncestors(children[i]); + } + + // "Abort these steps." + return; + } + + // "If current ancestor is not an editable indentation element, abort these + // steps." + if (!isEditable(currentAncestor) + || !isIndentationElement(currentAncestor)) { + return; + } + + // "Append current ancestor to ancestor list." + ancestorList.push(currentAncestor); + + // "Let original ancestor be current ancestor." + var originalAncestor = currentAncestor; + + // "While ancestor list is not empty:" + while (ancestorList.length) { + // "Let current ancestor be the last member of ancestor list." + // + // "Remove the last member of ancestor list." + currentAncestor = ancestorList.pop(); + + // "Let target be the child of current ancestor that is equal to either + // node or the last member of ancestor list." + var target = node.parentNode == currentAncestor + ? node + : ancestorList[ancestorList.length - 1]; + + // "If target is an inline node that is not a br, and its nextSibling + // is a br, remove target's nextSibling from its parent." + if (isInlineNode(target) + && !isHtmlElement(target, "BR") + && isHtmlElement(target.nextSibling, "BR")) { + target.parentNode.removeChild(target.nextSibling); + } + + // "Let preceding siblings be the preceding siblings of target, and let + // following siblings be the following siblings of target." + var precedingSiblings = [].slice.call(currentAncestor.childNodes, 0, getNodeIndex(target)); + var followingSiblings = [].slice.call(currentAncestor.childNodes, 1 + getNodeIndex(target)); + + // "Indent preceding siblings." + indentNodes(precedingSiblings); + + // "Indent following siblings." + indentNodes(followingSiblings); + } + + // "Outdent original ancestor." + outdentNode(originalAncestor); +} + + +//@} +///// Toggling lists ///// +//@{ + +function toggleLists(tagName) { + // "Let mode be "disable" if the selection's list state is tag name, and + // "enable" otherwise." + var mode = getSelectionListState() == tagName ? "disable" : "enable"; + + var range = getActiveRange(); + tagName = tagName.toUpperCase(); + + // "Let other tag name be "ol" if tag name is "ul", and "ul" if tag name is + // "ol"." + var otherTagName = tagName == "OL" ? "UL" : "OL"; + + // "Let items be a list of all lis that are ancestor containers of the + // range's start and/or end node." + // + // It's annoying to get this in tree order using functional stuff without + // doing getDescendants(document), which is slow, so I do it imperatively. + var items = []; + (function(){ + for ( + var ancestorContainer = range.endContainer; + ancestorContainer != range.commonAncestorContainer; + ancestorContainer = ancestorContainer.parentNode + ) { + if (isHtmlElement(ancestorContainer, "li")) { + items.unshift(ancestorContainer); + } + } + for ( + var ancestorContainer = range.startContainer; + ancestorContainer; + ancestorContainer = ancestorContainer.parentNode + ) { + if (isHtmlElement(ancestorContainer, "li")) { + items.unshift(ancestorContainer); + } + } + })(); + + // "For each item in items, normalize sublists of item." + items.forEach(normalizeSublists); + + // "Block-extend the range, and let new range be the result." + var newRange = blockExtend(range); + + // "If mode is "enable", then let lists to convert consist of every + // editable HTML element with local name other tag name that is contained + // in new range, and for every list in lists to convert:" + if (mode == "enable") { + getAllContainedNodes(newRange, function(node) { + return isEditable(node) + && isHtmlElement(node, otherTagName); + }).forEach(function(list) { + // "If list's previousSibling or nextSibling is an editable HTML + // element with local name tag name:" + if ((isEditable(list.previousSibling) && isHtmlElement(list.previousSibling, tagName)) + || (isEditable(list.nextSibling) && isHtmlElement(list.nextSibling, tagName))) { + // "Let children be list's children." + var children = [].slice.call(list.childNodes); + + // "Record the values of children, and let values be the + // result." + var values = recordValues(children); + + // "Split the parent of children." + splitParent(children); + + // "Wrap children, with sibling criteria returning true for an + // HTML element with local name tag name and false otherwise." + wrap(children, function(node) { return isHtmlElement(node, tagName) }); + + // "Restore the values from values." + restoreValues(values); + + // "Otherwise, set the tag name of list to tag name." + } else { + setTagName(list, tagName); + } + }); + } + + // "Let node list be a list of nodes, initially empty." + // + // "For each node node contained in new range, if node is editable; the + // last member of node list (if any) is not an ancestor of node; node + // is not an indentation element; and either node is an ol or ul, or its + // parent is an ol or ul, or it is an allowed child of "li"; then append + // node to node list." + var nodeList = getContainedNodes(newRange, function(node) { + return isEditable(node) + && !isIndentationElement(node) + && (isHtmlElement(node, ["OL", "UL"]) + || isHtmlElement(node.parentNode, ["OL", "UL"]) + || isAllowedChild(node, "li")); + }); + + // "If mode is "enable", remove from node list any ol or ul whose parent is + // not also an ol or ul." + if (mode == "enable") { + nodeList = nodeList.filter(function(node) { + return !isHtmlElement(node, ["ol", "ul"]) + || isHtmlElement(node.parentNode, ["ol", "ul"]); + }); + } + + // "If mode is "disable", then while node list is not empty:" + if (mode == "disable") { + while (nodeList.length) { + // "Let sublist be an empty list of nodes." + var sublist = []; + + // "Remove the first member from node list and append it to + // sublist." + sublist.push(nodeList.shift()); + + // "If the first member of sublist is an HTML element with local + // name tag name, outdent it and continue this loop from the + // beginning." + if (isHtmlElement(sublist[0], tagName)) { + outdentNode(sublist[0]); + continue; + } + + // "While node list is not empty, and the first member of node list + // is the nextSibling of the last member of sublist and is not an + // HTML element with local name tag name, remove the first member + // from node list and append it to sublist." + while (nodeList.length + && nodeList[0] == sublist[sublist.length - 1].nextSibling + && !isHtmlElement(nodeList[0], tagName)) { + sublist.push(nodeList.shift()); + } + + // "Record the values of sublist, and let values be the result." + var values = recordValues(sublist); + + // "Split the parent of sublist." + splitParent(sublist); + + // "Fix disallowed ancestors of each member of sublist." + for (var i = 0; i < sublist.length; i++) { + fixDisallowedAncestors(sublist[i]); + } + + // "Restore the values from values." + restoreValues(values); + } + + // "Otherwise, while node list is not empty:" + } else { + while (nodeList.length) { + // "Let sublist be an empty list of nodes." + var sublist = []; + + // "While either sublist is empty, or node list is not empty and + // its first member is the nextSibling of sublist's last member:" + while (!sublist.length + || (nodeList.length + && nodeList[0] == sublist[sublist.length - 1].nextSibling)) { + // "If node list's first member is a p or div, set the tag name + // of node list's first member to "li", and append the result + // to sublist. Remove the first member from node list." + if (isHtmlElement(nodeList[0], ["p", "div"])) { + sublist.push(setTagName(nodeList[0], "li")); + nodeList.shift(); + + // "Otherwise, if the first member of node list is an li or ol + // or ul, remove it from node list and append it to sublist." + } else if (isHtmlElement(nodeList[0], ["li", "ol", "ul"])) { + sublist.push(nodeList.shift()); + + // "Otherwise:" + } else { + // "Let nodes to wrap be a list of nodes, initially empty." + var nodesToWrap = []; + + // "While nodes to wrap is empty, or node list is not empty + // and its first member is the nextSibling of nodes to + // wrap's last member and the first member of node list is + // an inline node and the last member of nodes to wrap is + // an inline node other than a br, remove the first member + // from node list and append it to nodes to wrap." + while (!nodesToWrap.length + || (nodeList.length + && nodeList[0] == nodesToWrap[nodesToWrap.length - 1].nextSibling + && isInlineNode(nodeList[0]) + && isInlineNode(nodesToWrap[nodesToWrap.length - 1]) + && !isHtmlElement(nodesToWrap[nodesToWrap.length - 1], "br"))) { + nodesToWrap.push(nodeList.shift()); + } + + // "Wrap nodes to wrap, with new parent instructions + // returning the result of calling createElement("li") on + // the context object. Append the result to sublist." + sublist.push(wrap(nodesToWrap, + undefined, + function() { return document.createElement("li") })); + } + } + + // "If sublist's first member's parent is an HTML element with + // local name tag name, or if every member of sublist is an ol or + // ul, continue this loop from the beginning." + if (isHtmlElement(sublist[0].parentNode, tagName) + || sublist.every(function(node) { return isHtmlElement(node, ["ol", "ul"]) })) { + continue; + } + + // "If sublist's first member's parent is an HTML element with + // local name other tag name:" + if (isHtmlElement(sublist[0].parentNode, otherTagName)) { + // "Record the values of sublist, and let values be the + // result." + var values = recordValues(sublist); + + // "Split the parent of sublist." + splitParent(sublist); + + // "Wrap sublist, with sibling criteria returning true for an + // HTML element with local name tag name and false otherwise, + // and new parent instructions returning the result of calling + // createElement(tag name) on the context object." + wrap(sublist, + function(node) { return isHtmlElement(node, tagName) }, + function() { return document.createElement(tagName) }); + + // "Restore the values from values." + restoreValues(values); + + // "Continue this loop from the beginning." + continue; + } + + // "Wrap sublist, with sibling criteria returning true for an HTML + // element with local name tag name and false otherwise, and new + // parent instructions being the following:" + // . . . + // "Fix disallowed ancestors of the previous step's result." + fixDisallowedAncestors(wrap(sublist, + function(node) { return isHtmlElement(node, tagName) }, + function() { + // "If sublist's first member's parent is not an editable + // simple indentation element, or sublist's first member's + // parent's previousSibling is not an editable HTML element + // with local name tag name, call createElement(tag name) + // on the context object and return the result." + if (!isEditable(sublist[0].parentNode) + || !isSimpleIndentationElement(sublist[0].parentNode) + || !isEditable(sublist[0].parentNode.previousSibling) + || !isHtmlElement(sublist[0].parentNode.previousSibling, tagName)) { + return document.createElement(tagName); + } + + // "Let list be sublist's first member's parent's + // previousSibling." + var list = sublist[0].parentNode.previousSibling; + + // "Normalize sublists of list's lastChild." + normalizeSublists(list.lastChild); + + // "If list's lastChild is not an editable HTML element + // with local name tag name, call createElement(tag name) + // on the context object, and append the result as the last + // child of list." + if (!isEditable(list.lastChild) + || !isHtmlElement(list.lastChild, tagName)) { + list.appendChild(document.createElement(tagName)); + } + + // "Return the last child of list." + return list.lastChild; + } + )); + } + } +} + + +//@} +///// Justifying the selection ///// +//@{ + +function justifySelection(alignment) { + // "Block-extend the active range, and let new range be the result." + var newRange = blockExtend(globalRange); + + // "Let element list be a list of all editable Elements contained in new + // range that either has an attribute in the HTML namespace whose local + // name is "align", or has a style attribute that sets "text-align", or is + // a center." + var elementList = getAllContainedNodes(newRange, function(node) { + return node.nodeType == Node.ELEMENT_NODE + && isEditable(node) + // Ignoring namespaces here + && ( + node.hasAttribute("align") + || node.style.textAlign != "" + || isHtmlElement(node, "center") + ); + }); + + // "For each element in element list:" + for (var i = 0; i < elementList.length; i++) { + var element = elementList[i]; + + // "If element has an attribute in the HTML namespace whose local name + // is "align", remove that attribute." + element.removeAttribute("align"); + + // "Unset the CSS property "text-align" on element, if it's set by a + // style attribute." + element.style.textAlign = ""; + if (element.getAttribute("style") == "") { + element.removeAttribute("style"); + } + + // "If element is a div or span or center with no attributes, remove + // it, preserving its descendants." + if (isHtmlElement(element, ["div", "span", "center"]) + && !element.attributes.length) { + removePreservingDescendants(element); + } + + // "If element is a center with one or more attributes, set the tag + // name of element to "div"." + if (isHtmlElement(element, "center") + && element.attributes.length) { + setTagName(element, "div"); + } + } + + // "Block-extend the active range, and let new range be the result." + newRange = blockExtend(globalRange); + + // "Let node list be a list of nodes, initially empty." + var nodeList = []; + + // "For each node node contained in new range, append node to node list if + // the last member of node list (if any) is not an ancestor of node; node + // is editable; node is an allowed child of "div"; and node's alignment + // value is not alignment." + nodeList = getContainedNodes(newRange, function(node) { + return isEditable(node) + && isAllowedChild(node, "div") + && getAlignmentValue(node) != alignment; + }); + + // "While node list is not empty:" + while (nodeList.length) { + // "Let sublist be a list of nodes, initially empty." + var sublist = []; + + // "Remove the first member of node list and append it to sublist." + sublist.push(nodeList.shift()); + + // "While node list is not empty, and the first member of node list is + // the nextSibling of the last member of sublist, remove the first + // member of node list and append it to sublist." + while (nodeList.length + && nodeList[0] == sublist[sublist.length - 1].nextSibling) { + sublist.push(nodeList.shift()); + } + + // "Wrap sublist. Sibling criteria returns true for any div that has + // one or both of the following two attributes and no other attributes, + // and false otherwise:" + // + // * "An align attribute whose value is an ASCII case-insensitive + // match for alignment. + // * "A style attribute which sets exactly one CSS property + // (including unrecognized or invalid attributes), which is + // "text-align", which is set to alignment. + // + // "New parent instructions are to call createElement("div") on the + // context object, then set its CSS property "text-align" to alignment + // and return the result." + wrap(sublist, + function(node) { + return isHtmlElement(node, "div") + && [].every.call(node.attributes, function(attr) { + return (attr.name == "align" && attr.value.toLowerCase() == alignment) + || (attr.name == "style" && node.style.length == 1 && node.style.textAlign == alignment); + }); + }, + function() { + var newParent = document.createElement("div"); + newParent.setAttribute("style", "text-align: " + alignment); + return newParent; + } + ); + } +} + + +//@} +///// Automatic linking ///// +//@{ +// "An autolinkable URL is a string of the following form:" +var autolinkableUrlRegexp = + // "Either a string matching the scheme pattern from RFC 3986 section 3.1 + // followed by the literal string ://, or the literal string mailto:; + // followed by" + // + // From the RFC: scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) + "([a-zA-Z][a-zA-Z0-9+.-]*://|mailto:)" + // "Zero or more characters other than space characters; followed by" + + "[^ \t\n\f\r]*" + // "A character that is not one of the ASCII characters !"'(),-.:;<>[]`{}." + + "[^!\"'(),\\-.:;<>[\\]`{}]"; + +// "A valid e-mail address is a string that matches the ABNF production 1*( +// atext / "." ) "@" ldh-str *( "." ldh-str ) where atext is defined in RFC +// 5322 section 3.2.3, and ldh-str is defined in RFC 1034 section 3.5." +// +// atext: ALPHA / DIGIT / "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / +// "/" / "=" / "?" / "^" / "_" / "`" / "{" / "|" / "}" / "~" +// +//<ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str> +//<let-dig-hyp> ::= <let-dig> | "-" +//<let-dig> ::= <letter> | <digit> +var validEmailRegexp = + "[a-zA-Z0-9!#$%&'*+\\-/=?^_`{|}~.]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*"; + +function autolink(node, endOffset) { + // "While (node, end offset)'s previous equivalent point is not null, set + // it to its previous equivalent point." + while (getPreviousEquivalentPoint(node, endOffset)) { + var prev = getPreviousEquivalentPoint(node, endOffset); + node = prev[0]; + endOffset = prev[1]; + } + + // "If node is not a Text node, or has an a ancestor, do nothing and abort + // these steps." + if (node.nodeType != Node.TEXT_NODE + || getAncestors(node).some(function(ancestor) { return isHtmlElement(ancestor, "a") })) { + return; + } + + // "Let search be the largest substring of node's data whose end is end + // offset and that contains no space characters." + var search = /[^ \t\n\f\r]*$/.exec(node.substringData(0, endOffset))[0]; + + // "If some substring of search is an autolinkable URL:" + if (new RegExp(autolinkableUrlRegexp).test(search)) { + // "While there is no substring of node's data ending at end offset + // that is an autolinkable URL, decrement end offset." + while (!(new RegExp(autolinkableUrlRegexp + "$").test(node.substringData(0, endOffset)))) { + endOffset--; + } + + // "Let start offset be the start index of the longest substring of + // node's data that is an autolinkable URL ending at end offset." + var startOffset = new RegExp(autolinkableUrlRegexp + "$").exec(node.substringData(0, endOffset)).index; + + // "Let href be the substring of node's data starting at start offset + // and ending at end offset." + var href = node.substringData(startOffset, endOffset - startOffset); + + // "Otherwise, if some substring of search is a valid e-mail address:" + } else if (new RegExp(validEmailRegexp).test(search)) { + // "While there is no substring of node's data ending at end offset + // that is a valid e-mail address, decrement end offset." + while (!(new RegExp(validEmailRegexp + "$").test(node.substringData(0, endOffset)))) { + endOffset--; + } + + // "Let start offset be the start index of the longest substring of + // node's data that is a valid e-mail address ending at end offset." + var startOffset = new RegExp(validEmailRegexp + "$").exec(node.substringData(0, endOffset)).index; + + // "Let href be "mailto:" concatenated with the substring of node's + // data starting at start offset and ending at end offset." + var href = "mailto:" + node.substringData(startOffset, endOffset - startOffset); + + // "Otherwise, do nothing and abort these steps." + } else { + return; + } + + // "Let original range be the active range." + var originalRange = getActiveRange(); + + // "Create a new range with start (node, start offset) and end (node, end + // offset), and set the context object's selection's range to it." + var newRange = document.createRange(); + newRange.setStart(node, startOffset); + newRange.setEnd(node, endOffset); + getSelection().removeAllRanges(); + getSelection().addRange(newRange); + globalRange = newRange; + + // "Take the action for "createLink", with value equal to href." + commands.createlink.action(href); + + // "Set the context object's selection's range to original range." + getSelection().removeAllRanges(); + getSelection().addRange(originalRange); + globalRange = originalRange; +} +//@} +///// The delete command ///// +//@{ +commands["delete"] = { + preservesOverrides: true, + action: function() { + // "If the active range is not collapsed, delete the selection and + // return true." + if (!getActiveRange().collapsed) { + deleteSelection(); + return true; + } + + // "Canonicalize whitespace at the active range's start." + canonicalizeWhitespace(getActiveRange().startContainer, getActiveRange().startOffset); + + // "Let node and offset be the active range's start node and offset." + var node = getActiveRange().startContainer; + var offset = getActiveRange().startOffset; + + // "Repeat the following steps:" + while (true) { + // "If offset is zero and node's previousSibling is an editable + // invisible node, remove node's previousSibling from its parent." + if (offset == 0 + && isEditable(node.previousSibling) + && isInvisible(node.previousSibling)) { + node.parentNode.removeChild(node.previousSibling); + + // "Otherwise, if node has a child with index offset − 1 and that + // child is an editable invisible node, remove that child from + // node, then subtract one from offset." + } else if (0 <= offset - 1 + && offset - 1 < node.childNodes.length + && isEditable(node.childNodes[offset - 1]) + && isInvisible(node.childNodes[offset - 1])) { + node.removeChild(node.childNodes[offset - 1]); + offset--; + + // "Otherwise, if offset is zero and node is an inline node, or if + // node is an invisible node, set offset to the index of node, then + // set node to its parent." + } else if ((offset == 0 + && isInlineNode(node)) + || isInvisible(node)) { + offset = getNodeIndex(node); + node = node.parentNode; + + // "Otherwise, if node has a child with index offset − 1 and that + // child is an editable a, remove that child from node, preserving + // its descendants. Then return true." + } else if (0 <= offset - 1 + && offset - 1 < node.childNodes.length + && isEditable(node.childNodes[offset - 1]) + && isHtmlElement(node.childNodes[offset - 1], "a")) { + removePreservingDescendants(node.childNodes[offset - 1]); + return true; + + // "Otherwise, if node has a child with index offset − 1 and that + // child is not a block node or a br or an img, set node to that + // child, then set offset to the length of node." + } else if (0 <= offset - 1 + && offset - 1 < node.childNodes.length + && !isBlockNode(node.childNodes[offset - 1]) + && !isHtmlElement(node.childNodes[offset - 1], ["br", "img"])) { + node = node.childNodes[offset - 1]; + offset = getNodeLength(node); + + // "Otherwise, break from this loop." + } else { + break; + } + } + + // "If node is a Text node and offset is not zero, or if node is a + // block node that has a child with index offset − 1 and that child is + // a br or hr or img:" + if ((node.nodeType == Node.TEXT_NODE + && offset != 0) + || (isBlockNode(node) + && 0 <= offset - 1 + && offset - 1 < node.childNodes.length + && isHtmlElement(node.childNodes[offset - 1], ["br", "hr", "img"]))) { + // "Call collapse(node, offset) on the context object's Selection." + getSelection().collapse(node, offset); + getActiveRange().setEnd(node, offset); + + // "Call extend(node, offset − 1) on the context object's + // Selection." + getSelection().extend(node, offset - 1); + getActiveRange().setStart(node, offset - 1); + + // "Delete the selection." + deleteSelection(); + + // "Return true." + return true; + } + + // "If node is an inline node, return true." + if (isInlineNode(node)) { + return true; + } + + // "If node is an li or dt or dd and is the first child of its parent, + // and offset is zero:" + if (isHtmlElement(node, ["li", "dt", "dd"]) + && node == node.parentNode.firstChild + && offset == 0) { + // "Let items be a list of all lis that are ancestors of node." + // + // Remember, must be in tree order. + var items = []; + for (var ancestor = node.parentNode; ancestor; ancestor = ancestor.parentNode) { + if (isHtmlElement(ancestor, "li")) { + items.unshift(ancestor); + } + } + + // "Normalize sublists of each item in items." + for (var i = 0; i < items.length; i++) { + normalizeSublists(items[i]); + } + + // "Record the values of the one-node list consisting of node, and + // let values be the result." + var values = recordValues([node]); + + // "Split the parent of the one-node list consisting of node." + splitParent([node]); + + // "Restore the values from values." + restoreValues(values); + + // "If node is a dd or dt, and it is not an allowed child of any of + // its ancestors in the same editing host, set the tag name of node + // to the default single-line container name and let node be the + // result." + if (isHtmlElement(node, ["dd", "dt"]) + && getAncestors(node).every(function(ancestor) { + return !inSameEditingHost(node, ancestor) + || !isAllowedChild(node, ancestor) + })) { + node = setTagName(node, defaultSingleLineContainerName); + } + + // "Fix disallowed ancestors of node." + fixDisallowedAncestors(node); + + // "Return true." + return true; + } + + // "Let start node equal node and let start offset equal offset." + var startNode = node; + var startOffset = offset; + + // "Repeat the following steps:" + while (true) { + // "If start offset is zero, set start offset to the index of start + // node and then set start node to its parent." + if (startOffset == 0) { + startOffset = getNodeIndex(startNode); + startNode = startNode.parentNode; + + // "Otherwise, if start node has an editable invisible child with + // index start offset minus one, remove it from start node and + // subtract one from start offset." + } else if (0 <= startOffset - 1 + && startOffset - 1 < startNode.childNodes.length + && isEditable(startNode.childNodes[startOffset - 1]) + && isInvisible(startNode.childNodes[startOffset - 1])) { + startNode.removeChild(startNode.childNodes[startOffset - 1]); + startOffset--; + + // "Otherwise, break from this loop." + } else { + break; + } + } + + // "If offset is zero, and node has an editable ancestor container in + // the same editing host that's an indentation element:" + if (offset == 0 + && getAncestors(node).concat(node).filter(function(ancestor) { + return isEditable(ancestor) + && inSameEditingHost(ancestor, node) + && isIndentationElement(ancestor); + }).length) { + // "Block-extend the range whose start and end are both (node, 0), + // and let new range be the result." + var newRange = document.createRange(); + newRange.setStart(node, 0); + newRange = blockExtend(newRange); + + // "Let node list be a list of nodes, initially empty." + // + // "For each node current node contained in new range, append + // current node to node list if the last member of node list (if + // any) is not an ancestor of current node, and current node is + // editable but has no editable descendants." + var nodeList = getContainedNodes(newRange, function(currentNode) { + return isEditable(currentNode) + && !hasEditableDescendants(currentNode); + }); + + // "Outdent each node in node list." + for (var i = 0; i < nodeList.length; i++) { + outdentNode(nodeList[i]); + } + + // "Return true." + return true; + } + + // "If the child of start node with index start offset is a table, + // return true." + if (isHtmlElement(startNode.childNodes[startOffset], "table")) { + return true; + } + + // "If start node has a child with index start offset − 1, and that + // child is a table:" + if (0 <= startOffset - 1 + && startOffset - 1 < startNode.childNodes.length + && isHtmlElement(startNode.childNodes[startOffset - 1], "table")) { + // "Call collapse(start node, start offset − 1) on the context + // object's Selection." + getSelection().collapse(startNode, startOffset - 1); + getActiveRange().setStart(startNode, startOffset - 1); + + // "Call extend(start node, start offset) on the context object's + // Selection." + getSelection().extend(startNode, startOffset); + getActiveRange().setEnd(startNode, startOffset); + + // "Return true." + return true; + } + + // "If offset is zero; and either the child of start node with index + // start offset minus one is an hr, or the child is a br whose + // previousSibling is either a br or not an inline node:" + if (offset == 0 + && (isHtmlElement(startNode.childNodes[startOffset - 1], "hr") + || ( + isHtmlElement(startNode.childNodes[startOffset - 1], "br") + && ( + isHtmlElement(startNode.childNodes[startOffset - 1].previousSibling, "br") + || !isInlineNode(startNode.childNodes[startOffset - 1].previousSibling) + ) + ) + )) { + // "Call collapse(start node, start offset − 1) on the context + // object's Selection." + getSelection().collapse(startNode, startOffset - 1); + getActiveRange().setStart(startNode, startOffset - 1); + + // "Call extend(start node, start offset) on the context object's + // Selection." + getSelection().extend(startNode, startOffset); + getActiveRange().setEnd(startNode, startOffset); + + // "Delete the selection." + deleteSelection(); + + // "Call collapse(node, offset) on the Selection." + getSelection().collapse(node, offset); + getActiveRange().setStart(node, offset); + getActiveRange().collapse(true); + + // "Return true." + return true; + } + + // "If the child of start node with index start offset is an li or dt + // or dd, and that child's firstChild is an inline node, and start + // offset is not zero:" + if (isHtmlElement(startNode.childNodes[startOffset], ["li", "dt", "dd"]) + && isInlineNode(startNode.childNodes[startOffset].firstChild) + && startOffset != 0) { + // "Let previous item be the child of start node with index start + // offset minus one." + var previousItem = startNode.childNodes[startOffset - 1]; + + // "If previous item's lastChild is an inline node other than a br, + // call createElement("br") on the context object and append the + // result as the last child of previous item." + if (isInlineNode(previousItem.lastChild) + && !isHtmlElement(previousItem.lastChild, "br")) { + previousItem.appendChild(document.createElement("br")); + } + + // "If previous item's lastChild is an inline node, call + // createElement("br") on the context object and append the result + // as the last child of previous item." + if (isInlineNode(previousItem.lastChild)) { + previousItem.appendChild(document.createElement("br")); + } + } + + // "If start node's child with index start offset is an li or dt or dd, + // and that child's previousSibling is also an li or dt or dd:" + if (isHtmlElement(startNode.childNodes[startOffset], ["li", "dt", "dd"]) + && isHtmlElement(startNode.childNodes[startOffset].previousSibling, ["li", "dt", "dd"])) { + // "Call cloneRange() on the active range, and let original range + // be the result." + // + // We need to add it to extraRanges so it will actually get updated + // when moving preserving ranges. + var originalRange = getActiveRange().cloneRange(); + extraRanges.push(originalRange); + + // "Set start node to its child with index start offset − 1." + startNode = startNode.childNodes[startOffset - 1]; + + // "Set start offset to start node's length." + startOffset = getNodeLength(startNode); + + // "Set node to start node's nextSibling." + node = startNode.nextSibling; + + // "Call collapse(start node, start offset) on the context object's + // Selection." + getSelection().collapse(startNode, startOffset); + getActiveRange().setStart(startNode, startOffset); + + // "Call extend(node, 0) on the context object's Selection." + getSelection().extend(node, 0); + getActiveRange().setEnd(node, 0); + + // "Delete the selection." + deleteSelection(); + + // "Call removeAllRanges() on the context object's Selection." + getSelection().removeAllRanges(); + + // "Call addRange(original range) on the context object's + // Selection." + getSelection().addRange(originalRange); + getActiveRange().setStart(originalRange.startContainer, originalRange.startOffset); + getActiveRange().setEnd(originalRange.endContainer, originalRange.endOffset); + + // "Return true." + extraRanges.pop(); + return true; + } + + // "While start node has a child with index start offset minus one:" + while (0 <= startOffset - 1 + && startOffset - 1 < startNode.childNodes.length) { + // "If start node's child with index start offset minus one is + // editable and invisible, remove it from start node, then subtract + // one from start offset." + if (isEditable(startNode.childNodes[startOffset - 1]) + && isInvisible(startNode.childNodes[startOffset - 1])) { + startNode.removeChild(startNode.childNodes[startOffset - 1]); + startOffset--; + + // "Otherwise, set start node to its child with index start offset + // minus one, then set start offset to the length of start node." + } else { + startNode = startNode.childNodes[startOffset - 1]; + startOffset = getNodeLength(startNode); + } + } + + // "Call collapse(start node, start offset) on the context object's + // Selection." + getSelection().collapse(startNode, startOffset); + getActiveRange().setStart(startNode, startOffset); + + // "Call extend(node, offset) on the context object's Selection." + getSelection().extend(node, offset); + getActiveRange().setEnd(node, offset); + + // "Delete the selection, with direction "backward"." + deleteSelection({direction: "backward"}); + + // "Return true." + return true; + } +}; + +//@} +///// The formatBlock command ///// +//@{ +// "A formattable block name is "address", "dd", "div", "dt", "h1", "h2", "h3", +// "h4", "h5", "h6", "p", or "pre"." +var formattableBlockNames = ["address", "dd", "div", "dt", "h1", "h2", "h3", + "h4", "h5", "h6", "p", "pre"]; + +commands.formatblock = { + preservesOverrides: true, + action: function(value) { + // "If value begins with a "<" character and ends with a ">" character, + // remove the first and last characters from it." + if (/^<.*>$/.test(value)) { + value = value.slice(1, -1); + } + + // "Let value be converted to ASCII lowercase." + value = value.toLowerCase(); + + // "If value is not a formattable block name, return false." + if (formattableBlockNames.indexOf(value) == -1) { + return false; + } + + // "Block-extend the active range, and let new range be the result." + var newRange = blockExtend(getActiveRange()); + + // "Let node list be an empty list of nodes." + // + // "For each node node contained in new range, append node to node list + // if it is editable, the last member of original node list (if any) is + // not an ancestor of node, node is either a non-list single-line + // container or an allowed child of "p" or a dd or dt, and node is not + // the ancestor of a prohibited paragraph child." + var nodeList = getContainedNodes(newRange, function(node) { + return isEditable(node) + && (isNonListSingleLineContainer(node) + || isAllowedChild(node, "p") + || isHtmlElement(node, ["dd", "dt"])) + && !getDescendants(node).some(isProhibitedParagraphChild); + }); + + // "Record the values of node list, and let values be the result." + var values = recordValues(nodeList); + + // "For each node in node list, while node is the descendant of an + // editable HTML element in the same editing host, whose local name is + // a formattable block name, and which is not the ancestor of a + // prohibited paragraph child, split the parent of the one-node list + // consisting of node." + for (var i = 0; i < nodeList.length; i++) { + var node = nodeList[i]; + while (getAncestors(node).some(function(ancestor) { + return isEditable(ancestor) + && inSameEditingHost(ancestor, node) + && isHtmlElement(ancestor, formattableBlockNames) + && !getDescendants(ancestor).some(isProhibitedParagraphChild); + })) { + splitParent([node]); + } + } + + // "Restore the values from values." + restoreValues(values); + + // "While node list is not empty:" + while (nodeList.length) { + var sublist; + + // "If the first member of node list is a single-line + // container:" + if (isSingleLineContainer(nodeList[0])) { + // "Let sublist be the children of the first member of node + // list." + sublist = [].slice.call(nodeList[0].childNodes); + + // "Record the values of sublist, and let values be the + // result." + var values = recordValues(sublist); + + // "Remove the first member of node list from its parent, + // preserving its descendants." + removePreservingDescendants(nodeList[0]); + + // "Restore the values from values." + restoreValues(values); + + // "Remove the first member from node list." + nodeList.shift(); + + // "Otherwise:" + } else { + // "Let sublist be an empty list of nodes." + sublist = []; + + // "Remove the first member of node list and append it to + // sublist." + sublist.push(nodeList.shift()); + + // "While node list is not empty, and the first member of + // node list is the nextSibling of the last member of + // sublist, and the first member of node list is not a + // single-line container, and the last member of sublist is + // not a br, remove the first member of node list and + // append it to sublist." + while (nodeList.length + && nodeList[0] == sublist[sublist.length - 1].nextSibling + && !isSingleLineContainer(nodeList[0]) + && !isHtmlElement(sublist[sublist.length - 1], "BR")) { + sublist.push(nodeList.shift()); + } + } + + // "Wrap sublist. If value is "div" or "p", sibling criteria + // returns false; otherwise it returns true for an HTML element + // with local name value and no attributes, and false otherwise. + // New parent instructions return the result of running + // createElement(value) on the context object. Then fix disallowed + // ancestors of the result." + fixDisallowedAncestors(wrap(sublist, + ["div", "p"].indexOf(value) == - 1 + ? function(node) { return isHtmlElement(node, value) && !node.attributes.length } + : function() { return false }, + function() { return document.createElement(value) })); + } + + // "Return true." + return true; + }, indeterm: function() { + // "If the active range is null, return false." + if (!getActiveRange()) { + return false; + } + + // "Block-extend the active range, and let new range be the result." + var newRange = blockExtend(getActiveRange()); + + // "Let node list be all visible editable nodes that are contained in + // new range and have no children." + var nodeList = getAllContainedNodes(newRange, function(node) { + return isVisible(node) + && isEditable(node) + && !node.hasChildNodes(); + }); + + // "If node list is empty, return false." + if (!nodeList.length) { + return false; + } + + // "Let type be null." + var type = null; + + // "For each node in node list:" + for (var i = 0; i < nodeList.length; i++) { + var node = nodeList[i]; + + // "While node's parent is editable and in the same editing host as + // node, and node is not an HTML element whose local name is a + // formattable block name, set node to its parent." + while (isEditable(node.parentNode) + && inSameEditingHost(node, node.parentNode) + && !isHtmlElement(node, formattableBlockNames)) { + node = node.parentNode; + } + + // "Let current type be the empty string." + var currentType = ""; + + // "If node is an editable HTML element whose local name is a + // formattable block name, and node is not the ancestor of a + // prohibited paragraph child, set current type to node's local + // name." + if (isEditable(node) + && isHtmlElement(node, formattableBlockNames) + && !getDescendants(node).some(isProhibitedParagraphChild)) { + currentType = node.tagName; + } + + // "If type is null, set type to current type." + if (type === null) { + type = currentType; + + // "Otherwise, if type does not equal current type, return true." + } else if (type != currentType) { + return true; + } + } + + // "Return false." + return false; + }, value: function() { + // "If the active range is null, return the empty string." + if (!getActiveRange()) { + return ""; + } + + // "Block-extend the active range, and let new range be the result." + var newRange = blockExtend(getActiveRange()); + + // "Let node be the first visible editable node that is contained in + // new range and has no children. If there is no such node, return the + // empty string." + var nodes = getAllContainedNodes(newRange, function(node) { + return isVisible(node) + && isEditable(node) + && !node.hasChildNodes(); + }); + if (!nodes.length) { + return ""; + } + var node = nodes[0]; + + // "While node's parent is editable and in the same editing host as + // node, and node is not an HTML element whose local name is a + // formattable block name, set node to its parent." + while (isEditable(node.parentNode) + && inSameEditingHost(node, node.parentNode) + && !isHtmlElement(node, formattableBlockNames)) { + node = node.parentNode; + } + + // "If node is an editable HTML element whose local name is a + // formattable block name, and node is not the ancestor of a prohibited + // paragraph child, return node's local name, converted to ASCII + // lowercase." + if (isEditable(node) + && isHtmlElement(node, formattableBlockNames) + && !getDescendants(node).some(isProhibitedParagraphChild)) { + return node.tagName.toLowerCase(); + } + + // "Return the empty string." + return ""; + } +}; + +//@} +///// The forwardDelete command ///// +//@{ +commands.forwarddelete = { + preservesOverrides: true, + action: function() { + // "If the active range is not collapsed, delete the selection and + // return true." + if (!getActiveRange().collapsed) { + deleteSelection(); + return true; + } + + // "Canonicalize whitespace at the active range's start." + canonicalizeWhitespace(getActiveRange().startContainer, getActiveRange().startOffset); + + // "Let node and offset be the active range's start node and offset." + var node = getActiveRange().startContainer; + var offset = getActiveRange().startOffset; + + // "Repeat the following steps:" + while (true) { + // "If offset is the length of node and node's nextSibling is an + // editable invisible node, remove node's nextSibling from its + // parent." + if (offset == getNodeLength(node) + && isEditable(node.nextSibling) + && isInvisible(node.nextSibling)) { + node.parentNode.removeChild(node.nextSibling); + + // "Otherwise, if node has a child with index offset and that child + // is an editable invisible node, remove that child from node." + } else if (offset < node.childNodes.length + && isEditable(node.childNodes[offset]) + && isInvisible(node.childNodes[offset])) { + node.removeChild(node.childNodes[offset]); + + // "Otherwise, if offset is the length of node and node is an + // inline node, or if node is invisible, set offset to one plus the + // index of node, then set node to its parent." + } else if ((offset == getNodeLength(node) + && isInlineNode(node)) + || isInvisible(node)) { + offset = 1 + getNodeIndex(node); + node = node.parentNode; + + // "Otherwise, if node has a child with index offset and that child + // is neither a block node nor a br nor an img nor a collapsed + // block prop, set node to that child, then set offset to zero." + } else if (offset < node.childNodes.length + && !isBlockNode(node.childNodes[offset]) + && !isHtmlElement(node.childNodes[offset], ["br", "img"]) + && !isCollapsedBlockProp(node.childNodes[offset])) { + node = node.childNodes[offset]; + offset = 0; + + // "Otherwise, break from this loop." + } else { + break; + } + } + + // "If node is a Text node and offset is not node's length:" + if (node.nodeType == Node.TEXT_NODE + && offset != getNodeLength(node)) { + // "Let end offset be offset plus one." + var endOffset = offset + 1; + + // "While end offset is not node's length and the end offsetth + // element of node's data has general category M when interpreted + // as a Unicode code point, add one to end offset." + // + // TODO: Not even going to try handling anything beyond the most + // basic combining marks, since I couldn't find a good list. I + // special-case a few Hebrew diacritics too to test basic coverage + // of non-Latin stuff. + while (endOffset != node.length + && /^[\u0300-\u036f\u0591-\u05bd\u05c1\u05c2]$/.test(node.data[endOffset])) { + endOffset++; + } + + // "Call collapse(node, offset) on the context object's Selection." + getSelection().collapse(node, offset); + getActiveRange().setStart(node, offset); + + // "Call extend(node, end offset) on the context object's + // Selection." + getSelection().extend(node, endOffset); + getActiveRange().setEnd(node, endOffset); + + // "Delete the selection." + deleteSelection(); + + // "Return true." + return true; + } + + // "If node is an inline node, return true." + if (isInlineNode(node)) { + return true; + } + + // "If node has a child with index offset and that child is a br or hr + // or img, but is not a collapsed block prop:" + if (offset < node.childNodes.length + && isHtmlElement(node.childNodes[offset], ["br", "hr", "img"]) + && !isCollapsedBlockProp(node.childNodes[offset])) { + // "Call collapse(node, offset) on the context object's Selection." + getSelection().collapse(node, offset); + getActiveRange().setStart(node, offset); + + // "Call extend(node, offset + 1) on the context object's + // Selection." + getSelection().extend(node, offset + 1); + getActiveRange().setEnd(node, offset + 1); + + // "Delete the selection." + deleteSelection(); + + // "Return true." + return true; + } + + // "Let end node equal node and let end offset equal offset." + var endNode = node; + var endOffset = offset; + + // "If end node has a child with index end offset, and that child is a + // collapsed block prop, add one to end offset." + if (endOffset < endNode.childNodes.length + && isCollapsedBlockProp(endNode.childNodes[endOffset])) { + endOffset++; + } + + // "Repeat the following steps:" + while (true) { + // "If end offset is the length of end node, set end offset to one + // plus the index of end node and then set end node to its parent." + if (endOffset == getNodeLength(endNode)) { + endOffset = 1 + getNodeIndex(endNode); + endNode = endNode.parentNode; + + // "Otherwise, if end node has a an editable invisible child with + // index end offset, remove it from end node." + } else if (endOffset < endNode.childNodes.length + && isEditable(endNode.childNodes[endOffset]) + && isInvisible(endNode.childNodes[endOffset])) { + endNode.removeChild(endNode.childNodes[endOffset]); + + // "Otherwise, break from this loop." + } else { + break; + } + } + + // "If the child of end node with index end offset minus one is a + // table, return true." + if (isHtmlElement(endNode.childNodes[endOffset - 1], "table")) { + return true; + } + + // "If the child of end node with index end offset is a table:" + if (isHtmlElement(endNode.childNodes[endOffset], "table")) { + // "Call collapse(end node, end offset) on the context object's + // Selection." + getSelection().collapse(endNode, endOffset); + getActiveRange().setStart(endNode, endOffset); + + // "Call extend(end node, end offset + 1) on the context object's + // Selection." + getSelection().extend(endNode, endOffset + 1); + getActiveRange().setEnd(endNode, endOffset + 1); + + // "Return true." + return true; + } + + // "If offset is the length of node, and the child of end node with + // index end offset is an hr or br:" + if (offset == getNodeLength(node) + && isHtmlElement(endNode.childNodes[endOffset], ["br", "hr"])) { + // "Call collapse(end node, end offset) on the context object's + // Selection." + getSelection().collapse(endNode, endOffset); + getActiveRange().setStart(endNode, endOffset); + + // "Call extend(end node, end offset + 1) on the context object's + // Selection." + getSelection().extend(endNode, endOffset + 1); + getActiveRange().setEnd(endNode, endOffset + 1); + + // "Delete the selection." + deleteSelection(); + + // "Call collapse(node, offset) on the Selection." + getSelection().collapse(node, offset); + getActiveRange().setStart(node, offset); + getActiveRange().collapse(true); + + // "Return true." + return true; + } + + // "While end node has a child with index end offset:" + while (endOffset < endNode.childNodes.length) { + // "If end node's child with index end offset is editable and + // invisible, remove it from end node." + if (isEditable(endNode.childNodes[endOffset]) + && isInvisible(endNode.childNodes[endOffset])) { + endNode.removeChild(endNode.childNodes[endOffset]); + + // "Otherwise, set end node to its child with index end offset and + // set end offset to zero." + } else { + endNode = endNode.childNodes[endOffset]; + endOffset = 0; + } + } + + // "Call collapse(node, offset) on the context object's Selection." + getSelection().collapse(node, offset); + getActiveRange().setStart(node, offset); + + // "Call extend(end node, end offset) on the context object's + // Selection." + getSelection().extend(endNode, endOffset); + getActiveRange().setEnd(endNode, endOffset); + + // "Delete the selection." + deleteSelection(); + + // "Return true." + return true; + } +}; + +//@} +///// The indent command ///// +//@{ +commands.indent = { + preservesOverrides: true, + action: function() { + // "Let items be a list of all lis that are ancestor containers of the + // active range's start and/or end node." + // + // Has to be in tree order, remember! + var items = []; + for (var node = getActiveRange().endContainer; node != getActiveRange().commonAncestorContainer; node = node.parentNode) { + if (isHtmlElement(node, "LI")) { + items.unshift(node); + } + } + for (var node = getActiveRange().startContainer; node != getActiveRange().commonAncestorContainer; node = node.parentNode) { + if (isHtmlElement(node, "LI")) { + items.unshift(node); + } + } + for (var node = getActiveRange().commonAncestorContainer; node; node = node.parentNode) { + if (isHtmlElement(node, "LI")) { + items.unshift(node); + } + } + + // "For each item in items, normalize sublists of item." + for (var i = 0; i < items.length; i++) { + normalizeSublists(items[i]); + } + + // "Block-extend the active range, and let new range be the result." + var newRange = blockExtend(getActiveRange()); + + // "Let node list be a list of nodes, initially empty." + var nodeList = []; + + // "For each node node contained in new range, if node is editable and + // is an allowed child of "div" or "ol" and if the last member of node + // list (if any) is not an ancestor of node, append node to node list." + nodeList = getContainedNodes(newRange, function(node) { + return isEditable(node) + && (isAllowedChild(node, "div") + || isAllowedChild(node, "ol")); + }); + + // "If the first visible member of node list is an li whose parent is + // an ol or ul:" + if (isHtmlElement(nodeList.filter(isVisible)[0], "li") + && isHtmlElement(nodeList.filter(isVisible)[0].parentNode, ["ol", "ul"])) { + // "Let sibling be node list's first visible member's + // previousSibling." + var sibling = nodeList.filter(isVisible)[0].previousSibling; + + // "While sibling is invisible, set sibling to its + // previousSibling." + while (isInvisible(sibling)) { + sibling = sibling.previousSibling; + } + + // "If sibling is an li, normalize sublists of sibling." + if (isHtmlElement(sibling, "li")) { + normalizeSublists(sibling); + } + } + + // "While node list is not empty:" + while (nodeList.length) { + // "Let sublist be a list of nodes, initially empty." + var sublist = []; + + // "Remove the first member of node list and append it to sublist." + sublist.push(nodeList.shift()); + + // "While the first member of node list is the nextSibling of the + // last member of sublist, remove the first member of node list and + // append it to sublist." + while (nodeList.length + && nodeList[0] == sublist[sublist.length - 1].nextSibling) { + sublist.push(nodeList.shift()); + } + + // "Indent sublist." + indentNodes(sublist); + } + + // "Return true." + return true; + } +}; + +//@} +///// The insertHorizontalRule command ///// +//@{ +commands.inserthorizontalrule = { + preservesOverrides: true, + action: function() { + // "Let start node, start offset, end node, and end offset be the + // active range's start and end nodes and offsets." + var startNode = getActiveRange().startContainer; + var startOffset = getActiveRange().startOffset; + var endNode = getActiveRange().endContainer; + var endOffset = getActiveRange().endOffset; + + // "While start offset is 0 and start node's parent is not null, set + // start offset to start node's index, then set start node to its + // parent." + while (startOffset == 0 + && startNode.parentNode) { + startOffset = getNodeIndex(startNode); + startNode = startNode.parentNode; + } + + // "While end offset is end node's length, and end node's parent is not + // null, set end offset to one plus end node's index, then set end node + // to its parent." + while (endOffset == getNodeLength(endNode) + && endNode.parentNode) { + endOffset = 1 + getNodeIndex(endNode); + endNode = endNode.parentNode; + } + + // "Call collapse(start node, start offset) on the context object's + // Selection." + getSelection().collapse(startNode, startOffset); + getActiveRange().setStart(startNode, startOffset); + + // "Call extend(end node, end offset) on the context object's + // Selection." + getSelection().extend(endNode, endOffset); + getActiveRange().setEnd(endNode, endOffset); + + // "Delete the selection, with block merging false." + deleteSelection({blockMerging: false}); + + // "If the active range's start node is neither editable nor an editing + // host, return true." + if (!isEditable(getActiveRange().startContainer) + && !isEditingHost(getActiveRange().startContainer)) { + return true; + } + + // "If the active range's start node is a Text node and its start + // offset is zero, call collapse() on the context object's Selection, + // with first argument the active range's start node's parent and + // second argument the active range's start node's index." + if (getActiveRange().startContainer.nodeType == Node.TEXT_NODE + && getActiveRange().startOffset == 0) { + var newNode = getActiveRange().startContainer.parentNode; + var newOffset = getNodeIndex(getActiveRange().startContainer); + getSelection().collapse(newNode, newOffset); + getActiveRange().setStart(newNode, newOffset); + getActiveRange().collapse(true); + } + + // "If the active range's start node is a Text node and its start + // offset is the length of its start node, call collapse() on the + // context object's Selection, with first argument the active range's + // start node's parent, and the second argument one plus the active + // range's start node's index." + if (getActiveRange().startContainer.nodeType == Node.TEXT_NODE + && getActiveRange().startOffset == getNodeLength(getActiveRange().startContainer)) { + var newNode = getActiveRange().startContainer.parentNode; + var newOffset = 1 + getNodeIndex(getActiveRange().startContainer); + getSelection().collapse(newNode, newOffset); + getActiveRange().setStart(newNode, newOffset); + getActiveRange().collapse(true); + } + + // "Let hr be the result of calling createElement("hr") on the + // context object." + var hr = document.createElement("hr"); + + // "Run insertNode(hr) on the active range." + getActiveRange().insertNode(hr); + + // "Fix disallowed ancestors of hr." + fixDisallowedAncestors(hr); + + // "Run collapse() on the context object's Selection, with first + // argument hr's parent and the second argument equal to one plus hr's + // index." + getSelection().collapse(hr.parentNode, 1 + getNodeIndex(hr)); + getActiveRange().setStart(hr.parentNode, 1 + getNodeIndex(hr)); + getActiveRange().collapse(true); + + // "Return true." + return true; + } +}; + +//@} +///// The insertHTML command ///// +//@{ +commands.inserthtml = { + preservesOverrides: true, + action: function(value) { + // "Delete the selection." + deleteSelection(); + + // "If the active range's start node is neither editable nor an editing + // host, return true." + if (!isEditable(getActiveRange().startContainer) + && !isEditingHost(getActiveRange().startContainer)) { + return true; + } + + // "Let frag be the result of calling createContextualFragment(value) + // on the active range." + var frag = getActiveRange().createContextualFragment(value); + + // "Let last child be the lastChild of frag." + var lastChild = frag.lastChild; + + // "If last child is null, return true." + if (!lastChild) { + return true; + } + + // "Let descendants be all descendants of frag." + var descendants = getDescendants(frag); + + // "If the active range's start node is a block node:" + if (isBlockNode(getActiveRange().startContainer)) { + // "Let collapsed block props be all editable collapsed block prop + // children of the active range's start node that have index + // greater than or equal to the active range's start offset." + // + // "For each node in collapsed block props, remove node from its + // parent." + [].filter.call(getActiveRange().startContainer.childNodes, function(node) { + return isEditable(node) + && isCollapsedBlockProp(node) + && getNodeIndex(node) >= getActiveRange().startOffset; + }).forEach(function(node) { + node.parentNode.removeChild(node); + }); + } + + // "Call insertNode(frag) on the active range." + getActiveRange().insertNode(frag); + + // "If the active range's start node is a block node with no visible + // children, call createElement("br") on the context object and append + // the result as the last child of the active range's start node." + if (isBlockNode(getActiveRange().startContainer) + && ![].some.call(getActiveRange().startContainer.childNodes, isVisible)) { + getActiveRange().startContainer.appendChild(document.createElement("br")); + } + + // "Call collapse() on the context object's Selection, with last + // child's parent as the first argument and one plus its index as the + // second." + getActiveRange().setStart(lastChild.parentNode, 1 + getNodeIndex(lastChild)); + getActiveRange().setEnd(lastChild.parentNode, 1 + getNodeIndex(lastChild)); + + // "Fix disallowed ancestors of each member of descendants." + for (var i = 0; i < descendants.length; i++) { + fixDisallowedAncestors(descendants[i]); + } + + // "Return true." + return true; + } +}; + +//@} +///// The insertImage command ///// +//@{ +commands.insertimage = { + preservesOverrides: true, + action: function(value) { + // "If value is the empty string, return false." + if (value === "") { + return false; + } + + // "Delete the selection, with strip wrappers false." + deleteSelection({stripWrappers: false}); + + // "Let range be the active range." + var range = getActiveRange(); + + // "If the active range's start node is neither editable nor an editing + // host, return true." + if (!isEditable(getActiveRange().startContainer) + && !isEditingHost(getActiveRange().startContainer)) { + return true; + } + + // "If range's start node is a block node whose sole child is a br, and + // its start offset is 0, remove its start node's child from it." + if (isBlockNode(range.startContainer) + && range.startContainer.childNodes.length == 1 + && isHtmlElement(range.startContainer.firstChild, "br") + && range.startOffset == 0) { + range.startContainer.removeChild(range.startContainer.firstChild); + } + + // "Let img be the result of calling createElement("img") on the + // context object." + var img = document.createElement("img"); + + // "Run setAttribute("src", value) on img." + img.setAttribute("src", value); + + // "Run insertNode(img) on the range." + range.insertNode(img); + + // "Run collapse() on the Selection, with first argument equal to the + // parent of img and the second argument equal to one plus the index of + // img." + // + // Not everyone actually supports collapse(), so we do it manually + // instead. Also, we need to modify the actual range we're given as + // well, for the sake of autoimplementation.html's range-filling-in. + range.setStart(img.parentNode, 1 + getNodeIndex(img)); + range.setEnd(img.parentNode, 1 + getNodeIndex(img)); + getSelection().removeAllRanges(); + getSelection().addRange(range); + + // IE adds width and height attributes for some reason, so remove those + // to actually do what the spec says. + img.removeAttribute("width"); + img.removeAttribute("height"); + + // "Return true." + return true; + } +}; + +//@} +///// The insertLineBreak command ///// +//@{ +commands.insertlinebreak = { + preservesOverrides: true, + action: function(value) { + // "Delete the selection, with strip wrappers false." + deleteSelection({stripWrappers: false}); + + // "If the active range's start node is neither editable nor an editing + // host, return true." + if (!isEditable(getActiveRange().startContainer) + && !isEditingHost(getActiveRange().startContainer)) { + return true; + } + + // "If the active range's start node is an Element, and "br" is not an + // allowed child of it, return true." + if (getActiveRange().startContainer.nodeType == Node.ELEMENT_NODE + && !isAllowedChild("br", getActiveRange().startContainer)) { + return true; + } + + // "If the active range's start node is not an Element, and "br" is not + // an allowed child of the active range's start node's parent, return + // true." + if (getActiveRange().startContainer.nodeType != Node.ELEMENT_NODE + && !isAllowedChild("br", getActiveRange().startContainer.parentNode)) { + return true; + } + + // "If the active range's start node is a Text node and its start + // offset is zero, call collapse() on the context object's Selection, + // with first argument equal to the active range's start node's parent + // and second argument equal to the active range's start node's index." + if (getActiveRange().startContainer.nodeType == Node.TEXT_NODE + && getActiveRange().startOffset == 0) { + var newNode = getActiveRange().startContainer.parentNode; + var newOffset = getNodeIndex(getActiveRange().startContainer); + getSelection().collapse(newNode, newOffset); + getActiveRange().setStart(newNode, newOffset); + getActiveRange().setEnd(newNode, newOffset); + } + + // "If the active range's start node is a Text node and its start + // offset is the length of its start node, call collapse() on the + // context object's Selection, with first argument equal to the active + // range's start node's parent and second argument equal to one plus + // the active range's start node's index." + if (getActiveRange().startContainer.nodeType == Node.TEXT_NODE + && getActiveRange().startOffset == getNodeLength(getActiveRange().startContainer)) { + var newNode = getActiveRange().startContainer.parentNode; + var newOffset = 1 + getNodeIndex(getActiveRange().startContainer); + getSelection().collapse(newNode, newOffset); + getActiveRange().setStart(newNode, newOffset); + getActiveRange().setEnd(newNode, newOffset); + } + + // "Let br be the result of calling createElement("br") on the context + // object." + var br = document.createElement("br"); + + // "Call insertNode(br) on the active range." + getActiveRange().insertNode(br); + + // "Call collapse() on the context object's Selection, with br's parent + // as the first argument and one plus br's index as the second + // argument." + getSelection().collapse(br.parentNode, 1 + getNodeIndex(br)); + getActiveRange().setStart(br.parentNode, 1 + getNodeIndex(br)); + getActiveRange().setEnd(br.parentNode, 1 + getNodeIndex(br)); + + // "If br is a collapsed line break, call createElement("br") on the + // context object and let extra br be the result, then call + // insertNode(extra br) on the active range." + if (isCollapsedLineBreak(br)) { + getActiveRange().insertNode(document.createElement("br")); + + // Compensate for nonstandard implementations of insertNode + getSelection().collapse(br.parentNode, 1 + getNodeIndex(br)); + getActiveRange().setStart(br.parentNode, 1 + getNodeIndex(br)); + getActiveRange().setEnd(br.parentNode, 1 + getNodeIndex(br)); + } + + // "Return true." + return true; + } +}; + +//@} +///// The insertOrderedList command ///// +//@{ +commands.insertorderedlist = { + preservesOverrides: true, + // "Toggle lists with tag name "ol", then return true." + action: function() { toggleLists("ol"); return true }, + // "True if the selection's list state is "mixed" or "mixed ol", false + // otherwise." + indeterm: function() { return /^mixed( ol)?$/.test(getSelectionListState()) }, + // "True if the selection's list state is "ol", false otherwise." + state: function() { return getSelectionListState() == "ol" }, +}; + +//@} +///// The insertParagraph command ///// +//@{ +commands.insertparagraph = { + preservesOverrides: true, + action: function() { + // "Delete the selection." + deleteSelection(); + + // "If the active range's start node is neither editable nor an editing + // host, return true." + if (!isEditable(getActiveRange().startContainer) + && !isEditingHost(getActiveRange().startContainer)) { + return true; + } + + // "Let node and offset be the active range's start node and offset." + var node = getActiveRange().startContainer; + var offset = getActiveRange().startOffset; + + // "If node is a Text node, and offset is neither 0 nor the length of + // node, call splitText(offset) on node." + if (node.nodeType == Node.TEXT_NODE + && offset != 0 + && offset != getNodeLength(node)) { + node.splitText(offset); + } + + // "If node is a Text node and offset is its length, set offset to one + // plus the index of node, then set node to its parent." + if (node.nodeType == Node.TEXT_NODE + && offset == getNodeLength(node)) { + offset = 1 + getNodeIndex(node); + node = node.parentNode; + } + + // "If node is a Text or Comment node, set offset to the index of node, + // then set node to its parent." + if (node.nodeType == Node.TEXT_NODE + || node.nodeType == Node.COMMENT_NODE) { + offset = getNodeIndex(node); + node = node.parentNode; + } + + // "Call collapse(node, offset) on the context object's Selection." + getSelection().collapse(node, offset); + getActiveRange().setStart(node, offset); + getActiveRange().setEnd(node, offset); + + // "Let container equal node." + var container = node; + + // "While container is not a single-line container, and container's + // parent is editable and in the same editing host as node, set + // container to its parent." + while (!isSingleLineContainer(container) + && isEditable(container.parentNode) + && inSameEditingHost(node, container.parentNode)) { + container = container.parentNode; + } + + // "If container is an editable single-line container in the same + // editing host as node, and its local name is "p" or "div":" + if (isEditable(container) + && isSingleLineContainer(container) + && inSameEditingHost(node, container.parentNode) + && (container.tagName == "P" || container.tagName == "DIV")) { + // "Let outer container equal container." + var outerContainer = container; + + // "While outer container is not a dd or dt or li, and outer + // container's parent is editable, set outer container to its + // parent." + while (!isHtmlElement(outerContainer, ["dd", "dt", "li"]) + && isEditable(outerContainer.parentNode)) { + outerContainer = outerContainer.parentNode; + } + + // "If outer container is a dd or dt or li, set container to outer + // container." + if (isHtmlElement(outerContainer, ["dd", "dt", "li"])) { + container = outerContainer; + } + } + + // "If container is not editable or not in the same editing host as + // node or is not a single-line container:" + if (!isEditable(container) + || !inSameEditingHost(container, node) + || !isSingleLineContainer(container)) { + // "Let tag be the default single-line container name." + var tag = defaultSingleLineContainerName; + + // "Block-extend the active range, and let new range be the + // result." + var newRange = blockExtend(getActiveRange()); + + // "Let node list be a list of nodes, initially empty." + // + // "Append to node list the first node in tree order that is + // contained in new range and is an allowed child of "p", if any." + var nodeList = getContainedNodes(newRange, function(node) { return isAllowedChild(node, "p") }) + .slice(0, 1); + + // "If node list is empty:" + if (!nodeList.length) { + // "If tag is not an allowed child of the active range's start + // node, return true." + if (!isAllowedChild(tag, getActiveRange().startContainer)) { + return true; + } + + // "Set container to the result of calling createElement(tag) + // on the context object." + container = document.createElement(tag); + + // "Call insertNode(container) on the active range." + getActiveRange().insertNode(container); + + // "Call createElement("br") on the context object, and append + // the result as the last child of container." + container.appendChild(document.createElement("br")); + + // "Call collapse(container, 0) on the context object's + // Selection." + getSelection().collapse(container, 0); + getActiveRange().setStart(container, 0); + getActiveRange().setEnd(container, 0); + + // "Return true." + return true; + } + + // "While the nextSibling of the last member of node list is not + // null and is an allowed child of "p", append it to node list." + while (nodeList[nodeList.length - 1].nextSibling + && isAllowedChild(nodeList[nodeList.length - 1].nextSibling, "p")) { + nodeList.push(nodeList[nodeList.length - 1].nextSibling); + } + + // "Wrap node list, with sibling criteria returning false and new + // parent instructions returning the result of calling + // createElement(tag) on the context object. Set container to the + // result." + container = wrap(nodeList, + function() { return false }, + function() { return document.createElement(tag) } + ); + } + + // "If container's local name is "address", "listing", or "pre":" + if (container.tagName == "ADDRESS" + || container.tagName == "LISTING" + || container.tagName == "PRE") { + // "Let br be the result of calling createElement("br") on the + // context object." + var br = document.createElement("br"); + + // "Call insertNode(br) on the active range." + getActiveRange().insertNode(br); + + // "Call collapse(node, offset + 1) on the context object's + // Selection." + getSelection().collapse(node, offset + 1); + getActiveRange().setStart(node, offset + 1); + getActiveRange().setEnd(node, offset + 1); + + // "If br is the last descendant of container, let br be the result + // of calling createElement("br") on the context object, then call + // insertNode(br) on the active range." + // + // Work around browser bugs: some browsers select the + // newly-inserted node, not per spec. + if (!isDescendant(nextNode(br), container)) { + getActiveRange().insertNode(document.createElement("br")); + getSelection().collapse(node, offset + 1); + getActiveRange().setEnd(node, offset + 1); + } + + // "Return true." + return true; + } + + // "If container's local name is "li", "dt", or "dd"; and either it has + // no children or it has a single child and that child is a br:" + if (["LI", "DT", "DD"].indexOf(container.tagName) != -1 + && (!container.hasChildNodes() + || (container.childNodes.length == 1 + && isHtmlElement(container.firstChild, "br")))) { + // "Split the parent of the one-node list consisting of container." + splitParent([container]); + + // "If container has no children, call createElement("br") on the + // context object and append the result as the last child of + // container." + if (!container.hasChildNodes()) { + container.appendChild(document.createElement("br")); + } + + // "If container is a dd or dt, and it is not an allowed child of + // any of its ancestors in the same editing host, set the tag name + // of container to the default single-line container name and let + // container be the result." + if (isHtmlElement(container, ["dd", "dt"]) + && getAncestors(container).every(function(ancestor) { + return !inSameEditingHost(container, ancestor) + || !isAllowedChild(container, ancestor) + })) { + container = setTagName(container, defaultSingleLineContainerName); + } + + // "Fix disallowed ancestors of container." + fixDisallowedAncestors(container); + + // "Return true." + return true; + } + + // "Let new line range be a new range whose start is the same as + // the active range's, and whose end is (container, length of + // container)." + var newLineRange = document.createRange(); + newLineRange.setStart(getActiveRange().startContainer, getActiveRange().startOffset); + newLineRange.setEnd(container, getNodeLength(container)); + + // "While new line range's start offset is zero and its start node is + // not a prohibited paragraph child, set its start to (parent of start + // node, index of start node)." + while (newLineRange.startOffset == 0 + && !isProhibitedParagraphChild(newLineRange.startContainer)) { + newLineRange.setStart(newLineRange.startContainer.parentNode, getNodeIndex(newLineRange.startContainer)); + } + + // "While new line range's start offset is the length of its start node + // and its start node is not a prohibited paragraph child, set its + // start to (parent of start node, 1 + index of start node)." + while (newLineRange.startOffset == getNodeLength(newLineRange.startContainer) + && !isProhibitedParagraphChild(newLineRange.startContainer)) { + newLineRange.setStart(newLineRange.startContainer.parentNode, 1 + getNodeIndex(newLineRange.startContainer)); + } + + // "Let end of line be true if new line range contains either nothing + // or a single br, and false otherwise." + var containedInNewLineRange = getContainedNodes(newLineRange); + var endOfLine = !containedInNewLineRange.length + || (containedInNewLineRange.length == 1 + && isHtmlElement(containedInNewLineRange[0], "br")); + + // "If the local name of container is "h1", "h2", "h3", "h4", "h5", or + // "h6", and end of line is true, let new container name be the default + // single-line container name." + var newContainerName; + if (/^H[1-6]$/.test(container.tagName) + && endOfLine) { + newContainerName = defaultSingleLineContainerName; + + // "Otherwise, if the local name of container is "dt" and end of line + // is true, let new container name be "dd"." + } else if (container.tagName == "DT" + && endOfLine) { + newContainerName = "dd"; + + // "Otherwise, if the local name of container is "dd" and end of line + // is true, let new container name be "dt"." + } else if (container.tagName == "DD" + && endOfLine) { + newContainerName = "dt"; + + // "Otherwise, let new container name be the local name of container." + } else { + newContainerName = container.tagName.toLowerCase(); + } + + // "Let new container be the result of calling createElement(new + // container name) on the context object." + var newContainer = document.createElement(newContainerName); + + // "Copy all attributes of container to new container." + for (var i = 0; i < container.attributes.length; i++) { + newContainer.setAttributeNS(container.attributes[i].namespaceURI, container.attributes[i].name, container.attributes[i].value); + } + + // "If new container has an id attribute, unset it." + newContainer.removeAttribute("id"); + + // "Insert new container into the parent of container immediately after + // container." + container.parentNode.insertBefore(newContainer, container.nextSibling); + + // "Let contained nodes be all nodes contained in new line range." + var containedNodes = getAllContainedNodes(newLineRange); + + // "Let frag be the result of calling extractContents() on new line + // range." + var frag = newLineRange.extractContents(); + + // "Unset the id attribute (if any) of each Element descendant of frag + // that is not in contained nodes." + var descendants = getDescendants(frag); + for (var i = 0; i < descendants.length; i++) { + if (descendants[i].nodeType == Node.ELEMENT_NODE + && containedNodes.indexOf(descendants[i]) == -1) { + descendants[i].removeAttribute("id"); + } + } + + // "Call appendChild(frag) on new container." + newContainer.appendChild(frag); + + // "While container's lastChild is a prohibited paragraph child, set + // container to its lastChild." + while (isProhibitedParagraphChild(container.lastChild)) { + container = container.lastChild; + } + + // "While new container's lastChild is a prohibited paragraph child, + // set new container to its lastChild." + while (isProhibitedParagraphChild(newContainer.lastChild)) { + newContainer = newContainer.lastChild; + } + + // "If container has no visible children, call createElement("br") on + // the context object, and append the result as the last child of + // container." + if (![].some.call(container.childNodes, isVisible)) { + container.appendChild(document.createElement("br")); + } + + // "If new container has no visible children, call createElement("br") + // on the context object, and append the result as the last child of + // new container." + if (![].some.call(newContainer.childNodes, isVisible)) { + newContainer.appendChild(document.createElement("br")); + } + + // "Call collapse(new container, 0) on the context object's Selection." + getSelection().collapse(newContainer, 0); + getActiveRange().setStart(newContainer, 0); + getActiveRange().setEnd(newContainer, 0); + + // "Return true." + return true; + } +}; + +//@} +///// The insertText command ///// +//@{ +commands.inserttext = { + action: function(value) { + // "Delete the selection, with strip wrappers false." + deleteSelection({stripWrappers: false}); + + // "If the active range's start node is neither editable nor an editing + // host, return true." + if (!isEditable(getActiveRange().startContainer) + && !isEditingHost(getActiveRange().startContainer)) { + return true; + } + + // "If value's length is greater than one:" + if (value.length > 1) { + // "For each element el in value, take the action for the + // insertText command, with value equal to el." + for (var i = 0; i < value.length; i++) { + commands.inserttext.action(value[i]); + } + + // "Return true." + return true; + } + + // "If value is the empty string, return true." + if (value == "") { + return true; + } + + // "If value is a newline (U+00A0), take the action for the + // insertParagraph command and return true." + if (value == "\n") { + commands.insertparagraph.action(); + return true; + } + + // "Let node and offset be the active range's start node and offset." + var node = getActiveRange().startContainer; + var offset = getActiveRange().startOffset; + + // "If node has a child whose index is offset − 1, and that child is a + // Text node, set node to that child, then set offset to node's + // length." + if (0 <= offset - 1 + && offset - 1 < node.childNodes.length + && node.childNodes[offset - 1].nodeType == Node.TEXT_NODE) { + node = node.childNodes[offset - 1]; + offset = getNodeLength(node); + } + + // "If node has a child whose index is offset, and that child is a Text + // node, set node to that child, then set offset to zero." + if (0 <= offset + && offset < node.childNodes.length + && node.childNodes[offset].nodeType == Node.TEXT_NODE) { + node = node.childNodes[offset]; + offset = 0; + } + + // "Record current overrides, and let overrides be the result." + var overrides = recordCurrentOverrides(); + + // "Call collapse(node, offset) on the context object's Selection." + getSelection().collapse(node, offset); + getActiveRange().setStart(node, offset); + getActiveRange().setEnd(node, offset); + + // "Canonicalize whitespace at (node, offset)." + canonicalizeWhitespace(node, offset); + + // "Let (node, offset) be the active range's start." + node = getActiveRange().startContainer; + offset = getActiveRange().startOffset; + + // "If node is a Text node:" + if (node.nodeType == Node.TEXT_NODE) { + // "Call insertData(offset, value) on node." + node.insertData(offset, value); + + // "Call collapse(node, offset) on the context object's Selection." + getSelection().collapse(node, offset); + getActiveRange().setStart(node, offset); + + // "Call extend(node, offset + 1) on the context object's + // Selection." + // + // Work around WebKit bug: the extend() can throw if the text we're + // adding is trailing whitespace. + try { getSelection().extend(node, offset + 1); } catch(e) {} + getActiveRange().setEnd(node, offset + 1); + + // "Otherwise:" + } else { + // "If node has only one child, which is a collapsed line break, + // remove its child from it." + // + // FIXME: IE incorrectly returns false here instead of true + // sometimes? + if (node.childNodes.length == 1 + && isCollapsedLineBreak(node.firstChild)) { + node.removeChild(node.firstChild); + } + + // "Let text be the result of calling createTextNode(value) on the + // context object." + var text = document.createTextNode(value); + + // "Call insertNode(text) on the active range." + getActiveRange().insertNode(text); + + // "Call collapse(text, 0) on the context object's Selection." + getSelection().collapse(text, 0); + getActiveRange().setStart(text, 0); + + // "Call extend(text, 1) on the context object's Selection." + getSelection().extend(text, 1); + getActiveRange().setEnd(text, 1); + } + + // "Restore states and values from overrides." + restoreStatesAndValues(overrides); + + // "Canonicalize whitespace at the active range's start, with fix + // collapsed space false." + canonicalizeWhitespace(getActiveRange().startContainer, getActiveRange().startOffset, false); + + // "Canonicalize whitespace at the active range's end, with fix + // collapsed space false." + canonicalizeWhitespace(getActiveRange().endContainer, getActiveRange().endOffset, false); + + // "If value is a space character, autolink the active range's start." + if (/^[ \t\n\f\r]$/.test(value)) { + autolink(getActiveRange().startContainer, getActiveRange().startOffset); + } + + // "Call collapseToEnd() on the context object's Selection." + // + // Work around WebKit bug: sometimes it blows up the selection and + // throws, which we don't want. + try { getSelection().collapseToEnd(); } catch(e) {} + getActiveRange().collapse(false); + + // "Return true." + return true; + } +}; + +//@} +///// The insertUnorderedList command ///// +//@{ +commands.insertunorderedlist = { + preservesOverrides: true, + // "Toggle lists with tag name "ul", then return true." + action: function() { toggleLists("ul"); return true }, + // "True if the selection's list state is "mixed" or "mixed ul", false + // otherwise." + indeterm: function() { return /^mixed( ul)?$/.test(getSelectionListState()) }, + // "True if the selection's list state is "ul", false otherwise." + state: function() { return getSelectionListState() == "ul" }, +}; + +//@} +///// The justifyCenter command ///// +//@{ +commands.justifycenter = { + preservesOverrides: true, + // "Justify the selection with alignment "center", then return true." + action: function() { justifySelection("center"); return true }, + indeterm: function() { + // "Return false if the active range is null. Otherwise, block-extend + // the active range. Return true if among visible editable nodes that + // are contained in the result and have no children, at least one has + // alignment value "center" and at least one does not. Otherwise return + // false." + if (!getActiveRange()) { + return false; + } + var nodes = getAllContainedNodes(blockExtend(getActiveRange()), function(node) { + return isEditable(node) && isVisible(node) && !node.hasChildNodes(); + }); + return nodes.some(function(node) { return getAlignmentValue(node) == "center" }) + && nodes.some(function(node) { return getAlignmentValue(node) != "center" }); + }, state: function() { + // "Return false if the active range is null. Otherwise, block-extend + // the active range. Return true if there is at least one visible + // editable node that is contained in the result and has no children, + // and all such nodes have alignment value "center". Otherwise return + // false." + if (!getActiveRange()) { + return false; + } + var nodes = getAllContainedNodes(blockExtend(getActiveRange()), function(node) { + return isEditable(node) && isVisible(node) && !node.hasChildNodes(); + }); + return nodes.length + && nodes.every(function(node) { return getAlignmentValue(node) == "center" }); + }, value: function() { + // "Return the empty string if the active range is null. Otherwise, + // block-extend the active range, and return the alignment value of the + // first visible editable node that is contained in the result and has + // no children. If there is no such node, return "left"." + if (!getActiveRange()) { + return ""; + } + var nodes = getAllContainedNodes(blockExtend(getActiveRange()), function(node) { + return isEditable(node) && isVisible(node) && !node.hasChildNodes(); + }); + if (nodes.length) { + return getAlignmentValue(nodes[0]); + } else { + return "left"; + } + }, +}; + +//@} +///// The justifyFull command ///// +//@{ +commands.justifyfull = { + preservesOverrides: true, + // "Justify the selection with alignment "justify", then return true." + action: function() { justifySelection("justify"); return true }, + indeterm: function() { + // "Return false if the active range is null. Otherwise, block-extend + // the active range. Return true if among visible editable nodes that + // are contained in the result and have no children, at least one has + // alignment value "justify" and at least one does not. Otherwise + // return false." + if (!getActiveRange()) { + return false; + } + var nodes = getAllContainedNodes(blockExtend(getActiveRange()), function(node) { + return isEditable(node) && isVisible(node) && !node.hasChildNodes(); + }); + return nodes.some(function(node) { return getAlignmentValue(node) == "justify" }) + && nodes.some(function(node) { return getAlignmentValue(node) != "justify" }); + }, state: function() { + // "Return false if the active range is null. Otherwise, block-extend + // the active range. Return true if there is at least one visible + // editable node that is contained in the result and has no children, + // and all such nodes have alignment value "justify". Otherwise return + // false." + if (!getActiveRange()) { + return false; + } + var nodes = getAllContainedNodes(blockExtend(getActiveRange()), function(node) { + return isEditable(node) && isVisible(node) && !node.hasChildNodes(); + }); + return nodes.length + && nodes.every(function(node) { return getAlignmentValue(node) == "justify" }); + }, value: function() { + // "Return the empty string if the active range is null. Otherwise, + // block-extend the active range, and return the alignment value of the + // first visible editable node that is contained in the result and has + // no children. If there is no such node, return "left"." + if (!getActiveRange()) { + return ""; + } + var nodes = getAllContainedNodes(blockExtend(getActiveRange()), function(node) { + return isEditable(node) && isVisible(node) && !node.hasChildNodes(); + }); + if (nodes.length) { + return getAlignmentValue(nodes[0]); + } else { + return "left"; + } + }, +}; + +//@} +///// The justifyLeft command ///// +//@{ +commands.justifyleft = { + preservesOverrides: true, + // "Justify the selection with alignment "left", then return true." + action: function() { justifySelection("left"); return true }, + indeterm: function() { + // "Return false if the active range is null. Otherwise, block-extend + // the active range. Return true if among visible editable nodes that + // are contained in the result and have no children, at least one has + // alignment value "left" and at least one does not. Otherwise return + // false." + if (!getActiveRange()) { + return false; + } + var nodes = getAllContainedNodes(blockExtend(getActiveRange()), function(node) { + return isEditable(node) && isVisible(node) && !node.hasChildNodes(); + }); + return nodes.some(function(node) { return getAlignmentValue(node) == "left" }) + && nodes.some(function(node) { return getAlignmentValue(node) != "left" }); + }, state: function() { + // "Return false if the active range is null. Otherwise, block-extend + // the active range. Return true if there is at least one visible + // editable node that is contained in the result and has no children, + // and all such nodes have alignment value "left". Otherwise return + // false." + if (!getActiveRange()) { + return false; + } + var nodes = getAllContainedNodes(blockExtend(getActiveRange()), function(node) { + return isEditable(node) && isVisible(node) && !node.hasChildNodes(); + }); + return nodes.length + && nodes.every(function(node) { return getAlignmentValue(node) == "left" }); + }, value: function() { + // "Return the empty string if the active range is null. Otherwise, + // block-extend the active range, and return the alignment value of the + // first visible editable node that is contained in the result and has + // no children. If there is no such node, return "left"." + if (!getActiveRange()) { + return ""; + } + var nodes = getAllContainedNodes(blockExtend(getActiveRange()), function(node) { + return isEditable(node) && isVisible(node) && !node.hasChildNodes(); + }); + if (nodes.length) { + return getAlignmentValue(nodes[0]); + } else { + return "left"; + } + }, +}; + +//@} +///// The justifyRight command ///// +//@{ +commands.justifyright = { + preservesOverrides: true, + // "Justify the selection with alignment "right", then return true." + action: function() { justifySelection("right"); return true }, + indeterm: function() { + // "Return false if the active range is null. Otherwise, block-extend + // the active range. Return true if among visible editable nodes that + // are contained in the result and have no children, at least one has + // alignment value "right" and at least one does not. Otherwise return + // false." + if (!getActiveRange()) { + return false; + } + var nodes = getAllContainedNodes(blockExtend(getActiveRange()), function(node) { + return isEditable(node) && isVisible(node) && !node.hasChildNodes(); + }); + return nodes.some(function(node) { return getAlignmentValue(node) == "right" }) + && nodes.some(function(node) { return getAlignmentValue(node) != "right" }); + }, state: function() { + // "Return false if the active range is null. Otherwise, block-extend + // the active range. Return true if there is at least one visible + // editable node that is contained in the result and has no children, + // and all such nodes have alignment value "right". Otherwise return + // false." + if (!getActiveRange()) { + return false; + } + var nodes = getAllContainedNodes(blockExtend(getActiveRange()), function(node) { + return isEditable(node) && isVisible(node) && !node.hasChildNodes(); + }); + return nodes.length + && nodes.every(function(node) { return getAlignmentValue(node) == "right" }); + }, value: function() { + // "Return the empty string if the active range is null. Otherwise, + // block-extend the active range, and return the alignment value of the + // first visible editable node that is contained in the result and has + // no children. If there is no such node, return "left"." + if (!getActiveRange()) { + return ""; + } + var nodes = getAllContainedNodes(blockExtend(getActiveRange()), function(node) { + return isEditable(node) && isVisible(node) && !node.hasChildNodes(); + }); + if (nodes.length) { + return getAlignmentValue(nodes[0]); + } else { + return "left"; + } + }, +}; + +//@} +///// The outdent command ///// +//@{ +commands.outdent = { + preservesOverrides: true, + action: function() { + // "Let items be a list of all lis that are ancestor containers of the + // range's start and/or end node." + // + // It's annoying to get this in tree order using functional stuff + // without doing getDescendants(document), which is slow, so I do it + // imperatively. + var items = []; + (function(){ + for ( + var ancestorContainer = getActiveRange().endContainer; + ancestorContainer != getActiveRange().commonAncestorContainer; + ancestorContainer = ancestorContainer.parentNode + ) { + if (isHtmlElement(ancestorContainer, "li")) { + items.unshift(ancestorContainer); + } + } + for ( + var ancestorContainer = getActiveRange().startContainer; + ancestorContainer; + ancestorContainer = ancestorContainer.parentNode + ) { + if (isHtmlElement(ancestorContainer, "li")) { + items.unshift(ancestorContainer); + } + } + })(); + + // "For each item in items, normalize sublists of item." + items.forEach(normalizeSublists); + + // "Block-extend the active range, and let new range be the result." + var newRange = blockExtend(getActiveRange()); + + // "Let node list be a list of nodes, initially empty." + // + // "For each node node contained in new range, append node to node list + // if the last member of node list (if any) is not an ancestor of node; + // node is editable; and either node has no editable descendants, or is + // an ol or ul, or is an li whose parent is an ol or ul." + var nodeList = getContainedNodes(newRange, function(node) { + return isEditable(node) + && (!getDescendants(node).some(isEditable) + || isHtmlElement(node, ["ol", "ul"]) + || (isHtmlElement(node, "li") && isHtmlElement(node.parentNode, ["ol", "ul"]))); + }); + + // "While node list is not empty:" + while (nodeList.length) { + // "While the first member of node list is an ol or ul or is not + // the child of an ol or ul, outdent it and remove it from node + // list." + while (nodeList.length + && (isHtmlElement(nodeList[0], ["OL", "UL"]) + || !isHtmlElement(nodeList[0].parentNode, ["OL", "UL"]))) { + outdentNode(nodeList.shift()); + } + + // "If node list is empty, break from these substeps." + if (!nodeList.length) { + break; + } + + // "Let sublist be a list of nodes, initially empty." + var sublist = []; + + // "Remove the first member of node list and append it to sublist." + sublist.push(nodeList.shift()); + + // "While the first member of node list is the nextSibling of the + // last member of sublist, and the first member of node list is not + // an ol or ul, remove the first member of node list and append it + // to sublist." + while (nodeList.length + && nodeList[0] == sublist[sublist.length - 1].nextSibling + && !isHtmlElement(nodeList[0], ["OL", "UL"])) { + sublist.push(nodeList.shift()); + } + + // "Record the values of sublist, and let values be the result." + var values = recordValues(sublist); + + // "Split the parent of sublist, with new parent null." + splitParent(sublist); + + // "Fix disallowed ancestors of each member of sublist." + sublist.forEach(fixDisallowedAncestors); + + // "Restore the values from values." + restoreValues(values); + } + + // "Return true." + return true; + } +}; + +//@} + +////////////////////////////////// +///// Miscellaneous commands ///// +////////////////////////////////// + +///// The defaultParagraphSeparator command ///// +//@{ +commands.defaultparagraphseparator = { + action: function(value) { + // "Let value be converted to ASCII lowercase. If value is then equal + // to "p" or "div", set the context object's default single-line + // container name to value and return true. Otherwise, return false." + value = value.toLowerCase(); + if (value == "p" || value == "div") { + defaultSingleLineContainerName = value; + return true; + } + return false; + }, value: function() { + // "Return the context object's default single-line container name." + return defaultSingleLineContainerName; + }, +}; + +//@} +///// The selectAll command ///// +//@{ +commands.selectall = { + // Note, this ignores the whole globalRange/getActiveRange() thing and + // works with actual selections. Not suitable for autoimplementation.html. + action: function() { + // "Let target be the body element of the context object." + var target = document.body; + + // "If target is null, let target be the context object's + // documentElement." + if (!target) { + target = document.documentElement; + } + + // "If target is null, call getSelection() on the context object, and + // call removeAllRanges() on the result." + if (!target) { + getSelection().removeAllRanges(); + + // "Otherwise, call getSelection() on the context object, and call + // selectAllChildren(target) on the result." + } else { + getSelection().selectAllChildren(target); + } + + // "Return true." + return true; + } +}; + +//@} +///// The styleWithCSS command ///// +//@{ +commands.stylewithcss = { + action: function(value) { + // "If value is an ASCII case-insensitive match for the string + // "false", set the CSS styling flag to false. Otherwise, set the + // CSS styling flag to true. Either way, return true." + cssStylingFlag = String(value).toLowerCase() != "false"; + return true; + }, state: function() { return cssStylingFlag } +}; + +//@} +///// The useCSS command ///// +//@{ +commands.usecss = { + action: function(value) { + // "If value is an ASCII case-insensitive match for the string "false", + // set the CSS styling flag to true. Otherwise, set the CSS styling + // flag to false. Either way, return true." + cssStylingFlag = String(value).toLowerCase() == "false"; + return true; + } +}; +//@} + +// Some final setup +//@{ +(function() { +// Opera 11.50 doesn't implement Object.keys, so I have to make an explicit +// temporary, which means I need an extra closure to not leak the temporaries +// into the global namespace. >:( +var commandNames = []; +for (var command in commands) { + commandNames.push(command); +} +commandNames.forEach(function(command) { + // "If a command does not have a relevant CSS property specified, it + // defaults to null." + if (!("relevantCssProperty" in commands[command])) { + commands[command].relevantCssProperty = null; + } + + // "If a command has inline command activated values defined but nothing + // else defines when it is indeterminate, it is indeterminate if among + // formattable nodes effectively contained in the active range, there is at + // least one whose effective command value is one of the given values and + // at least one whose effective command value is not one of the given + // values." + if ("inlineCommandActivatedValues" in commands[command] + && !("indeterm" in commands[command])) { + commands[command].indeterm = function() { + if (!getActiveRange()) { + return false; + } + + var values = getAllEffectivelyContainedNodes(getActiveRange(), isFormattableNode) + .map(function(node) { return getEffectiveCommandValue(node, command) }); + + var matchingValues = values.filter(function(value) { + return commands[command].inlineCommandActivatedValues.indexOf(value) != -1; + }); + + return matchingValues.length >= 1 + && values.length - matchingValues.length >= 1; + }; + } + + // "If a command has inline command activated values defined, its state is + // true if either no formattable node is effectively contained in the + // active range, and the active range's start node's effective command + // value is one of the given values; or if there is at least one + // formattable node effectively contained in the active range, and all of + // them have an effective command value equal to one of the given values." + if ("inlineCommandActivatedValues" in commands[command]) { + commands[command].state = function() { + if (!getActiveRange()) { + return false; + } + + var nodes = getAllEffectivelyContainedNodes(getActiveRange(), isFormattableNode); + + if (nodes.length == 0) { + return commands[command].inlineCommandActivatedValues + .indexOf(getEffectiveCommandValue(getActiveRange().startContainer, command)) != -1; + } else { + return nodes.every(function(node) { + return commands[command].inlineCommandActivatedValues + .indexOf(getEffectiveCommandValue(node, command)) != -1; + }); + } + }; + } + + // "If a command is a standard inline value command, it is indeterminate if + // among formattable nodes that are effectively contained in the active + // range, there are two that have distinct effective command values. Its + // value is the effective command value of the first formattable node that + // is effectively contained in the active range; or if there is no such + // node, the effective command value of the active range's start node; or + // if that is null, the empty string." + if ("standardInlineValueCommand" in commands[command]) { + commands[command].indeterm = function() { + if (!getActiveRange()) { + return false; + } + + var values = getAllEffectivelyContainedNodes(getActiveRange()) + .filter(isFormattableNode) + .map(function(node) { return getEffectiveCommandValue(node, command) }); + for (var i = 1; i < values.length; i++) { + if (values[i] != values[i - 1]) { + return true; + } + } + return false; + }; + + commands[command].value = function() { + if (!getActiveRange()) { + return ""; + } + + var refNode = getAllEffectivelyContainedNodes(getActiveRange(), isFormattableNode)[0]; + + if (typeof refNode == "undefined") { + refNode = getActiveRange().startContainer; + } + + var ret = getEffectiveCommandValue(refNode, command); + if (ret === null) { + return ""; + } + return ret; + }; + } + + // "If a command preserves overrides, then before taking its action, the + // user agent must record current overrides. After taking the action, if + // the active range is collapsed, it must restore states and values from + // the recorded list." + if ("preservesOverrides" in commands[command]) { + var oldAction = commands[command].action; + + commands[command].action = function(value) { + var overrides = recordCurrentOverrides(); + var ret = oldAction(value); + if (getActiveRange().collapsed) { + restoreStatesAndValues(overrides); + } + return ret; + }; + } +}); +})(); +//@} + +// vim: foldmarker=@{,@} foldmethod=marker diff --git a/testing/web-platform/tests/editing/include/manualtest.js b/testing/web-platform/tests/editing/include/manualtest.js new file mode 100644 index 0000000000..504fdae4cc --- /dev/null +++ b/testing/web-platform/tests/editing/include/manualtest.js @@ -0,0 +1,225 @@ +// Initial setup +//@{ +var globalValue; +if (globalValue === undefined) { + globalValue = command in defaultValues ? defaultValues[command] : ""; +} +var keyPrefix = globalValue == "" + ? "manualtest-" + command + "-" + : "manualtest-" + command + "-" + globalValue + "-"; +(function(){ + var manualTests = tests[command] + .map(function(test) { return normalizeTest(command, test) }) + .filter(function(test) { return test[1][1] == globalValue }); + var relevantMultiTests = tests.multitest + .map(function(test) { return normalizeTest("multitest", test) }) + .filter(function(test) { + // We only want multitests if there's exactly one occurrence of the + // command we're testing for, and the value is correct, and that's + // the last command we're testing. Some of these limitations could + // be removed in the future. + return test[test.length - 1][0] === command + && test[test.length - 1][1] === globalValue; + }); + + tests = manualTests.concat(relevantMultiTests); +})(); +//@} + +function clearCachedResults() { +//@{ + for (var key in localStorage) { + if (key.indexOf(keyPrefix) === 0) { + localStorage.removeItem(key); + } + } +} +//@} + +var numManualTests = 0; +var currentTestIdx = null; + +// Make sure styleWithCss is always reset to false at the start of a test run +// (I'm looking at you, Firefox) +try { document.execCommand("stylewithcss", false, "false") } catch(e) {} + +function runTests() { +//@{ + // We don't ask the user to hit a key on all tests, so make sure not to + // claim more tests are going to be run than actually are. + for (var i = 0; i < tests.length; i++) { + if (localStorage.getItem(keyPrefix + JSON.stringify(tests[i])) === null) { + numManualTests++; + } + } + + currentTestIdx = 0; + + var runTestsButton = document.querySelector("#tests input[type=button]"); + runTestsButton.parentNode.removeChild(runTestsButton); + + var addTestButton = document.querySelector("#tests input[type=button]"); + var input = document.querySelector("#tests label input"); + // This code actually focuses and clicks everything because for some + // reason, anything else doesn't work in IE9 . . . + input.value = JSON.stringify(tests[0]); + input.focus(); + addTestButton.click(); +} +//@} + +function addTest() { +//@{ + var tr = doSetup("#tests table", 0); + var input = document.querySelector("#tests label input"); + var test = JSON.parse(input.value); + doInputCell(tr, test, test.length == 2 ? command : "multitest"); + doSpecCell(tr, test, test.length == 2 ? command : "multitest"); + if (localStorage.getItem(keyPrefix + JSON.stringify(test)) !== null) { + // Yay, I get to cheat. Remove the overlay div so the user doesn't + // keep hitting the key, in case it takes a while. + var browserCell = document.createElement("td"); + tr.appendChild(browserCell); + browserCell.innerHTML = localStorage[keyPrefix + JSON.stringify(test)]; + doBrowserCellButton(browserCell, test); + document.getElementById("overlay").style.display = ""; + doSameCell(tr); + runNextTest(test); + } else { + doBrowserCell(tr, test, function() { + doSameCell(tr); + runNextTest(); + }); + } +} +//@} + +function runNextTest() { +//@{ + doTearDown(); + var input = document.querySelector("#tests label input"); + if (currentTestIdx === null + || currentTestIdx + 1 >= tests.length) { + currentTestIdx = null; + document.getElementById("overlay").style.display = ""; + input.value = ""; + return; + } + currentTestIdx++; + input.value = JSON.stringify(tests[currentTestIdx]); + input.focus(); + addTest(); +} +//@} + +function doBrowserCell(tr, test, callback) { +//@{ + var browserCell = document.createElement("td"); + tr.appendChild(browserCell); + + try { + var points = setupCell(browserCell, test[0]); + + var testDiv = browserCell.firstChild; + // Work around weird Firefox bug: + // https://bugzilla.mozilla.org/show_bug.cgi?id=649138 + document.body.appendChild(testDiv); + testDiv.onkeyup = function() { + continueBrowserCell(test, testDiv, browserCell); + callback(); + }; + testDiv.contentEditable = "true"; + testDiv.spellcheck = false; + if (currentTestIdx === null) { + document.getElementById("testcount").style.display = "none"; + } else { + document.getElementById("testcount").style.display = ""; + document.querySelector("#testcount > span").textContent = numManualTests; + numManualTests--; + } + document.getElementById("overlay").style.display = "block"; + testDiv.focus(); + setSelection(points[0], points[1], points[2], points[3]); + // Execute any extra commands beforehand, for multitests + for (var i = 1; i < test.length - 1; i++) { + document.execCommand(test[i][0], false, test[i][1]); + } + } catch (e) { + browserCellException(e, testDiv, browserCell); + callback(); + } +} +//@} + +function continueBrowserCell(test, testDiv, browserCell) { +//@{ + try { + testDiv.contentEditable = "inherit"; + testDiv.removeAttribute("spellcheck"); + var compareDiv1 = testDiv.cloneNode(true); + + if (getSelection().rangeCount) { + addBrackets(getSelection().getRangeAt(0)); + } + browserCell.insertBefore(testDiv, browserCell.firstChild); + + if (!browserCell.childNodes.length == 2) { + throw "The cell didn't have two children. Did something spill outside the test div?"; + } + + compareDiv1.normalize(); + // Sigh, Gecko is crazy + var treeWalker = document.createTreeWalker(compareDiv1, NodeFilter.SHOW_ELEMENT, null, null); + while (treeWalker.nextNode()) { + var remove = [].filter.call(treeWalker.currentNode.attributes, function(attrib) { + return /^_moz_/.test(attrib.name) || attrib.value == "_moz"; + }); + for (var i = 0; i < remove.length; i++) { + treeWalker.currentNode.removeAttribute(remove[i].name); + } + } + var compareDiv2 = compareDiv1.cloneNode(false); + compareDiv2.innerHTML = compareDiv1.innerHTML; + if (!compareDiv1.isEqualNode(compareDiv2) + && compareDiv1.innerHTML != compareDiv2.innerHTML) { + throw "DOM does not round-trip through serialization! " + + compareDiv1.innerHTML + " vs. " + compareDiv2.innerHTML; + } + if (!compareDiv1.isEqualNode(compareDiv2)) { + throw "DOM does not round-trip through serialization (although innerHTML is the same)! " + + compareDiv1.innerHTML; + } + + browserCell.lastChild.textContent = browserCell.firstChild.innerHTML; + } catch (e) { + browserCellException(e, testDiv, browserCell); + } + + localStorage[keyPrefix + JSON.stringify(test)] = browserCell.innerHTML; + + doBrowserCellButton(browserCell, test); +} +//@} + +function doBrowserCellButton(browserCell, test) { +//@{ + var button = document.createElement("button"); + browserCell.lastChild.appendChild(button); + button.textContent = "Redo browser output"; + button.onclick = function() { + localStorage.removeItem(keyPrefix + JSON.stringify(test)); + var tr = browserCell.parentNode; + while (browserCell.nextSibling) { + tr.removeChild(browserCell.nextSibling); + } + tr.removeChild(browserCell); + doBrowserCell(tr, test, function() { + doSameCell(tr); + doTearDown(); + document.getElementById("overlay").style.display = ""; + tr.scrollIntoView(); + }); + }; +} +//@} +// vim: foldmarker=@{,@} foldmethod=marker diff --git a/testing/web-platform/tests/editing/include/reset.css b/testing/web-platform/tests/editing/include/reset.css new file mode 100644 index 0000000000..b711d724c3 --- /dev/null +++ b/testing/web-platform/tests/editing/include/reset.css @@ -0,0 +1,27 @@ +/* Make sure various CSS values are what are expected, so that tests work + * right. */ +body { font-family: serif } +/* http://www.w3.org/Bugs/Public/show_bug.cgi?id=12154 + * https://bugzilla.mozilla.org/show_bug.cgi?id=589124 + * https://bugs.webkit.org/show_bug.cgi?id=56400 */ +b, strong { font-weight: bold } +.bold { font-weight: bold } +.notbold { font-weight: normal } +.underline { text-decoration: underline } +.line-through { text-decoration: line-through } +.underline-and-line-through { text-decoration: underline line-through } +#purple { color: purple } +/* https://bugs.webkit.org/show_bug.cgi?id=56670 */ +dfn { font-style: italic } +/* Opera has weird default blockquote style */ +blockquote { margin: 1em 40px } +/* Some tests assume links are blue, for the sake of argument, but they aren't + * blue in any browser. And :visited definitely isn't blue, except in engines + * like Gecko that lie. + * + * This should really be #00e, probably. See: + * http://www.w3.org/Bugs/Public/show_bug.cgi?id=13330 */ +:link, :visited { color: blue } +/* http://www.w3.org/Bugs/Public/show_bug.cgi?id=14066 + * https://bugs.webkit.org/show_bug.cgi?id=68392 */ +quasit { text-align: inherit } diff --git a/testing/web-platform/tests/editing/include/tests.css b/testing/web-platform/tests/editing/include/tests.css new file mode 100644 index 0000000000..e72f338085 --- /dev/null +++ b/testing/web-platform/tests/editing/include/tests.css @@ -0,0 +1,84 @@ +@import "reset.css"; +.yes { color: green } +.no { color: red } +.maybe { color: orange } +.yes, .no, .maybe { + text-align: center; + vertical-align: middle; + font-size: 3em; + /* Somehow Opera doesn't render the X's if the font is serif, on my + * machine. */ + font-family: sans-serif; + border-color: black; +} +div.alert { + color: red; + font-weight: bold; +} +.extra-results { font-size: small } +.good-result { color: green } +.bad-result { color: red } +body > div > table > tbody > tr > td > div:first-child { + padding-bottom: 0.2em; +} +body > div > table > tbody > tr > td > div:last-child { + padding-top: 0.2em; + border-top: 1px solid black; +} +/* Workaround for browsers that don't treat <wbr> as a line-break opportunity + * (activated via JS feature-detection) */ +body.wbr-workaround > div > table > tbody > tr > td > div:last-child { + word-wrap: break-word; +} +body > div > table > tbody > tr > td > div:last-child { + white-space: pre-wrap; +} +/* Let the rendered HTML line up so it's easier to compare whitespace */ +body > div > table > tbody > tr > td { vertical-align: top } +/* We don't want test cells to not wrap */ +listing, plaintext, pre, xmp { white-space: pre-wrap } +img, video { width: 50px } +body > div > table { + width: 100%; + table-layout: fixed; +} +body > div > table > tbody > tr > td, +body > div > table > tbody > tr > th { + width: 30%; +} +body > div > table > tbody > tr > td:last-child, +body > div > table > tbody > tr > th:last-child { + width: 10%; +} +body > div > p > label > input { width: 30% } +#toolbar { + position: fixed; + top: 0; + left: 0; + right: 0; + height: 1.5em; + background: white; + border-bottom: 2px solid gray; +} +body { + /* So the toolbar doesn't block it */ + margin-top: 2em; +} +/* For easy visibility of nesting */ +ol ol { list-style-type: lower-alpha } +ol ol ol { list-style-type: lower-roman } +/* For manual tests */ +#overlay { + display: none; + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; + color: red; + background: yellow; + font-size: 4em; + font-weight: bold; + text-align: center; + padding: 2em; +} diff --git a/testing/web-platform/tests/editing/include/tests.js b/testing/web-platform/tests/editing/include/tests.js new file mode 100644 index 0000000000..c18aef136b --- /dev/null +++ b/testing/web-platform/tests/editing/include/tests.js @@ -0,0 +1,5756 @@ +// For the original (development) tests, we want to make a bunch of changes to +// the page as it loads. We don't want this for the conformance tests, so let +// them opt out. +if (typeof testsJsLibraryOnly == "undefined" || !testsJsLibraryOnly) { + // Alert the reader of egregious Opera bug that will make the specced + // implementation horribly buggy + //@{ + (function() { + var div = document.createElement("div"); + div.appendChild(document.createElement("br")); + document.body.insertBefore(div, document.body.firstChild); + var range = document.createRange(); + range.setStart(div, 1); + div.insertBefore(document.createElement("p"), div.firstChild); + if (range.startOffset > range.startContainer.childNodes.length) { + var warningDiv = document.createElement("p"); + document.body.insertBefore(warningDiv, document.body.firstChild); + warningDiv.style.fontWeight = "bold"; + warningDiv.style.fontSize = "2em"; + warningDiv.style.color = "red"; + warningDiv.innerHTML = 'Your browser suffers from an <a href="http://software.hixie.ch/utilities/js/live-dom-viewer/saved/1028">egregious bug</a> in range mutation that will give incorrect results for the spec columns in many cases. To ensure that the spec column contains the output actually required by the spec, use a different browser.'; + } + div.parentNode.removeChild(div); + })(); + //@} + + // Insert the toolbar thingie as soon as the script file is loaded + //@{ + (function() { + var toolbarDiv = document.createElement("div"); + toolbarDiv.id = "toolbar"; + // Note: this is completely not a hack at all. + toolbarDiv.innerHTML = "<style id=alerts>body > div > table > tbody > tr:not(.alert):not(:first-child):not(.active) { display: none }</style>" + + "<label><input id=alert-checkbox type=checkbox accesskey=a checked onclick='updateAlertRowStyle()'> Display rows without spec <u>a</u>lerts</label>" + + "<label><input id=browser-checkbox type=checkbox accesskey=b checked onclick='localStorage[\"display-browser-tests\"] = event.target.checked'> Run <u>b</u>rowser tests as well as spec tests</label>"; + + document.body.appendChild(toolbarDiv); + })(); + //@} + + // Confusingly, we're storing a string here, not a boolean. + document.querySelector("#alert-checkbox").checked = localStorage["display-alerts"] != "false"; + document.querySelector("#browser-checkbox").checked = localStorage["display-browser-tests"] != "false"; + + function updateAlertRowStyle() { + //@{ + var checked = document.querySelector("#alert-checkbox").checked; + document.querySelector("#alerts").disabled = checked; + localStorage["display-alerts"] = checked; + } + //@} + updateAlertRowStyle(); + + // Feature-test whether the browser wraps at <wbr> or not, and set word-wrap: + // break-word where necessary if not. (IE and Opera don't wrap, Gecko and + // WebKit do.) word-wrap: break-word will break anywhere at all, so it looks + // significantly uglier. + //@{ + (function() { + var wordWrapTestDiv = document.createElement("div"); + wordWrapTestDiv.style.width = "5em"; + document.body.appendChild(wordWrapTestDiv); + wordWrapTestDiv.innerHTML = "abc"; + var height1 = getComputedStyle(wordWrapTestDiv).height; + wordWrapTestDiv.innerHTML = "abc<wbr>abc<wbr>abc<wbr>abc<wbr>abc<wbr>abc"; + var height2 = getComputedStyle(wordWrapTestDiv).height; + document.body.removeChild(wordWrapTestDiv); + if (height1 == height2) { + document.body.className = (document.body.className + " wbr-workaround").trim(); + } + })(); + //@} +} + +// Now for the meat of the file. +var tests = { + backcolor: [ + //@{ Same as hilitecolor (set below) + ], + //@} + bold: [ + //@{ + 'foo[]bar', + '<p>[foo</p> <p>bar]</p>', + '<span>[foo</span> <span>bar]</span>', + '<p>[foo</p><p> <span>bar</span> </p><p>baz]</p>', + '<p>[foo<p><br><p>bar]', + '<b>foo[]bar</b>', + '<i>foo[]bar</i>', + '<span>foo</span>{}<span>bar</span>', + '<span>foo[</span><span>]bar</span>', + 'foo[bar]baz', + 'foo[bar<b>baz]qoz</b>quz', + 'foo[bar<i>baz]qoz</i>quz', + '{<p><p> <p>foo</p>}', + + 'foo<span contenteditable=false>[bar]</span>baz', + 'fo[o<span contenteditable=false>bar</span>b]az', + 'foo<span contenteditable=false>ba[r</span>b]az', + 'fo[o<span contenteditable=false>b]ar</span>baz', + 'fo[<b>o</b><span contenteditable=false>bar</span><b>b</b>]az', + '<span contenteditable=false>foo<span contenteditable=true>[bar]</span>baz</span>', + '<span contenteditable=false>fo[o<span contenteditable=true>bar</span>b]az</span>', + '<span contenteditable=false>foo<span contenteditable=true>ba[r</span>b]az</span>', + '<span contenteditable=false>fo[o<span contenteditable=true>b]ar</span>baz</span>', + '<span contenteditable=false>fo[<b>o<span contenteditable=true>bar</span>b</b>]az</span>', + + '<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>', + '<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table>', + '<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table>', + '<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>', + '<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>', + '{<table><tr><td>foo<td>bar<td>baz</table>}', + + 'foo<span style="font-weight: bold">[bar]</span>baz', + 'foo<b>[bar]</b>baz', + 'foo<b>bar</b>[baz]', + '[foo]<b>bar</b>baz', + '<b>foo</b>[bar]<b>baz</b>', + 'foo<strong>bar</strong>[baz]', + '[foo]<strong>bar</strong>baz', + '<strong>foo</strong>[bar]<strong>baz</strong>', + '<b>foo</b>[bar]<strong>baz</strong>', + '<strong>foo</strong>[bar]<b>baz</b>', + 'foo[<b>bar</b>]baz', + 'foo[<b>bar]</b>baz', + 'foo<b>[bar</b>]baz', + + 'foo{<b></b>}baz', + 'foo{<i></i>}baz', + 'foo{<b><i></i></b>}baz', + 'foo{<i><b></b></i>}baz', + + 'foo<strong>[bar]</strong>baz', + 'foo[<strong>bar</strong>]baz', + 'foo[<strong>bar]</strong>baz', + 'foo<strong>[bar</strong>]baz', + 'foo[<span style="font-weight: bold">bar</span>]baz', + 'foo[<span style="font-weight: bold">bar]</span>baz', + 'foo<span style="font-weight: bold">[bar</span>]baz', + + '<b>{<p>foo</p><p>bar</p>}<p>baz</p></b>', + '<b><p>foo[<i>bar</i>}</p><p>baz</p></b>', + + 'foo [bar <b>baz] qoz</b> quz sic', + 'foo bar <b>baz [qoz</b> quz] sic', + + '<b id=purple>bar [baz] qoz</b>', + + 'foo<span style="font-weight: 100">[bar]</span>baz', + 'foo<span style="font-weight: 200">[bar]</span>baz', + 'foo<span style="font-weight: 300">[bar]</span>baz', + 'foo<span style="font-weight: 400">[bar]</span>baz', + 'foo<span style="font-weight: 500">[bar]</span>baz', + 'foo<span style="font-weight: 600">[bar]</span>baz', + 'foo<span style="font-weight: 700">[bar]</span>baz', + 'foo<span style="font-weight: 800">[bar]</span>baz', + 'foo<span style="font-weight: 900">[bar]</span>baz', + 'foo<span style="font-weight: 400">[bar</span>]baz', + 'foo<span style="font-weight: 700">[bar</span>]baz', + 'foo[<span style="font-weight: 400">bar]</span>baz', + 'foo[<span style="font-weight: 700">bar]</span>baz', + 'foo[<span style="font-weight: 400">bar</span>]baz', + 'foo[<span style="font-weight: 700">bar</span>]baz', + '<span style="font-weight: 100">foo[bar]baz</span>', + '<span style="font-weight: 400">foo[bar]baz</span>', + '<span style="font-weight: 700">foo[bar]baz</span>', + '<span style="font-weight: 900">foo[bar]baz</span>', + '{<span style="font-weight: 100">foobar]baz</span>', + '{<span style="font-weight: 400">foobar]baz</span>', + '{<span style="font-weight: 700">foobar]baz</span>', + '{<span style="font-weight: 900">foobar]baz</span>', + '<span style="font-weight: 100">foo[barbaz</span>}', + '<span style="font-weight: 400">foo[barbaz</span>}', + '<span style="font-weight: 700">foo[barbaz</span>}', + '<span style="font-weight: 900">foo[barbaz</span>}', + + '<h3>foo[bar]baz</h3>', + '{<h3>foobar]baz</h3>', + '<h3>foo[barbaz</h3>}', + '<h3>[foobarbaz]</h3>', + '{<h3>foobarbaz]</h3>', + '<h3>[foobarbaz</h3>}', + '{<h3>foobarbaz</h3>}', + + '<b>foo<span style="font-weight: normal">bar<b>[baz]</b>quz</span>qoz</b>', + '<b>foo<span style="font-weight: normal">[bar]</span>baz</b>', + + '{<b>foo</b> <b>bar</b>}', + '{<h3>foo</h3><b>bar</b>}', + + '<i><b>foo</b></i>[bar]<i><b>baz</b></i>', + '<i><b>foo</b></i>[bar]<b>baz</b>', + '<b>foo</b>[bar]<i><b>baz</b></i>', + '<font color=blue face=monospace><b>foo</b></font>[bar]', + + 'foo<span style="font-weight: normal"><b>{bar}</b></span>baz', + '[foo<span class=notbold>bar</span>baz]', + '<b><span class=notbold>[foo]</span></b>', + '<b><span class=notbold>foo[bar]baz</span></b>', + + '<p style="font-weight: bold">foo[bar]baz</p>', + + // Tests for queryCommandIndeterm() and queryCommandState() + 'fo[o<b>b]ar</b>baz', + 'foo<b>ba[r</b>b]az', + 'fo[o<b>bar</b>b]az', + 'foo[<b>b]ar</b>baz', + 'foo<b>ba[r</b>]baz', + 'foo{<b>bar</b>}baz', + 'fo[o<span style=font-weight:bold>b]ar</span>baz', + '<span style=font-weight:800>fo[o</span><span style=font-weight:900>b]ar</span>', + '<span style=font-weight:700>fo[o</span><span style=font-weight:800>b]ar</span>', + '<span style=font-weight:600>fo[o</span><span style=font-weight:700>b]ar</span>', + '<span style=font-weight:500>fo[o</span><span style=font-weight:600>b]ar</span>', + '<span style=font-weight:400>fo[o</span><span style=font-weight:500>b]ar</span>', + '<span style=font-weight:300>fo[o</span><span style=font-weight:400>b]ar</span>', + '<span style=font-weight:200>fo[o</span><span style=font-weight:300>b]ar</span>', + '<span style=font-weight:100>fo[o</span><span style=font-weight:200>b]ar</span>', + ], + //@} + createlink: [ + //@{ + 'foo[]bar', + '<p>[foo</p> <p>bar]</p>', + '<span>[foo</span> <span>bar]</span>', + '<p>[foo</p><p> <span>bar</span> </p><p>baz]</p>', + '<p>[foo<p><br><p>bar]', + '<b>foo[]bar</b>', + '<i>foo[]bar</i>', + '<span>foo</span>{}<span>bar</span>', + '<span>foo[</span><span>]bar</span>', + 'foo[bar]baz', + 'foo[bar<b>baz]qoz</b>quz', + 'foo[bar<i>baz]qoz</i>quz', + '{<p><p> <p>foo</p>}', + + '<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>', + '<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table>', + '<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table>', + '<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>', + '<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>', + '{<table><tr><td>foo<td>bar<td>baz</table>}', + + '<a href=http://www.google.com/>foo[bar]baz</a>', + '<a href=http://www.google.com/>foo[barbaz</a>}', + '{<a href=http://www.google.com/>foobar]baz</a>', + '{<a href=http://www.google.com/>foobarbaz</a>}', + '<a href=http://www.google.com/>[foobarbaz]</a>', + + 'foo<a href=http://www.google.com/>[bar]</a>baz', + '[foo]<a href=http://www.google.com/>bar</a>baz', + 'foo<a href=http://www.google.com/>bar</a>[baz]', + 'foo[<a href=http://www.google.com/>bar</a>]baz', + 'foo<a href=http://www.google.com/>[bar</a>baz]', + '[foo<a href=http://www.google.com/>bar]</a>baz', + '[foo<a href=http://www.google.com/>bar</a>baz]', + + '<a href=otherurl>foo[bar]baz</a>', + '<a href=otherurl>foo[barbaz</a>}', + '{<a href=otherurl>foobar]baz</a>', + '{<a href=otherurl>foobarbaz</a>}', + '<a href=otherurl>[foobarbaz]</a>', + + 'foo<a href=otherurl>[bar]</a>baz', + 'foo[<a href=otherurl>bar</a>]baz', + 'foo<a href=otherurl>[bar</a>baz]', + '[foo<a href=otherurl>bar]</a>baz', + '[foo<a href=otherurl>bar</a>baz]', + + '<a href=otherurl><b>foo[bar]baz</b></a>', + '<a href=otherurl><b>foo[barbaz</b></a>}', + '{<a href=otherurl><b>foobar]baz</b></a>', + '<a href=otherurl><b>[foobarbaz]</b></a>', + + '<a name=abc>foo[bar]baz</a>', + '<a name=abc><b>foo[bar]baz</b></a>', + + ['', 'foo[bar]baz'], + ], + //@} + // Opera requires this to be quoted, contrary to ES5 11.1.5 which allows + // PropertyName to be any IdentifierName, and see 7.6 which defines + // IdentifierName to include ReservedWord; Identifier excludes it. + "delete": [ + //@{ + // Collapsed selection + // + // These three commented-out test call Firefox 5.0a2 to blow up, not + // just throwing exceptions on the tests themselves but on many + // subsequent tests too. + //'[]foo', + //'<span>[]foo</span>', + //'<p>[]foo</p>', + 'foo[]bar', + '<span>foo</span>{}<span>bar</span>', + '<span>foo[</span><span>]bar</span>', + 'foo<span style=display:none>bar</span>[]baz', + 'foo<script>bar</script>[]baz', + + 'foö[]bar', + 'foö[]bar', + 'foö̧[]bar', + 'ö[]bar', + 'ö[]bar', + 'ö̧[]bar', + + 'שָׁ[]לוֹם', + 'שָׁלוֹ[]ם', + + '<p>foo</p><p>[]bar</p>', + '<p>foo</p>[]bar', + 'foo<p>[]bar</p>', + '<p>foo<br></p><p>[]bar</p>', + '<p>foo<br></p>[]bar', + 'foo<br><p>[]bar</p>', + '<p>foo<br><br></p><p>[]bar</p>', + '<p>foo<br><br></p>[]bar', + 'foo<br><br><p>[]bar</p>', + + '<div><p>foo</p></div><p>[]bar</p>', + '<p>foo</p><div><p>[]bar</p></div>', + '<div><p>foo</p></div><div><p>[]bar</p></div>', + '<div><p>foo</p></div>[]bar', + 'foo<div><p>[]bar</p></div>', + + '<div>foo</div><div>[]bar</div>', + '<pre>foo</pre>[]bar', + + 'foo<br>[]bar', + 'foo<br><b>[]bar</b>', + 'foo<hr>[]bar', + '<p>foo<hr><p>[]bar', + '<p>foo</p><br><p>[]bar</p>', + '<p>foo</p><br><br><p>[]bar</p>', + '<p>foo</p><img src=/img/lion.svg><p>[]bar', + 'foo<img src=/img/lion.svg>[]bar', + + '<a>foo</a>[]bar', + '<a href=/>foo</a>[]bar', + '<a name=abc>foo</a>[]bar', + '<a href=/ name=abc>foo</a>[]bar', + '<span><a>foo</a></span>[]bar', + '<span><a href=/>foo</a></span>[]bar', + '<span><a name=abc>foo</a></span>[]bar', + '<span><a href=/ name=abc>foo</a></span>[]bar', + 'foo<a>[]bar</a>', + 'foo<a href=/>[]bar</a>', + 'foo<a name=abc>[]bar</a>', + 'foo<a href=/ name=abc>[]bar</a>', + + 'foo []', + ' [] foo', + 'foo []bar', + 'foo []bar', + 'foo []bar', + 'foo []bar', + 'foo [] bar', + 'foo [] bar', + 'foo []bar', + 'foo []<span> </span> bar', + 'foo <span> </span>[] bar', + 'foo <span> </span> []bar', + '<b>foo </b> []bar', + '<b>foo </b> []bar', + '<b>foo </b> []bar', + '<b>foo </b> []bar', + '<p>foo </p><p>[] bar</p>', + + '<pre>foo []</pre>', + '<pre> [] foo</pre>', + '<pre>foo []bar</pre>', + '<pre>foo []bar</pre>', + '<pre>foo []bar</pre>', + + '<div style=white-space:pre>foo []</div>', + '<div style=white-space:pre> [] foo</div>', + '<div style=white-space:pre>foo []bar</div>', + '<div style=white-space:pre>foo []bar</div>', + '<div style=white-space:pre>foo []bar</div>', + + '<div style=white-space:pre-wrap>foo []</div>', + '<div style=white-space:pre-wrap> [] foo</div>', + '<div style=white-space:pre-wrap>foo []bar</div>', + '<div style=white-space:pre-wrap>foo []bar</div>', + '<div style=white-space:pre-wrap>foo []bar</div>', + + '<div style=white-space:pre-line>foo []</div>', + '<div style=white-space:pre-line> [] foo</div>', + '<div style=white-space:pre-line>foo []bar</div>', + '<div style=white-space:pre-line>foo []bar</div>', + '<div style=white-space:pre-line>foo []bar</div>', + + '<div style=white-space:nowrap>foo []</div>', + '<div style=white-space:nowrap> [] foo</div>', + '<div style=white-space:nowrap>foo []bar</div>', + '<div style=white-space:nowrap>foo []bar</div>', + '<div style=white-space:nowrap>foo []bar</div>', + + // Tables with collapsed selection + 'foo<table><tr><td>[]bar</table>baz', + 'foo<table><tr><td>bar</table>[]baz', + '<p>foo<table><tr><td>[]bar</table><p>baz', + '<p>foo<table><tr><td>bar</table><p>[]baz', + '<table><tr><td>foo<td>[]bar</table>', + '<table><tr><td>foo<tr><td>[]bar</table>', + + 'foo<br><table><tr><td>[]bar</table>baz', + 'foo<table><tr><td>bar<br></table>[]baz', + '<p>foo<br><table><tr><td>[]bar</table><p>baz', + '<p>foo<table><tr><td>bar<br></table><p>[]baz', + '<table><tr><td>foo<br><td>[]bar</table>', + '<table><tr><td>foo<br><tr><td>[]bar</table>', + + 'foo<br><br><table><tr><td>[]bar</table>baz', + 'foo<table><tr><td>bar<br><br></table>[]baz', + '<p>foo<br><br><table><tr><td>[]bar</table><p>baz', + '<p>foo<table><tr><td>bar<br><br></table><p>[]baz', + '<table><tr><td>foo<br><br><td>[]bar</table>', + '<table><tr><td>foo<br><br><tr><td>[]bar</table>', + + 'foo<hr><table><tr><td>[]bar</table>baz', + 'foo<table><tr><td>bar<hr></table>[]baz', + '<table><tr><td>foo<hr><td>[]bar</table>', + '<table><tr><td>foo<hr><tr><td>[]bar</table>', + + // Lists with collapsed selection + 'foo<ol><li>[]bar<li>baz</ol>', + 'foo<br><ol><li>[]bar<li>baz</ol>', + 'foo<br><br><ol><li>[]bar<li>baz</ol>', + '<ol><li>foo<li>[]bar</ol>', + '<ol><li>foo<br><li>[]bar</ol>', + '<ol><li>foo<br><br><li>[]bar</ol>', + '<ol><li>foo<li>[]bar<br>baz</ol>', + '<ol><li>foo<br>bar<li>[]baz</ol>', + + '<ol><li><p>foo</p>{}bar</ol>', + + '<ol><li><p>foo<li>[]bar</ol>', + '<ol><li>foo<li><p>[]bar</ol>', + '<ol><li><p>foo<li><p>[]bar</ol>', + + '<ol><li>foo<ul><li>[]bar</ul></ol>', + 'foo<ol><ol><li>[]bar</ol></ol>', + 'foo<div><ol><li>[]bar</ol></div>', + + 'foo<dl><dt>[]bar<dd>baz</dl>', + 'foo<dl><dd>[]bar</dl>', + '<dl><dt>foo<dd>[]bar</dl>', + '<dl><dt>foo<dt>[]bar<dd>baz</dl>', + '<dl><dt>foo<dd>bar<dd>[]baz</dl>', + + '<ol><li>foo</ol>[]bar', + '<ol><li>foo<br></ol>[]bar', + '<ol><li>foo<br><br></ol>[]bar', + '<ol><li><br></ol>[]bar', + '<ol><li>foo<li><br></ol>[]bar', + + '<ol><li>foo</ol><p>[]bar', + '<ol><li>foo<br></ol><p>[]bar', + '<ol><li>foo<br><br></ol><p>[]bar', + '<ol><li><br></ol><p>[]bar', + '<ol><li>foo<li><br></ol><p>[]bar', + + '<ol><li>foo</ol>{}<br>', + '<ol><li>foo<br></ol>{}<br>', + '<ol><li>foo<br><br></ol>{}<br>', + '<ol><li><br></ol>{}<br>', + '<ol><li>foo<li><br></ol>{}<br>', + + '<ol><li>foo</ol><p>{}<br>', + '<ol><li>foo<br></ol><p>{}<br>', + '<ol><li>foo<br><br></ol><p>{}<br>', + '<ol><li><br></ol><p>{}<br>', + '<ol><li>foo<li><br></ol><p>{}<br>', + + // Indented stuff with collapsed selection + 'foo<blockquote>[]bar</blockquote>', + 'foo<blockquote><blockquote>[]bar</blockquote></blockquote>', + 'foo<blockquote><div>[]bar</div></blockquote>', + 'foo<blockquote style="color: blue">[]bar</blockquote>', + + 'foo<blockquote><blockquote><p>[]bar<p>baz</blockquote></blockquote>', + 'foo<blockquote><div><p>[]bar<p>baz</div></blockquote>', + 'foo<blockquote style="color: blue"><p>[]bar<p>baz</blockquote>', + + 'foo<blockquote><p><b>[]bar</b><p>baz</blockquote>', + 'foo<blockquote><p><strong>[]bar</strong><p>baz</blockquote>', + 'foo<blockquote><p><span>[]bar</span><p>baz</blockquote>', + + 'foo<blockquote><ol><li>[]bar</ol></blockquote><p>extra', + 'foo<blockquote>bar<ol><li>[]baz</ol>quz</blockquote><p>extra', + 'foo<blockquote><ol><li>bar</li><ol><li>[]baz</ol><li>quz</ol></blockquote><p>extra', + + // Invisible stuff with collapsed selection + 'foo<span></span>[]bar', + 'foo<span><span></span></span>[]bar', + 'foo<quasit></quasit>[]bar', + 'foo<br><span></span>[]bar', + '<span>foo<span></span></span>[]bar', + 'foo<span></span><span>[]bar</span>', + 'foo<div><div><p>[]bar</div></div>', + 'foo<div><div><p><!--abc-->[]bar</div></div>', + 'foo<div><div><!--abc--><p>[]bar</div></div>', + 'foo<div><!--abc--><div><p>[]bar</div></div>', + 'foo<!--abc--><div><div><p>[]bar</div></div>', + '<div><div><p>foo</div></div>[]bar', + '<div><div><p>foo</div></div><!--abc-->[]bar', + '<div><div><p>foo</div><!--abc--></div>[]bar', + '<div><div><p>foo</p><!--abc--></div></div>[]bar', + '<div><div><p>foo<!--abc--></div></div>[]bar', + '<div><div><p>foo</p></div></div><div><div><div>[]bar</div></div></div>', + '<div><div><p>foo<!--abc--></p></div></div><div><div><div>[]bar</div></div></div>', + '<div><div><p>foo</p><!--abc--></div></div><div><div><div>[]bar</div></div></div>', + '<div><div><p>foo</p></div><!--abc--></div><div><div><div>[]bar</div></div></div>', + '<div><div><p>foo</p></div></div><!--abc--><div><div><div>[]bar</div></div></div>', + '<div><div><p>foo</p></div></div><div><!--abc--><div><div>[]bar</div></div></div>', + '<div><div><p>foo</p></div></div><div><div><!--abc--><div>[]bar</div></div></div>', + '<div><div><p>foo</p></div></div><div><div><div><!--abc-->[]bar</div></div></div>', + + // Styled stuff with collapsed selection + '<p style=color:blue>foo<p>[]bar', + '<p style=color:blue>foo<p style=color:brown>[]bar', + '<p style=color:blue>foo<p style=color:rgba(0,0,255,1)>[]bar', + '<p style=color:transparent>foo<p style=color:rgba(0,0,0,0)>[]bar', + '<p>foo<p style=color:brown>[]bar', + '<p><font color=blue>foo</font><p>[]bar', + '<p><font color=blue>foo</font><p><font color=brown>[]bar</font>', + '<p>foo<p><font color=brown>[]bar</font>', + '<p><span style=color:blue>foo</font><p>[]bar', + '<p><span style=color:blue>foo</font><p><span style=color:brown>[]bar</font>', + '<p>foo<p><span style=color:brown>[]bar</font>', + + '<p style=background-color:aqua>foo<p>[]bar', + '<p style=background-color:aqua>foo<p style=background-color:tan>[]bar', + '<p>foo<p style=background-color:tan>[]bar', + '<p><span style=background-color:aqua>foo</font><p>[]bar', + '<p><span style=background-color:aqua>foo</font><p><span style=background-color:tan>[]bar</font>', + '<p>foo<p><span style=background-color:tan>[]bar</font>', + + '<p style=text-decoration:underline>foo<p>[]bar', + '<p style=text-decoration:underline>foo<p style=text-decoration:line-through>[]bar', + '<p>foo<p style=text-decoration:line-through>[]bar', + '<p><u>foo</u><p>[]bar', + '<p><u>foo</u><p><s>[]bar</s>', + '<p>foo<p><s>[]bar</s>', + + '<p style=color:blue>foo</p>[]bar', + 'foo<p style=color:brown>[]bar', + '<div style=color:blue><p style=color:green>foo</div>[]bar', + '<div style=color:blue><p style=color:green>foo</div><p style=color:brown>[]bar', + '<p style=color:blue>foo<div style=color:brown><p style=color:green>[]bar', + + // Uncollapsed selection + 'foo[bar]baz', + '<p>foo<span style=color:#aBcDeF>[bar]</span>baz', + '<p>foo<span style=color:#aBcDeF>{bar}</span>baz', + '<p>foo{<span style=color:#aBcDeF>bar</span>}baz', + '<p>[foo<span style=color:#aBcDeF>bar]</span>baz', + '<p>{foo<span style=color:#aBcDeF>bar}</span>baz', + '<p>foo<span style=color:#aBcDeF>[bar</span>baz]', + '<p>foo<span style=color:#aBcDeF>{bar</span>baz}', + '<p>foo<span style=color:#aBcDeF>[bar</span><span style=color:#fEdCbA>baz]</span>quz', + + 'foo<b>[bar]</b>baz', + 'foo<b>{bar}</b>baz', + 'foo{<b>bar</b>}baz', + 'foo<span>[bar]</span>baz', + 'foo<span>{bar}</span>baz', + 'foo{<span>bar</span>}baz', + '<b>foo[bar</b><i>baz]quz</i>', + '<p>foo</p><p>[bar]</p><p>baz</p>', + '<p>foo</p><p>{bar}</p><p>baz</p>', + '<p>foo</p><p>{bar</p>}<p>baz</p>', + '<p>foo</p>{<p>bar}</p><p>baz</p>', + '<p>foo</p>{<p>bar</p>}<p>baz</p>', + + '<p>foo[bar<p>baz]quz', + '<p>foo[bar<div>baz]quz</div>', + '<p>foo[bar<h1>baz]quz</h1>', + '<div>foo[bar</div><p>baz]quz', + '<blockquote>foo[bar</blockquote><pre>baz]quz</pre>', + + '<p><b>foo[bar</b><p>baz]quz', + '<div><p>foo[bar</div><p>baz]quz', + '<p>foo[bar<blockquote><p>baz]quz<p>qoz</blockquote', + '<p>foo[bar<p style=color:blue>baz]quz', + '<p>foo[bar<p><b>baz]quz</b>', + + '<div><p>foo<p>[bar<p>baz]</div>', + + 'foo[<br>]bar', + '<p>foo[</p><p>]bar</p>', + '<p>foo[</p><p>]bar<br>baz</p>', + 'foo[<p>]bar</p>', + 'foo{<p>}bar</p>', + 'foo[<p>]bar<br>baz</p>', + 'foo[<p>]bar</p>baz', + 'foo{<p>bar</p>}baz', + 'foo<p>{bar</p>}baz', + 'foo{<p>bar}</p>baz', + '<p>foo[</p>]bar', + '<p>foo{</p>}bar', + '<p>foo[</p>]bar<br>baz', + '<p>foo[</p>]bar<p>baz</p>', + 'foo[<div><p>]bar</div>', + '<div><p>foo[</p></div>]bar', + 'foo[<div><p>]bar</p>baz</div>', + 'foo[<div>]bar<p>baz</p></div>', + '<div><p>foo</p>bar[</div>]baz', + '<div>foo<p>bar[</p></div>]baz', + + '<p>foo<br>{</p>]bar', + '<p>foo<br><br>{</p>]bar', + 'foo<br>{<p>]bar</p>', + 'foo<br><br>{<p>]bar</p>', + '<p>foo<br>{</p><p>}bar</p>', + '<p>foo<br><br>{</p><p>}bar</p>', + + '<table><tbody><tr><th>foo<th>[bar]<th>baz<tr><td>quz<td>qoz<td>qiz</table>', + '<table><tbody><tr><th>foo<th>ba[r<th>b]az<tr><td>quz<td>qoz<td>qiz</table>', + '<table><tbody><tr><th>fo[o<th>bar<th>b]az<tr><td>quz<td>qoz<td>qiz</table>', + '<table><tbody><tr><th>foo<th>bar<th>ba[z<tr><td>q]uz<td>qoz<td>qiz</table>', + '<table><tbody><tr><th>[foo<th>bar<th>baz]<tr><td>quz<td>qoz<td>qiz</table>', + '<table><tbody><tr><th>[foo<th>bar<th>baz<tr><td>quz<td>qoz<td>qiz]</table>', + '{<table><tbody><tr><th>foo<th>bar<th>baz<tr><td>quz<td>qoz<td>qiz</table>}', + '<table><tbody><tr><td>foo<td>ba[r<tr><td>baz<td>quz<tr><td>q]oz<td>qiz</table>', + '<p>fo[o<table><tr><td>b]ar</table><p>baz', + '<p>foo<table><tr><td>ba[r</table><p>b]az', + '<p>fo[o<table><tr><td>bar</table><p>b]az', + + '<p>foo<ol><li>ba[r<li>b]az</ol><p>quz', + '<p>foo<ol><li>bar<li>[baz]</ol><p>quz', + '<p>fo[o<ol><li>b]ar<li>baz</ol><p>quz', + '<p>foo<ol><li>bar<li>ba[z</ol><p>q]uz', + '<p>fo[o<ol><li>bar<li>b]az</ol><p>quz', + '<p>fo[o<ol><li>bar<li>baz</ol><p>q]uz', + + '<ol><li>fo[o</ol><ol><li>b]ar</ol>', + '<ol><li>fo[o</ol><ul><li>b]ar</ul>', + + 'foo[<ol><li>]bar</ol>', + '<ol><li>foo[<li>]bar</ol>', + 'foo[<dl><dt>]bar<dd>baz</dl>', + 'foo[<dl><dd>]bar</dl>', + '<dl><dt>foo[<dd>]bar</dl>', + '<dl><dt>foo[<dt>]bar<dd>baz</dl>', + '<dl><dt>foo<dd>bar[<dd>]baz</dl>', + + '<b>foo [ </b>bar]', + 'foo<b> [ bar]</b>', + '<b>[foo ] </b>bar', + '[foo<b> ] bar</b>', + + // Do we merge based on element names or the display property? + '<p style=display:inline>fo[o<p style=display:inline>b]ar', + '<span style=display:block>fo[o</span><span style=display:block>b]ar</span>', + '<span style=display:inline-block>fo[o</span><span style=display:inline-block>b]ar</span>', + '<span style=display:inline-table>fo[o</span><span style=display:inline-table>b]ar</span>', + '<span style=display:none>fo[o</span><span style=display:none>b]ar</span>', + '<quasit style=display:block>fo[o</quasit><quasit style=display:block>b]ar</quasit>', + + // https://bugs.webkit.org/show_bug.cgi?id=35281 + // http://www.w3.org/Bugs/Public/show_bug.cgi?id=13976 + '<ol><li>foo</ol>{}<br><ol><li>bar</ol>', + '<ol><li>foo</ol><p>{}<br></p><ol><li>bar</ol>', + '<ol><li><p>foo</ol><p>{}<br></p><ol><li>bar</ol>', + '<ol id=a><li>foo</ol>{}<br><ol><li>bar</ol>', + '<ol><li>foo</ol>{}<br><ol id=b><li>bar</ol>', + '<ol id=a><li>foo</ol>{}<br><ol id=b><li>bar</ol>', + '<ol class=a><li>foo</ol>{}<br><ol class=b><li>bar</ol>', + // Broken test: http://www.w3.org/Bugs/Public/show_bug.cgi?id=14727 + '!<ol><ol><li>foo</ol><li>{}<br><ol><li>bar</ol></ol>', + '<ol><ol><li>foo</ol><li>{}<br></li><ol><li>bar</ol></ol>', + '<ol><li>foo[</ol>bar]<ol><li>baz</ol>', + '<ol><li>foo[</ol><p>bar]<ol><li>baz</ol>', + '<ol><li><p>foo[</ol><p>bar]<ol><li>baz</ol>', + '<ol><li>foo[]</ol><ol><li>bar</ol>', + '<ol><li>foo</ol>[bar<ol><li>]baz</ol>', + '<ol><li>foo</ol><p>[bar<ol><li>]baz</ol>', + '<ol><li>foo</ol><p>[bar<ol><li><p>]baz</ol>', + '<ol><li>foo</ol><ol><li>b[]ar</ol>', + '<ol><ol><li>foo[</ol><li>bar</ol>baz]<ol><li>quz</ol>', + '<ul><li>foo</ul>{}<br><ul><li>bar</ul>', + '<ul><li>foo</ul><p>{}<br></p><ul><li>bar</ul>', + '<ol><li>foo[<li>bar]</ol><ol><li>baz</ol><ol><li>quz</ol>', + '<ol><li>foo</ol>{}<br><ul><li>bar</ul>', + '<ol><li>foo</ol><p>{}<br></p><ul><li>bar</ul>', + '<ul><li>foo</ul>{}<br><ol><li>bar</ol>', + '<ul><li>foo</ul><p>{}<br></p><ol><li>bar</ol>', + + // http://www.w3.org/Bugs/Public/show_bug.cgi?id=13831 + '<p><b>[foo]</b>', + '<p><quasit>[foo]</quasit>', + '<p><b><i>[foo]</i></b>', + '<p><b>{foo}</b>', + '<p>{<b>foo</b>}', + '<p><b>f[]</b>', + '<b>[foo]</b>', + '<div><b>[foo]</b></div>', + ], + //@} + fontname: [ + //@{ + 'foo[]bar', + '<p>[foo</p> <p>bar]</p>', + '<span>[foo</span> <span>bar]</span>', + '<p>[foo</p><p> <span>bar</span> </p><p>baz]</p>', + '<p>[foo<p><br><p>bar]', + '<b>foo[]bar</b>', + '<i>foo[]bar</i>', + '<span>foo</span>{}<span>bar</span>', + '<span>foo[</span><span>]bar</span>', + 'foo[bar]baz', + 'foo[bar<b>baz]qoz</b>quz', + 'foo[bar<i>baz]qoz</i>quz', + '{<p><p> <p>foo</p>}', + + '<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>', + '<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table>', + '<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table>', + '<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>', + '<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>', + '{<table><tr><td>foo<td>bar<td>baz</table>}', + + 'foo<code>[bar]</code>baz', + 'foo<kbd>[bar]</kbd>baz', + 'foo<listing>[bar]</listing>baz', + 'foo<pre>[bar]</pre>baz', + 'foo<samp>[bar]</samp>baz', + 'foo<tt>[bar]</tt>baz', + + 'foo<code>b[a]r</code>baz', + 'foo<kbd>b[a]r</kbd>baz', + 'foo<listing>b[a]r</listing>baz', + 'foo<pre>b[a]r</pre>baz', + 'foo<samp>b[a]r</samp>baz', + 'foo<tt>b[a]r</tt>baz', + + '[foo<code>bar</code>baz]', + '[foo<kbd>bar</kbd>baz]', + '[foo<listing>bar</listing>baz]', + '[foo<pre>bar</pre>baz]', + '[foo<samp>bar</samp>baz]', + '[foo<tt>bar</tt>baz]', + + '[foo<code>ba]r</code>baz', + '[foo<kbd>ba]r</kbd>baz', + '[foo<listing>ba]r</listing>baz', + '[foo<pre>ba]r</pre>baz', + '[foo<samp>ba]r</samp>baz', + '[foo<tt>ba]r</tt>baz', + + 'foo<code>b[ar</code>baz]', + 'foo<kbd>b[ar</kbd>baz]', + 'foo<listing>b[ar</listing>baz]', + 'foo<pre>b[ar</pre>baz]', + 'foo<samp>b[ar</samp>baz]', + 'foo<tt>b[ar</tt>baz]', + + 'foo<span style="font-family: sans-serif">[bar]</span>baz', + 'foo<span style="font-family: sans-serif">b[a]r</span>baz', + 'foo<span style="font-family: monospace">[bar]</span>baz', + 'foo<span style="font-family: monospace">b[a]r</span>baz', + + 'foo<tt contenteditable=false>ba[r</tt>b]az', + 'fo[o<tt contenteditable=false>b]ar</tt>baz', + 'foo<tt>{}<br></tt>bar', + 'foo<tt>{<br></tt>}bar', + 'foo<tt>{<br></tt>b]ar', + + // Tests for queryCommandIndeterm() and queryCommandState() + 'fo[o<span style=font-family:monospace>b]ar</span>baz', + 'foo<span style=font-family:monospace>ba[r</span>b]az', + 'fo[o<span style=font-family:monospace>bar</span>b]az', + 'foo[<span style=font-family:monospace>b]ar</span>baz', + 'foo<span style=font-family:monospace>ba[r</span>]baz', + 'foo[<span style=font-family:monospace>bar</span>]baz', + 'foo<span style=font-family:monospace>[bar]</span>baz', + 'foo{<span style=font-family:monospace>bar</span>}baz', + 'fo[o<code>b]ar</code>', + 'fo[o<kbd>b]ar</kbd>', + 'fo[o<listing>b]ar</listing>', + 'fo[o<pre>b]ar</pre>', + 'fo[o<samp>b]ar</samp>', + 'fo[o<tt>b]ar</tt>', + '<tt>fo[o</tt><code>b]ar</code>', + '<pre>fo[o</pre><samp>b]ar</samp>', + '<span style=font-family:monospace>fo[o</span><kbd>b]ar</kbd>', + ], + //@} + fontsize: [ + //@{ + 'foo[]bar', + '<p>[foo</p> <p>bar]</p>', + '<span>[foo</span> <span>bar]</span>', + '<p>[foo</p><p> <span>bar</span> </p><p>baz]</p>', + '<p>[foo<p><br><p>bar]', + '<b>foo[]bar</b>', + '<i>foo[]bar</i>', + '<span>foo</span>{}<span>bar</span>', + '<span>foo[</span><span>]bar</span>', + 'foo[bar]baz', + 'foo[bar<b>baz]qoz</b>quz', + 'foo[bar<i>baz]qoz</i>quz', + '{<p><p> <p>foo</p>}', + + ["1", 'foo[bar]baz'], + ["0", 'foo[bar]baz'], + ["-5", 'foo[bar]baz'], + ["6", 'foo[bar]baz'], + ["7", 'foo[bar]baz'], + ["8", 'foo[bar]baz'], + ["100", 'foo[bar]baz'], + ["2em", 'foo[bar]baz'], + ["20pt", 'foo[bar]baz'], + ["xx-large", 'foo[bar]baz'], + [" 1 ", 'foo[bar]baz'], + ["1.", 'foo[bar]baz'], + ["1.0", 'foo[bar]baz'], + ["1.0e2", 'foo[bar]baz'], + ["1.1", 'foo[bar]baz'], + ["1.9", 'foo[bar]baz'], + ["+0", 'foo[bar]baz'], + ["+1", 'foo[bar]baz'], + ["+9", 'foo[bar]baz'], + ["-0", 'foo[bar]baz'], + ["-1", 'foo[bar]baz'], + ["-9", 'foo[bar]baz'], + ["", 'foo[bar]baz'], + + '<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>', + '<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table>', + '<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table>', + '<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>', + '<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>', + '{<table><tr><td>foo<td>bar<td>baz</table>}', + + 'foo<font size=1>[bar]</font>baz', + '<font size=1>foo[bar]baz</font>', + 'foo<font size=3>[bar]</font>baz', + '<font size=3>foo[bar]baz</font>', + 'foo<font size=4>[bar]</font>baz', + '<font size=4>foo[bar]baz</font>', + 'foo<font size=+1>[bar]</font>baz', + '<font size=+1>foo[bar]baz</font>', + '<font size=4>foo<font size=1>b[a]r</font>baz</font>', + + 'foo<span style="font-size: xx-small">[bar]</span>baz', + '<span style="font-size: xx-small">foo[bar]baz</span>', + 'foo<span style="font-size: medium">[bar]</span>baz', + '<span style="font-size: medium">foo[bar]baz</span>', + 'foo<span style="font-size: large">[bar]</span>baz', + '<span style="font-size: large">foo[bar]baz</span>', + '<span style="font-size: large">foo<span style="font-size: xx-small">b[a]r</span>baz</span>', + + 'foo<span style="font-size: 2em">[bar]</span>baz', + '<span style="font-size: 2em">foo[bar]baz</span>', + + '<p style="font-size: xx-small">foo[bar]baz</p>', + '<p style="font-size: medium">foo[bar]baz</p>', + '<p style="font-size: large">foo[bar]baz</p>', + '<p style="font-size: 2em">foo[bar]baz</p>', + + ["3", '<p style="font-size: xx-small">foo[bar]baz</p>'], + ["3", '<p style="font-size: medium">foo[bar]baz</p>'], + ["3", '<p style="font-size: large">foo[bar]baz</p>'], + ["3", '<p style="font-size: 2em">foo[bar]baz</p>'], + + // Minor algorithm bug: this changes the size of the "b" and "r" in + // "bar" when we pull down styles + ["3", '<font size=6>foo <span style="font-size: 2em">b[a]r</span> baz</font>'], + + ["3", 'foo<big>[bar]</big>baz'], + ["3", 'foo<big>b[a]r</big>baz'], + ["3", 'foo<small>[bar]</small>baz'], + ["3", 'foo<small>b[a]r</small>baz'], + + // Tests for queryCommandIndeterm() and queryCommandState() + 'fo[o<font size=2>b]ar</font>baz', + 'foo<font size=2>ba[r</font>b]az', + 'fo[o<font size=2>bar</font>b]az', + 'foo[<font size=2>b]ar</font>baz', + 'foo<font size=2>ba[r</font>]baz', + 'foo[<font size=2>bar</font>]baz', + 'foo<font size=2>[bar]</font>baz', + 'foo{<font size=2>bar</font>}baz', + '<font size=1>fo[o</font><span style=font-size:xx-small>b]ar</span>', + '<font size=2>fo[o</font><span style=font-size:small>b]ar</span>', + '<font size=3>fo[o</font><span style=font-size:medium>b]ar</span>', + '<font size=4>fo[o</font><span style=font-size:large>b]ar</span>', + '<font size=5>fo[o</font><span style=font-size:x-large>b]ar</span>', + '<font size=6>fo[o</font><span style=font-size:xx-large>b]ar</span>', + + // http://www.w3.org/Bugs/Public/show_bug.cgi?id=13829 + ["!6", '<span style=background-color:aqua>[foo]</span>'], + ["!6", '<span style=background-color:aqua>foo[bar]baz</span>'], + ["!6", '[foo<span style=background-color:aqua>bar</span>baz]'], + ], + //@} + forecolor: [ + //@{ + 'foo[]bar', + '<p>[foo</p> <p>bar]</p>', + '<span>[foo</span> <span>bar]</span>', + '<p>[foo</p><p> <span>bar</span> </p><p>baz]</p>', + '<p>[foo<p><br><p>bar]', + '<b>foo[]bar</b>', + '<i>foo[]bar</i>', + '<span>foo</span>{}<span>bar</span>', + '<span>foo[</span><span>]bar</span>', + 'foo[bar]baz', + 'foo[bar<b>baz]qoz</b>quz', + 'foo[bar<i>baz]qoz</i>quz', + '{<p><p> <p>foo</p>}', + + ['blue', 'foo[bar]baz'], + ['f', 'foo[bar]baz'], + ['#f', 'foo[bar]baz'], + ['00f', 'foo[bar]baz'], + ['#00f', 'foo[bar]baz'], + ['0000ff', 'foo[bar]baz'], + ['#0000ff', 'foo[bar]baz'], + ['000000fff', 'foo[bar]baz'], + ['#000000fff', 'foo[bar]baz'], + ['rgb(0, 0, 255)', 'foo[bar]baz'], + ['rgb(0%, 0%, 100%)', 'foo[bar]baz'], + ['rgb( 0 ,0 ,255)', 'foo[bar]baz'], + ['rgba(0, 0, 255, 0.0)', 'foo[bar]baz'], + ['rgb(15, -10, 375)', 'foo[bar]baz'], + ['rgba(0, 0, 0, 1)', 'foo[bar]baz'], + ['rgba(255, 255, 255, 1)', 'foo[bar]baz'], + ['rgba(0, 0, 255, 0.5)', 'foo[bar]baz'], + ['hsl(240, 100%, 50%)', 'foo[bar]baz'], + ['cornsilk', 'foo[bar]baz'], + ['potato quiche', 'foo[bar]baz'], + ['transparent', 'foo[bar]baz'], + ['currentColor', 'foo[bar]baz'], + + '<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>', + '<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table>', + '<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table>', + '<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>', + '<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>', + '{<table><tr><td>foo<td>bar<td>baz</table>}', + + 'foo<font color=blue>[bar]</font>baz', + 'foo{<font color=blue>bar</font>}baz', + '<span style="color: blue">foo<span style="color: brown">[bar]</span>baz</span>', + '<span style="color: #00f">foo<span style="color: brown">[bar]</span>baz</span>', + '<span style="color: #0000ff">foo<span style="color: brown">[bar]</span>baz</span>', + '<span style="color: rgb(0, 0, 255)">foo<span style="color: brown">[bar]</span>baz</span>', + '<font color=blue>foo<font color=brown>[bar]</font>baz</font>', + '<span style="color: rgb(0, 0, 255)">foo<span style="color: brown">b[ar]</span>baz</span>', + 'foo<span id=purple>ba[r</span>ba]z', + '<span style="color: rgb(0, 0, 255)">foo<span id=purple>b[a]r</span>baz</span>', + + ['blue', '<a href=http://www.google.com>foo[bar]baz</a>'], + ['#0000ff', '<a href=http://www.google.com>foo[bar]baz</a>'], + ['rgb(0,0,255)', '<a href=http://www.google.com>foo[bar]baz</a>'], + + // Tests for queryCommandValue() + '<font color="blue">[foo]</font>', + '<font color="0000ff">[foo]</font>', + '<font color="#0000ff">[foo]</font>', + '<span style="color: blue">[foo]</span>', + '<span style="color: #0000ff">[foo]</span>', + '<span style="color: rgb(0, 0, 255)">[foo]</span>', + '<span style="color: rgb(0%, 0%, 100%)">[foo]</span>', + '<span style="color: rgb( 0 ,0 ,255)">[foo]</span>', + '<span style="color: rgba(0, 0, 255, 0.0)">[foo]</span>', + '<span style="color: rgb(15, -10, 375)">[foo]</span>', + '<span style="color: rgba(0, 0, 0, 1)">[foo]</span>', + '<span style="color: rgba(255, 255, 255, 1)">[foo]</span>', + '<span style="color: rgba(0, 0, 255, 0.5)">[foo]</span>', + '<span style="color: hsl(240, 100%, 50%)">[foo]</span>', + '<span style="color: cornsilk">[foo]</span>', + '<span style="color: transparent">[foo]</span>', + '<span style="color: currentColor">[foo]</span>', + + // Tests for queryCommandIndeterm() and queryCommandState() + 'fo[o<font color=brown>b]ar</font>baz', + 'foo<font color=brown>ba[r</font>b]az', + 'fo[o<font color=brown>bar</font>b]az', + 'foo[<font color=brown>b]ar</font>baz', + 'foo<font color=brown>ba[r</font>]baz', + 'foo[<font color=brown>bar</font>]baz', + 'foo<font color=brown>[bar]</font>baz', + 'foo{<font color=brown>bar</font>}baz', + '<font color=brown>fo[o</font><span style=color:brown>b]ar</span>', + '<span style=color:brown>fo[o</span><span style=color:#0000ff>b]ar</span>', + ], + //@} + formatblock: [ + //@{ + 'foo[]bar<p>extra', + '<span>foo</span>{}<span>bar</span><p>extra', + '<span>foo[</span><span>]bar</span><p>extra', + 'foo[bar]baz<p>extra', + 'foo]bar[baz<p>extra', + '{<p><p> <p>foo</p>}', + 'foo[bar<i>baz]qoz</i>quz<p>extra', + + '<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>', + '<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table>', + '<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table>', + '<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>', + '<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>', + '{<table><tr><td>foo<td>bar<td>baz</table>}', + + '<div>[foobar]</div>', + '<p>[foobar]</p>', + '<blockquote>[foobar]</blockquote>', + '<h1>[foobar]</h1>', + '<h2>[foobar]</h2>', + '<h3>[foobar]</h3>', + '<h4>[foobar]</h4>', + '<h5>[foobar]</h5>', + '<h6>[foobar]</h6>', + '<dl><dt>[foo]<dd>bar</dl>', + '<dl><dt>foo<dd>[bar]</dl>', + '<dl><dt>[foo<dd>bar]</dl>', + '<ol><li>[foobar]</ol>', + '<ul><li>[foobar]</ul>', + '<address>[foobar]</address>', + '<pre>[foobar]</pre>', + '<article>[foobar]</article>', + '<ins>[foobar]</ins>', + '<del>[foobar]</del>', + '<quasit>[foobar]</quasit>', + '<quasit style="display: block">[foobar]</quasit>', + + ['<p>', 'foo[]bar<p>extra'], + ['<p>', '<span>foo</span>{}<span>bar</span><p>extra'], + ['<p>', '<span>foo[</span><span>]bar</span><p>extra'], + ['<p>', 'foo[bar]baz<p>extra'], + ['<p>', 'foo]bar[baz<p>extra'], + ['<p>', '{<p><p> <p>foo</p>}'], + ['<p>', 'foo[bar<i>baz]qoz</i>quz<p>extra'], + + ['<p>', '<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>'], + ['<p>', '<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table>'], + ['<p>', '<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table>'], + ['<p>', '<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>'], + ['<p>', '<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>'], + ['<p>', '{<table><tr><td>foo<td>bar<td>baz</table>}'], + + ['<p>', '<div>[foobar]</div>'], + ['<p>', '<p>[foobar]</p>'], + ['<p>', '<blockquote>[foobar]</blockquote>'], + ['<p>', '<h1>[foobar]</h1>'], + ['<p>', '<h2>[foobar]</h2>'], + ['<p>', '<h3>[foobar]</h3>'], + ['<p>', '<h4>[foobar]</h4>'], + ['<p>', '<h5>[foobar]</h5>'], + ['<p>', '<h6>[foobar]</h6>'], + ['<p>', '<dl><dt>[foo]<dd>bar</dl>'], + ['<p>', '<dl><dt>foo<dd>[bar]</dl>'], + ['<p>', '<dl><dt>[foo<dd>bar]</dl>'], + ['<p>', '<ol><li>[foobar]</ol>'], + ['<p>', '<ul><li>[foobar]</ul>'], + ['<p>', '<address>[foobar]</address>'], + ['<p>', '<pre>[foobar]</pre>'], + ['<p>', '<listing>[foobar]</listing>'], + ['<p>', '<xmp>[foobar]</xmp>'], + ['<p>', '<article>[foobar]</article>'], + ['<p>', '<ins>[foobar]</ins>'], + ['<p>', '<del>[foobar]</del>'], + ['<p>', '<quasit>[foobar]</quasit>'], + ['<p>', '<quasit style="display: block">[foobar]</quasit>'], + + ['<blockquote>', '<blockquote>[foo]</blockquote><p>extra'], + ['<blockquote>', '<blockquote><p>[foo]<p>bar</blockquote><p>extra'], + ['<blockquote>', '[foo]<blockquote>bar</blockquote><p>extra'], + ['<blockquote>', '<p>[foo<p>bar]<p>baz'], + ['<blockquote>', '<section>[foo]</section>'], + ['<blockquote>', '<section><p>[foo]</section>'], + ['<blockquote>', '<section><hgroup><h1>[foo]</h1><h2>bar</h2></hgroup><p>baz</section>'], + ['<article>', '<section>[foo]</section>'], + + ['<address>', '<div>[foobar]</div>'], + ['<article>', '<div>[foobar]</div>'], + ['<blockquote>', '<div>[foobar]</div>'], + ['<dd>', '<div>[foobar]</div>'], + ['<del>', '<div>[foobar]</div>'], + ['<dl>', '<div>[foobar]</div>'], + ['<dt>', '<div>[foobar]</div>'], + ['<h1>', '<div>[foobar]</div>'], + ['<h2>', '<div>[foobar]</div>'], + ['<h3>', '<div>[foobar]</div>'], + ['<h4>', '<div>[foobar]</div>'], + ['<h5>', '<div>[foobar]</div>'], + ['<h6>', '<div>[foobar]</div>'], + ['<ins>', '<div>[foobar]</div>'], + ['<li>', '<div>[foobar]</div>'], + ['<ol>', '<div>[foobar]</div>'], + ['<pre>', '<div>[foobar]</div>'], + ['<ul>', '<div>[foobar]</div>'], + ['<quasit>', '<div>[foobar]</div>'], + + ['<address>', '<p>[foobar]</p>'], + ['<article>', '<p>[foobar]</p>'], + ['<aside>', '<p>[foobar]</p>'], + ['<blockquote>', '<p>[foobar]</p>'], + ['<body>', '<p>[foobar]</p>'], + ['<dd>', '<p>[foobar]</p>'], + ['<del>', '<p>[foobar]</p>'], + ['<details>', '<p>[foobar]</p>'], + ['<dir>', '<p>[foobar]</p>'], + ['<dl>', '<p>[foobar]</p>'], + ['<dt>', '<p>[foobar]</p>'], + ['<fieldset>', '<p>[foobar]</p>'], + ['<figcaption>', '<p>[foobar]</p>'], + ['<figure>', '<p>[foobar]</p>'], + ['<footer>', '<p>[foobar]</p>'], + ['<form>', '<p>[foobar]</p>'], + ['<h1>', '<p>[foobar]</p>'], + ['<h2>', '<p>[foobar]</p>'], + ['<h3>', '<p>[foobar]</p>'], + ['<h4>', '<p>[foobar]</p>'], + ['<h5>', '<p>[foobar]</p>'], + ['<h6>', '<p>[foobar]</p>'], + ['<header>', '<p>[foobar]</p>'], + ['<head>', '<p>[foobar]</p>'], + ['<hgroup>', '<p>[foobar]</p>'], + ['<hr>', '<p>[foobar]</p>'], + ['<html>', '<p>[foobar]</p>'], + ['<ins>', '<p>[foobar]</p>'], + ['<li>', '<p>[foobar]</p>'], + ['<listing>', '<p>[foobar]</p>'], + ['<menu>', '<p>[foobar]</p>'], + ['<nav>', '<p>[foobar]</p>'], + ['<ol>', '<p>[foobar]</p>'], + ['<plaintext>', '<p>[foobar]</p>'], + ['<pre>', '<p>[foobar]</p>'], + ['<section>', '<p>[foobar]</p>'], + ['<ul>', '<p>[foobar]</p>'], + ['<xmp>', '<p>[foobar]</p>'], + ['<quasit>', '<p>[foobar]</p>'], + + ['<address>', '<p>[foo<p>bar]'], + ['<article>', '<p>[foo<p>bar]'], + ['<aside>', '<p>[foo<p>bar]'], + ['<blockquote>', '<p>[foo<p>bar]'], + ['<body>', '<p>[foo<p>bar]'], + ['<dd>', '<p>[foo<p>bar]'], + ['<del>', '<p>[foo<p>bar]'], + ['<details>', '<p>[foo<p>bar]'], + ['<dir>', '<p>[foo<p>bar]'], + ['<div>', '<p>[foo<p>bar]'], + ['<dl>', '<p>[foo<p>bar]'], + ['<dt>', '<p>[foo<p>bar]'], + ['<fieldset>', '<p>[foo<p>bar]'], + ['<figcaption>', '<p>[foo<p>bar]'], + ['<figure>', '<p>[foo<p>bar]'], + ['<footer>', '<p>[foo<p>bar]'], + ['<form>', '<p>[foo<p>bar]'], + ['<h1>', '<p>[foo<p>bar]'], + ['<h2>', '<p>[foo<p>bar]'], + ['<h3>', '<p>[foo<p>bar]'], + ['<h4>', '<p>[foo<p>bar]'], + ['<h5>', '<p>[foo<p>bar]'], + ['<h6>', '<p>[foo<p>bar]'], + ['<header>', '<p>[foo<p>bar]'], + ['<head>', '<p>[foo<p>bar]'], + ['<hgroup>', '<p>[foo<p>bar]'], + ['<hr>', '<p>[foo<p>bar]'], + ['<html>', '<p>[foo<p>bar]'], + ['<ins>', '<p>[foo<p>bar]'], + ['<li>', '<p>[foo<p>bar]'], + ['<listing>', '<p>[foo<p>bar]'], + ['<menu>', '<p>[foo<p>bar]'], + ['<nav>', '<p>[foo<p>bar]'], + ['<ol>', '<p>[foo<p>bar]'], + ['<p>', '<p>[foo<p>bar]'], + ['<plaintext>', '<p>[foo<p>bar]'], + ['<pre>', '<p>[foo<p>bar]'], + ['<section>', '<p>[foo<p>bar]'], + ['<ul>', '<p>[foo<p>bar]'], + ['<xmp>', '<p>[foo<p>bar]'], + ['<quasit>', '<p>[foo<p>bar]'], + + ['p', '<div>[foobar]</div>'], + + '<ol><li>[foo]<li>bar</ol>', + + ['<p>', '<h1>[foo]<br>bar</h1>'], + ['<p>', '<h1>foo<br>[bar]</h1>'], + ['<p>', '<h1>[foo<br>bar]</h1>'], + ['<address>', '<h1>[foo]<br>bar</h1>'], + ['<address>', '<h1>foo<br>[bar]</h1>'], + ['<address>', '<h1>[foo<br>bar]</h1>'], + ['<pre>', '<h1>[foo]<br>bar</h1>'], + ['<pre>', '<h1>foo<br>[bar]</h1>'], + ['<pre>', '<h1>[foo<br>bar]</h1>'], + ['<h2>', '<h1>[foo]<br>bar</h1>'], + ['<h2>', '<h1>foo<br>[bar]</h1>'], + ['<h2>', '<h1>[foo<br>bar]</h1>'], + + ['<h1>', '<p>[foo]<br>bar</p>'], + ['<h1>', '<p>foo<br>[bar]</p>'], + ['<h1>', '<p>[foo<br>bar]</p>'], + ['<address>', '<p>[foo]<br>bar</p>'], + ['<address>', '<p>foo<br>[bar]</p>'], + ['<address>', '<p>[foo<br>bar]</p>'], + ['<pre>', '<p>[foo]<br>bar</p>'], + ['<pre>', '<p>foo<br>[bar]</p>'], + ['<pre>', '<p>[foo<br>bar]</p>'], + + ['<p>', '<address>[foo]<br>bar</address>'], + ['<p>', '<address>foo<br>[bar]</address>'], + ['<p>', '<address>[foo<br>bar]</address>'], + ['<pre>', '<address>[foo]<br>bar</address>'], + ['<pre>', '<address>foo<br>[bar]</address>'], + ['<pre>', '<address>[foo<br>bar]</address>'], + ['<h1>', '<address>[foo]<br>bar</address>'], + ['<h1>', '<address>foo<br>[bar]</address>'], + ['<h1>', '<address>[foo<br>bar]</address>'], + + ['<p>', '<pre>[foo]<br>bar</pre>'], + ['<p>', '<pre>foo<br>[bar]</pre>'], + ['<p>', '<pre>[foo<br>bar]</pre>'], + ['<address>', '<pre>[foo]<br>bar</pre>'], + ['<address>', '<pre>foo<br>[bar]</pre>'], + ['<address>', '<pre>[foo<br>bar]</pre>'], + ['<h1>', '<pre>[foo]<br>bar</pre>'], + ['<h1>', '<pre>foo<br>[bar]</pre>'], + ['<h1>', '<pre>[foo<br>bar]</pre>'], + + ['<h1>', '<p>[foo</p>bar]'], + ['<h1>', '[foo<p>bar]</p>'], + ['<p>', '<div>[foo<p>bar]</p></div>'], + ['<p>', '<xmp>[foo]</xmp>'], + ['<div>', '<xmp>[foo]</xmp>'], + + '<div><ol><li>[foo]</ol></div>', + '<div><table><tr><td>[foo]</table></div>', + '<p>[foo<h1>bar]</h1>', + '<h1>[foo</h1><h2>bar]</h2>', + '<div>[foo</div>bar]', + + // https://bugs.webkit.org/show_bug.cgi?id=47054 + ['<p>', '<div style=color:blue>[foo]</div>'], + // https://bugs.webkit.org/show_bug.cgi?id=47574 + ['<h1>', '{<p>foo</p>ba]r'], + ['<pre>', ' [foo<p>bar]</p>'], + // From https://bugs.webkit.org/show_bug.cgi?id=47300 + // http://www.w3.org/Bugs/Public/show_bug.cgi?id=14009 + ['!<p>', '{<pre> foo bar </pre>}'], + ], + //@} + forwarddelete: [ + //@{ + // Collapsed selection + 'foo[]', + '<span>foo[]</span>', + '<p>foo[]</p>', + 'foo[]bar', + '<span>foo</span>{}<span>bar</span>', + '<span>foo[</span><span>]bar</span>', + 'foo[]<span style=display:none>bar</span>baz', + 'foo[]<script>bar</script>baz', + 'fo[]öbar', + 'fo[]öbar', + 'fo[]ö̧bar', + '[]öbar', + '[]öbar', + '[]ö̧bar', + + '[]שָׁלוֹם', + 'שָׁל[]וֹם', + + '<p>foo[]</p><p>bar</p>', + '<p>foo[]</p>bar', + 'foo[]<p>bar</p>', + '<p>foo[]<br></p><p>bar</p>', + '<p>foo[]<br></p>bar', + 'foo[]<br><p>bar</p>', + + '<p>{}<br></p>foo', + '<p>{}<span><br></span></p>foo', + 'foo{}<p><br>', + 'foo{}<p><span><br></span>', + 'foo{}<br><p><br>', + 'foo{}<span><br></span><p><br>', + 'foo{}<br><p><span><br></span>', + 'foo{}<span><br></span><p><span><br></span>', + 'foo{}<p>', + '<table><tr><td>{}</table>foo', + '<table><tr><td>{}<br></table>foo', + '<table><tr><td>{}<span><br></span></table>foo', + + '<div><p>foo[]</p></div><p>bar</p>', + '<p>foo[]</p><div><p>bar</p></div>', + '<div><p>foo[]</p></div><div><p>bar</p></div>', + '<div><p>foo[]</p></div>bar', + 'foo[]<div><p>bar</p></div>', + + '<div>foo[]</div><div>bar</div>', + '<pre>foo[]</pre>bar', + + 'foo[]<br>bar', + '<b>foo[]</b><br>bar', + 'foo[]<hr>bar', + '<p>foo[]<hr><p>bar', + '<p>foo[]</p><br><p>bar</p>', + '<p>foo[]</p><br><br><p>bar</p>', + '<p>foo[]</p><img src=/img/lion.svg><p>bar', + 'foo[]<img src=/img/lion.svg>bar', + + 'foo[]<a>bar</a>', + 'foo[]<a href=/>bar</a>', + 'foo[]<a name=abc>bar</a>', + 'foo[]<a href=/ name=abc>bar</a>', + 'foo[]<span><a>bar</a></span>', + 'foo[]<span><a href=/>bar</a></span>', + 'foo[]<span><a name=abc>bar</a></span>', + 'foo[]<span><a href=/ name=abc>bar</a></span>', + '<a>foo[]</a>bar', + '<a href=/>foo[]</a>bar', + '<a name=abc>foo[]</a>bar', + '<a href=/ name=abc>foo[]</a>bar', + + 'foo [] ', + '[] foo', + 'foo[] bar', + 'foo[] bar', + 'foo[] bar', + 'foo[] bar', + 'foo[] bar', + 'foo [] bar', + 'foo [] bar', + 'foo[] <span> </span> bar', + 'foo []<span> </span> bar', + 'foo <span> </span>[] bar', + '<b>foo[] </b> bar', + '<b>foo[] </b> bar', + '<b>foo[] </b> bar', + '<b>foo[] </b> bar', + + '<pre>foo [] </pre>', + '<pre>[] foo</pre>', + '<pre>foo[] bar</pre>', + '<pre>foo[] bar</pre>', + '<pre>foo[] bar</pre>', + + '<div style=white-space:pre>foo [] </div>', + '<div style=white-space:pre>[] foo</div>', + '<div style=white-space:pre>foo[] bar</div>', + '<div style=white-space:pre>foo[] bar</div>', + '<div style=white-space:pre>foo[] bar</div>', + + '<div style=white-space:pre-wrap>foo [] </div>', + '<div style=white-space:pre-wrap>[] foo</div>', + '<div style=white-space:pre-wrap>foo[] bar</div>', + '<div style=white-space:pre-wrap>foo[] bar</div>', + '<div style=white-space:pre-wrap>foo[] bar</div>', + + '<div style=white-space:pre-line>foo [] </div>', + '<div style=white-space:pre-line>[] foo</div>', + '<div style=white-space:pre-line>foo[] bar</div>', + '<div style=white-space:pre-line>foo[] bar</div>', + '<div style=white-space:pre-line>foo[] bar</div>', + + '<div style=white-space:nowrap>foo [] </div>', + '<div style=white-space:nowrap>[] foo</div>', + '<div style=white-space:nowrap>foo[] bar</div>', + '<div style=white-space:nowrap>foo[] bar</div>', + '<div style=white-space:nowrap>foo[] bar</div>', + + // Tables with collapsed selection + 'foo[]<table><tr><td>bar</table>baz', + 'foo<table><tr><td>bar[]</table>baz', + '<p>foo[]<table><tr><td>bar</table><p>baz', + '<table><tr><td>foo[]<td>bar</table>', + '<table><tr><td>foo[]<tr><td>bar</table>', + + 'foo[]<br><table><tr><td>bar</table>baz', + 'foo<table><tr><td>bar[]<br></table>baz', + '<p>foo[]<br><table><tr><td>bar</table><p>baz', + '<p>foo<table><tr><td>bar[]<br></table><p>baz', + '<table><tr><td>foo[]<br><td>bar</table>', + '<table><tr><td>foo[]<br><tr><td>bar</table>', + + 'foo<table><tr><td>bar[]</table><br>baz', + 'foo[]<table><tr><td><hr>bar</table>baz', + '<table><tr><td>foo[]<td><hr>bar</table>', + '<table><tr><td>foo[]<tr><td><hr>bar</table>', + + // Lists with collapsed selection + 'foo[]<ol><li>bar<li>baz</ol>', + 'foo[]<br><ol><li>bar<li>baz</ol>', + '<ol><li>foo[]<li>bar</ol>', + '<ol><li>foo[]<br><li>bar</ol>', + '<ol><li>foo[]<li>bar<br>baz</ol>', + + '<ol><li><p>foo[]<li>bar</ol>', + '<ol><li>foo[]<li><p>bar</ol>', + '<ol><li><p>foo[]<li><p>bar</ol>', + + '<ol><li>foo[]<ul><li>bar</ul></ol>', + 'foo[]<ol><ol><li>bar</ol></ol>', + 'foo[]<div><ol><li>bar</ol></div>', + + 'foo[]<dl><dt>bar<dd>baz</dl>', + 'foo[]<dl><dd>bar</dl>', + '<dl><dt>foo[]<dd>bar</dl>', + '<dl><dt>foo[]<dt>bar<dd>baz</dl>', + '<dl><dt>foo<dd>bar[]<dd>baz</dl>', + + '<ol><li>foo[]</ol>bar', + '<ol><li>foo[]<br></ol>bar', + '<ol><li>{}<br></ol>bar', + '<ol><li>foo<li>{}<br></ol>bar', + + '<ol><li>foo[]</ol><p>bar', + '<ol><li>foo[]<br></ol><p>bar', + '<ol><li>{}<br></ol><p>bar', + '<ol><li>foo<li>{}<br></ol><p>bar', + + '<ol><li>foo[]</ol><br>', + '<ol><li>foo[]<br></ol><br>', + '<ol><li>{}<br></ol><br>', + '<ol><li>foo<li>{}<br></ol><br>', + + '<ol><li>foo[]</ol><p><br>', + '<ol><li>foo[]<br></ol><p><br>', + '<ol><li>{}<br></ol><p><br>', + '<ol><li>foo<li>{}<br></ol><p><br>', + + // Indented stuff with collapsed selection + 'foo[]<blockquote>bar</blockquote>', + 'foo[]<blockquote><blockquote>bar</blockquote></blockquote>', + 'foo[]<blockquote><div>bar</div></blockquote>', + 'foo[]<blockquote style="color: blue">bar</blockquote>', + + 'foo[]<blockquote><blockquote><p>bar<p>baz</blockquote></blockquote>', + 'foo[]<blockquote><div><p>bar<p>baz</div></blockquote>', + 'foo[]<blockquote style="color: blue"><p>bar<p>baz</blockquote>', + + 'foo[]<blockquote><p><b>bar</b><p>baz</blockquote>', + 'foo[]<blockquote><p><strong>bar</strong><p>baz</blockquote>', + 'foo[]<blockquote><p><span>bar</span><p>baz</blockquote>', + + 'foo[]<blockquote><ol><li>bar</ol></blockquote><p>extra', + 'foo[]<blockquote>bar<ol><li>baz</ol>quz</blockquote><p>extra', + 'foo<blockquote><ol><li>bar[]</li><ol><li>baz</ol><li>quz</ol></blockquote><p>extra', + + // Invisible stuff with collapsed selection + 'foo[]<span></span>bar', + 'foo[]<span><span></span></span>bar', + 'foo[]<quasit></quasit>bar', + 'foo[]<span></span><br>bar', + '<span>foo[]<span></span></span>bar', + 'foo[]<span></span><span>bar</span>', + 'foo[]<div><div><p>bar</div></div>', + 'foo[]<div><div><p><!--abc-->bar</div></div>', + 'foo[]<div><div><!--abc--><p>bar</div></div>', + 'foo[]<div><!--abc--><div><p>bar</div></div>', + 'foo[]<!--abc--><div><div><p>bar</div></div>', + '<div><div><p>foo[]</div></div>bar', + '<div><div><p>foo[]</div></div><!--abc-->bar', + '<div><div><p>foo[]</div><!--abc--></div>bar', + '<div><div><p>foo[]</p><!--abc--></div></div>bar', + '<div><div><p>foo[]<!--abc--></div></div>bar', + '<div><div><p>foo[]</p></div></div><div><div><div>bar</div></div></div>', + '<div><div><p>foo[]<!--abc--></p></div></div><div><div><div>bar</div></div></div>', + '<div><div><p>foo[]</p><!--abc--></div></div><div><div><div>bar</div></div></div>', + '<div><div><p>foo[]</p></div><!--abc--></div><div><div><div>bar</div></div></div>', + '<div><div><p>foo[]</p></div></div><!--abc--><div><div><div>bar</div></div></div>', + '<div><div><p>foo[]</p></div></div><div><!--abc--><div><div>bar</div></div></div>', + '<div><div><p>foo[]</p></div></div><div><div><!--abc--><div>bar</div></div></div>', + '<div><div><p>foo[]</p></div></div><div><div><div><!--abc-->bar</div></div></div>', + + // Styled stuff with collapsed selection + '<p style=color:blue>foo[]<p>bar', + '<p style=color:blue>foo[]<p style=color:brown>bar', + '<p>foo[]<p style=color:brown>bar', + '<p><font color=blue>foo[]</font><p>bar', + '<p><font color=blue>foo[]</font><p><font color=brown>bar</font>', + '<p>foo[]<p><font color=brown>bar</font>', + '<p><span style=color:blue>foo[]</font><p>bar', + '<p><span style=color:blue>foo[]</font><p><span style=color:brown>bar</font>', + '<p>foo[]<p><span style=color:brown>bar</font>', + + '<p style=background-color:aqua>foo[]<p>bar', + '<p style=background-color:aqua>foo[]<p style=background-color:tan>bar', + '<p>foo[]<p style=background-color:tan>bar', + '<p><span style=background-color:aqua>foo[]</font><p>bar', + '<p><span style=background-color:aqua>foo[]</font><p><span style=background-color:tan>bar</font>', + '<p>foo[]<p><span style=background-color:tan>bar</font>', + + '<p style=text-decoration:underline>foo[]<p>bar', + '<p style=text-decoration:underline>foo[]<p style=text-decoration:line-through>bar', + '<p>foo[]<p style=text-decoration:line-through>bar', + '<p><u>foo[]</u><p>bar', + '<p><u>foo[]</u><p><s>bar</s>', + '<p>foo[]<p><s>bar</s>', + + '<p style=color:blue>foo[]</p>bar', + 'foo[]<p style=color:brown>bar', + '<div style=color:blue><p style=color:green>foo[]</div>bar', + '<div style=color:blue><p style=color:green>foo[]</div><p style=color:brown>bar', + '<p style=color:blue>foo[]<div style=color:brown><p style=color:green>bar', + + // Uncollapsed selection (should be same as delete command) + 'foo[bar]baz', + '<p>foo<span style=color:#aBcDeF>[bar]</span>baz', + '<p>foo<span style=color:#aBcDeF>{bar}</span>baz', + '<p>foo{<span style=color:#aBcDeF>bar</span>}baz', + '<p>[foo<span style=color:#aBcDeF>bar]</span>baz', + '<p>{foo<span style=color:#aBcDeF>bar}</span>baz', + '<p>foo<span style=color:#aBcDeF>[bar</span>baz]', + '<p>foo<span style=color:#aBcDeF>{bar</span>baz}', + '<p>foo<span style=color:#aBcDeF>[bar</span><span style=color:#fEdCbA>baz]</span>quz', + + 'foo<b>[bar]</b>baz', + 'foo<b>{bar}</b>baz', + 'foo{<b>bar</b>}baz', + 'foo<span>[bar]</span>baz', + 'foo<span>{bar}</span>baz', + 'foo{<span>bar</span>}baz', + '<b>foo[bar</b><i>baz]quz</i>', + '<p>foo</p><p>[bar]</p><p>baz</p>', + '<p>foo</p><p>{bar}</p><p>baz</p>', + '<p>foo</p><p>{bar</p>}<p>baz</p>', + '<p>foo</p>{<p>bar}</p><p>baz</p>', + '<p>foo</p>{<p>bar</p>}<p>baz</p>', + + '<p>foo[bar<p>baz]quz', + '<p>foo[bar<div>baz]quz</div>', + '<p>foo[bar<h1>baz]quz</h1>', + '<div>foo[bar</div><p>baz]quz', + '<blockquote>foo[bar</blockquote><pre>baz]quz</pre>', + + '<p><b>foo[bar</b><p>baz]quz', + '<div><p>foo[bar</div><p>baz]quz', + '<p>foo[bar<blockquote><p>baz]quz<p>qoz</blockquote', + '<p>foo[bar<p style=color:blue>baz]quz', + '<p>foo[bar<p><b>baz]quz</b>', + + '<div><p>foo<p>[bar<p>baz]</div>', + + 'foo[<br>]bar', + '<p>foo[</p><p>]bar</p>', + '<p>foo[</p><p>]bar<br>baz</p>', + 'foo[<p>]bar</p>', + 'foo{<p>}bar</p>', + 'foo[<p>]bar<br>baz</p>', + 'foo[<p>]bar</p>baz', + 'foo{<p>bar</p>}baz', + 'foo<p>{bar</p>}baz', + 'foo{<p>bar}</p>baz', + '<p>foo[</p>]bar', + '<p>foo{</p>}bar', + '<p>foo[</p>]bar<br>baz', + '<p>foo[</p>]bar<p>baz</p>', + 'foo[<div><p>]bar</div>', + '<div><p>foo[</p></div>]bar', + 'foo[<div><p>]bar</p>baz</div>', + 'foo[<div>]bar<p>baz</p></div>', + '<div><p>foo</p>bar[</div>]baz', + '<div>foo<p>bar[</p></div>]baz', + + '<p>foo<br>{</p>]bar', + '<p>foo<br><br>{</p>]bar', + 'foo<br>{<p>]bar</p>', + 'foo<br><br>{<p>]bar</p>', + '<p>foo<br>{</p><p>}bar</p>', + '<p>foo<br><br>{</p><p>}bar</p>', + + '<table><tbody><tr><th>foo<th>[bar]<th>baz<tr><td>quz<td>qoz<td>qiz</table>', + '<table><tbody><tr><th>foo<th>ba[r<th>b]az<tr><td>quz<td>qoz<td>qiz</table>', + '<table><tbody><tr><th>fo[o<th>bar<th>b]az<tr><td>quz<td>qoz<td>qiz</table>', + '<table><tbody><tr><th>foo<th>bar<th>ba[z<tr><td>q]uz<td>qoz<td>qiz</table>', + '<table><tbody><tr><th>[foo<th>bar<th>baz]<tr><td>quz<td>qoz<td>qiz</table>', + '<table><tbody><tr><th>[foo<th>bar<th>baz<tr><td>quz<td>qoz<td>qiz]</table>', + '{<table><tbody><tr><th>foo<th>bar<th>baz<tr><td>quz<td>qoz<td>qiz</table>}', + '<table><tbody><tr><td>foo<td>ba[r<tr><td>baz<td>quz<tr><td>q]oz<td>qiz</table>', + '<p>fo[o<table><tr><td>b]ar</table><p>baz', + '<p>foo<table><tr><td>ba[r</table><p>b]az', + '<p>fo[o<table><tr><td>bar</table><p>b]az', + + '<p>foo<ol><li>ba[r<li>b]az</ol><p>quz', + '<p>foo<ol><li>bar<li>[baz]</ol><p>quz', + '<p>fo[o<ol><li>b]ar<li>baz</ol><p>quz', + '<p>foo<ol><li>bar<li>ba[z</ol><p>q]uz', + '<p>fo[o<ol><li>bar<li>b]az</ol><p>quz', + '<p>fo[o<ol><li>bar<li>baz</ol><p>q]uz', + + '<ol><li>fo[o</ol><ol><li>b]ar</ol>', + '<ol><li>fo[o</ol><ul><li>b]ar</ul>', + + 'foo[<ol><li>]bar</ol>', + '<ol><li>foo[<li>]bar</ol>', + 'foo[<dl><dt>]bar<dd>baz</dl>', + 'foo[<dl><dd>]bar</dl>', + '<dl><dt>foo[<dd>]bar</dl>', + '<dl><dt>foo[<dt>]bar<dd>baz</dl>', + '<dl><dt>foo<dd>bar[<dd>]baz</dl>', + + // https://bugs.webkit.org/show_bug.cgi?id=35281 + // http://www.w3.org/Bugs/Public/show_bug.cgi?id=13976 + '<ol><li>foo</ol>{}<br><ol><li>bar</ol>', + '<ol><li>foo</ol><p>{}<br></p><ol><li>bar</ol>', + '<ol><li><p>foo</ol><p>{}<br></p><ol><li>bar</ol>', + '<ol id=a><li>foo</ol>{}<br><ol><li>bar</ol>', + '<ol><li>foo</ol>{}<br><ol id=b><li>bar</ol>', + '<ol id=a><li>foo</ol>{}<br><ol id=b><li>bar</ol>', + '<ol class=a><li>foo</ol>{}<br><ol class=b><li>bar</ol>', + '<ol><ol><li>foo</ol><li>{}<br><ol><li>bar</ol></ol>', + '<ol><ol><li>foo</ol><li>{}<br></li><ol><li>bar</ol></ol>', + '<ol><li>foo[</ol>bar]<ol><li>baz</ol>', + '<ol><li>foo[</ol><p>bar]<ol><li>baz</ol>', + '<ol><li><p>foo[</ol><p>bar]<ol><li>baz</ol>', + '<ol><li>fo[]o</ol><ol><li>bar</ol>', + '<ol><li>foo</ol>[bar<ol><li>]baz</ol>', + '<ol><li>foo</ol><p>[bar<ol><li>]baz</ol>', + '<ol><li>foo</ol><p>[bar<ol><li><p>]baz</ol>', + '<ol><li>foo</ol><ol><li>[]bar</ol>', + '<ol><ol><li>foo[</ol><li>bar</ol>baz]<ol><li>quz</ol>', + '<ul><li>foo</ul>{}<br><ul><li>bar</ul>', + '<ul><li>foo</ul><p>{}<br></p><ul><li>bar</ul>', + '<ol><li>foo[<li>bar]</ol><ol><li>baz</ol><ol><li>quz</ol>', + '<ol><li>foo</ol>{}<br><ul><li>bar</ul>', + '<ol><li>foo</ol><p>{}<br></p><ul><li>bar</ul>', + '<ul><li>foo</ul>{}<br><ol><li>bar</ol>', + '<ul><li>foo</ul><p>{}<br></p><ol><li>bar</ol>', + + // http://www.w3.org/Bugs/Public/show_bug.cgi?id=13831 + '<p><b>[foo]</b>', + '<p><quasit>[foo]</quasit>', + '<p><b><i>[foo]</i></b>', + '<p><b>{foo}</b>', + '<p>{<b>foo</b>}', + '<p><b>[]f</b>', + '<b>[foo]</b>', + '<div><b>[foo]</b></div>', + ], + //@} + hilitecolor: [ + //@{ + 'foo[]bar', + '<p>[foo</p> <p>bar]</p>', + '<span>[foo</span> <span>bar]</span>', + '<p>[foo</p><p> <span>bar</span> </p><p>baz]</p>', + '<p>[foo<p><br><p>bar]', + '<b>foo[]bar</b>', + '<i>foo[]bar</i>', + '<span>foo</span>{}<span>bar</span>', + '<span>foo[</span><span>]bar</span>', + 'foo[bar]baz', + 'foo[bar<b>baz]qoz</b>quz', + 'foo[bar<i>baz]qoz</i>quz', + '{<p><p> <p>foo</p>}', + + '<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>', + '<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table>', + '<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table>', + '<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>', + '<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>', + '{<table><tr><td>foo<td>bar<td>baz</table>}', + + '<p style="background-color: rgb(0, 255, 255)">foo[bar]baz</p>', + '<p style="background-color: #00ffff">foo[bar]baz</p>', + '<p style="background-color: aqua">foo[bar]baz</p>', + '{<p style="background-color: aqua">foo</p><p>bar</p>}', + '<span style="background-color: aqua">foo<span style="background-color: tan">[bar]</span>baz</span>', + '<span style="background-color: #00ffff">foo<span style="background-color: tan">[bar]</span>baz</span>', + '<span style="background-color: #0ff">foo<span style="background-color: tan">[bar]</span>baz</span>', + '<span style="background-color: rgb(0, 255, 255)">foo<span style="background-color: tan">[bar]</span>baz</span>', + '<span style="background-color: aqua">foo<span style="background-color: tan">b[ar]</span>baz</span>', + '<p style="background-color: aqua">foo<span style="background-color: tan">b[ar]</span>baz</p>', + '<div style="background-color: aqua"><p style="background-color: tan">b[ar]</p></div>', + '<span style="display: block; background-color: aqua"><span style="display: block; background-color: tan">b[ar]</span></span>', + + // Tests for queryCommandIndeterm() and queryCommandState() + 'fo[o<span style=background-color:tan>b]ar</span>baz', + 'foo<span style=background-color:tan>ba[r</span>b]az', + 'fo[o<span style=background-color:tan>bar</span>b]az', + 'foo[<span style=background-color:tan>b]ar</span>baz', + 'foo<span style=background-color:tan>ba[r</span>]baz', + 'foo[<span style=background-color:tan>bar</span>]baz', + 'foo<span style=background-color:tan>[bar]</span>baz', + 'foo{<span style=background-color:tan>bar</span>}baz', + '<span style=background-color:tan>fo[o</span><span style=background-color:yellow>b]ar</span>', + '<span style=background-color:tan>fo[o</span><span style=background-color:tan>b]ar</span>', + '<span style=background-color:tan>fo[o<span style=background-color:transparent>b]ar</span></span>', + + // http://www.w3.org/Bugs/Public/show_bug.cgi?id=13829 + '!<font size=6>[foo]</font>', + '!<span style=font-size:xx-large>[foo]</span>', + '!<font size=6>foo[bar]baz</font>', + '!<span style=font-size:xx-large>foo[bar]baz</span>', + '![foo<font size=6>bar</font>baz]', + '![foo<span style=font-size:xx-large>bar</span>baz]', + ], + //@} + indent: [ + //@{ + // All these have a trailing unselected paragraph, because otherwise + // Gecko is unhappy: it throws exceptions in non-CSS mode, and in CSS + // mode it adds the indentation invisibly to the wrapper div in many + // cases. + 'foo[]bar<p>extra', + '<span>foo</span>{}<span>bar</span><p>extra', + '<span>foo[</span><span>]bar</span><p>extra', + 'foo[bar]baz<p>extra', + '<p dir=rtl>פו[בר]בז<p dir=rtl>נוםף', + '<p dir=rtl>פו[ברבז<p>Foobar]baz<p>Extra', + '<p>Foo[barbaz<p dir=rtl>פובר]בז<p>Extra', + '<div><p>Foo[barbaz<p dir=rtl>פובר]בז</div><p>Extra', + 'foo]bar[baz<p>extra', + '{<p><p> <p>foo</p>}<p>extra', + 'foo[bar<i>baz]qoz</i>quz<p>extra', + '[]foo<p>extra', + 'foo[]<p>extra', + '<p>[]foo<p>extra', + '<p>foo[]<p>extra', + '<p>{}<br>foo</p><p>extra', + '<p>foo<br>{}</p><p>extra', + '<span>{}<br>foo</span>bar<p>extra', + '<span>foo<br>{}</span>bar<p>extra', + '<p>foo</p>{}<p>bar</p>', + + '<table><tbody><tr><td>foo<td>b[a]r<td>baz</table><p>extra', + '<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra', + '<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra', + '<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra', + '<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table><p>extra', + '{<table><tr><td>foo<td>bar<td>baz</table>}<p>extra', + + '<p>foo[bar]</p><p>baz</p><p>extra', + '<p>[foobar</p><p>ba]z</p><p>extra', + 'foo[bar]<br>baz<p>extra', + 'foo[bar]<br><br><br><br>baz<p>extra', + 'foobar<br>[ba]z<p>extra', + 'foobar<br><br><br><br>[ba]z<p>extra', + 'foo[bar<br>ba]z<p>extra', + '<div>foo<p>[bar]</p>baz</div><p>extra', + + // These mimic existing indentation in various browsers, to see how + // they cope with indenting twice. This is spec, Gecko non-CSS, and + // Opera: + '<blockquote><p>foo[bar]</p><p>baz</p></blockquote><p>extra', + '<blockquote><p>foo[bar</p><p>b]az</p></blockquote><p>extra', + '<blockquote><p>foo[bar]</p></blockquote><p>baz</p><p>extra', + '<blockquote><p>foo[bar</p></blockquote><p>b]az</p><p>extra', + '<p>[foo]<blockquote><p>bar</blockquote><p>extra', + '<p>[foo<blockquote><p>b]ar</blockquote><p>extra', + '<p>foo<blockquote><p>bar</blockquote><p>[baz]<p>extra', + '<p>foo<blockquote><p>[bar</blockquote><p>baz]<p>extra', + '<p>[foo<blockquote><p>bar</blockquote><p>baz]<p>extra', + '<blockquote><p>foo</blockquote><p>[bar]<blockquote><p>baz</blockquote><p>extra', + + '<blockquote>foo[bar]<br>baz</blockquote><p>extra', + '<blockquote>foo[bar<br>b]az</blockquote><p>extra', + '<blockquote>foo[bar]</blockquote>baz<p>extra', + '<blockquote>foo[bar</blockquote>b]az<p>extra', + '[foo]<blockquote>bar</blockquote><p>extra', + '[foo<blockquote>b]ar</blockquote><p>extra', + 'foo<blockquote>bar</blockquote>[baz]<p>extra', + '[foo<blockquote>bar</blockquote>baz]<p>extra', + '<blockquote>foo</blockquote>[bar]<blockquote>baz</blockquote><p>extra', + + // IE: + '<blockquote style="margin-right: 0" dir="ltr"><p>foo[bar]</p><p>baz</p></blockquote><p>extra', + '<blockquote style="margin-right: 0" dir="ltr"><p>foo[bar</p><p>b]az</p></blockquote><p>extra', + '<blockquote style="margin-right: 0" dir="ltr"><p>foo[bar]</p></blockquote><p>baz</p><p>extra', + '<blockquote style="margin-right: 0" dir="ltr"><p>foo[bar</p></blockquote><p>b]az</p><p>extra', + '<p>[foo]<blockquote style="margin-right: 0" dir="ltr"><p>bar</blockquote><p>extra', + '<p>[foo<blockquote style="margin-right: 0" dir="ltr"><p>b]ar</blockquote><p>extra', + '<p>foo<blockquote style="margin-right: 0" dir="ltr"><p>bar</blockquote><p>[baz]<p>extra', + '<p>foo<blockquote style="margin-right: 0" dir="ltr"><p>[bar</blockquote><p>baz]<p>extra', + '<p>[foo<blockquote style="margin-right: 0" dir="ltr"><p>bar</blockquote><p>baz]<p>extra', + '<blockquote style="margin-right: 0" dir="ltr"><p>foo</blockquote><p>[bar]<blockquote style="margin-right: 0" dir="ltr"><p>baz</blockquote><p>extra', + + // Firefox CSS mode: + '<p style="margin-left: 40px">foo[bar]</p><p style="margin-left: 40px">baz</p><p>extra', + '<p style="margin-left: 40px">foo[bar</p><p style="margin-left: 40px">b]az</p><p>extra', + '<p style="margin-left: 40px">foo[bar]</p><p>baz</p><p>extra', + '<p style="margin-left: 40px">foo[bar</p><p>b]az</p><p>extra', + '<p>[foo]<p style="margin-left: 40px">bar<p>extra', + '<p>[foo<p style="margin-left: 40px">b]ar<p>extra', + '<p>foo<p style="margin-left: 40px">bar<p>[baz]<p>extra', + '<p>foo<p style="margin-left: 40px">[bar<p>baz]<p>extra', + '<p>[foo<p style="margin-left: 40px">bar<p>baz]<p>extra', + '<p style="margin-left: 40px">foo<p>[bar]<p style="margin-left: 40px">baz<p>extra', + + // WebKit: + '<blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px"><p>foo[bar]</p><p>baz</p></blockquote><p>extra', + '<blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px"><p>foo[bar</p><p>b]az</p></blockquote><p>extra', + '<blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px"><p>foo[bar]</p></blockquote><p>baz</p><p>extra', + '<blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px"><p>foo[bar</p></blockquote><p>b]az</p><p>extra', + '<p>[foo]<blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px"><p>bar</blockquote><p>extra', + '<p>[foo<blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px"><p>b]ar</blockquote><p>extra', + '<p>foo<blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px"><p>bar</blockquote><p>[baz]<p>extra', + '<p>foo<blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px"><p>[bar</blockquote><p>baz]<p>extra', + '<p>[foo<blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px"><p>bar</blockquote><p>baz]<p>extra', + '<blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px"><p>foo</blockquote><p>[bar]<blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px"><p>baz</blockquote><p>extra', + + // MDC says "In Firefox, if the selection spans multiple lines at + // different levels of indentation, only the least indented lines in + // the selection will be indented." Let's test that. + '<blockquote>f[oo<blockquote>b]ar</blockquote></blockquote><p>extra', + + // Lists! + '<ol><li>foo<li>[bar]<li>baz</ol>', + '<ol data-start=1 data-end=2><li>foo<li>bar<li>baz</ol>', + '<ol><li>foo</ol>[bar]', + '<ol><li>[foo]<br>bar<li>baz</ol>', + '<ol><li>foo<br>[bar]<li>baz</ol>', + '<ol><li><div>[foo]</div>bar<li>baz</ol>', + '<ol><li>foo<ol><li>[bar]<li>baz</ol><li>quz</ol>', + '<ol><li>foo<ol><li>bar<li>[baz]</ol><li>quz</ol>', + '<ol><li>foo</li><ol><li>[bar]<li>baz</ol><li>quz</ol>', + '<ol><li>foo</li><ol data-start=0 data-end=1><li>bar<li>baz</ol><li>quz</ol>', + '<ol><li>foo</li><ol><li>bar<li>[baz]</ol><li>quz</ol>', + '<ol><li>foo</li><ol data-start=1 data-end=2><li>bar<li>baz</ol><li>quz</ol>', + '<ol><li>foo<ol><li>b[a]r</ol><li>baz</ol>', + '<ol><li>foo</li><ol><li>b[a]r</ol><li>baz</ol>', + '<ol><li>foo{<ol><li>bar</ol>}<li>baz</ol>', + '<ol><li>foo</li>{<ol><li>bar</ol>}<li>baz</ol>', + '<ol><li>[foo]<ol><li>bar</ol><li>baz</ol>', + '<ol><li>[foo]</li><ol><li>bar</ol><li>baz</ol>', + '<ol><li>foo<li>[bar]<ol><li>baz</ol><li>quz</ol>', + '<ol><li>foo<li>[bar]</li><ol><li>baz</ol><li>quz</ol>', + '<ol><li>foo<ol><li>bar<li>baz</ol><li>[quz]</ol>', + '<ol><li>foo</li><ol><li>bar<li>baz</ol><li>[quz]</ol>', + + // Lists with id's: + // http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2009-July/020721.html + '<ol><ol id=u1><li id=i1>foo</ol><li id=i2>[bar]</li><ol id=u3><li id=i3>baz</ol></ol>', + '<ol><ol><li id=i1>foo</ol><li id=i2>[bar]</li><ol id=u3><li id=i3>baz</ol></ol>', + '<ol><ol id=u1><li id=i1>foo</ol><li id=i2>[bar]</li><ol><li id=i3>baz</ol></ol>', + '<ol><li id=i2>[bar]</li><ol id=u3><li id=i3>baz</ol></ol>', + '<ol><ol id=u1><li id=i1>foo</ol><li id=i2>[bar]</ol>', + + // Try indenting multiple items at once. + '<ol><li>foo<li>b[ar<li>baz]</ol>', + '<ol><li>[foo<ol><li>bar]</ol><li>baz</ol>', + '<ol><li>[foo</li><ol><li>bar]</ol><li>baz</ol>', + '<ol><li>foo<ol><li>b[ar</ol><li>b]az</ol>', + '<ol><li>foo</li><ol><li>b[ar</ol><li>b]az</ol>', + '<ol><li>[foo<ol><li>bar</ol><li>baz]</ol><p>extra', + '<ol><li>[foo</li><ol><li>bar</ol><li>baz]</ol><p>extra', + + // We probably can't actually get this DOM . . . + '<ol><li>[foo]<ol><li>bar</ol>baz</ol>', + '<ol><li>foo<ol><li>[bar]</ol>baz</ol>', + '<ol><li>foo<ol><li>bar</ol>[baz]</ol>', + '<ol><li>[foo<ol><li>bar]</ol>baz</ol>', + + 'foo<!--bar-->[baz]<p>extra', + '[foo]<!--bar-->baz<p>extra', + '<p>foo<!--bar-->{}<p>extra', + '<p>{}<!--foo-->bar<p>extra', + + // Whitespace nodes + '<blockquote><p>foo</blockquote> <p>[bar]', + '<p>[foo]</p> <blockquote><p>bar</blockquote>', + '<blockquote><p>foo</blockquote> <p>[bar]</p> <blockquote><p>baz</blockquote>', + '<ol><li>foo</li><ol><li>bar</li> </ol><li>[baz]</ol>', + '<ol><li>foo</li><ol><li>bar</li></ol> <li>[baz]</ol>', + '<ol><li>foo</li><ol><li>bar</li> </ol> <li>[baz]</ol>', + '<ol><li>foo<ol><li>bar</li> </ol></li><li>[baz]</ol>', + '<ol><li>foo<ol><li>bar</li></ol></li> <li>[baz]</ol>', + '<ol><li>foo<ol><li>bar</li> </ol></li> <li>[baz]</ol>', + '<ol><li>foo<li>[bar]</li> <ol><li>baz</ol></ol>', + '<ol><li>foo<li>[bar]</li><ol> <li>baz</ol></ol>', + '<ol><li>foo<li>[bar]</li> <ol> <li>baz</ol></ol>', + '<ol><li>foo<li>[bar] <ol><li>baz</ol></ol>', + '<ol><li>foo<li>[bar]<ol> <li>baz</ol></ol>', + '<ol><li>foo<li>[bar] <ol> <li>baz</ol></ol>', + + // https://bugs.webkit.org/show_bug.cgi?id=32003 + '<ul><li>a<br>{<br>}</li><li>b</li></ul>', + ], + //@} + inserthorizontalrule: [ + //@{ + 'foo[]bar', + '<span>foo</span>{}<span>bar</span>', + '<span>foo[</span><span>]bar</span>', + '<p>foo[bar<p>baz]quz', + '<div><b>foo</b>{}<b>bar</b></div>', + '<div><b>foo[</b><b>]bar</b></div>', + '<div><b>foo</b>{<b>bar</b>}<b>baz</b></div>', + '<b>foo[]bar</b>', + '<b id=abc>foo[]bar</b>', + ["abc", 'foo[bar]baz'], + 'foo[bar]baz', + + 'foo<b>[bar]</b>baz', + 'foo<b>{bar}</b>baz', + 'foo{<b>bar</b>}baz', + '<p>foo<p>[bar]<p>baz', + '<p>foo<p>{bar}<p>baz', + '<p>foo{<p>bar</p>}<p>baz', + + '<p>foo[bar]baz</p>', + '<p id=abc>foo[bar]baz</p>', + '<h1>foo[bar]baz</h1>', + '<p>foo<b>b[a]r</b>baz</p>', + + '<a>foo[bar]baz</a>', + '<a href=/>foo[bar]baz</a>', + '<abbr>foo[bar]baz</abbr>', + '<address>foo[bar]baz</address>', + '<article>foo[bar]baz</article>', + '<aside>foo[bar]baz</aside>', + '<b>foo[bar]baz</b>', + '<bdi>foo[bar]baz</bdi>', + '<bdo dir=rtl>foo[bar]baz</bdo>', + '<blockquote>foo[bar]baz</blockquote>', + '<table><caption>foo[bar]baz</caption><tr><td>quz</table>', + '<cite>foo[bar]baz</cite>', + '<code>foo[bar]baz</code>', + '<dl><dd>foo[bar]baz</dd></dl>', + '<del>foo[bar]baz</del>', + '<details>foo[bar]baz</details>', + '<dfn>foo[bar]baz</dfn>', + '<div>foo[bar]baz</div>', + '<dl><dt>foo[bar]baz</dt></dl>', + '<em>foo[bar]baz</em>', + '<figure><figcaption>foo[bar]baz</figcaption>quz</figure>', + '<figure>foo[bar]baz</figure>', + '<footer>foo[bar]baz</footer>', + '<h1>foo[bar]baz</h1>', + '<h2>foo[bar]baz</h2>', + '<h3>foo[bar]baz</h3>', + '<h4>foo[bar]baz</h4>', + '<h5>foo[bar]baz</h5>', + '<h6>foo[bar]baz</h6>', + '<header>foo[bar]baz</header>', + '<hgroup>foo[bar]baz</hgroup>', + '<hgroup><h1>foo[bar]baz</h1></hgroup>', + '<i>foo[bar]baz</i>', + '<ins>foo[bar]baz</ins>', + '<kbd>foo[bar]baz</kbd>', + '<mark>foo[bar]baz</mark>', + '<nav>foo[bar]baz</nav>', + '<ol><li>foo[bar]baz</li></ol>', + '<p>foo[bar]baz</p>', + '<pre>foo[bar]baz</pre>', + '<q>foo[bar]baz</q>', + '<ruby>foo[bar]baz<rt>quz</rt></ruby>', + '<ruby>foo<rt>bar[baz]quz</rt></ruby>', + '<ruby>foo<rp>bar[baz]quz</rp><rt>qoz</rt><rp>qiz</rp></ruby>', + '<s>foo[bar]baz</s>', + '<samp>foo[bar]baz</samp>', + '<section>foo[bar]baz</section>', + '<small>foo[bar]baz</small>', + '<span>foo[bar]baz</span>', + '<strong>foo[bar]baz</strong>', + '<sub>foo[bar]baz</sub>', + '<sup>foo[bar]baz</sup>', + '<table><tr><td>foo[bar]baz</td></table>', + '<table><tr><th>foo[bar]baz</th></table>', + '<u>foo[bar]baz</u>', + '<ul><li>foo[bar]baz</li></ul>', + '<var>foo[bar]baz</var>', + + '<acronym>foo[bar]baz</acronym>', + '<big>foo[bar]baz</big>', + '<blink>foo[bar]baz</blink>', + '<center>foo[bar]baz</center>', + '<dir>foo[bar]baz</dir>', + '<dir><li>foo[bar]baz</li></dir>', + '<font>foo[bar]baz</font>', + '<listing>foo[bar]baz</listing>', + '<marquee>foo[bar]baz</marquee>', + '<nobr>foo[bar]baz</nobr>', + '<strike>foo[bar]baz</strike>', + '<tt>foo[bar]baz</tt>', + '<xmp>foo[bar]baz</xmp>', + + '<quasit>foo[bar]baz</quasit>', + + '<table><tr><td>fo[o<td>b]ar</table>', + 'fo[o<span contenteditable=false>bar</span>b]az', + ], + //@} + inserthtml: [ + //@{ + 'foo[]bar', + 'foo[bar]baz', + 'foo<span style=color:#aBcDeF>[bar]</span>baz', + 'foo<span style=color:#aBcDeF>{bar}</span>baz', + 'foo{<span style=color:#aBcDeF>bar</span>}baz', + '[foo<span style=color:#aBcDeF>bar]</span>baz', + '{foo<span style=color:#aBcDeF>bar}</span>baz', + 'foo<span style=color:#aBcDeF>[bar</span>baz]', + 'foo<span style=color:#aBcDeF>{bar</span>baz}', + 'foo<span style=color:#aBcDeF>[bar</span><span style=color:#fEdCbA>baz]</span>quz', + + ['', 'foo[bar]baz'], + ['\0', 'foo[bar]baz'], + ['\x07', 'foo[bar]baz'], + // The following line makes Firefox 7.0a2 go into an infinite loop on + // my machine. + //['\ud800', 'foo[bar]baz'], + + ['<b>', 'foo[bar]baz'], + ['<b>abc', 'foo[bar]baz'], + ['<p>abc', '<p>foo[bar]baz'], + ['<li>abc', '<p>foo[bar]baz'], + ['<p>abc', '<ol>{<li>foo</li>}<li>bar</ol>'], + ['<p>abc', '<ol><li>foo</li>{<li>bar</li>}<li>baz</ol>'], + ['<p>abc', '<ol><li>[foo]</li><li>bar</ol>'], + + ['abc', '<xmp>f[o]o</xmp>'], + ['<b>abc</b>', '<xmp>f[o]o</xmp>'], + ['abc', '<script>f[o]o</script>bar'], + ['<b>abc</b>', '<script>f[o]o</script>bar'], + + ['<a>abc</a>', '<a>f[o]o</a>'], + ['<a href=/>abc</a>', '<a href=.>f[o]o</a>'], + ['<hr>', '<p>f[o]o'], + ['<hr>', '<b>f[o]o</b>'], + ['<h2>abc</h2>', '<h1>f[o]o</h1>'], + ['<td>abc</td>', '<table><tr><td>f[o]o</table>'], + ['<td>abc</td>', 'f[o]o'], + + ['<dt>abc</dt>', '<dl><dt>f[o]o<dd>bar</dl>'], + ['<dt>abc</dt>', '<dl><dt>foo<dd>b[a]r</dl>'], + ['<dd>abc</dd>', '<dl><dt>f[o]o<dd>bar</dl>'], + ['<dd>abc</dd>', '<dl><dt>foo<dd>b[a]r</dl>'], + ['<dt>abc</dt>', 'f[o]o'], + ['<dt>abc</dt>', '<ol><li>f[o]o</ol>'], + ['<dd>abc</dd>', 'f[o]o'], + ['<dd>abc</dd>', '<ol><li>f[o]o</ol>'], + + ['<li>abc</li>', '<dir><li>f[o]o</dir>'], + ['<li>abc</li>', '<ol><li>f[o]o</ol>'], + ['<li>abc</li>', '<ul><li>f[o]o</ul>'], + ['<dir><li>abc</dir>', '<dir><li>f[o]o</dir>'], + ['<dir><li>abc</dir>', '<ol><li>f[o]o</ol>'], + ['<dir><li>abc</dir>', '<ul><li>f[o]o</ul>'], + ['<ol><li>abc</ol>', '<dir><li>f[o]o</dir>'], + ['<ol><li>abc</ol>', '<ol><li>f[o]o</ol>'], + ['<ol><li>abc</ol>', '<ul><li>f[o]o</ul>'], + ['<ul><li>abc</ul>', '<dir><li>f[o]o</dir>'], + ['<ul><li>abc</ul>', '<ol><li>f[o]o</ol>'], + ['<ul><li>abc</ul>', '<ul><li>f[o]o</ul>'], + ['<li>abc</li>', 'f[o]o'], + + ['<nobr>abc</nobr>', '<nobr>f[o]o</nobr>'], + ['<nobr>abc</nobr>', 'f[o]o'], + + ['<p>abc', '<font color=blue>foo[]bar</font>'], + ['<p>abc', '<span style=color:blue>foo[]bar</span>'], + ['<p>abc', '<span style=font-variant:small-caps>foo[]bar</span>'], + [' ', '<p>[foo]</p>'], + ['<span style=display:none></span>', '<p>[foo]</p>'], + ['<!--abc-->', '<p>[foo]</p>'], + + ['abc', '<p>{}<br></p>'], + ['<!--abc-->', '<p>{}<br></p>'], + ['abc', '<p><!--foo-->{}<span><br></span><!--bar--></p>'], + ['<!--abc-->', '<p><!--foo-->{}<span><br></span><!--bar--></p>'], + ['abc', '<p>{}<span><!--foo--><br><!--bar--></span></p>'], + ['<!--abc-->', '<p>{}<span><!--foo--><br><!--bar--></span></p>'], + + ['abc', '<p><br>{}</p>'], + ['<!--abc-->', '<p><br>{}</p>'], + ['abc', '<p><!--foo--><span><br></span>{}<!--bar--></p>'], + ['<!--abc-->', '<p><!--foo--><span><br></span>{}<!--bar--></p>'], + ['abc', '<p><span><!--foo--><br><!--bar--></span>{}</p>'], + ['<!--abc-->', '<p><span><!--foo--><br><!--bar--></span>{}</p>'], + ], + //@} + insertimage: [ + //@{ + 'foo[]bar', + '<span>foo</span>{}<span>bar</span>', + '<span>foo[</span><span>]bar</span>', + ["", 'foo[bar]baz'], + 'foo[bar]baz', + 'foo<span style=color:#aBcDeF>[bar]</span>baz', + 'foo<span style=color:#aBcDeF>{bar}</span>baz', + 'foo{<span style=color:#aBcDeF>bar</span>}baz', + '[foo<span style=color:#aBcDeF>bar]</span>baz', + '{foo<span style=color:#aBcDeF>bar}</span>baz', + 'foo<span style=color:#aBcDeF>[bar</span>baz]', + 'foo<span style=color:#aBcDeF>{bar</span>baz}', + 'foo<span style=color:#aBcDeF>[bar</span><span style=color:#fEdCbA>baz]</span>quz', + + 'foo<b>[bar]</b>baz', + 'foo<b>{bar}</b>baz', + 'foo{<b>bar</b>}baz', + 'foo<span>[bar]</span>baz', + 'foo<span>{bar}</span>baz', + 'foo{<span>bar</span>}baz', + '<b>foo[bar</b><i>baz]quz</i>', + '<p>foo</p><p>[bar]</p><p>baz</p>', + '<p>foo</p><p>{bar}</p><p>baz</p>', + '<p>foo</p>{<p>bar</p>}<p>baz</p>', + + '<p>foo[bar<p>baz]quz', + '<p>foo[bar<div>baz]quz</div>', + '<p>foo[bar<h1>baz]quz</h1>', + '<div>foo[bar</div><p>baz]quz', + '<blockquote>foo[bar</blockquote><pre>baz]quz</pre>', + + '<p><b>foo[bar</b><p>baz]quz', + '<div><p>foo[bar</div><p>baz]quz', + '<p>foo[bar<blockquote><p>baz]quz<p>qoz</blockquote', + '<p>foo[bar<p style=color:blue>baz]quz', + '<p>foo[bar<p><b>baz]quz</b>', + + '<div><p>foo<p>[bar<p>baz]</div>', + + 'foo[<br>]bar', + '<p>foo[</p><p>]bar</p>', + '<p>foo[</p><p>]bar<br>baz</p>', + 'foo[<p>]bar</p>', + 'foo[<p>]bar<br>baz</p>', + 'foo[<p>]bar</p>baz', + '<p>foo[</p>]bar', + '<p>foo[</p>]bar<br>baz', + '<p>foo[</p>]bar<p>baz</p>', + 'foo[<div><p>]bar</div>', + '<div><p>foo[</p></div>]bar', + 'foo[<div><p>]bar</p>baz</div>', + 'foo[<div>]bar<p>baz</p></div>', + '<div><p>foo</p>bar[</div>]baz', + '<div>foo<p>bar[</p></div>]baz', + ], + //@} + insertlinebreak: [ + //@{ Same as insertparagraph (set below) + ], + //@} + insertorderedlist: [ + //@{ + 'foo[]bar', + 'foo[bar]baz', + 'foo<br>[bar]', + 'f[oo<br>b]ar<br>baz', + '<p>[foo]<br>bar</p>', + '[foo<ol><li>bar]</ol>baz', + 'foo<ol><li>[bar</ol>baz]', + '[foo<ul><li>bar]</ul>baz', + 'foo<ul><li>[bar</ul>baz]', + 'foo<ul><li>[bar</ul><ol><li>baz]</ol>quz', + 'foo<ol><li>[bar</ol><ul><li>baz]</ul>quz', + + '<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>', + '<table><tbody><tr><td>fo[o<td>b]ar<td>baz</table>', + '{<table><tr><td>foo<td>bar<td>baz</table>}', + + '<p>foo<p>[bar]<p>baz', + '<p>foo<blockquote>[bar]</blockquote><p>baz', + '<dl><dt>foo<dd>[bar]<dt>baz<dd>quz</dl>', + '<dl><dt>foo<dd>bar<dt>[baz]<dd>quz</dl>', + + '<p>[foo<p>bar]<p>baz', + '<p>[foo<blockquote>bar]</blockquote><p>baz', + '<dl><dt>[foo<dd>bar]<dt>baz<dd>quz</dl>', + '<dl><dt>foo<dd>[bar<dt>baz]<dd>quz</dl>', + + '<p>[foo<blockquote><p>bar]<p>baz</blockquote>', + + + // Various <ol> stuff + '<ol><li>foo<li>[bar]<li>baz</ol>', + '<ol><li>foo</ol>[bar]', + '[foo]<ol><li>bar</ol>', + '<ol><li>foo</ol>[bar]<ol><li>baz</ol>', + '<ol><ol><li>[foo]</ol></ol>', + '<ol><li>[foo]<br>bar<li>baz</ol>', + '<ol><li>foo<br>[bar]<li>baz</ol>', + '<ol><li><div>[foo]</div>bar<li>baz</ol>', + '<ol><li>foo<ol><li>[bar]<li>baz</ol><li>quz</ol>', + '<ol><li>foo<ol><li>bar<li>[baz]</ol><li>quz</ol>', + '<ol><li>foo</li><ol><li>[bar]<li>baz</ol><li>quz</ol>', + '<ol><li>foo</li><ol><li>bar<li>[baz]</ol><li>quz</ol>', + '<ol><li>[foo]<ol><li>bar</ol><li>baz</ol>', + '<ol><li>[foo]</li><ol><li>bar</ol><li>baz</ol>', + '<ol><li>foo<li>[bar]<ol><li>baz</ol><li>quz</ol>', + '<ol><li>foo<li>[bar]</li><ol><li>baz</ol><li>quz</ol>', + '<ol><li>foo<ol><li>bar<li>baz</ol><li>[quz]</ol>', + '<ol><li>foo</li><ol><li>bar<li>baz</ol><li>[quz]</ol>', + + // Multiple items at once. + '<ol><li>foo<li>[bar<li>baz]</ol>', + '<ol><li>[foo<ol><li>bar]</ol><li>baz</ol>', + '<ol><li>foo<ol><li>b[ar</ol><li>b]az</ol>', + '<ol><li>[foo<ol><li>bar</ol><li>baz]</ol><p>extra', + + // We probably can't actually get this DOM . . . + '<ol><li>[foo]<ol><li>bar</ol>baz</ol>', + '<ol><li>foo<ol><li>[bar]</ol>baz</ol>', + '<ol><li>foo<ol><li>bar</ol>[baz]</ol>', + '<ol><li>[foo<ol><li>bar]</ol>baz</ol>', + + + // Same stuff but with <ul> + '<ul><li>foo<li>[bar]<li>baz</ul>', + '<ul><li>foo</ul>[bar]', + '[foo]<ul><li>bar</ul>', + '<ul><li>foo</ul>[bar]<ul><li>baz</ul>', + '<ul><ul><li>[foo]</ul></ul>', + '<ul><li>[foo]<br>bar<li>baz</ul>', + '<ul><li>foo<br>[bar]<li>baz</ul>', + '<ul><li><div>[foo]</div>bar<li>baz</ul>', + '<ul><li>foo<ul><li>[bar]<li>baz</ul><li>quz</ul>', + '<ul><li>foo<ul><li>bar<li>[baz]</ul><li>quz</ul>', + '<ul><li>foo</li><ul><li>[bar]<li>baz</ul><li>quz</ul>', + '<ul><li>foo</li><ul><li>bar<li>[baz]</ul><li>quz</ul>', + '<ul><li>[foo]<ul><li>bar</ul><li>baz</ul>', + '<ul><li>[foo]</li><ul><li>bar</ul><li>baz</ul>', + '<ul><li>foo<li>[bar]<ul><li>baz</ul><li>quz</ul>', + '<ul><li>foo<li>[bar]</li><ul><li>baz</ul><li>quz</ul>', + '<ul><li>foo<ul><li>bar<li>baz</ul><li>[quz]</ul>', + '<ul><li>foo</li><ul><li>bar<li>baz</ul><li>[quz]</ul>', + + // Multiple items at once. + '<ul><li>foo<li>[bar<li>baz]</ul>', + '<ul><li>[foo<ul><li>bar]</ul><li>baz</ul>', + '<ul><li>foo<ul><li>b[ar</ul><li>b]az</ul>', + '<ul><li>[foo<ul><li>bar</ul><li>baz]</ul><p>extra', + + // We probably can't actually get this DOM . . . + '<ul><li>[foo]<ul><li>bar</ul>baz</ul>', + '<ul><li>foo<ul><li>[bar]</ul>baz</ul>', + '<ul><li>foo<ul><li>bar</ul>[baz]</ul>', + '<ul><li>[foo<ul><li>bar]</ul>baz</ul>', + + + // Mix of <ol> and <ul> + 'foo<ol><li>bar</ol><ul><li>[baz]</ul>quz', + 'foo<ol><li>bar</ol><ul><li>[baz</ul>quz]', + 'foo<ul><li>[bar]</ul><ol><li>baz</ol>quz', + '[foo<ul><li>bar]</ul><ol><li>baz</ol>quz', + + // Interaction with indentation + '[foo]<blockquote>bar</blockquote>baz', + 'foo<blockquote>[bar]</blockquote>baz', + '[foo<blockquote>bar]</blockquote>baz', + '<ol><li>foo</ol><blockquote>[bar]</blockquote>baz', + '[foo]<blockquote><ol><li>bar</ol></blockquote>baz', + 'foo<blockquote>[bar]<br>baz</blockquote>', + '[foo<blockquote>bar]<br>baz</blockquote>', + '<ol><li>foo</ol><blockquote>[bar]<br>baz</blockquote>', + + '<p>[foo]<blockquote><p>bar</blockquote><p>baz', + '<p>foo<blockquote><p>[bar]</blockquote><p>baz', + '<p>[foo<blockquote><p>bar]</blockquote><p>baz', + '<ol><li>foo</ol><blockquote><p>[bar]</blockquote><p>baz', + + // Attributes + '<ul id=abc><li>foo<li>[bar]<li>baz</ul>', + '<ul style=color:blue><li>foo<li>[bar]<li>baz</ul>', + '<ul style=text-indent:1em><li>foo<li>[bar]<li>baz</ul>', + '<ul id=abc><li>[foo]<li>bar<li>baz</ul>', + '<ul style=color:blue><li>[foo]<li>bar<li>baz</ul>', + '<ul style=text-indent:1em><li>[foo]<li>bar<li>baz</ul>', + '<ul id=abc><li>foo<li>bar<li>[baz]</ul>', + '<ul style=color:blue><li>foo<li>bar<li>[baz]</ul>', + '<ul style=text-indent:1em><li>foo<li>bar<li>[baz]</ul>', + + // Whitespace nodes + '<ol><li>foo</ol> <p>[bar]', + '<p>[foo]</p> <ol><li>bar</ol>', + '<ol><li>foo</ol> <p>[bar]</p> <ol><li>baz</ol>', + + // This caused an infinite loop at one point due to a bug in "fix + // disallowed ancestors". Disabled because I'm not sure how we want it + // to behave: + // http://www.w3.org/Bugs/Public/show_bug.cgi?id=14578 + '!<span contenteditable=true>foo[]</span>', + ], + //@} + insertparagraph: [ + //@{ + 'foo[bar]baz', + 'fo[o<table><tr><td>b]ar</table>', + '<table><tr><td>[foo<td>bar]<tr><td>baz<td>quz</table>', + '<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<tr><td>baz<td>quz</table>', + '<table><tr><td>fo[o</table>b]ar', + '<table><tr><td>fo[o<td>b]ar<td>baz</table>', + '{<table><tr><td>foo</table>}', + '<table><tr><td>[foo]</table>', + '<ol><li>[foo]<li>bar</ol>', + '<ol><li>f[o]o<li>bar</ol>', + + '[]foo', + 'foo[]', + '<span>foo[]</span>', + 'foo[]<br>', + 'foo[]bar', + '<address>[]foo</address>', + '<address>foo[]</address>', + '<address>foo[]<br></address>', + '<address>foo[]bar</address>', + '<div>[]foo</div>', + '<div>foo[]</div>', + '<div>foo[]<br></div>', + '<div>foo[]bar</div>', + '<dl><dt>[]foo<dd>bar</dl>', + '<dl><dt>foo[]<dd>bar</dl>', + '<dl><dt>foo[]<br><dd>bar</dl>', + '<dl><dt>foo[]bar<dd>baz</dl>', + '<dl><dt>foo<dd>[]bar</dl>', + '<dl><dt>foo<dd>bar[]</dl>', + '<dl><dt>foo<dd>bar[]<br></dl>', + '<dl><dt>foo<dd>bar[]baz</dl>', + '<h1>[]foo</h1>', + '<h1>foo[]</h1>', + '<h1>foo[]<br></h1>', + '<h1>foo[]bar</h1>', + '<ol><li>[]foo</ol>', + '<ol><li>foo[]</ol>', + '<ol><li>foo[]<br></ol>', + '<ol><li>foo[]bar</ol>', + '<p>[]foo</p>', + '<p>foo[]</p>', + '<p>foo[]<br></p>', + '<p>foo[]bar</p>', + '<pre>[]foo</pre>', + '<pre>foo[]</pre>', + '<pre>foo[]<br></pre>', + '<pre>foo[]bar</pre>', + + '<pre>foo[]<br><br></pre>', + '<pre>foo<br>{}<br></pre>', + '<pre>foo []</pre>', + '<pre>foo[] </pre>', + '<pre>foo [] </pre>', + + '<xmp>foo[]bar</xmp>', + '<script>foo[]bar</script>baz', + '<div style=display:none>foo[]bar</div>baz', + '<listing>foo[]bar</listing>', + + '<ol><li>{}<br></li></ol>', + 'foo<ol><li>{}<br></li></ol>', + '<ol><li>{}<br></li></ol>foo', + '<ol><li>foo<li>{}<br></ol>', + '<ol><li>{}<br><li>bar</ol>', + '<ol><li>foo</li><ul><li>{}<br></ul></ol>', + + '<dl><dt>{}<br></dt></dl>', + '<dl><dt>foo<dd>{}<br></dl>', + '<dl><dt>{}<br><dd>bar</dl>', + '<dl><dt>foo<dd>bar<dl><dt>{}<br><dd>baz</dl></dl>', + '<dl><dt>foo<dd>bar<dl><dt>baz<dd>{}<br></dl></dl>', + + '<h1>foo[bar</h1><p>baz]quz</p>', + '<p>foo[bar</p><h1>baz]quz</h1>', + '<p>foo</p>{}<br>', + '{}<br><p>foo</p>', + '<p>foo</p>{}<br><h1>bar</h1>', + '<h1>foo</h1>{}<br><p>bar</p>', + '<h1>foo</h1>{}<br><h2>bar</h2>', + '<p>foo</p><h1>[bar]</h1><p>baz</p>', + '<p>foo</p>{<h1>bar</h1>}<p>baz</p>', + + '<table><tr><td>foo[]bar</table>', + '<table><tr><td><p>foo[]bar</table>', + + '<blockquote>[]foo</blockquote>', + '<blockquote>foo[]</blockquote>', + '<blockquote>foo[]<br></blockquote>', + '<blockquote>foo[]bar</blockquote>', + '<blockquote><p>[]foo</blockquote>', + '<blockquote><p>foo[]</blockquote>', + '<blockquote><p>foo[]bar</blockquote>', + '<blockquote><p>foo[]<p>bar</blockquote>', + '<blockquote><p>foo[]bar<p>baz</blockquote>', + + '<span>foo[]bar</span>', + '<span>foo[]bar</span>baz', + '<b>foo[]bar</b>', + '<b>foo[]bar</b>baz', + '<b>foo[]</b>bar', + 'foo<b>[]bar</b>', + '<b>foo[]</b><i>bar</i>', + '<b id=x class=y>foo[]bar</b>', + '<i><b>foo[]bar</b>baz</i>', + + '<p><b>foo[]bar</b></p>', + '<p><b>[]foo</b></p>', + '<p><b id=x class=y>foo[]bar</b></p>', + '<div><b>foo[]bar</b></div>', + + '<a href=foo>foo[]bar</a>', + '<a href=foo>foo[]bar</a>baz', + '<a href=foo>foo[]</a>bar', + 'foo<a href=foo>[]bar</a>', + + '<p>foo[]<!--bar-->', + '<p><!--foo-->[]bar', + + '<p>foo<span style=color:#aBcDeF>[bar]</span>baz', + '<p>foo<span style=color:#aBcDeF>{bar}</span>baz', + '<p>foo{<span style=color:#aBcDeF>bar</span>}baz', + '<p>[foo<span style=color:#aBcDeF>bar]</span>baz', + '<p>{foo<span style=color:#aBcDeF>bar}</span>baz', + '<p>foo<span style=color:#aBcDeF>[bar</span>baz]', + '<p>foo<span style=color:#aBcDeF>{bar</span>baz}', + '<p>foo<span style=color:#aBcDeF>[bar</span><span style=color:#fEdCbA>baz]</span>quz', + + // https://bugs.webkit.org/show_bug.cgi?id=5036 + '<ul contenteditable><li>{}<br></ul>', + '<ul contenteditable><li>foo[]</ul>', + '<div contenteditable=false><ul contenteditable><li>{}<br></ul></div>', + '<div contenteditable=false><ul contenteditable><li>foo[]</ul></div>', + + // http://www.w3.org/Bugs/Public/show_bug.cgi?id=13841 + // https://bugs.webkit.org/show_bug.cgi?id=23507 + '<address><p>foo[]</address>', + '<dl><dt><p>foo[]</dl>', + '<dl><dd><p>foo[]</dl>', + '<ol><li><p>foo[]</ol>', + '<ul><li><p>foo[]</ul>', + '<address><div>foo[]</address>', + '<dl><dt><div>foo[]</dl>', + '<dl><dd><div>foo[]</dl>', + '<ol><li><div>foo[]</ol>', + '<ul><li><div>foo[]</ul>', + '<div><p>foo[]</div>', + '<div><div>foo[]</div>', + + '<address><p>[]foo</address>', + '<dl><dt><p>[]foo</dl>', + '<dl><dd><p>[]foo</dl>', + '<ol><li><p>[]foo</ol>', + '<ul><li><p>[]foo</ul>', + '<address><div>[]foo</address>', + '<dl><dt><div>[]foo</dl>', + '<dl><dd><div>[]foo</dl>', + '<ol><li><div>[]foo</ol>', + '<ul><li><div>[]foo</ul>', + '<div><p>[]foo</div>', + '<div><div>[]foo</div>', + + '<address><p>foo[]bar</address>', + '<dl><dt><p>foo[]bar</dl>', + '<dl><dd><p>foo[]bar</dl>', + '<ol><li><p>foo[]bar</ol>', + '<ul><li><p>foo[]bar</ul>', + '<address><div>foo[]bar</address>', + '<dl><dt><div>foo[]bar</dl>', + '<dl><dd><div>foo[]bar</dl>', + '<ol><li><div>foo[]bar</ol>', + '<ul><li><div>foo[]bar</ul>', + '<div><p>foo[]bar</div>', + '<div><div>foo[]bar</div>', + + '<ol><li class=a id=x><p class=b id=y>foo[]</ol>', + '<div class=a id=x><div class=b id=y>foo[]</div></div>', + '<div class=a id=x><p class=b id=y>foo[]</div>', + '<ol><li class=a id=x><p class=b id=y>[]foo</ol>', + '<div class=a id=x><div class=b id=y>[]foo</div></div>', + '<div class=a id=x><p class=b id=y>[]foo</div>', + '<ol><li class=a id=x><p class=b id=y>foo[]bar</ol>', + '<div class=a id=x><div class=b id=y>foo[]bar</div></div>', + '<div class=a id=x><p class=b id=y>foo[]bar</div>', + ], + //@} + inserttext: [ + //@{ + 'foo[bar]baz', + ['', 'foo[bar]baz'], + + ['\t', 'foo[]bar'], + ['&', 'foo[]bar'], + ['\n', 'foo[]bar'], + ['abc\ndef', 'foo[]bar'], + ['\x07', 'foo[]bar'], + + ['<b>hi</b>', 'foo[]bar'], + ['<', 'foo[]bar'], + ['&', 'foo[]bar'], + + // http://www.w3.org/Bugs/Public/show_bug.cgi?id=14254 + ['!\r', 'foo[]bar'], + ['!\r\n', 'foo[]bar'], + ['!\0', 'foo[]bar'], + ['!\ud800', 'foo[]bar'], + + // Whitespace tests! The following two bugs are relevant to some of + // these: + // http://www.w3.org/Bugs/Public/show_bug.cgi?id=14119 + // https://bugzilla.mozilla.org/show_bug.cgi?id=681626 + [' ', 'foo[]bar'], + [' ', 'foo []bar'], + [' ', 'foo[] bar'], + [' ', 'foo []bar'], + [' ', 'foo [] bar'], + [' ', 'foo[] bar'], + [' ', 'foo []bar'], + [' ', 'foo [] bar'], + [' ', 'foo[] bar'], + [' ', 'foo []bar'], + [' ', 'foo [] bar'], + [' ', 'foo[] bar'], + [' ', 'foo [] bar'], + [' ', 'foo []bar'], + [' ', 'foo [] bar'], + + [' ', '[]foo'], + [' ', '{}foo'], + [' ', 'foo[]'], + [' ', 'foo{}'], + [' ', 'foo []'], + [' ', 'foo {}'], + [' ', 'foo []'], + [' ', 'foo {}'], + [' ', '<b>foo[]</b>bar'], + [' ', 'foo[]<b>bar</b>'], + + [' ', 'foo[] '], + [' ', ' foo [] '], + [' ', 'foo[]<span> </span>'], + [' ', 'foo[]<span> </span> '], + [' ', ' []foo'], + [' ', ' [] foo '], + [' ', '<span> </span>[]foo'], + [' ', ' <span> </span>[]foo'], + + [' ', '{}<br>'], + [' ', '<p>{}<br>'], + + [' ', '<p>foo[]<p>bar'], + [' ', '<p>foo []<p>bar'], + [' ', '<p>foo[]<p> bar'], + + // Some of the same tests as above, repeated with various values of + // white-space. + [' ', '<pre>foo[]bar</pre>'], + [' ', '<pre>foo []bar</pre>'], + [' ', '<pre>foo[] bar</pre>'], + [' ', '<pre>foo []bar</pre>'], + [' ', '<pre>[]foo</pre>'], + [' ', '<pre>foo[]</pre>'], + [' ', '<pre>foo []</pre>'], + [' ', '<pre> foo [] </pre>'], + + [' ', '<div style=white-space:pre>foo[]bar</div>'], + [' ', '<div style=white-space:pre>foo []bar</div>'], + [' ', '<div style=white-space:pre>foo[] bar</div>'], + [' ', '<div style=white-space:pre>foo []bar</div>'], + [' ', '<div style=white-space:pre>[]foo</div>'], + [' ', '<div style=white-space:pre>foo[]</div>'], + [' ', '<div style=white-space:pre>foo []</div>'], + [' ', '<div style=white-space:pre> foo [] </div>'], + + [' ', '<div style=white-space:pre-wrap>foo[]bar</div>'], + [' ', '<div style=white-space:pre-wrap>foo []bar</div>'], + [' ', '<div style=white-space:pre-wrap>foo[] bar</div>'], + [' ', '<div style=white-space:pre-wrap>foo []bar</div>'], + [' ', '<div style=white-space:pre-wrap>[]foo</div>'], + [' ', '<div style=white-space:pre-wrap>foo[]</div>'], + [' ', '<div style=white-space:pre-wrap>foo []</div>'], + [' ', '<div style=white-space:pre-wrap> foo [] </div>'], + + [' ', '<div style=white-space:pre-line>foo[]bar</div>'], + [' ', '<div style=white-space:pre-line>foo []bar</div>'], + [' ', '<div style=white-space:pre-line>foo[] bar</div>'], + [' ', '<div style=white-space:pre-line>foo []bar</div>'], + [' ', '<div style=white-space:pre-line>[]foo</div>'], + [' ', '<div style=white-space:pre-line>foo[]</div>'], + [' ', '<div style=white-space:pre-line>foo []</div>'], + [' ', '<div style=white-space:pre-line> foo [] </div>'], + + [' ', '<div style=white-space:nowrap>foo[]bar</div>'], + [' ', '<div style=white-space:nowrap>foo []bar</div>'], + [' ', '<div style=white-space:nowrap>foo[] bar</div>'], + [' ', '<div style=white-space:nowrap>foo []bar</div>'], + [' ', '<div style=white-space:nowrap>[]foo</div>'], + [' ', '<div style=white-space:nowrap>foo[]</div>'], + [' ', '<div style=white-space:nowrap>foo []</div>'], + [' ', '<div style=white-space:nowrap> foo [] </div>'], + + // End whitespace tests + + // Autolinking tests + [' ', 'http://a[]'], + [' ', 'ftp://a[]'], + [' ', 'quasit://a[]'], + [' ', '.x-++-.://a[]'], + [' ', '(http://a)[]'], + [' ', '<http://a>[]'], + // http://www.w3.org/Bugs/Public/show_bug.cgi?id=14744 + ['! ', '[http://a][]'], + ['! ', '{http://a}[]'], + [' ', 'http://a![]'], + [' ', '!"#$%&\'()*+,-./:;<=>?\^_`|~http://a!"#$%&\'()*+,-./:;<=>?\^_`|~[]'], + [' ', 'http://a!"\'(),-.:;<>`[]'], + [' ', 'http://a#$%&*+/=?\^_|~[]'], + [' ', 'mailto:a[]'], + [' ', 'a@b[]'], + [' ', 'a@[]'], + [' ', '@b[]'], + [' ', '#@x[]'], + [' ', 'a@.[]'], + [' ', '!"#$%&\'()*+,-./:;<=>?\^_`|~a@b!"#$%&\'()*+,-./:;<=>?\^_`|~[]'], + [' ', '<b>a@b</b>{}'], + [' ', '<b>a</b><i>@</i><u>b</u>{}'], + [' ', 'a@b<b>[]c</b>'], + [' ', '<p>a@b</p><p>[]c</p>'], + ['a', 'http://a[]'], + ['\t', 'http://a[]'], + // http://www.w3.org/Bugs/Public/show_bug.cgi?id=14254 + ['!\r', 'http://a[]'], + // http://www.w3.org/Bugs/Public/show_bug.cgi?id=14745 + ['!\n', 'http://a[]'], + ['\f', 'http://a[]'], + ['\u00A0', 'http://a[]'], + + [' ', 'foo[]'], + + 'foo[]bar', + 'foo []', + 'foo\xa0[]', + '<p>foo[]', + '<p>foo</p>{}', + '<p>[]foo', + '<p>{}foo', + '{}<p>foo', + '<p>foo</p>{}<p>bar</p>', + '<b>foo[]</b>bar', + '<b>foo</b>[]bar', + 'foo<b>{}</b>bar', + '<a>foo[]</a>bar', + '<a>foo</a>[]bar', + '<a href=/>foo[]</a>bar', + '<a href=/>foo</a>[]bar', + '<p>fo[o<p>b]ar', + '<p>fo[o<p>bar<p>b]az', + '{}<br>', + '<p>{}<br>', + '<p><span>{}<br></span>', + '<p>foo<span style=color:#aBcDeF>[bar]</span>baz', + '<p>foo<span style=color:#aBcDeF>{bar}</span>baz', + '<p>foo{<span style=color:#aBcDeF>bar</span>}baz', + '<p>[foo<span style=color:#aBcDeF>bar]</span>baz', + '<p>{foo<span style=color:#aBcDeF>bar}</span>baz', + '<p>foo<span style=color:#aBcDeF>[bar</span>baz]', + '<p>foo<span style=color:#aBcDeF>{bar</span>baz}', + '<p>foo<span style=color:#aBcDeF>[bar</span><span style=color:#fEdCbA>baz]</span>quz', + + + // These are like the corresponding tests in the multitest section, but + // because the selection isn't collapsed, we don't need to do + // multitests to set overrides. + 'foo<b>[bar]</b>baz', + 'foo<i>[bar]</i>baz', + 'foo<s>[bar]</s>baz', + 'foo<sub>[bar]</sub>baz', + 'foo<sup>[bar]</sup>baz', + 'foo<u>[bar]</u>baz', + 'foo<a href=http://www.google.com>[bar]</a>baz', + 'foo<font face=sans-serif>[bar]</font>baz', + 'foo<font size=4>[bar]</font>baz', + 'foo<font color=#0000FF>[bar]</font>baz', + 'foo<span style=background-color:#00FFFF>[bar]</span>baz', + 'foo<a href=http://www.google.com><font color=blue>[bar]</font></a>baz', + 'foo<font color=blue><a href=http://www.google.com>[bar]</a></font>baz', + 'foo<a href=http://www.google.com><font color=brown>[bar]</font></a>baz', + 'foo<font color=brown><a href=http://www.google.com>[bar]</a></font>baz', + 'foo<a href=http://www.google.com><font color=black>[bar]</font></a>baz', + 'foo<a href=http://www.google.com><u>[bar]</u></a>baz', + 'foo<u><a href=http://www.google.com>[bar]</a></u>baz', + 'foo<sub><font size=2>[bar]</font></sub>baz', + 'foo<font size=2><sub>[bar]</sub></font>baz', + 'foo<sub><font size=3>[bar]</font></sub>baz', + 'foo<font size=3><sub>[bar]</sub></font>baz', + + // Now repeat but with different selections. + '[foo<b>bar]</b>baz', + '[foo<i>bar]</i>baz', + '[foo<s>bar]</s>baz', + '[foo<sub>bar]</sub>baz', + '[foo<sup>bar]</sup>baz', + '[foo<u>bar]</u>baz', + '[foo<a href=http://www.google.com>bar]</a>baz', + '[foo<font face=sans-serif>bar]</font>baz', + '[foo<font size=4>bar]</font>baz', + '[foo<font color=#0000FF>bar]</font>baz', + '[foo<span style=background-color:#00FFFF>bar]</span>baz', + '[foo<a href=http://www.google.com><font color=blue>bar]</font></a>baz', + '[foo<font color=blue><a href=http://www.google.com>bar]</a></font>baz', + '[foo<a href=http://www.google.com><font color=brown>bar]</font></a>baz', + '[foo<font color=brown><a href=http://www.google.com>bar]</a></font>baz', + '[foo<a href=http://www.google.com><font color=black>bar]</font></a>baz', + '[foo<a href=http://www.google.com><u>bar]</u></a>baz', + '[foo<u><a href=http://www.google.com>bar]</a></u>baz', + '[foo<sub><font size=2>bar]</font></sub>baz', + '[foo<font size=2><sub>bar]</sub></font>baz', + '[foo<sub><font size=3>bar]</font></sub>baz', + '[foo<font size=3><sub>bar]</sub></font>baz', + + 'foo<b>[bar</b>baz]', + 'foo<i>[bar</i>baz]', + 'foo<s>[bar</s>baz]', + 'foo<sub>[bar</sub>baz]', + 'foo<sup>[bar</sup>baz]', + 'foo<u>[bar</u>baz]', + 'foo<a href=http://www.google.com>[bar</a>baz]', + 'foo<font face=sans-serif>[bar</font>baz]', + 'foo<font size=4>[bar</font>baz]', + 'foo<font color=#0000FF>[bar</font>baz]', + 'foo<span style=background-color:#00FFFF>[bar</span>baz]', + 'foo<a href=http://www.google.com><font color=blue>[bar</font></a>baz]', + 'foo<font color=blue><a href=http://www.google.com>[bar</a></font>baz]', + 'foo<a href=http://www.google.com><font color=brown>[bar</font></a>baz]', + 'foo<font color=brown><a href=http://www.google.com>[bar</a></font>baz]', + 'foo<a href=http://www.google.com><font color=black>[bar</font></a>baz]', + 'foo<a href=http://www.google.com><u>[bar</u></a>baz]', + 'foo<u><a href=http://www.google.com>[bar</a></u>baz]', + 'foo<sub><font size=2>[bar</font></sub>baz]', + 'foo<font size=2><sub>[bar</sub></font>baz]', + 'foo<sub><font size=3>[bar</font></sub>baz]', + 'foo<font size=3><sub>[bar</sub></font>baz]', + + // https://bugs.webkit.org/show_bug.cgi?id=19702 + '<blockquote><font color=blue>[foo]</font></blockquote>', + ], + //@} + insertunorderedlist: [ + //@{ + 'foo[]bar', + 'foo[bar]baz', + 'foo<br>[bar]', + 'f[oo<br>b]ar<br>baz', + '<p>[foo]<br>bar</p>', + '[foo<ol><li>bar]</ol>baz', + 'foo<ol><li>[bar</ol>baz]', + '[foo<ul><li>bar]</ul>baz', + 'foo<ul><li>[bar</ul>baz]', + 'foo<ul><li>[bar</ul><ol><li>baz]</ol>quz', + 'foo<ol><li>[bar</ol><ul><li>baz]</ul>quz', + + '<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>', + '<table><tbody><tr><td>fo[o<td>b]ar<td>baz</table>', + '{<table><tr><td>foo<td>bar<td>baz</table>}', + + '<p>foo<p>[bar]<p>baz', + '<p>foo<blockquote>[bar]</blockquote><p>baz', + '<dl><dt>foo<dd>[bar]<dt>baz<dd>quz</dl>', + '<dl><dt>foo<dd>bar<dt>[baz]<dd>quz</dl>', + + '<p>[foo<p>bar]<p>baz', + '<p>[foo<blockquote>bar]</blockquote><p>baz', + '<dl><dt>[foo<dd>bar]<dt>baz<dd>quz</dl>', + '<dl><dt>foo<dd>[bar<dt>baz]<dd>quz</dl>', + + '<p>[foo<blockquote><p>bar]<p>baz</blockquote>', + + + // Various <ol> stuff + '<ol><li>foo<li>[bar]<li>baz</ol>', + '<ol><li>foo</ol>[bar]', + '[foo]<ol><li>bar</ol>', + '<ol><li>foo</ol>[bar]<ol><li>baz</ol>', + '<ol><ol><li>[foo]</ol></ol>', + '<ol><li>[foo]<br>bar<li>baz</ol>', + '<ol><li>foo<br>[bar]<li>baz</ol>', + '<ol><li><div>[foo]</div>bar<li>baz</ol>', + '<ol><li>foo<ol><li>[bar]<li>baz</ol><li>quz</ol>', + '<ol><li>foo<ol><li>bar<li>[baz]</ol><li>quz</ol>', + '<ol><li>foo</li><ol><li>[bar]<li>baz</ol><li>quz</ol>', + '<ol><li>foo</li><ol><li>bar<li>[baz]</ol><li>quz</ol>', + '<ol><li>[foo]<ol><li>bar</ol><li>baz</ol>', + '<ol><li>[foo]</li><ol><li>bar</ol><li>baz</ol>', + '<ol><li>foo<li>[bar]<ol><li>baz</ol><li>quz</ol>', + '<ol><li>foo<li>[bar]</li><ol><li>baz</ol><li>quz</ol>', + '<ol><li>foo<ol><li>bar<li>baz</ol><li>[quz]</ol>', + '<ol><li>foo</li><ol><li>bar<li>baz</ol><li>[quz]</ol>', + + // Multiple items at once. + '<ol><li>foo<li>[bar<li>baz]</ol>', + '<ol><li>[foo<ol><li>bar]</ol><li>baz</ol>', + '<ol><li>foo<ol><li>b[ar</ol><li>b]az</ol>', + '<ol><li>[foo<ol><li>bar</ol><li>baz]</ol><p>extra', + + // We probably can't actually get this DOM . . . + '<ol><li>[foo]<ol><li>bar</ol>baz</ol>', + '<ol><li>foo<ol><li>[bar]</ol>baz</ol>', + '<ol><li>foo<ol><li>bar</ol>[baz]</ol>', + '<ol><li>[foo<ol><li>bar]</ol>baz</ol>', + + + // Same stuff but with <ul> + '<ul><li>foo<li>[bar]<li>baz</ul>', + '<ul><li>foo</ul>[bar]', + '[foo]<ul><li>bar</ul>', + '<ul><li>foo</ul>[bar]<ul><li>baz</ul>', + '<ul><ul><li>[foo]</ul></ul>', + '<ul><li>[foo]<br>bar<li>baz</ul>', + '<ul><li>foo<br>[bar]<li>baz</ul>', + '<ul><li><div>[foo]</div>bar<li>baz</ul>', + '<ul><li>foo<ul><li>[bar]<li>baz</ul><li>quz</ul>', + '<ul><li>foo<ul><li>bar<li>[baz]</ul><li>quz</ul>', + '<ul><li>foo</li><ul><li>[bar]<li>baz</ul><li>quz</ul>', + '<ul><li>foo</li><ul><li>bar<li>[baz]</ul><li>quz</ul>', + '<ul><li>[foo]<ul><li>bar</ul><li>baz</ul>', + '<ul><li>[foo]</li><ul><li>bar</ul><li>baz</ul>', + '<ul><li>foo<li>[bar]<ul><li>baz</ul><li>quz</ul>', + '<ul><li>foo<li>[bar]</li><ul><li>baz</ul><li>quz</ul>', + '<ul><li>foo<ul><li>bar<li>baz</ul><li>[quz]</ul>', + '<ul><li>foo</li><ul><li>bar<li>baz</ul><li>[quz]</ul>', + + // Multiple items at once. + '<ul><li>foo<li>[bar<li>baz]</ul>', + '<ul><li>[foo<ul><li>bar]</ul><li>baz</ul>', + '<ul><li>foo<ul><li>b[ar</ul><li>b]az</ul>', + '<ul><li>[foo<ul><li>bar</ul><li>baz]</ul><p>extra', + + // We probably can't actually get this DOM . . . + '<ul><li>[foo]<ul><li>bar</ul>baz</ul>', + '<ul><li>foo<ul><li>[bar]</ul>baz</ul>', + '<ul><li>foo<ul><li>bar</ul>[baz]</ul>', + '<ul><li>[foo<ul><li>bar]</ul>baz</ul>', + + + // Mix of <ol> and <ul> + 'foo<ol><li>bar</ol><ul><li>[baz]</ul>quz', + 'foo<ol><li>bar</ol><ul><li>[baz</ul>quz]', + 'foo<ul><li>[bar]</ul><ol><li>baz</ol>quz', + '[foo<ul><li>bar]</ul><ol><li>baz</ol>quz', + + // Interaction with indentation + '[foo]<blockquote>bar</blockquote>baz', + 'foo<blockquote>[bar]</blockquote>baz', + '[foo<blockquote>bar]</blockquote>baz', + '<ol><li>foo</ol><blockquote>[bar]</blockquote>baz', + '[foo]<blockquote><ol><li>bar</ol></blockquote>baz', + 'foo<blockquote>[bar]<br>baz</blockquote>', + '[foo<blockquote>bar]<br>baz</blockquote>', + '<ol><li>foo</ol><blockquote>[bar]<br>baz</blockquote>', + + '<p>[foo]<blockquote><p>bar</blockquote><p>baz', + '<p>foo<blockquote><p>[bar]</blockquote><p>baz', + '<p>[foo<blockquote><p>bar]</blockquote><p>baz', + '<ol><li>foo</ol><blockquote><p>[bar]</blockquote><p>baz', + + // Attributes + '<ul id=abc><li>foo<li>[bar]<li>baz</ul>', + '<ul style=color:blue><li>foo<li>[bar]<li>baz</ul>', + '<ul style=text-indent:1em><li>foo<li>[bar]<li>baz</ul>', + '<ul id=abc><li>[foo]<li>bar<li>baz</ul>', + '<ul style=color:blue><li>[foo]<li>bar<li>baz</ul>', + '<ul style=text-indent:1em><li>[foo]<li>bar<li>baz</ul>', + '<ul id=abc><li>foo<li>bar<li>[baz]</ul>', + '<ul style=color:blue><li>foo<li>bar<li>[baz]</ul>', + '<ul style=text-indent:1em><li>foo<li>bar<li>[baz]</ul>', + + // Whitespace nodes + '<ul><li>foo</ul> <p>[bar]', + '<p>[foo]</p> <ul><li>bar</ul>', + '<ul><li>foo</ul> <p>[bar]</p> <ul><li>baz</ul>', + + // https://bugs.webkit.org/show_bug.cgi?id=24167 + '{<div style="font-size: 1.3em">1</div><div style="font-size: 1.1em">2</div>}', + ], + //@} + italic: [ + //@{ + 'foo[]bar', + '<p>[foo</p> <p>bar]</p>', + '<span>[foo</span> <span>bar]</span>', + '<p>[foo</p><p> <span>bar</span> </p><p>baz]</p>', + '<p>[foo<p><br><p>bar]', + '<b>foo[]bar</b>', + '<i>foo[]bar</i>', + '<span>foo</span>{}<span>bar</span>', + '<span>foo[</span><span>]bar</span>', + 'foo[bar]baz', + 'foo[bar<b>baz]qoz</b>quz', + 'foo[bar<i>baz]qoz</i>quz', + '{<p><p> <p>foo</p>}', + + '<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>', + '<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table>', + '<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table>', + '<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>', + '<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>', + '{<table><tr><td>foo<td>bar<td>baz</table>}', + + 'foo<span style="font-style: italic">[bar]</span>baz', + 'foo<address>[bar]</address>baz', + 'foo<cite>[bar]</cite>baz', + 'foo<dfn>[bar]</dfn>baz', + 'foo<em>[bar]</em>baz', + 'foo<i>[bar]</i>baz', + 'foo<var>[bar]</var>baz', + + 'foo{<address>bar</address>}baz', + 'foo{<cite>bar</cite>}baz', + 'foo{<dfn>bar</dfn>}baz', + 'foo{<em>bar</em>}baz', + 'foo{<i>bar</i>}baz', + 'foo{<var>bar</var>}baz', + + 'foo<address>b[a]r</address>baz', + 'foo<cite>b[a]r</cite>baz', + 'foo<dfn>b[a]r</dfn>baz', + 'foo<em>b[a]r</em>baz', + 'foo<i>b[a]r</i>baz', + 'foo<var>b[a]r</var>baz', + + 'fo[o<address>bar</address>b]az', + 'fo[o<cite>bar</cite>b]az', + 'fo[o<dfn>bar</dfn>b]az', + 'fo[o<em>bar</em>b]az', + 'fo[o<i>bar</i>b]az', + 'fo[o<var>bar</var>b]az', + + 'foo[<address>bar</address>baz]', + 'foo[<cite>bar</cite>baz]', + 'foo[<dfn>bar</dfn>baz]', + 'foo[<em>bar</em>baz]', + 'foo[<i>bar</i>baz]', + 'foo[<var>bar</var>baz]', + + '[foo<address>bar</address>]baz', + '[foo<cite>bar</cite>]baz', + '[foo<dfn>bar</dfn>]baz', + '[foo<em>bar</em>]baz', + '[foo<i>bar</i>]baz', + '[foo<var>bar</var>]baz', + + 'foo<span style="font-style: italic">[bar]</span>baz', + 'foo<span style="font-style: oblique">[bar]</span>baz', + 'foo<span style="font-style: oblique">b[a]r</span>baz', + + '<i>{<p>foo</p><p>bar</p>}<p>baz</p></i>', + '<i><p>foo[<b>bar</b>}</p><p>baz</p></i>', + 'foo [bar <b>baz] qoz</b> quz sic', + 'foo bar <b>baz [qoz</b> quz] sic', + 'foo [bar <i>baz] qoz</i> quz sic', + 'foo bar <i>baz [qoz</i> quz] sic', + + // Tests for queryCommandIndeterm() and queryCommandState() + 'fo[o<i>b]ar</i>baz', + 'foo<i>ba[r</i>b]az', + 'fo[o<i>bar</i>b]az', + 'foo[<i>b]ar</i>baz', + 'foo<i>ba[r</i>]baz', + 'foo[<i>bar</i>]baz', + 'foo<i>[bar]</i>baz', + 'foo{<i>bar</i>}baz', + 'fo[o<span style=font-style:italic>b]ar</span>baz', + 'fo[o<span style=font-style:oblique>b]ar</span>baz', + '<span style=font-style:italic>fo[o</span><span style=font-style:oblique>b]ar</span>', + '<span style=font-style:oblique>fo[o</span><span style=font-style:italic>b]ar</span>', + '<i>fo[o</i><address>b]ar</address>', + ], + //@} + justifycenter: [ + //@{ + 'foo[]bar<p>extra', + '<span>foo</span>{}<span>bar</span><p>extra', + '<span>foo[</span><span>]bar</span><p>extra', + 'foo[bar]baz<p>extra', + 'foo[bar<b>baz]qoz</b>quz<p>extra', + '<p>foo[]bar<p>extra', + '<p>foo[bar]baz<p>extra', + '<h1>foo[bar]baz</h1><p>extra', + '<pre>foo[bar]baz</pre><p>extra', + '<xmp>foo[bar]baz</xmp><p>extra', + '<center><p>[foo]<p>bar</center><p>extra', + '<center><p>[foo<p>bar]</center><p>extra', + + '<table><tbody><tr><td>foo<td>b[a]r<td>baz</table><p>extra', + '<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra', + '<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra', + '<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra', + '<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table><p>extra', + '{<table><tr><td>foo<td>bar<td>baz</table>}<p>extra', + + '<table align=center><tbody><tr><td>foo<td>b[a]r<td>baz</table><p>extra', + '<table align=center><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra', + '<table align=center><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra', + '<table align=center><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra', + '<table align=center data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table><p>extra', + '{<table align=center><tr><td>foo<td>bar<td>baz</table>}<p>extra', + + '<table><tbody align=center><tr><td>foo<td>b[a]r<td>baz</table><p>extra', + '<table><tbody align=center><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra', + '<table><tbody align=center><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra', + '<table><tbody align=center data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra', + '<table data-start=0 data-end=1><tbody align=center><tr><td>foo<td>bar<td>baz</table><p>extra', + '{<table><tbody align=center><tr><td>foo<td>bar<td>baz</table>}<p>extra', + + '<table><tbody><tr align=center><td>foo<td>b[a]r<td>baz</table><p>extra', + '<table><tbody><tr align=center data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra', + '<table><tbody><tr align=center data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra', + '<table><tbody data-start=0 data-end=1><tr align=center><td>foo<td>bar<td>baz</table><p>extra', + '<table data-start=0 data-end=1><tbody><tr align=center><td>foo<td>bar<td>baz</table><p>extra', + '{<table><tr align=center><td>foo<td>bar<td>baz</table>}<p>extra', + + '<div align=center><p>[foo]<p>bar</div><p>extra', + '<div align=center><p>[foo<p>bar}</div><p>extra', + '<div style=text-align:center><p>[foo]<p>bar</div><p>extra', + '<div style=text-align:center><p>[foo<p>bar]</div><p>extra', + + '<div align=justify><p>[foo]<p>bar</div><p>extra', + '<div align=justify><p>[foo<p>bar}</div><p>extra', + '<div style=text-align:justify><p>[foo]<p>bar</div><p>extra', + '<div style=text-align:justify><p>[foo<p>bar]</div><p>extra', + + '<div align=left><p>[foo]<p>bar</div><p>extra', + '<div align=left><p>[foo<p>bar}</div><p>extra', + '<div style=text-align:left><p>[foo]<p>bar</div><p>extra', + '<div style=text-align:left><p>[foo<p>bar]</div><p>extra', + + '<div align=right><p>[foo]<p>bar</div><p>extra', + '<div align=right><p>[foo<p>bar}</div><p>extra', + '<div style=text-align:right><p>[foo]<p>bar</div><p>extra', + '<div style=text-align:right><p>[foo<p>bar]</div><p>extra', + + '<center>foo</center>[bar]<p>extra', + '[foo]<center>bar</center><p>extra', + '<center>foo</center>[bar]<center>baz</center><p>extra', + '<div align=center>foo</div>[bar]<p>extra', + '[foo]<div align=center>bar</div><p>extra', + '<div align=center>foo</div>[bar]<div align=center>baz</div><p>extra', + '<div align=center><p>foo</div><p>[bar]<p>extra', + '<p>[foo]<div align=center><p>bar</div><p>extra', + '<div align=center><p>foo</div><p>[bar]<div align=center><p>baz</div><p>extra', + '<div style=text-align:center>foo</div>[bar]<p>extra', + '[foo]<div style=text-align:center>bar</div><p>extra', + '<div style=text-align:center>foo</div>[bar]<div style=text-align:center>baz</div><p>extra', + '<div style=text-align:center><p>foo</div><p>[bar]<p>extra', + '<p>[foo]<div style=text-align:center><p>bar</div><p>extra', + '<div style=text-align:center><p>foo</div><p>[bar]<div style=text-align:center><p>baz</div><p>extra', + '<p align=center>foo<p>[bar]<p>extra', + '<p>[foo]<p align=center>bar<p>extra', + '<p align=center>foo<p>[bar]<p align=center>baz<p>extra', + + '<center>[foo</center>bar]<p>extra', + '<center>fo[o</center>b]ar<p>extra', + '<div align=center>[foo</div>bar]<p>extra', + '<div align=center>fo[o</div>b]ar<p>extra', + '<div style=text-align:center>[foo</div>bar]<p>extra', + '<div style=text-align:center>fo[o</div>b]ar<p>extra', + '<span style=text-align:center>[foo]</span><p>extra', + '<span style=text-align:center>f[o]o</span><p>extra', + + '<div style=text-align:center>[foo<div style=text-align:left contenteditable=false>bar</div>baz]</div><p>extra', + + '<div align=nonsense><p>[foo]</div><p>extra', + '<div style=text-align:inherit><p>[foo]</div><p>extra', + '<quasit align=right><p>[foo]</p></quasit><p>extra', + + '<div align=center>{<div align=left>foo</div>}</div>', + '<div align=left>{<div align=center>foo</div>}</div>', + '<div align=center>{<div align=left>foo</div>bar}</div>', + '<div align=left>{<div align=center>foo</div>bar}</div>', + '<div align=center>{<div align=left>foo</div><img src=/img/lion.svg>}</div>', + '<div align=left>{<div align=center>foo</div><img src=/img/lion.svg>}</div>', + '<div align=center>{<div align=left>foo</div><!-- bar -->}</div>', + '<div align=left>{<div align=center>foo</div><!-- bar -->}</div>', + + '<div style=text-align:start>[foo]</div><p>extra', + '<div style=text-align:end>[foo]</div><p>extra', + '<div dir=rtl style=text-align:start>[foo]</div><p>extra', + '<div dir=rtl style=text-align:end>[foo]</div><p>extra', + + // Whitespace nodes + '<div style=text-align:center><p>foo</div> <p>[bar]', + '<div align=center><p>foo</div> <p>[bar]', + '<center><p>foo</center> <p>[bar]', + '<p>[foo]</p> <div style=text-align:center><p>bar</div>', + '<p>[foo]</p> <div align=center><p>bar</div>', + '<p>[foo]</p> <center><p>bar</center>', + '<div style=text-align:center><p>foo</div> <p>[bar]</p> <div style=text-align:center><p>baz</div>', + '<div align=center><p>foo</div> <p>[bar]</p> <div align=center><p>baz</div>', + '<center><p>foo</center> <p>[bar]</p> <center><p>baz</center>', + ], + //@} + justifyfull: [ + //@{ + 'foo[]bar<p>extra', + '<span>foo</span>{}<span>bar</span><p>extra', + '<span>foo[</span><span>]bar</span><p>extra', + 'foo[bar]baz<p>extra', + 'foo[bar<b>baz]qoz</b>quz<p>extra', + '<p>foo[]bar<p>extra', + '<p>foo[bar]baz<p>extra', + '<h1>foo[bar]baz</h1><p>extra', + '<pre>foo[bar]baz</pre><p>extra', + '<xmp>foo[bar]baz</xmp><p>extra', + '<center><p>[foo]<p>bar</center><p>extra', + '<center><p>[foo<p>bar]</center><p>extra', + + '<table><tbody><tr><td>foo<td>b[a]r<td>baz</table><p>extra', + '<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra', + '<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra', + '<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra', + '<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table><p>extra', + '{<table><tr><td>foo<td>bar<td>baz</table>}<p>extra', + + '<table align=justify><tbody><tr><td>foo<td>b[a]r<td>baz</table><p>extra', + '<table align=justify><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra', + '<table align=justify><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra', + '<table align=justify><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra', + '<table align=justify data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table><p>extra', + '{<table align=justify><tr><td>foo<td>bar<td>baz</table>}<p>extra', + + '<table><tbody align=justify><tr><td>foo<td>b[a]r<td>baz</table><p>extra', + '<table><tbody align=justify><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra', + '<table><tbody align=justify><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra', + '<table><tbody align=justify data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra', + '<table data-start=0 data-end=1><tbody align=justify><tr><td>foo<td>bar<td>baz</table><p>extra', + '{<table><tbody align=justify><tr><td>foo<td>bar<td>baz</table>}<p>extra', + + '<table><tbody><tr align=justify><td>foo<td>b[a]r<td>baz</table><p>extra', + '<table><tbody><tr align=justify data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra', + '<table><tbody><tr align=justify data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra', + '<table><tbody data-start=0 data-end=1><tr align=justify><td>foo<td>bar<td>baz</table><p>extra', + '<table data-start=0 data-end=1><tbody><tr align=justify><td>foo<td>bar<td>baz</table><p>extra', + '{<table><tr align=justify><td>foo<td>bar<td>baz</table>}<p>extra', + + '<div align=center><p>[foo]<p>bar</div><p>extra', + '<div align=center><p>[foo<p>bar}</div><p>extra', + '<div style=text-align:center><p>[foo]<p>bar</div><p>extra', + '<div style=text-align:center><p>[foo<p>bar]</div><p>extra', + + '<div align=justify><p>[foo]<p>bar</div><p>extra', + '<div align=justify><p>[foo<p>bar}</div><p>extra', + '<div style=text-align:justify><p>[foo]<p>bar</div><p>extra', + '<div style=text-align:justify><p>[foo<p>bar]</div><p>extra', + + '<div align=left><p>[foo]<p>bar</div><p>extra', + '<div align=left><p>[foo<p>bar}</div><p>extra', + '<div style=text-align:left><p>[foo]<p>bar</div><p>extra', + '<div style=text-align:left><p>[foo<p>bar]</div><p>extra', + + '<div align=right><p>[foo]<p>bar</div><p>extra', + '<div align=right><p>[foo<p>bar}</div><p>extra', + '<div style=text-align:right><p>[foo]<p>bar</div><p>extra', + '<div style=text-align:right><p>[foo<p>bar]</div><p>extra', + + '<div align=justify>foo</div>[bar]<p>extra', + '[foo]<div align=justify>bar</div><p>extra', + '<div align=justify>foo</div>[bar]<div align=justify>baz</div><p>extra', + '<div align=justify><p>foo</div><p>[bar]<p>extra', + '<p>[foo]<div align=justify><p>bar</div><p>extra', + '<div align=justify><p>foo</div><p>[bar]<div align=justify><p>baz</div><p>extra', + '<div style=text-align:justify>foo</div>[bar]<p>extra', + '[foo]<div style=text-align:justify>bar</div><p>extra', + '<div style=text-align:justify>foo</div>[bar]<div style=text-align:justify>baz</div><p>extra', + '<div style=text-align:justify><p>foo</div><p>[bar]<p>extra', + '<p>[foo]<div style=text-align:justify><p>bar</div><p>extra', + '<div style=text-align:justify><p>foo</div><p>[bar]<div style=text-align:justify><p>baz</div><p>extra', + '<p align=justify>foo<p>[bar]<p>extra', + '<p>[foo]<p align=justify>bar<p>extra', + '<p align=justify>foo<p>[bar]<p align=justify>baz<p>extra', + + '<div align=justify>[foo</div>bar]<p>extra', + '<div align=justify>fo[o</div>b]ar<p>extra', + '<div style=text-align:justify>[foo</div>bar]<p>extra', + '<div style=text-align:justify>fo[o</div>b]ar<p>extra', + '<span style=text-align:justify>[foo]</span><p>extra', + '<span style=text-align:justify>f[o]o</span><p>extra', + + '<div style=text-align:justify>[foo<div style=text-align:left contenteditable=false>bar</div>baz]</div><p>extra', + + '<div align=nonsense><p>[foo]</div><p>extra', + '<div style=text-align:inherit><p>[foo]</div><p>extra', + '<quasit align=center><p>[foo]</p></quasit><p>extra', + + '<div style=text-align:start>[foo]</div><p>extra', + '<div style=text-align:end>[foo]</div><p>extra', + '<div dir=rtl style=text-align:start>[foo]</div><p>extra', + '<div dir=rtl style=text-align:end>[foo]</div><p>extra', + + // Whitespace nodes + '<div style=text-align:justify><p>foo</div> <p>[bar]', + '<div align=justify><p>foo</div> <p>[bar]', + '<p>[foo]</p> <div style=text-align:justify><p>bar</div>', + '<p>[foo]</p> <div align=justify><p>bar</div>', + '<div style=text-align:justify><p>foo</div> <p>[bar]</p> <div style=text-align:justify><p>baz</div>', + '<div align=justify><p>foo</div> <p>[bar]</p> <div align=justify><p>baz</div>', + ], + //@} + justifyleft: [ + //@{ + 'foo[]bar<p>extra', + '<span>foo</span>{}<span>bar</span><p>extra', + '<span>foo[</span><span>]bar</span><p>extra', + 'foo[bar]baz<p>extra', + 'foo[bar<b>baz]qoz</b>quz<p>extra', + '<p>foo[]bar<p>extra', + '<p>foo[bar]baz<p>extra', + '<h1>foo[bar]baz</h1><p>extra', + '<pre>foo[bar]baz</pre><p>extra', + '<xmp>foo[bar]baz</xmp><p>extra', + '<center><p>[foo]<p>bar</center><p>extra', + '<center><p>[foo<p>bar]</center><p>extra', + + '<table><tbody><tr><td>foo<td>b[a]r<td>baz</table><p>extra', + '<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra', + '<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra', + '<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra', + '<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table><p>extra', + '{<table><tr><td>foo<td>bar<td>baz</table>}<p>extra', + + '<table align=left><tbody><tr><td>foo<td>b[a]r<td>baz</table><p>extra', + '<table align=left><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra', + '<table align=left><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra', + '<table align=left><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra', + '<table align=left data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table><p>extra', + '{<table align=left><tr><td>foo<td>bar<td>baz</table>}<p>extra', + + '<table><tbody align=left><tr><td>foo<td>b[a]r<td>baz</table><p>extra', + '<table><tbody align=left><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra', + '<table><tbody align=left><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra', + '<table><tbody align=left data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra', + '<table data-start=0 data-end=1><tbody align=left><tr><td>foo<td>bar<td>baz</table><p>extra', + '{<table><tbody align=left><tr><td>foo<td>bar<td>baz</table>}<p>extra', + + '<table><tbody><tr align=left><td>foo<td>b[a]r<td>baz</table><p>extra', + '<table><tbody><tr align=left data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra', + '<table><tbody><tr align=left data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra', + '<table><tbody data-start=0 data-end=1><tr align=left><td>foo<td>bar<td>baz</table><p>extra', + '<table data-start=0 data-end=1><tbody><tr align=left><td>foo<td>bar<td>baz</table><p>extra', + '{<table><tr align=left><td>foo<td>bar<td>baz</table>}<p>extra', + + '<div align=center><p>[foo]<p>bar</div><p>extra', + '<div align=center><p>[foo<p>bar}</div><p>extra', + '<div style=text-align:center><p>[foo]<p>bar</div><p>extra', + '<div style=text-align:center><p>[foo<p>bar]</div><p>extra', + + '<div align=justify><p>[foo]<p>bar</div><p>extra', + '<div align=justify><p>[foo<p>bar}</div><p>extra', + '<div style=text-align:justify><p>[foo]<p>bar</div><p>extra', + '<div style=text-align:justify><p>[foo<p>bar]</div><p>extra', + + '<div align=left><p>[foo]<p>bar</div><p>extra', + '<div align=left><p>[foo<p>bar}</div><p>extra', + '<div style=text-align:left><p>[foo]<p>bar</div><p>extra', + '<div style=text-align:left><p>[foo<p>bar]</div><p>extra', + + '<div align=right><p>[foo]<p>bar</div><p>extra', + '<div align=right><p>[foo<p>bar}</div><p>extra', + '<div style=text-align:right><p>[foo]<p>bar</div><p>extra', + '<div style=text-align:right><p>[foo<p>bar]</div><p>extra', + + '<div align=left>foo</div>[bar]<p>extra', + '[foo]<div align=left>bar</div><p>extra', + '<div align=left>foo</div>[bar]<div align=left>baz</div><p>extra', + '<div align=left><p>foo</div><p>[bar]<p>extra', + '<p>[foo]<div align=left><p>bar</div><p>extra', + '<div align=left><p>foo</div><p>[bar]<div align=left><p>baz</div><p>extra', + '<div style=text-align:left>foo</div>[bar]<p>extra', + '[foo]<div style=text-align:left>bar</div><p>extra', + '<div style=text-align:left>foo</div>[bar]<div style=text-align:left>baz</div><p>extra', + '<div style=text-align:left><p>foo</div><p>[bar]<p>extra', + '<p>[foo]<div style=text-align:left><p>bar</div><p>extra', + '<div style=text-align:left><p>foo</div><p>[bar]<div style=text-align:left><p>baz</div><p>extra', + '<p align=left>foo<p>[bar]<p>extra', + '<p>[foo]<p align=left>bar<p>extra', + '<p align=left>foo<p>[bar]<p align=left>baz<p>extra', + + '<div align=left>[foo</div>bar]<p>extra', + '<div align=left>fo[o</div>b]ar<p>extra', + '<div style=text-align:left>[foo</div>bar]<p>extra', + '<div style=text-align:left>fo[o</div>b]ar<p>extra', + '<span style=text-align:left>[foo]</span><p>extra', + '<span style=text-align:left>f[o]o</span><p>extra', + + '<div style=text-align:left>[foo<div style=text-align:left contenteditable=false>bar</div>baz]</div><p>extra', + + '<div align=nonsense><p>[foo]</div><p>extra', + '<div style=text-align:inherit><p>[foo]</div><p>extra', + '<quasit align=center><p>[foo]</p></quasit><p>extra', + + '<div style=text-align:start>[foo]</div><p>extra', + '<div style=text-align:end>[foo]</div><p>extra', + '<div dir=rtl style=text-align:start>[foo]</div><p>extra', + '<div dir=rtl style=text-align:end>[foo]</div><p>extra', + + // Whitespace nodes + '<div style=text-align:left><p>foo</div> <p>[bar]', + '<div align=left><p>foo</div> <p>[bar]', + '<p>[foo]</p> <div style=text-align:left><p>bar</div>', + '<p>[foo]</p> <div align=left><p>bar</div>', + '<div style=text-align:left><p>foo</div> <p>[bar]</p> <div style=text-align:left><p>baz</div>', + '<div align=left><p>foo</div> <p>[bar]</p> <div align=left><p>baz</div>', + ], + //@} + justifyright: [ + //@{ + 'foo[]bar<p>extra', + '<span>foo</span>{}<span>bar</span><p>extra', + '<span>foo[</span><span>]bar</span><p>extra', + 'foo[bar]baz<p>extra', + 'foo[bar<b>baz]qoz</b>quz<p>extra', + '<p>foo[]bar<p>extra', + '<p>foo[bar]baz<p>extra', + '<h1>foo[bar]baz</h1><p>extra', + '<pre>foo[bar]baz</pre><p>extra', + '<xmp>foo[bar]baz</xmp><p>extra', + '<center><p>[foo]<p>bar</center><p>extra', + '<center><p>[foo<p>bar]</center><p>extra', + + '<table><tbody><tr><td>foo<td>b[a]r<td>baz</table><p>extra', + '<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra', + '<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra', + '<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra', + '<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table><p>extra', + '{<table><tr><td>foo<td>bar<td>baz</table>}<p>extra', + + '<table align=right><tbody><tr><td>foo<td>b[a]r<td>baz</table><p>extra', + '<table align=right><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra', + '<table align=right><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra', + '<table align=right><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra', + '<table align=right data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table><p>extra', + '{<table align=right><tr><td>foo<td>bar<td>baz</table>}<p>extra', + + '<table><tbody align=right><tr><td>foo<td>b[a]r<td>baz</table><p>extra', + '<table><tbody align=right><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra', + '<table><tbody align=right><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra', + '<table><tbody align=right data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table><p>extra', + '<table data-start=0 data-end=1><tbody align=right><tr><td>foo<td>bar<td>baz</table><p>extra', + '{<table><tbody align=right><tr><td>foo<td>bar<td>baz</table>}<p>extra', + + '<table><tbody><tr align=right><td>foo<td>b[a]r<td>baz</table><p>extra', + '<table><tbody><tr align=right data-start=1 data-end=2><td>foo<td>bar<td>baz</table><p>extra', + '<table><tbody><tr align=right data-start=0 data-end=2><td>foo<td>bar<td>baz</table><p>extra', + '<table><tbody data-start=0 data-end=1><tr align=right><td>foo<td>bar<td>baz</table><p>extra', + '<table data-start=0 data-end=1><tbody><tr align=right><td>foo<td>bar<td>baz</table><p>extra', + '{<table><tr align=right><td>foo<td>bar<td>baz</table>}<p>extra', + + '<div align=center><p>[foo]<p>bar</div><p>extra', + '<div align=center><p>[foo<p>bar}</div><p>extra', + '<div style=text-align:center><p>[foo]<p>bar</div><p>extra', + '<div style=text-align:center><p>[foo<p>bar]</div><p>extra', + + '<div align=justify><p>[foo]<p>bar</div><p>extra', + '<div align=justify><p>[foo<p>bar}</div><p>extra', + '<div style=text-align:justify><p>[foo]<p>bar</div><p>extra', + '<div style=text-align:justify><p>[foo<p>bar]</div><p>extra', + + '<div align=left><p>[foo]<p>bar</div><p>extra', + '<div align=left><p>[foo<p>bar}</div><p>extra', + '<div style=text-align:left><p>[foo]<p>bar</div><p>extra', + '<div style=text-align:left><p>[foo<p>bar]</div><p>extra', + + '<div align=right><p>[foo]<p>bar</div><p>extra', + '<div align=right><p>[foo<p>bar}</div><p>extra', + '<div style=text-align:right><p>[foo]<p>bar</div><p>extra', + '<div style=text-align:right><p>[foo<p>bar]</div><p>extra', + + '<div align=right>foo</div>[bar]<p>extra', + '[foo]<div align=right>bar</div><p>extra', + '<div align=right>foo</div>[bar]<div align=right>baz</div><p>extra', + '<div align=right><p>foo</div><p>[bar]<p>extra', + '<p>[foo]<div align=right><p>bar</div><p>extra', + '<div align=right><p>foo</div><p>[bar]<div align=right><p>baz</div><p>extra', + '<div style=text-align:right>foo</div>[bar]<p>extra', + '[foo]<div style=text-align:right>bar</div><p>extra', + '<div style=text-align:right>foo</div>[bar]<div style=text-align:right>baz</div><p>extra', + '<div style=text-align:right><p>foo</div><p>[bar]<p>extra', + '<p>[foo]<div style=text-align:right><p>bar</div><p>extra', + '<div style=text-align:right><p>foo</div><p>[bar]<div style=text-align:right><p>baz</div><p>extra', + '<p align=right>foo<p>[bar]<p>extra', + '<p>[foo]<p align=right>bar<p>extra', + '<p align=right>foo<p>[bar]<p align=right>baz<p>extra', + + '<div align=right>[foo</div>bar]<p>extra', + '<div align=right>fo[o</div>b]ar<p>extra', + '<div style=text-align:right>[foo</div>bar]<p>extra', + '<div style=text-align:right>fo[o</div>b]ar<p>extra', + '<span style=text-align:right>[foo]</span><p>extra', + '<span style=text-align:right>f[o]o</span><p>extra', + + '<div style=text-align:right>[foo<div style=text-align:left contenteditable=false>bar</div>baz]</div><p>extra', + + '<div align=nonsense><p>[foo]</div><p>extra', + '<div style=text-align:inherit><p>[foo]</div><p>extra', + '<quasit align=center><p>[foo]</p></quasit><p>extra', + + '<div style=text-align:start>[foo]</div><p>extra', + '<div style=text-align:end>[foo]</div><p>extra', + '<div dir=rtl style=text-align:start>[foo]</div><p>extra', + '<div dir=rtl style=text-align:end>[foo]</div><p>extra', + + // Whitespace nodes + '<div style=text-align:right><p>foo</div> <p>[bar]', + '<div align=right><p>foo</div> <p>[bar]', + '<p>[foo]</p> <div style=text-align:right><p>bar</div>', + '<p>[foo]</p> <div align=right><p>bar</div>', + '<div style=text-align:right><p>foo</div> <p>[bar]</p> <div style=text-align:right><p>baz</div>', + '<div align=right><p>foo</div> <p>[bar]</p> <div align=right><p>baz</div>', + ], + //@} + outdent: [ + //@{ + // These mimic existing indentation in various browsers, to see how + // they cope with outdenting various things. This is spec, Gecko + // non-CSS, and Opera: + '<blockquote><p>foo[bar]</p><p>baz</p></blockquote><p>extra', + '<blockquote><p>foo[bar</p><p>b]az</p></blockquote><p>extra', + '<blockquote><p>foo[bar]</p></blockquote><p>baz</p><p>extra', + '<blockquote><p>foo[bar</p></blockquote><p>b]az</p><p>extra', + + // IE: + '<blockquote style="margin-right: 0px;" dir="ltr"><p>foo[bar]</p><p>baz</p></blockquote><p>extra', + '<blockquote style="margin-right: 0px;" dir="ltr"><p>foo[bar</p><p>b]az</p></blockquote><p>extra', + '<blockquote style="margin-right: 0px;" dir="ltr"><p>foo[bar]</p></blockquote><p>baz</p><p>extra', + '<blockquote style="margin-right: 0px;" dir="ltr"><p>foo[bar</p></blockquote><p>b]az</p><p>extra', + + // Firefox CSS mode: + '<p style="margin-left: 40px">foo[bar]</p><p style="margin-left: 40px">baz</p><p>extra', + '<p style="margin-left: 40px">foo[bar</p><p style="margin-left: 40px">b]az</p><p>extra', + '<p style="margin-left: 40px">foo[bar]</p><p>baz</p><p>extra', + '<p style="margin-left: 40px">foo[bar</p><p>b]az</p><p>extra', + + // WebKit: + '<blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"><p>foo[bar]</p><p>baz</p></blockquote><p>extra', + '<blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"><p>foo[bar</p><p>b]az</p></blockquote><p>extra', + '<blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"><p>foo[bar]</p></blockquote><p>baz</p><p>extra', + '<blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"><p>foo[bar</p></blockquote><p>b]az</p><p>extra', + + // Now let's try nesting lots of stuff and see what happens. + '<blockquote><blockquote>foo[bar]baz</blockquote></blockquote>', + '<blockquote><blockquote data-abc=def>foo[bar]baz</blockquote></blockquote>', + '<blockquote data-abc=def><blockquote>foo[bar]baz</blockquote></blockquote>', + '<blockquote><div>foo[bar]baz</div></blockquote>', + '<blockquote><div id=abc>foo[bar]baz</div></blockquote>', + '<blockquote id=abc>foo[bar]baz</blockquote>', + '<blockquote style="color: blue">foo[bar]baz</blockquote>', + + '<blockquote><blockquote><p>foo[bar]<p>baz</blockquote></blockquote>', + '<blockquote><blockquote data-abc=def><p>foo[bar]<p>baz</blockquote></blockquote>', + '<blockquote data-abc=def><blockquote><p>foo[bar]<p>baz</blockquote></blockquote>', + '<blockquote><div><p>foo[bar]<p>baz</div></blockquote>', + '<blockquote><div id=abc><p>foo[bar]<p>baz</div></blockquote>', + '<blockquote id=abc><p>foo[bar]<p>baz</blockquote>', + '<blockquote style="color: blue"><p>foo[bar]<p>baz</blockquote>', + + '<blockquote><p><b>foo[bar]</b><p>baz</blockquote>', + '<blockquote><p><strong>foo[bar]</strong><p>baz</blockquote>', + '<blockquote><p><span>foo[bar]</span><p>baz</blockquote>', + '<blockquote><blockquote style="color: blue"><p>foo[bar]</blockquote><p>baz</blockquote>', + '<blockquote style="color: blue"><blockquote><p>foo[bar]</blockquote><p>baz</blockquote>', + + // Lists! + '<ol><li>foo<li>[bar]<li>baz</ol>', + '<ol data-start=1 data-end=2><li>foo<li>bar<li>baz</ol>', + '<ol><li>foo</ol>[bar]', + '<ol><li>[foo]<br>bar<li>baz</ol>', + '<ol><li>foo<br>[bar]<li>baz</ol>', + '<ol><li><div>[foo]</div>bar<li>baz</ol>', + '<ol><li>foo<ol><li>[bar]<li>baz</ol><li>quz</ol>', + '<ol><li>foo<ol><li>bar<li>[baz]</ol><li>quz</ol>', + '<ol><li>foo</li><ol><li>[bar]<li>baz</ol><li>quz</ol>', + '<ol><li>foo</li><ol data-start=0 data-end=1><li>bar<li>baz</ol><li>quz</ol>', + '<ol><li>foo</li><ol><li>bar<li>[baz]</ol><li>quz</ol>', + '<ol><li>foo</li><ol data-start=1 data-end=2><li>bar<li>baz</ol><li>quz</ol>', + '<ol><li>foo<ol><li>b[a]r</ol><li>baz</ol>', + '<ol><li>foo</li><ol><li>b[a]r</ol><li>baz</ol>', + '<ol><li>foo{<ol><li>bar</ol>}<li>baz</ol>', + '<ol><li>foo</li>{<ol><li>bar</ol>}<li>baz</ol>', + '<ol><li>[foo]<ol><li>bar</ol><li>baz</ol>', + '<ol><li>[foo]</li><ol><li>bar</ol><li>baz</ol>', + '<ol><li>foo<li>[bar]<ol><li>baz</ol><li>quz</ol>', + '<ol><li>foo<li>[bar]</li><ol><li>baz</ol><li>quz</ol>', + '<ol><li>foo<ol><li>bar<li>baz</ol><li>[quz]</ol>', + '<ol><li>foo</li><ol><li>bar<li>baz</ol><li>[quz]</ol>', + + // Try outdenting multiple items at once. + '<ol><li>foo<li>b[ar<li>baz]</ol>', + '<ol><li>[foo<ol><li>bar]</ol><li>baz</ol>', + '<ol><li>[foo</li><ol><li>bar]</ol><li>baz</ol>', + '<ol><li>foo<ol><li>b[ar</ol><li>b]az</ol>', + '<ol><li>foo</li><ol><li>b[ar</ol><li>b]az</ol>', + '<ol><li>[foo<ol><li>bar</ol><li>baz]</ol><p>extra', + '<ol><li>[foo</li><ol><li>bar</ol><li>baz]</ol><p>extra', + + // We probably can't actually get this DOM . . . + '<ol><li>[foo]<ol><li>bar</ol>baz</ol>', + '<ol><li>foo<ol><li>[bar]</ol>baz</ol>', + '<ol><li>foo<ol><li>bar</ol>[baz]</ol>', + '<ol><li>[foo<ol><li>bar]</ol>baz</ol>', + + // Attribute handling on lists + 'foo<ol start=5><li>[bar]</ol>baz', + 'foo<ol id=abc><li>[bar]</ol>baz', + 'foo<ol style=color:blue><li>[bar]</ol>baz', + 'foo<ol><li value=5>[bar]</ol>baz', + 'foo<ol><li id=abc>[bar]</ol>baz', + 'foo<ol><li style=color:blue>[bar]</ol>baz', + '<ol><li>foo</li><ol><li value=5>[bar]</ol></ol>', + '<ul><li>foo</li><ol><li value=5>[bar]</ol></ul>', + '<ol><li>foo</li><ol start=5><li>[bar]</ol><li>baz</ol>', + '<ol><li>foo</li><ol id=abc><li>[bar]</ol><li>baz</ol>', + '<ol><li>foo</li><ol style=color:blue><li>[bar]</ol><li>baz</ol>', + '<ol><li>foo</li><ol style=text-indent:1em><li>[bar]</ol><li>baz</ol>', + '<ol><li>foo</li><ol start=5><li>[bar<li>baz]</ol><li>quz</ol>', + '<ol><li>foo</li><ol id=abc><li>[bar<li>baz]</ol><li>quz</ol>', + '<ol><li>foo</li><ol style=color:blue><li>[bar<li>baz]</ol><li>quz</ol>', + '<ol><li>foo</li><ol style=text-indent:1em><li>[bar<li>baz]</ol><li>quz</ol>', + + // List inside indentation element + '<blockquote><ol><li>[foo]</ol></blockquote><p>extra', + '<blockquote>foo<ol><li>[bar]</ol>baz</blockquote><p>extra', + '<blockquote><ol><li>foo</li><ol><li>[bar]</ol><li>baz</ol></blockquote><p>extra', + + '<ol><li><h1>[foo]</h1></ol>', + '<ol><li><xmp>[foo]</xmp></li></ol>', + '<blockquote><ol><li>foo<div><ol><li>[bar]</ol></div><li>baz</ol></blockquote>', + + // Whitespace nodes + '<blockquote> <p>[foo]</p></blockquote>', + '<blockquote><p>[foo]</p> </blockquote>', + '<blockquote> <p>[foo]</p> </blockquote>', + '<ol> <li>[foo]</li></ol>', + '<ol><li>[foo]</li> </ol>', + '<ol> <li>[foo]</li> </ol>', + '<ul> <li>[foo]</li></ul>', + '<ul><li>[foo]</li> </ul>', + '<ul> <li>[foo]</li> </ul>', + '<blockquote> <p>[foo]</p> <p>bar</p> <p>baz</p></blockquote>', + '<blockquote> <p>foo</p> <p>[bar]</p> <p>baz</p></blockquote>', + '<blockquote> <p>foo</p> <p>bar</p> <p>[baz]</p></blockquote>', + '<ol> <li>[foo]</li> <li>bar</li> <li>baz</li></ol>', + '<ol> <li>foo</li> <li>[bar]</li> <li>baz</li></ol>', + '<ol> <li>foo</li> <li>bar</li> <li>[baz]</li></ol>', + '<ul> <li>[foo]</li> <li>bar</li> <li>baz</li></ul>', + '<ul> <li>foo</li> <li>[bar]</li> <li>baz</li></ul>', + '<ul> <li>foo</li> <li>bar</li> <li>[baz]</li></ul>', + + // https://bugs.webkit.org/show_bug.cgi?id=24249 + '<ol><li>[]a<table><tr><td><br></table></ol>', + // https://bugs.webkit.org/show_bug.cgi?id=43447 + '<blockquote><span>foo<br>[bar]</span></blockquote>', + ], + //@} + removeformat: [ + //@{ + 'foo[]bar', + '<span>foo</span>{}<span>bar</span>', + '<span>foo[</span><span>]bar</span>', + '[foo<b>bar</b>baz]', + 'foo[<b>bar</b>baz]', + 'foo[<b>bar</b>]baz', + 'foo<b>[bar]</b>baz', + 'foo<b>b[a]r</b>baz', + '[foo<strong>bar</strong>baz]', + '[foo<span style="font-weight: bold">bar</span>baz]', + 'foo<span style="font-weight: bold">b[a]r</span>baz', + '[foo<span style="font-variant: small-caps">bar</span>baz]', + 'foo<span style="font-variant: small-caps">b[a]r</span>baz', + '[foo<b id=foo>bar</b>baz]', + 'foo<b id=foo>b[a]r</b>baz', + + // HTML has lots of inline elements, doesn't it? + '[foo<a>bar</a>baz]', + 'foo<a>b[a]r</a>baz', + '[foo<a href=foo>bar</a>baz]', + 'foo<a href=foo>b[a]r</a>baz', + '[foo<abbr>bar</abbr>baz]', + 'foo<abbr>b[a]r</abbr>baz', + '[foo<acronym>bar</acronym>baz]', + 'foo<acronym>b[a]r</acronym>baz', + '[foo<b>bar</b>baz]', + 'foo<b>b[a]r</b>baz', + '[foo<bdi dir=rtl>bar</bdi>baz]', + 'foo<bdi dir=rtl>b[a]r</bdi>baz', + '[foo<bdo dir=rtl>bar</bdo>baz]', + 'foo<bdo dir=rtl>b[a]r</bdo>baz', + '[foo<big>bar</big>baz]', + 'foo<big>b[a]r</big>baz', + '[foo<blink>bar</blink>baz]', + 'foo<blink>b[a]r</blink>baz', + '[foo<cite>bar</cite>baz]', + 'foo<cite>b[a]r</cite>baz', + '[foo<code>bar</code>baz]', + 'foo<code>b[a]r</code>baz', + '[foo<del>bar</del>baz]', + 'foo<del>b[a]r</del>baz', + '[foo<dfn>bar</dfn>baz]', + 'foo<dfn>b[a]r</dfn>baz', + '[foo<em>bar</em>baz]', + 'foo<em>b[a]r</em>baz', + '[foo<font>bar</font>baz]', + 'foo<font>b[a]r</font>baz', + '[foo<font color=blue>bar</font>baz]', + 'foo<font color=blue>b[a]r</font>baz', + '[foo<i>bar</i>baz]', + 'foo<i>b[a]r</i>baz', + '[foo<ins>bar</ins>baz]', + 'foo<ins>b[a]r</ins>baz', + '[foo<kbd>bar</kbd>baz]', + 'foo<kbd>b[a]r</kbd>baz', + '[foo<mark>bar</mark>baz]', + 'foo<mark>b[a]r</mark>baz', + '[foo<nobr>bar</nobr>baz]', + 'foo<nobr>b[a]r</nobr>baz', + '[foo<q>bar</q>baz]', + 'foo<q>b[a]r</q>baz', + '[foo<samp>bar</samp>baz]', + 'foo<samp>b[a]r</samp>baz', + '[foo<s>bar</s>baz]', + 'foo<s>b[a]r</s>baz', + '[foo<small>bar</small>baz]', + 'foo<small>b[a]r</small>baz', + '[foo<span>bar</span>baz]', + 'foo<span>b[a]r</span>baz', + '[foo<strike>bar</strike>baz]', + 'foo<strike>b[a]r</strike>baz', + '[foo<strong>bar</strong>baz]', + 'foo<strong>b[a]r</strong>baz', + '[foo<sub>bar</sub>baz]', + 'foo<sub>b[a]r</sub>baz', + '[foo<sup>bar</sup>baz]', + 'foo<sup>b[a]r</sup>baz', + '[foo<tt>bar</tt>baz]', + 'foo<tt>b[a]r</tt>baz', + '[foo<u>bar</u>baz]', + 'foo<u>b[a]r</u>baz', + '[foo<var>bar</var>baz]', + 'foo<var>b[a]r</var>baz', + + // Empty and replaced elements + '[foo<br>bar]', + '[foo<hr>bar]', + '[foo<wbr>bar]', + '[foo<img>bar]', + '[foo<img src=abc>bar]', + '[foo<video></video>bar]', + '[foo<video src=abc></video>bar]', + '[foo<svg><circle fill=blue r=20 cx=20 cy=20 /></svg>bar]', + + // Unrecognized elements + '[foo<nonexistentelement>bar</nonexistentelement>baz]', + 'foo<nonexistentelement>b[a]r</nonexistentelement>baz', + '[foo<nonexistentelement style="display: block">bar</nonexistentelement>baz]', + 'foo<nonexistentelement style="display: block">b[a]r</nonexistentelement>baz', + + // Random stuff + '[foo<span id=foo>bar</span>baz]', + 'foo<span id=foo>b[a]r</span>baz', + '[foo<span class=foo>bar</span>baz]', + 'foo<span class=foo>b[a]r</span>baz', + '[foo<b style="font-weight: normal">bar</b>baz]', + 'foo<b style="font-weight: normal">b[a]r</b>baz', + '<p style="background-color: aqua">foo[bar]baz</p>', + '<p><span style="background-color: aqua">foo[bar]baz</span></p>', + '<p style="font-weight: bold">foo[bar]baz</p>', + '<b><p style="font-weight: bold">foo[bar]baz</p></b>', + '<p style="font-variant: small-caps">foo[bar]baz</p>', + '{<p style="font-variant: small-caps">foobarbaz</p>}', + '<p style="text-indent: 2em">foo[bar]baz</p>', + '{<p style="text-indent: 2em">foobarbaz</p>}', + + // https://bugzilla.mozilla.org/show_bug.cgi?id=649138 + // Chrome 15 dev fails this for some unclear reason. + '<table data-start=0 data-end=1><tr><td><b>foo</b></table>', + ], + //@} + strikethrough: [ + //@{ + 'foo[]bar', + '<p>[foo</p> <p>bar]</p>', + '<span>[foo</span> <span>bar]</span>', + '<p>[foo</p><p> <span>bar</span> </p><p>baz]</p>', + '<p>[foo<p><br><p>bar]', + '<b>foo[]bar</b>', + '<i>foo[]bar</i>', + '<span>foo</span>{}<span>bar</span>', + '<span>foo[</span><span>]bar</span>', + 'foo[bar]baz', + 'foo[bar<b>baz]qoz</b>quz', + 'foo[bar<i>baz]qoz</i>quz', + '{<p><p> <p>foo</p>}', + + '<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>', + '<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table>', + '<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table>', + '<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>', + '<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>', + '{<table><tr><td>foo<td>bar<td>baz</table>}', + + 'foo<u>[bar]</u>baz', + 'foo<span style="text-decoration: underline">[bar]</span>baz', + '<u>foo[bar]baz</u>', + '<u>foo[b<span style="color:blue">ar]ba</span>z</u>', + '<u>foo[b<span style="color:blue" id=foo>ar]ba</span>z</u>', + '<u>foo[b<span style="font-size:3em">ar]ba</span>z</u>', + '<u>foo[b<i>ar]ba</i>z</u>', + '<p style="text-decoration: underline">foo[bar]baz</p>', + + 'foo<s>[bar]</s>baz', + 'foo<span style="text-decoration: line-through">[bar]</span>baz', + '<s>foo[bar]baz</s>', + '<s>foo[b<span style="color:blue">ar]ba</span>z</s>', + '<s>foo[b<span style="color:blue" id=foo>ar]ba</span>z</s>', + '<s>foo[b<span style="font-size:3em">ar]ba</span>z</s>', + '<s>foo[b<i>ar]ba</i>z</s>', + '<p style="text-decoration: line-through">foo[bar]baz</p>', + + 'foo<strike>[bar]</strike>baz', + '<strike>foo[bar]baz</strike>', + '<strike>foo[b<span style="color:blue">ar]ba</span>z</strike>', + '<strike>foo[b<span style="color:blue" id=foo>ar]ba</span>z</strike>', + '<strike>foo[b<span style="font-size:3em">ar]ba</span>z</strike>', + '<strike>foo[b<i>ar]ba</i>z</strike>', + + 'foo<ins>[bar]</ins>baz', + '<ins>foo[bar]baz</ins>', + '<ins>foo[b<span style="color:blue">ar]ba</span>z</ins>', + '<ins>foo[b<span style="color:blue" id=foo>ar]ba</span>z</ins>', + '<ins>foo[b<span style="font-size:3em">ar]ba</span>z</ins>', + '<ins>foo[b<i>ar]ba</i>z</ins>', + + 'foo<del>[bar]</del>baz', + '<del>foo[bar]baz</del>', + '<del>foo[b<span style="color:blue">ar]ba</span>z</del>', + '<del>foo[b<span style="color:blue" id=foo>ar]ba</span>z</del>', + '<del>foo[b<span style="font-size:3em">ar]ba</span>z</del>', + '<del>foo[b<i>ar]ba</i>z</del>', + + 'foo<span style="text-decoration: underline line-through">[bar]</span>baz', + 'foo<span style="text-decoration: underline line-through">b[a]r</span>baz', + 'foo<s style="text-decoration: underline">[bar]</s>baz', + 'foo<s style="text-decoration: underline">b[a]r</s>baz', + 'foo<u style="text-decoration: line-through">[bar]</u>baz', + 'foo<u style="text-decoration: line-through">b[a]r</u>baz', + 'foo<s style="text-decoration: overline">[bar]</s>baz', + 'foo<s style="text-decoration: overline">b[a]r</s>baz', + 'foo<u style="text-decoration: overline">[bar]</u>baz', + 'foo<u style="text-decoration: overline">b[a]r</u>baz', + + '<p style="text-decoration: line-through">foo[bar]baz</p>', + '<p style="text-decoration: overline">foo[bar]baz</p>', + + 'foo<span class="underline">[bar]</span>baz', + 'foo<span class="underline">b[a]r</span>baz', + 'foo<span class="line-through">[bar]</span>baz', + 'foo<span class="line-through">b[a]r</span>baz', + 'foo<span class="underline-and-line-through">[bar]</span>baz', + 'foo<span class="underline-and-line-through">b[a]r</span>baz', + + // Tests for queryCommandIndeterm() and queryCommandState() + 'fo[o<s>b]ar</s>baz', + 'foo<s>ba[r</s>b]az', + 'fo[o<s>bar</s>b]az', + 'foo[<s>b]ar</s>baz', + 'foo<s>ba[r</s>]baz', + 'foo[<s>bar</s>]baz', + 'foo<s>[bar]</s>baz', + 'foo{<s>bar</s>}baz', + 'fo[o<span style=text-decoration:line-through>b]ar</span>baz', + '<strike>fo[o</strike><s>b]ar</s>', + '<s>fo[o</s><del>b]ar</del>', + ], + //@} + subscript: [ + //@{ + 'foo[]bar', + '<p>[foo</p> <p>bar]</p>', + '<span>[foo</span> <span>bar]</span>', + '<p>[foo</p><p> <span>bar</span> </p><p>baz]</p>', + '<p>[foo<p><br><p>bar]', + '<b>foo[]bar</b>', + '<i>foo[]bar</i>', + '<span>foo</span>{}<span>bar</span>', + '<span>foo[</span><span>]bar</span>', + 'foo[bar]baz', + 'foo[bar<b>baz]qoz</b>quz', + 'foo[bar<i>baz]qoz</i>quz', + '{<p><p> <p>foo</p>}', + + '<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>', + '<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table>', + '<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table>', + '<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>', + '<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>', + '{<table><tr><td>foo<td>bar<td>baz</table>}', + + 'foo<sub>[bar]</sub>baz', + 'foo<sub>b[a]r</sub>baz', + 'foo<sup>[bar]</sup>baz', + 'foo<sup>b[a]r</sup>baz', + + 'foo<span style=vertical-align:sub>[bar]</span>baz', + 'foo<span style=vertical-align:super>[bar]</span>baz', + + 'foo<sub><sub>[bar]</sub></sub>baz', + 'foo<sub><sub>b[a]r</sub></sub>baz', + 'foo<sub>b<sub>[a]</sub>r</sub>baz', + 'foo<sup><sup>[bar]</sup></sup>baz', + 'foo<sup><sup>b[a]r</sup></sup>baz', + 'foo<sup>b<sup>[a]</sup>r</sup>baz', + 'foo<sub><sup>[bar]</sup></sub>baz', + 'foo<sub><sup>b[a]r</sup></sub>baz', + 'foo<sub>b<sup>[a]</sup>r</sub>baz', + 'foo<sup><sub>[bar]</sub></sup>baz', + 'foo<sup><sub>b[a]r</sub></sup>baz', + 'foo<sup>b<sub>[a]</sub>r</sup>baz', + + // Tests for queryCommandIndeterm() and queryCommandState() + 'fo[o<sub>b]ar</sub>baz', + 'foo<sub>ba[r</sub>b]az', + 'fo[o<sub>bar</sub>b]az', + 'foo[<sub>b]ar</sub>baz', + 'foo<sub>ba[r</sub>]baz', + 'foo[<sub>bar</sub>]baz', + 'foo<sub>[bar]</sub>baz', + 'foo{<sub>bar</sub>}baz', + '<sub>fo[o</sub><sup>b]ar</sup>', + '<sub>fo[o</sub><span style=vertical-align:sub>b]ar</span>', + 'foo<span style=vertical-align:top>[bar]</span>baz', + '<sub>fo[o</sub><span style=vertical-align:top>b]ar</span>', + ], + //@} + superscript: [ + //@{ + 'foo[]bar', + '<p>[foo</p> <p>bar]</p>', + '<span>[foo</span> <span>bar]</span>', + '<p>[foo</p><p> <span>bar</span> </p><p>baz]</p>', + '<p>[foo<p><br><p>bar]', + '<b>foo[]bar</b>', + '<i>foo[]bar</i>', + '<span>foo</span>{}<span>bar</span>', + '<span>foo[</span><span>]bar</span>', + 'foo[bar]baz', + 'foo[bar<b>baz]qoz</b>quz', + 'foo[bar<i>baz]qoz</i>quz', + '{<p><p> <p>foo</p>}', + + '<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>', + '<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table>', + '<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table>', + '<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>', + '<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>', + '{<table><tr><td>foo<td>bar<td>baz</table>}', + + 'foo<sub>[bar]</sub>baz', + 'foo<sub>b[a]r</sub>baz', + 'foo<sup>[bar]</sup>baz', + 'foo<sup>b[a]r</sup>baz', + + 'foo<span style=vertical-align:sub>[bar]</span>baz', + 'foo<span style=vertical-align:super>[bar]</span>baz', + + 'foo<sub><sub>[bar]</sub></sub>baz', + 'foo<sub><sub>b[a]r</sub></sub>baz', + 'foo<sub>b<sub>[a]</sub>r</sub>baz', + 'foo<sup><sup>[bar]</sup></sup>baz', + 'foo<sup><sup>b[a]r</sup></sup>baz', + 'foo<sup>b<sup>[a]</sup>r</sup>baz', + 'foo<sub><sup>[bar]</sup></sub>baz', + 'foo<sub><sup>b[a]r</sup></sub>baz', + 'foo<sub>b<sup>[a]</sup>r</sub>baz', + 'foo<sup><sub>[bar]</sub></sup>baz', + 'foo<sup><sub>b[a]r</sub></sup>baz', + 'foo<sup>b<sub>[a]</sub>r</sup>baz', + + // Tests for queryCommandIndeterm() and queryCommandState() + 'fo[o<sup>b]ar</sup>baz', + 'foo<sup>ba[r</sup>b]az', + 'fo[o<sup>bar</sup>b]az', + 'foo[<sup>b]ar</sup>baz', + 'foo<sup>ba[r</sup>]baz', + 'foo[<sup>bar</sup>]baz', + 'foo<sup>[bar]</sup>baz', + 'foo{<sup>bar</sup>}baz', + '<sup>fo[o</sup><sub>b]ar</sub>', + '<sup>fo[o</sup><span style=vertical-align:super>b]ar</span>', + 'foo<span style=vertical-align:bottom>[bar]</span>baz', + '<sup>fo[o</sup><span style=vertical-align:bottom>b]ar</span>', + + // https://bugs.webkit.org/show_bug.cgi?id=28472 + 'foo<sup>[bar]<br></sup>', + ], + //@} + underline: [ + //@{ + 'foo[]bar', + '<p>[foo</p> <p>bar]</p>', + '<span>[foo</span> <span>bar]</span>', + '<p>[foo</p><p> <span>bar</span> </p><p>baz]</p>', + '<p>[foo<p><br><p>bar]', + '<b>foo[]bar</b>', + '<i>foo[]bar</i>', + '<span>foo</span>{}<span>bar</span>', + '<span>foo[</span><span>]bar</span>', + 'foo[bar]baz', + 'foo[bar<b>baz]qoz</b>quz', + 'foo[bar<i>baz]qoz</i>quz', + '{<p><p> <p>foo</p>}', + + '<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>', + '<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table>', + '<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table>', + '<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>', + '<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>', + '{<table><tr><td>foo<td>bar<td>baz</table>}', + + 'foo<u>[bar]</u>baz', + 'foo<span style="text-decoration: underline">[bar]</span>baz', + '<u>foo[bar]baz</u>', + '<u>foo[b<span style="color:blue">ar]ba</span>z</u>', + '<u>foo[b<span style="color:blue" id=foo>ar]ba</span>z</u>', + '<u>foo[b<span style="font-size:3em">ar]ba</span>z</u>', + '<u>foo[b<i>ar]ba</i>z</u>', + '<p style="text-decoration: underline">foo[bar]baz</p>', + + 'foo<s>[bar]</s>baz', + 'foo<span style="text-decoration: line-through">[bar]</span>baz', + '<s>foo[bar]baz</s>', + '<s>foo[b<span style="color:blue">ar]ba</span>z</s>', + '<s>foo[b<span style="color:blue" id=foo>ar]ba</span>z</s>', + '<s>foo[b<span style="font-size:3em">ar]ba</span>z</s>', + '<s>foo[b<i>ar]ba</i>z</s>', + '<p style="text-decoration: line-through">foo[bar]baz</p>', + + 'foo<strike>[bar]</strike>baz', + '<strike>foo[bar]baz</strike>', + '<strike>foo[b<span style="color:blue">ar]ba</span>z</strike>', + '<strike>foo[b<span style="color:blue" id=foo>ar]ba</span>z</strike>', + '<strike>foo[b<span style="font-size:3em">ar]ba</span>z</strike>', + '<strike>foo[b<i>ar]ba</i>z</strike>', + + 'foo<ins>[bar]</ins>baz', + '<ins>foo[bar]baz</ins>', + '<ins>foo[b<span style="color:blue">ar]ba</span>z</ins>', + '<ins>foo[b<span style="color:blue" id=foo>ar]ba</span>z</ins>', + '<ins>foo[b<span style="font-size:3em">ar]ba</span>z</ins>', + '<ins>foo[b<i>ar]ba</i>z</ins>', + + 'foo<del>[bar]</del>baz', + '<del>foo[bar]baz</del>', + '<del>foo[b<span style="color:blue">ar]ba</span>z</del>', + '<del>foo[b<span style="color:blue" id=foo>ar]ba</span>z</del>', + '<del>foo[b<span style="font-size:3em">ar]ba</span>z</del>', + '<del>foo[b<i>ar]ba</i>z</del>', + + 'foo<span style="text-decoration: underline line-through">[bar]</span>baz', + 'foo<span style="text-decoration: underline line-through">b[a]r</span>baz', + 'foo<s style="text-decoration: underline">[bar]</s>baz', + 'foo<s style="text-decoration: underline">b[a]r</s>baz', + 'foo<u style="text-decoration: line-through">[bar]</u>baz', + 'foo<u style="text-decoration: line-through">b[a]r</u>baz', + 'foo<s style="text-decoration: overline">[bar]</s>baz', + 'foo<s style="text-decoration: overline">b[a]r</s>baz', + 'foo<u style="text-decoration: overline">[bar]</u>baz', + 'foo<u style="text-decoration: overline">b[a]r</u>baz', + + '<p style="text-decoration: line-through">foo[bar]baz</p>', + '<p style="text-decoration: overline">foo[bar]baz</p>', + + 'foo<span class="underline">[bar]</span>baz', + 'foo<span class="underline">b[a]r</span>baz', + 'foo<span class="line-through">[bar]</span>baz', + 'foo<span class="line-through">b[a]r</span>baz', + 'foo<span class="underline-and-line-through">[bar]</span>baz', + 'foo<span class="underline-and-line-through">b[a]r</span>baz', + + // Tests for queryCommandIndeterm() and queryCommandState() + 'fo[o<u>b]ar</u>baz', + 'foo<u>ba[r</u>b]az', + 'fo[o<u>bar</u>b]az', + 'foo[<u>b]ar</u>baz', + 'foo<u>ba[r</u>]baz', + 'foo[<u>bar</u>]baz', + 'foo<u>[bar]</u>baz', + 'foo{<u>bar</u>}baz', + 'fo[o<span style=text-decoration:underline>b]ar</span>baz', + '<ins>fo[o</ins><u>b]ar</u>', + '<u>fo[o</u><ins>b]ar</ins>', + ], + //@} + unlink: [ + //@{ + 'foo[]bar', + '<p>[foo</p> <p>bar]</p>', + '<span>[foo</span> <span>bar]</span>', + '<p>[foo</p><p> <span>bar</span> </p><p>baz]</p>', + '<b>foo[]bar</b>', + '<i>foo[]bar</i>', + '<span>foo</span>{}<span>bar</span>', + '<span>foo[</span><span>]bar</span>', + 'foo[bar]baz', + 'foo[bar<b>baz]qoz</b>quz', + 'foo[bar<i>baz]qoz</i>quz', + '{<p><p> <p>foo</p>}', + + '<a href=http://www.google.com/>foo[bar]baz</a>', + '<a href=http://www.google.com/>foo[barbaz</a>}', + '{<a href=http://www.google.com/>foobar]baz</a>', + '{<a href=http://www.google.com/>foobarbaz</a>}', + '<a href=http://www.google.com/>[foobarbaz]</a>', + + 'foo<a href=http://www.google.com/>b[]ar</a>baz', + 'foo<a href=http://www.google.com/>[bar]</a>baz', + 'foo[<a href=http://www.google.com/>bar</a>]baz', + 'foo<a href=http://www.google.com/>[bar</a>baz]', + '[foo<a href=http://www.google.com/>bar]</a>baz', + '[foo<a href=http://www.google.com/>bar</a>baz]', + + '<a id=foo href=http://www.google.com/>foobar[]baz</a>', + '<a id=foo href=http://www.google.com/>foo[bar]baz</a>', + '<a id=foo href=http://www.google.com/>[foobarbaz]</a>', + 'foo<a id=foo href=http://www.google.com/>[bar]</a>baz', + 'foo[<a id=foo href=http://www.google.com/>bar</a>]baz', + '[foo<a id=foo href=http://www.google.com/>bar</a>baz]', + + '<a name=foo>foobar[]baz</a>', + '<a name=foo>foo[bar]baz</a>', + '<a name=foo>[foobarbaz]</a>', + 'foo<a name=foo>[bar]</a>baz', + 'foo[<a name=foo>bar</a>]baz', + '[foo<a name=foo>bar</a>baz]', + ], + //@} + copy: ['!foo[bar]baz'], + cut: ['!foo[bar]baz'], + defaultparagraphseparator: [ + //@{ + ['', 'foo[bar]baz'], + ['div', 'foo[bar]baz'], + ['p', 'foo[bar]baz'], + ['DIV', 'foo[bar]baz'], + ['P', 'foo[bar]baz'], + [' div ', 'foo[bar]baz'], + [' p ', 'foo[bar]baz'], + ['<div>', 'foo[bar]baz'], + ['<p>', 'foo[bar]baz'], + ['li', 'foo[bar]baz'], + ['blockquote', 'foo[bar]baz'], + ], + //@} + paste: ['!foo[bar]baz'], + selectall: ['foo[bar]baz'], + stylewithcss: [ + //@{ + ['true', 'foo[bar]baz'], + ['TRUE', 'foo[bar]baz'], + ['TrUe', 'foo[bar]baz'], + ['true ', 'foo[bar]baz'], + [' true', 'foo[bar]baz'], + ['truer', 'foo[bar]baz'], + [' true ', 'foo[bar]baz'], + [' TrUe', 'foo[bar]baz'], + ['', 'foo[bar]baz'], + [' ', 'foo[bar]baz'], + ['false', 'foo[bar]baz'], + ['FALSE', 'foo[bar]baz'], + ['FaLsE', 'foo[bar]baz'], + [' false', 'foo[bar]baz'], + ['false ', 'foo[bar]baz'], + ['falser', 'foo[bar]baz'], + ['falsé', 'foo[bar]baz'], + ], + //@} + usecss: [ + //@{ + ['true', 'foo[bar]baz'], + ['TRUE', 'foo[bar]baz'], + ['TrUe', 'foo[bar]baz'], + ['true ', 'foo[bar]baz'], + [' true', 'foo[bar]baz'], + ['truer', 'foo[bar]baz'], + [' true ', 'foo[bar]baz'], + [' TrUe', 'foo[bar]baz'], + ['', 'foo[bar]baz'], + [' ', 'foo[bar]baz'], + ['false', 'foo[bar]baz'], + ['FALSE', 'foo[bar]baz'], + ['FaLsE', 'foo[bar]baz'], + [' false', 'foo[bar]baz'], + ['false ', 'foo[bar]baz'], + ['falser', 'foo[bar]baz'], + ['falsé', 'foo[bar]baz'], + ], + //@} + quasit: ['foo[bar]baz'], + multitest: [ + //@{ + // Insertion-affecting state. Test that insertText works right, and + // test that various block commands preserve (or don't preserve) the + // state. + ['foo[]bar', 'bold', 'inserttext'], + ['foo[]bar', 'bold', 'delete'], + ['foo[]bar', 'bold', 'delete', 'inserttext'], + ['foo[]bar', 'bold', 'formatblock'], + ['foo[]bar', 'bold', 'formatblock', 'inserttext'], + ['foo[]bar', 'bold', 'forwarddelete'], + ['foo[]bar', 'bold', 'forwarddelete', 'inserttext'], + ['foo[]bar', 'bold', 'indent'], + ['foo[]bar', 'bold', 'indent', 'inserttext'], + ['foo[]bar', 'bold', 'inserthorizontalrule'], + ['foo[]bar', 'bold', 'inserthorizontalrule', 'inserttext'], + ['foo[]bar', 'bold', 'inserthtml'], + ['foo[]bar', 'bold', 'inserthtml', 'inserttext'], + ['foo[]bar', 'bold', 'insertimage'], + ['foo[]bar', 'bold', 'insertimage', 'inserttext'], + ['foo[]bar', 'bold', 'insertlinebreak'], + ['foo[]bar', 'bold', 'insertlinebreak', 'inserttext'], + ['foo[]bar', 'bold', 'insertorderedlist'], + ['foo[]bar', 'bold', 'insertorderedlist', 'inserttext'], + ['foo[]bar', 'bold', 'insertparagraph'], + ['foo[]bar', 'bold', 'insertparagraph', 'inserttext'], + ['foo[]bar', 'bold', 'insertunorderedlist'], + ['foo[]bar', 'bold', 'insertunorderedlist', 'inserttext'], + ['foo[]bar', 'bold', 'justifycenter'], + ['foo[]bar', 'bold', 'justifycenter', 'inserttext'], + ['foo[]bar', 'bold', 'justifyfull'], + ['foo[]bar', 'bold', 'justifyfull', 'inserttext'], + ['foo[]bar', 'bold', 'justifyleft'], + ['foo[]bar', 'bold', 'justifyleft', 'inserttext'], + ['foo[]bar', 'bold', 'justifyright'], + ['foo[]bar', 'bold', 'justifyright', 'inserttext'], + ['foo[]bar', 'bold', 'outdent'], + ['foo[]bar', 'bold', 'outdent', 'inserttext'], + + ['foo[]bar', 'italic', 'inserttext'], + ['foo[]bar', 'italic', 'delete'], + ['foo[]bar', 'italic', 'delete', 'inserttext'], + ['foo[]bar', 'italic', 'formatblock'], + ['foo[]bar', 'italic', 'formatblock', 'inserttext'], + ['foo[]bar', 'italic', 'forwarddelete'], + ['foo[]bar', 'italic', 'forwarddelete', 'inserttext'], + ['foo[]bar', 'italic', 'indent'], + ['foo[]bar', 'italic', 'indent', 'inserttext'], + ['foo[]bar', 'italic', 'inserthorizontalrule'], + ['foo[]bar', 'italic', 'inserthorizontalrule', 'inserttext'], + ['foo[]bar', 'italic', 'inserthtml'], + ['foo[]bar', 'italic', 'inserthtml', 'inserttext'], + ['foo[]bar', 'italic', 'insertimage'], + ['foo[]bar', 'italic', 'insertimage', 'inserttext'], + ['foo[]bar', 'italic', 'insertlinebreak'], + ['foo[]bar', 'italic', 'insertlinebreak', 'inserttext'], + ['foo[]bar', 'italic', 'insertorderedlist'], + ['foo[]bar', 'italic', 'insertorderedlist', 'inserttext'], + ['foo[]bar', 'italic', 'insertparagraph'], + ['foo[]bar', 'italic', 'insertparagraph', 'inserttext'], + ['foo[]bar', 'italic', 'insertunorderedlist'], + ['foo[]bar', 'italic', 'insertunorderedlist', 'inserttext'], + ['foo[]bar', 'italic', 'justifycenter'], + ['foo[]bar', 'italic', 'justifycenter', 'inserttext'], + ['foo[]bar', 'italic', 'justifyfull'], + ['foo[]bar', 'italic', 'justifyfull', 'inserttext'], + ['foo[]bar', 'italic', 'justifyleft'], + ['foo[]bar', 'italic', 'justifyleft', 'inserttext'], + ['foo[]bar', 'italic', 'justifyright'], + ['foo[]bar', 'italic', 'justifyright', 'inserttext'], + ['foo[]bar', 'italic', 'outdent'], + ['foo[]bar', 'italic', 'outdent', 'inserttext'], + + ['foo[]bar', 'strikethrough', 'inserttext'], + ['foo[]bar', 'strikethrough', 'delete'], + ['foo[]bar', 'strikethrough', 'delete', 'inserttext'], + ['foo[]bar', 'strikethrough', 'formatblock'], + ['foo[]bar', 'strikethrough', 'formatblock', 'inserttext'], + ['foo[]bar', 'strikethrough', 'forwarddelete'], + ['foo[]bar', 'strikethrough', 'forwarddelete', 'inserttext'], + ['foo[]bar', 'strikethrough', 'indent'], + ['foo[]bar', 'strikethrough', 'indent', 'inserttext'], + ['foo[]bar', 'strikethrough', 'inserthorizontalrule'], + ['foo[]bar', 'strikethrough', 'inserthorizontalrule', 'inserttext'], + ['foo[]bar', 'strikethrough', 'inserthtml'], + ['foo[]bar', 'strikethrough', 'inserthtml', 'inserttext'], + ['foo[]bar', 'strikethrough', 'insertimage'], + ['foo[]bar', 'strikethrough', 'insertimage', 'inserttext'], + ['foo[]bar', 'strikethrough', 'insertlinebreak'], + ['foo[]bar', 'strikethrough', 'insertlinebreak', 'inserttext'], + ['foo[]bar', 'strikethrough', 'insertorderedlist'], + ['foo[]bar', 'strikethrough', 'insertorderedlist', 'inserttext'], + ['foo[]bar', 'strikethrough', 'insertparagraph'], + ['foo[]bar', 'strikethrough', 'insertparagraph', 'inserttext'], + ['foo[]bar', 'strikethrough', 'insertunorderedlist'], + ['foo[]bar', 'strikethrough', 'insertunorderedlist', 'inserttext'], + ['foo[]bar', 'strikethrough', 'justifycenter'], + ['foo[]bar', 'strikethrough', 'justifycenter', 'inserttext'], + ['foo[]bar', 'strikethrough', 'justifyfull'], + ['foo[]bar', 'strikethrough', 'justifyfull', 'inserttext'], + ['foo[]bar', 'strikethrough', 'justifyleft'], + ['foo[]bar', 'strikethrough', 'justifyleft', 'inserttext'], + ['foo[]bar', 'strikethrough', 'justifyright'], + ['foo[]bar', 'strikethrough', 'justifyright', 'inserttext'], + ['foo[]bar', 'strikethrough', 'outdent'], + ['foo[]bar', 'strikethrough', 'outdent', 'inserttext'], + + ['foo[]bar', 'subscript', 'inserttext'], + ['foo[]bar', 'subscript', 'delete'], + ['foo[]bar', 'subscript', 'delete', 'inserttext'], + ['foo[]bar', 'subscript', 'formatblock'], + ['foo[]bar', 'subscript', 'formatblock', 'inserttext'], + ['foo[]bar', 'subscript', 'forwarddelete'], + ['foo[]bar', 'subscript', 'forwarddelete', 'inserttext'], + ['foo[]bar', 'subscript', 'indent'], + ['foo[]bar', 'subscript', 'indent', 'inserttext'], + ['foo[]bar', 'subscript', 'inserthorizontalrule'], + ['foo[]bar', 'subscript', 'inserthorizontalrule', 'inserttext'], + ['foo[]bar', 'subscript', 'inserthtml'], + ['foo[]bar', 'subscript', 'inserthtml', 'inserttext'], + ['foo[]bar', 'subscript', 'insertimage'], + ['foo[]bar', 'subscript', 'insertimage', 'inserttext'], + ['foo[]bar', 'subscript', 'insertlinebreak'], + ['foo[]bar', 'subscript', 'insertlinebreak', 'inserttext'], + ['foo[]bar', 'subscript', 'insertorderedlist'], + ['foo[]bar', 'subscript', 'insertorderedlist', 'inserttext'], + ['foo[]bar', 'subscript', 'insertparagraph'], + ['foo[]bar', 'subscript', 'insertparagraph', 'inserttext'], + ['foo[]bar', 'subscript', 'insertunorderedlist'], + ['foo[]bar', 'subscript', 'insertunorderedlist', 'inserttext'], + ['foo[]bar', 'subscript', 'justifycenter'], + ['foo[]bar', 'subscript', 'justifycenter', 'inserttext'], + ['foo[]bar', 'subscript', 'justifyfull'], + ['foo[]bar', 'subscript', 'justifyfull', 'inserttext'], + ['foo[]bar', 'subscript', 'justifyleft'], + ['foo[]bar', 'subscript', 'justifyleft', 'inserttext'], + ['foo[]bar', 'subscript', 'justifyright'], + ['foo[]bar', 'subscript', 'justifyright', 'inserttext'], + ['foo[]bar', 'subscript', 'outdent'], + ['foo[]bar', 'subscript', 'outdent', 'inserttext'], + + ['foo[]bar', 'superscript', 'inserttext'], + ['foo[]bar', 'superscript', 'delete'], + ['foo[]bar', 'superscript', 'delete', 'inserttext'], + ['foo[]bar', 'superscript', 'formatblock'], + ['foo[]bar', 'superscript', 'formatblock', 'inserttext'], + ['foo[]bar', 'superscript', 'forwarddelete'], + ['foo[]bar', 'superscript', 'forwarddelete', 'inserttext'], + ['foo[]bar', 'superscript', 'indent'], + ['foo[]bar', 'superscript', 'indent', 'inserttext'], + ['foo[]bar', 'superscript', 'inserthorizontalrule'], + ['foo[]bar', 'superscript', 'inserthorizontalrule', 'inserttext'], + ['foo[]bar', 'superscript', 'inserthtml'], + ['foo[]bar', 'superscript', 'inserthtml', 'inserttext'], + ['foo[]bar', 'superscript', 'insertimage'], + ['foo[]bar', 'superscript', 'insertimage', 'inserttext'], + ['foo[]bar', 'superscript', 'insertlinebreak'], + ['foo[]bar', 'superscript', 'insertlinebreak', 'inserttext'], + ['foo[]bar', 'superscript', 'insertorderedlist'], + ['foo[]bar', 'superscript', 'insertorderedlist', 'inserttext'], + ['foo[]bar', 'superscript', 'insertparagraph'], + ['foo[]bar', 'superscript', 'insertparagraph', 'inserttext'], + ['foo[]bar', 'superscript', 'insertunorderedlist'], + ['foo[]bar', 'superscript', 'insertunorderedlist', 'inserttext'], + ['foo[]bar', 'superscript', 'justifycenter'], + ['foo[]bar', 'superscript', 'justifycenter', 'inserttext'], + ['foo[]bar', 'superscript', 'justifyfull'], + ['foo[]bar', 'superscript', 'justifyfull', 'inserttext'], + ['foo[]bar', 'superscript', 'justifyleft'], + ['foo[]bar', 'superscript', 'justifyleft', 'inserttext'], + ['foo[]bar', 'superscript', 'justifyright'], + ['foo[]bar', 'superscript', 'justifyright', 'inserttext'], + ['foo[]bar', 'superscript', 'outdent'], + ['foo[]bar', 'superscript', 'outdent', 'inserttext'], + + ['foo[]bar', 'underline', 'inserttext'], + ['foo[]bar', 'underline', 'delete'], + ['foo[]bar', 'underline', 'delete', 'inserttext'], + ['foo[]bar', 'underline', 'formatblock'], + ['foo[]bar', 'underline', 'formatblock', 'inserttext'], + ['foo[]bar', 'underline', 'forwarddelete'], + ['foo[]bar', 'underline', 'forwarddelete', 'inserttext'], + ['foo[]bar', 'underline', 'indent'], + ['foo[]bar', 'underline', 'indent', 'inserttext'], + ['foo[]bar', 'underline', 'inserthorizontalrule'], + ['foo[]bar', 'underline', 'inserthorizontalrule', 'inserttext'], + ['foo[]bar', 'underline', 'inserthtml'], + ['foo[]bar', 'underline', 'inserthtml', 'inserttext'], + ['foo[]bar', 'underline', 'insertimage'], + ['foo[]bar', 'underline', 'insertimage', 'inserttext'], + ['foo[]bar', 'underline', 'insertlinebreak'], + ['foo[]bar', 'underline', 'insertlinebreak', 'inserttext'], + ['foo[]bar', 'underline', 'insertorderedlist'], + ['foo[]bar', 'underline', 'insertorderedlist', 'inserttext'], + ['foo[]bar', 'underline', 'insertparagraph'], + ['foo[]bar', 'underline', 'insertparagraph', 'inserttext'], + ['foo[]bar', 'underline', 'insertunorderedlist'], + ['foo[]bar', 'underline', 'insertunorderedlist', 'inserttext'], + ['foo[]bar', 'underline', 'justifycenter'], + ['foo[]bar', 'underline', 'justifycenter', 'inserttext'], + ['foo[]bar', 'underline', 'justifyfull'], + ['foo[]bar', 'underline', 'justifyfull', 'inserttext'], + ['foo[]bar', 'underline', 'justifyleft'], + ['foo[]bar', 'underline', 'justifyleft', 'inserttext'], + ['foo[]bar', 'underline', 'justifyright'], + ['foo[]bar', 'underline', 'justifyright', 'inserttext'], + ['foo[]bar', 'underline', 'outdent'], + ['foo[]bar', 'underline', 'outdent', 'inserttext'], + + // Insertion-affecting value. Test that insertText works right, and + // test that various block commands preserve (or don't preserve) the + // value. + ['foo[]bar', 'backcolor', 'inserttext'], + ['foo[]bar', 'backcolor', 'delete'], + ['foo[]bar', 'backcolor', 'delete', 'inserttext'], + ['foo[]bar', 'backcolor', 'formatblock'], + ['foo[]bar', 'backcolor', 'formatblock', 'inserttext'], + ['foo[]bar', 'backcolor', 'forwarddelete'], + ['foo[]bar', 'backcolor', 'forwarddelete', 'inserttext'], + ['foo[]bar', 'backcolor', 'indent'], + ['foo[]bar', 'backcolor', 'indent', 'inserttext'], + ['foo[]bar', 'backcolor', 'inserthorizontalrule'], + ['foo[]bar', 'backcolor', 'inserthorizontalrule', 'inserttext'], + ['foo[]bar', 'backcolor', 'inserthtml'], + ['foo[]bar', 'backcolor', 'inserthtml', 'inserttext'], + ['foo[]bar', 'backcolor', 'insertimage'], + ['foo[]bar', 'backcolor', 'insertimage', 'inserttext'], + ['foo[]bar', 'backcolor', 'insertlinebreak'], + ['foo[]bar', 'backcolor', 'insertlinebreak', 'inserttext'], + ['foo[]bar', 'backcolor', 'insertorderedlist'], + ['foo[]bar', 'backcolor', 'insertorderedlist', 'inserttext'], + ['foo[]bar', 'backcolor', 'insertparagraph'], + ['foo[]bar', 'backcolor', 'insertparagraph', 'inserttext'], + ['foo[]bar', 'backcolor', 'insertunorderedlist'], + ['foo[]bar', 'backcolor', 'insertunorderedlist', 'inserttext'], + ['foo[]bar', 'backcolor', 'justifycenter'], + ['foo[]bar', 'backcolor', 'justifycenter', 'inserttext'], + ['foo[]bar', 'backcolor', 'justifyfull'], + ['foo[]bar', 'backcolor', 'justifyfull', 'inserttext'], + ['foo[]bar', 'backcolor', 'justifyleft'], + ['foo[]bar', 'backcolor', 'justifyleft', 'inserttext'], + ['foo[]bar', 'backcolor', 'justifyright'], + ['foo[]bar', 'backcolor', 'justifyright', 'inserttext'], + ['foo[]bar', 'backcolor', 'outdent'], + ['foo[]bar', 'backcolor', 'outdent', 'inserttext'], + + ['foo[]bar', 'createlink', 'inserttext'], + ['foo[]bar', 'createlink', 'delete'], + ['foo[]bar', 'createlink', 'delete', 'inserttext'], + ['foo[]bar', 'createlink', 'formatblock'], + ['foo[]bar', 'createlink', 'formatblock', 'inserttext'], + ['foo[]bar', 'createlink', 'forwarddelete'], + ['foo[]bar', 'createlink', 'forwarddelete', 'inserttext'], + ['foo[]bar', 'createlink', 'indent'], + ['foo[]bar', 'createlink', 'indent', 'inserttext'], + ['foo[]bar', 'createlink', 'inserthorizontalrule'], + ['foo[]bar', 'createlink', 'inserthorizontalrule', 'inserttext'], + ['foo[]bar', 'createlink', 'inserthtml'], + ['foo[]bar', 'createlink', 'inserthtml', 'inserttext'], + ['foo[]bar', 'createlink', 'insertimage'], + ['foo[]bar', 'createlink', 'insertimage', 'inserttext'], + ['foo[]bar', 'createlink', 'insertlinebreak'], + ['foo[]bar', 'createlink', 'insertlinebreak', 'inserttext'], + ['foo[]bar', 'createlink', 'insertorderedlist'], + ['foo[]bar', 'createlink', 'insertorderedlist', 'inserttext'], + ['foo[]bar', 'createlink', 'insertparagraph'], + ['foo[]bar', 'createlink', 'insertparagraph', 'inserttext'], + ['foo[]bar', 'createlink', 'insertunorderedlist'], + ['foo[]bar', 'createlink', 'insertunorderedlist', 'inserttext'], + ['foo[]bar', 'createlink', 'justifycenter'], + ['foo[]bar', 'createlink', 'justifycenter', 'inserttext'], + ['foo[]bar', 'createlink', 'justifyfull'], + ['foo[]bar', 'createlink', 'justifyfull', 'inserttext'], + ['foo[]bar', 'createlink', 'justifyleft'], + ['foo[]bar', 'createlink', 'justifyleft', 'inserttext'], + ['foo[]bar', 'createlink', 'justifyright'], + ['foo[]bar', 'createlink', 'justifyright', 'inserttext'], + ['foo[]bar', 'createlink', 'outdent'], + ['foo[]bar', 'createlink', 'outdent', 'inserttext'], + + ['foo[]bar', 'fontname', 'inserttext'], + ['foo[]bar', 'fontname', 'delete'], + ['foo[]bar', 'fontname', 'delete', 'inserttext'], + ['foo[]bar', 'fontname', 'formatblock'], + ['foo[]bar', 'fontname', 'formatblock', 'inserttext'], + ['foo[]bar', 'fontname', 'forwarddelete'], + ['foo[]bar', 'fontname', 'forwarddelete', 'inserttext'], + ['foo[]bar', 'fontname', 'indent'], + ['foo[]bar', 'fontname', 'indent', 'inserttext'], + ['foo[]bar', 'fontname', 'inserthorizontalrule'], + ['foo[]bar', 'fontname', 'inserthorizontalrule', 'inserttext'], + ['foo[]bar', 'fontname', 'inserthtml'], + ['foo[]bar', 'fontname', 'inserthtml', 'inserttext'], + ['foo[]bar', 'fontname', 'insertimage'], + ['foo[]bar', 'fontname', 'insertimage', 'inserttext'], + ['foo[]bar', 'fontname', 'insertlinebreak'], + ['foo[]bar', 'fontname', 'insertlinebreak', 'inserttext'], + ['foo[]bar', 'fontname', 'insertorderedlist'], + ['foo[]bar', 'fontname', 'insertorderedlist', 'inserttext'], + ['foo[]bar', 'fontname', 'insertparagraph'], + ['foo[]bar', 'fontname', 'insertparagraph', 'inserttext'], + ['foo[]bar', 'fontname', 'insertunorderedlist'], + ['foo[]bar', 'fontname', 'insertunorderedlist', 'inserttext'], + ['foo[]bar', 'fontname', 'justifycenter'], + ['foo[]bar', 'fontname', 'justifycenter', 'inserttext'], + ['foo[]bar', 'fontname', 'justifyfull'], + ['foo[]bar', 'fontname', 'justifyfull', 'inserttext'], + ['foo[]bar', 'fontname', 'justifyleft'], + ['foo[]bar', 'fontname', 'justifyleft', 'inserttext'], + ['foo[]bar', 'fontname', 'justifyright'], + ['foo[]bar', 'fontname', 'justifyright', 'inserttext'], + ['foo[]bar', 'fontname', 'outdent'], + ['foo[]bar', 'fontname', 'outdent', 'inserttext'], + + ['foo[]bar', 'fontsize', 'inserttext'], + ['foo[]bar', 'fontsize', 'delete'], + ['foo[]bar', 'fontsize', 'delete', 'inserttext'], + ['foo[]bar', 'fontsize', 'formatblock'], + ['foo[]bar', 'fontsize', 'formatblock', 'inserttext'], + ['foo[]bar', 'fontsize', 'forwarddelete'], + ['foo[]bar', 'fontsize', 'forwarddelete', 'inserttext'], + ['foo[]bar', 'fontsize', 'indent'], + ['foo[]bar', 'fontsize', 'indent', 'inserttext'], + ['foo[]bar', 'fontsize', 'inserthorizontalrule'], + ['foo[]bar', 'fontsize', 'inserthorizontalrule', 'inserttext'], + ['foo[]bar', 'fontsize', 'inserthtml'], + ['foo[]bar', 'fontsize', 'inserthtml', 'inserttext'], + ['foo[]bar', 'fontsize', 'insertimage'], + ['foo[]bar', 'fontsize', 'insertimage', 'inserttext'], + ['foo[]bar', 'fontsize', 'insertlinebreak'], + ['foo[]bar', 'fontsize', 'insertlinebreak', 'inserttext'], + ['foo[]bar', 'fontsize', 'insertorderedlist'], + ['foo[]bar', 'fontsize', 'insertorderedlist', 'inserttext'], + ['foo[]bar', 'fontsize', 'insertparagraph'], + ['foo[]bar', 'fontsize', 'insertparagraph', 'inserttext'], + ['foo[]bar', 'fontsize', 'insertunorderedlist'], + ['foo[]bar', 'fontsize', 'insertunorderedlist', 'inserttext'], + ['foo[]bar', 'fontsize', 'justifycenter'], + ['foo[]bar', 'fontsize', 'justifycenter', 'inserttext'], + ['foo[]bar', 'fontsize', 'justifyfull'], + ['foo[]bar', 'fontsize', 'justifyfull', 'inserttext'], + ['foo[]bar', 'fontsize', 'justifyleft'], + ['foo[]bar', 'fontsize', 'justifyleft', 'inserttext'], + ['foo[]bar', 'fontsize', 'justifyright'], + ['foo[]bar', 'fontsize', 'justifyright', 'inserttext'], + ['foo[]bar', 'fontsize', 'outdent'], + ['foo[]bar', 'fontsize', 'outdent', 'inserttext'], + + ['foo[]bar', 'forecolor', 'inserttext'], + ['foo[]bar', 'forecolor', 'delete'], + ['foo[]bar', 'forecolor', 'delete', 'inserttext'], + ['foo[]bar', 'forecolor', 'formatblock'], + ['foo[]bar', 'forecolor', 'formatblock', 'inserttext'], + ['foo[]bar', 'forecolor', 'forwarddelete'], + ['foo[]bar', 'forecolor', 'forwarddelete', 'inserttext'], + ['foo[]bar', 'forecolor', 'indent'], + ['foo[]bar', 'forecolor', 'indent', 'inserttext'], + ['foo[]bar', 'forecolor', 'inserthorizontalrule'], + ['foo[]bar', 'forecolor', 'inserthorizontalrule', 'inserttext'], + ['foo[]bar', 'forecolor', 'inserthtml'], + ['foo[]bar', 'forecolor', 'inserthtml', 'inserttext'], + ['foo[]bar', 'forecolor', 'insertimage'], + ['foo[]bar', 'forecolor', 'insertimage', 'inserttext'], + ['foo[]bar', 'forecolor', 'insertlinebreak'], + ['foo[]bar', 'forecolor', 'insertlinebreak', 'inserttext'], + ['foo[]bar', 'forecolor', 'insertorderedlist'], + ['foo[]bar', 'forecolor', 'insertorderedlist', 'inserttext'], + ['foo[]bar', 'forecolor', 'insertparagraph'], + ['foo[]bar', 'forecolor', 'insertparagraph', 'inserttext'], + ['foo[]bar', 'forecolor', 'insertunorderedlist'], + ['foo[]bar', 'forecolor', 'insertunorderedlist', 'inserttext'], + ['foo[]bar', 'forecolor', 'justifycenter'], + ['foo[]bar', 'forecolor', 'justifycenter', 'inserttext'], + ['foo[]bar', 'forecolor', 'justifyfull'], + ['foo[]bar', 'forecolor', 'justifyfull', 'inserttext'], + ['foo[]bar', 'forecolor', 'justifyleft'], + ['foo[]bar', 'forecolor', 'justifyleft', 'inserttext'], + ['foo[]bar', 'forecolor', 'justifyright'], + ['foo[]bar', 'forecolor', 'justifyright', 'inserttext'], + ['foo[]bar', 'forecolor', 'outdent'], + ['foo[]bar', 'forecolor', 'outdent', 'inserttext'], + + ['foo[]bar', 'hilitecolor', 'inserttext'], + ['foo[]bar', 'hilitecolor', 'delete'], + ['foo[]bar', 'hilitecolor', 'delete', 'inserttext'], + ['foo[]bar', 'hilitecolor', 'formatblock'], + ['foo[]bar', 'hilitecolor', 'formatblock', 'inserttext'], + ['foo[]bar', 'hilitecolor', 'forwarddelete'], + ['foo[]bar', 'hilitecolor', 'forwarddelete', 'inserttext'], + ['foo[]bar', 'hilitecolor', 'indent'], + ['foo[]bar', 'hilitecolor', 'indent', 'inserttext'], + ['foo[]bar', 'hilitecolor', 'inserthorizontalrule'], + ['foo[]bar', 'hilitecolor', 'inserthorizontalrule', 'inserttext'], + ['foo[]bar', 'hilitecolor', 'inserthtml'], + ['foo[]bar', 'hilitecolor', 'inserthtml', 'inserttext'], + ['foo[]bar', 'hilitecolor', 'insertimage'], + ['foo[]bar', 'hilitecolor', 'insertimage', 'inserttext'], + ['foo[]bar', 'hilitecolor', 'insertlinebreak'], + ['foo[]bar', 'hilitecolor', 'insertlinebreak', 'inserttext'], + ['foo[]bar', 'hilitecolor', 'insertorderedlist'], + ['foo[]bar', 'hilitecolor', 'insertorderedlist', 'inserttext'], + ['foo[]bar', 'hilitecolor', 'insertparagraph'], + ['foo[]bar', 'hilitecolor', 'insertparagraph', 'inserttext'], + ['foo[]bar', 'hilitecolor', 'insertunorderedlist'], + ['foo[]bar', 'hilitecolor', 'insertunorderedlist', 'inserttext'], + ['foo[]bar', 'hilitecolor', 'justifycenter'], + ['foo[]bar', 'hilitecolor', 'justifycenter', 'inserttext'], + ['foo[]bar', 'hilitecolor', 'justifyfull'], + ['foo[]bar', 'hilitecolor', 'justifyfull', 'inserttext'], + ['foo[]bar', 'hilitecolor', 'justifyleft'], + ['foo[]bar', 'hilitecolor', 'justifyleft', 'inserttext'], + ['foo[]bar', 'hilitecolor', 'justifyright'], + ['foo[]bar', 'hilitecolor', 'justifyright', 'inserttext'], + ['foo[]bar', 'hilitecolor', 'outdent'], + ['foo[]bar', 'hilitecolor', 'outdent', 'inserttext'], + + // Test things that interfere with each other + ['foo[]bar', 'superscript', 'subscript', 'inserttext'], + ['foo[]bar', 'subscript', 'superscript', 'inserttext'], + + ['foo[]bar', 'createlink', ['forecolor', '#0000FF'], 'inserttext'], + ['foo[]bar', ['forecolor', '#0000FF'], 'createlink', 'inserttext'], + ['foo[]bar', 'createlink', ['forecolor', 'blue'], 'inserttext'], + ['foo[]bar', ['forecolor', 'blue'], 'createlink', 'inserttext'], + ['foo[]bar', 'createlink', ['forecolor', 'brown'], 'inserttext'], + ['foo[]bar', ['forecolor', 'brown'], 'createlink', 'inserttext'], + ['foo[]bar', 'createlink', ['forecolor', 'black'], 'inserttext'], + ['foo[]bar', ['forecolor', 'black'], 'createlink', 'inserttext'], + ['foo[]bar', 'createlink', 'underline', 'inserttext'], + ['foo[]bar', 'underline', 'createlink', 'inserttext'], + ['foo[]bar', 'createlink', 'underline', 'underline', 'inserttext'], + ['foo[]bar', 'underline', 'underline', 'createlink', 'inserttext'], + + ['foo[]bar', 'subscript', ['fontsize', '2'], 'inserttext'], + ['foo[]bar', ['fontsize', '2'], 'subscript', 'inserttext'], + ['foo[]bar', 'subscript', ['fontsize', '3'], 'inserttext'], + ['foo[]bar', ['fontsize', '3'], 'subscript', 'inserttext'], + + ['foo[]bar', ['hilitecolor', 'aqua'], ['backcolor', 'tan'], 'inserttext'], + ['foo[]bar', ['backcolor', 'tan'], ['hilitecolor', 'aqua'], 'inserttext'], + + + // The following are all just inserttext tests that we took from there, + // but we first backspace the selected text instead of letting + // inserttext handle it. This tests that deletion correctly sets + // overrides. + ['foo<b>[bar]</b>baz', 'delete', 'inserttext'], + ['foo<i>[bar]</i>baz', 'delete', 'inserttext'], + ['foo<s>[bar]</s>baz', 'delete', 'inserttext'], + ['foo<sub>[bar]</sub>baz', 'delete', 'inserttext'], + ['foo<sup>[bar]</sup>baz', 'delete', 'inserttext'], + ['foo<u>[bar]</u>baz', 'delete', 'inserttext'], + ['foo<a href=http://www.google.com>[bar]</a>baz', 'delete', 'inserttext'], + ['foo<font face=sans-serif>[bar]</font>baz', 'delete', 'inserttext'], + ['foo<font size=4>[bar]</font>baz', 'delete', 'inserttext'], + ['foo<font color=#0000FF>[bar]</font>baz', 'delete', 'inserttext'], + ['foo<span style=background-color:#00FFFF>[bar]</span>baz', 'delete', 'inserttext'], + ['foo<a href=http://www.google.com><font color=blue>[bar]</font></a>baz', 'delete', 'inserttext'], + ['foo<font color=blue><a href=http://www.google.com>[bar]</a></font>baz', 'delete', 'inserttext'], + ['foo<a href=http://www.google.com><font color=brown>[bar]</font></a>baz', 'delete', 'inserttext'], + ['foo<font color=brown><a href=http://www.google.com>[bar]</a></font>baz', 'delete', 'inserttext'], + ['foo<a href=http://www.google.com><font color=black>[bar]</font></a>baz', 'delete', 'inserttext'], + ['foo<a href=http://www.google.com><u>[bar]</u></a>baz', 'delete', 'inserttext'], + ['foo<u><a href=http://www.google.com>[bar]</a></u>baz', 'delete', 'inserttext'], + ['foo<sub><font size=2>[bar]</font></sub>baz', 'delete', 'inserttext'], + ['foo<font size=2><sub>[bar]</sub></font>baz', 'delete', 'inserttext'], + ['foo<sub><font size=3>[bar]</font></sub>baz', 'delete', 'inserttext'], + ['foo<font size=3><sub>[bar]</sub></font>baz', 'delete', 'inserttext'], + + // Now repeat but with different selections. + ['[foo<b>bar]</b>baz', 'delete', 'inserttext'], + ['[foo<i>bar]</i>baz', 'delete', 'inserttext'], + ['[foo<s>bar]</s>baz', 'delete', 'inserttext'], + ['[foo<sub>bar]</sub>baz', 'delete', 'inserttext'], + ['[foo<sup>bar]</sup>baz', 'delete', 'inserttext'], + ['[foo<u>bar]</u>baz', 'delete', 'inserttext'], + ['[foo<a href=http://www.google.com>bar]</a>baz', 'delete', 'inserttext'], + ['[foo<font face=sans-serif>bar]</font>baz', 'delete', 'inserttext'], + ['[foo<font size=4>bar]</font>baz', 'delete', 'inserttext'], + ['[foo<font color=#0000FF>bar]</font>baz', 'delete', 'inserttext'], + ['[foo<span style=background-color:#00FFFF>bar]</span>baz', 'delete', 'inserttext'], + ['[foo<a href=http://www.google.com><font color=blue>bar]</font></a>baz', 'delete', 'inserttext'], + ['[foo<font color=blue><a href=http://www.google.com>bar]</a></font>baz', 'delete', 'inserttext'], + ['[foo<a href=http://www.google.com><font color=brown>bar]</font></a>baz', 'delete', 'inserttext'], + ['[foo<font color=brown><a href=http://www.google.com>bar]</a></font>baz', 'delete', 'inserttext'], + ['[foo<a href=http://www.google.com><font color=black>bar]</font></a>baz', 'delete', 'inserttext'], + ['[foo<a href=http://www.google.com><u>bar]</u></a>baz', 'delete', 'inserttext'], + ['[foo<u><a href=http://www.google.com>bar]</a></u>baz', 'delete', 'inserttext'], + ['[foo<sub><font size=2>bar]</font></sub>baz', 'delete', 'inserttext'], + ['[foo<font size=2><sub>bar]</sub></font>baz', 'delete', 'inserttext'], + ['[foo<sub><font size=3>bar]</font></sub>baz', 'delete', 'inserttext'], + ['[foo<font size=3><sub>bar]</sub></font>baz', 'delete', 'inserttext'], + + ['foo<b>[bar</b>baz]', 'delete', 'inserttext'], + ['foo<i>[bar</i>baz]', 'delete', 'inserttext'], + ['foo<s>[bar</s>baz]', 'delete', 'inserttext'], + ['foo<sub>[bar</sub>baz]', 'delete', 'inserttext'], + ['foo<sup>[bar</sup>baz]', 'delete', 'inserttext'], + ['foo<u>[bar</u>baz]', 'delete', 'inserttext'], + ['foo<a href=http://www.google.com>[bar</a>baz]', 'delete', 'inserttext'], + ['foo<font face=sans-serif>[bar</font>baz]', 'delete', 'inserttext'], + ['foo<font size=4>[bar</font>baz]', 'delete', 'inserttext'], + ['foo<font color=#0000FF>[bar</font>baz]', 'delete', 'inserttext'], + ['foo<span style=background-color:#00FFFF>[bar</span>baz]', 'delete', 'inserttext'], + ['foo<a href=http://www.google.com><font color=blue>[bar</font></a>baz]', 'delete', 'inserttext'], + ['foo<font color=blue><a href=http://www.google.com>[bar</a></font>baz]', 'delete', 'inserttext'], + ['foo<a href=http://www.google.com><font color=brown>[bar</font></a>baz]', 'delete', 'inserttext'], + ['foo<font color=brown><a href=http://www.google.com>[bar</a></font>baz]', 'delete', 'inserttext'], + ['foo<a href=http://www.google.com><font color=black>[bar</font></a>baz]', 'delete', 'inserttext'], + ['foo<a href=http://www.google.com><u>[bar</u></a>baz]', 'delete', 'inserttext'], + ['foo<u><a href=http://www.google.com>[bar</a></u>baz]', 'delete', 'inserttext'], + ['foo<sub><font size=2>[bar</font></sub>baz]', 'delete', 'inserttext'], + ['foo<font size=2><sub>[bar</sub></font>baz]', 'delete', 'inserttext'], + ['foo<sub><font size=3>[bar</font></sub>baz]', 'delete', 'inserttext'], + ['foo<font size=3><sub>[bar</sub></font>baz]', 'delete', 'inserttext'], + + // https://bugs.webkit.org/show_bug.cgi?id=19702 + ['<blockquote><font color=blue>[foo]</font></blockquote>', 'delete', 'inserttext'], + ], + //@} +}; +tests.backcolor = tests.hilitecolor; +tests.insertlinebreak = tests.insertparagraph; + +// Tests that start with "!" are believed to have bogus results and should be +// skipped until the relevant bugs are fixed. +var badTests = {}; +(function(){ + for (var command in tests) { + badTests[command] = []; + for (var i = 0; i < tests[command].length; i++) { + var test = tests[command][i]; + if (typeof test == "string" && test[0] == "!") { + test = test.slice(1); + tests[command][i] = test; + badTests[command].push(test); + } + if (typeof test == "object" && test[0][0] == "!") { + test = [test[0].slice(1)].concat(test.slice(1)); + tests[command][i] = test; + badTests[command].push(test); + } + } + } +})(); + +var defaultValues = { +//@{ + backcolor: "#00FFFF", + createlink: "http://www.google.com/", + fontname: "sans-serif", + fontsize: "4", + forecolor: "#0000FF", + formatblock: "<div>", + hilitecolor: "#00FFFF", + inserthorizontalrule: "", + inserthtml: "ab<b>c</b>d", + insertimage: "/img/lion.svg", + inserttext: "a", + defaultparagraphseparator: "div", + stylewithcss: "true", + usecss: "true", +}; +//@} + +var notes = { +//@{ + fontname: 'Note that the body\'s font-family is "serif".', +}; +//@} + +var doubleTestingCommands = [ +//@{ + "backcolor", + "bold", + "fontname", + "fontsize", + "forecolor", + "italic", + "justifycenter", + "justifyfull", + "justifyleft", + "justifyright", + "strikethrough", + "stylewithcss", + "subscript", + "superscript", + "underline", + "usecss", +]; +//@} + +function prettyPrint(value) { +//@{ + // Partly stolen from testharness.js + if (typeof value != "string") { + return String(value); + } + + value = value.replace(/\\/g, "\\\\") + .replace(/"/g, '\\"'); + + for (var i = 0; i < 32; i++) { + var replace = "\\"; + switch (i) { + case 0: replace += "0"; break; + case 1: replace += "x01"; break; + case 2: replace += "x02"; break; + case 3: replace += "x03"; break; + case 4: replace += "x04"; break; + case 5: replace += "x05"; break; + case 6: replace += "x06"; break; + case 7: replace += "x07"; break; + case 8: replace += "b"; break; + case 9: replace += "t"; break; + case 10: replace += "n"; break; + case 11: replace += "v"; break; + case 12: replace += "f"; break; + case 13: replace += "r"; break; + case 14: replace += "x0e"; break; + case 15: replace += "x0f"; break; + case 16: replace += "x10"; break; + case 17: replace += "x11"; break; + case 18: replace += "x12"; break; + case 19: replace += "x13"; break; + case 20: replace += "x14"; break; + case 21: replace += "x15"; break; + case 22: replace += "x16"; break; + case 23: replace += "x17"; break; + case 24: replace += "x18"; break; + case 25: replace += "x19"; break; + case 26: replace += "x1a"; break; + case 27: replace += "x1b"; break; + case 28: replace += "x1c"; break; + case 29: replace += "x1d"; break; + case 30: replace += "x1e"; break; + case 31: replace += "x1f"; break; + } + value = value.replace(new RegExp(String.fromCharCode(i), "g"), replace); + } + return '"' + value + '"'; +} +//@} + +function doSetup(selector, idx) { +//@{ + var table = document.querySelectorAll(selector)[idx]; + + var tr = document.createElement("tr"); + table.firstChild.appendChild(tr); + tr.className = (tr.className + " active").trim(); + + return tr; +} +//@} + +function queryOutputHelper(beforeIndeterm, beforeState, beforeValue, + afterIndeterm, afterState, afterValue, + command, value) { +//@{ + var frag = document.createDocumentFragment(); + var beforeDiv = document.createElement("div"); + var afterDiv = document.createElement("div"); + frag.appendChild(beforeDiv); + frag.appendChild(afterDiv); + beforeDiv.className = afterDiv.className = "extra-results"; + beforeDiv.textContent = "Before: "; + afterDiv.textContent = "After: "; + + beforeDiv.appendChild(document.createElement("span")); + afterDiv.appendChild(document.createElement("span")); + if ("indeterm" in commands[command]) { + // We only know it has to be either true or false. + if (beforeIndeterm !== true && beforeIndeterm !== false) { + beforeDiv.lastChild.className = "bad-result"; + } + } else { + // It always has to be false. + beforeDiv.lastChild.className = beforeIndeterm === false + ? "good-result" + : "bad-result"; + } + // After running the command, indeterminate must always be false, except if + // it's an exception, or if it's insert*list and the state was true to + // begin with. And we can't help strikethrough/underline. + if ((/^insert(un)?orderedlist$/.test(command) && beforeState) + || command == "strikethrough" + || command == "underline") { + if (afterIndeterm !== true && afterIndeterm !== false) { + afterDiv.lastChild.className = "bad-result"; + } + } else { + afterDiv.lastChild.className = + afterIndeterm === false + ? "good-result" + : "bad-result"; + } + beforeDiv.lastChild.textContent = "indeterm " + prettyPrint(beforeIndeterm); + afterDiv.lastChild.textContent = "indeterm " + prettyPrint(afterIndeterm); + + beforeDiv.appendChild(document.createTextNode(", ")); + afterDiv.appendChild(document.createTextNode(", ")); + + beforeDiv.appendChild(document.createElement("span")); + afterDiv.appendChild(document.createElement("span")); + if (/^insert(un)?orderedlist$/.test(command)) { + // If the before state is true, the after state could be either true or + // false. But if the before state is false, the after state has to be + // true. + if (beforeState !== true && beforeState !== false) { + beforeDiv.lastChild.className = "bad-result"; + } + if (!beforeState) { + afterDiv.lastChild.className = afterState === true + ? "good-result" + : "bad-result"; + } else if (afterState !== true && afterState !== false) { + afterDiv.lastChild.className = "bad-result"; + } + } else if (/^justify(center|full|left|right)$/.test(command)) { + // We don't know about the before state, but the after state is always + // supposed to be true. + if (beforeState !== true && beforeState !== false) { + beforeDiv.lastChild.className = "bad-result"; + } + afterDiv.lastChild.className = afterState === true + ? "good-result" + : "bad-result"; + } else if (command == "strikethrough" || command == "underline") { + // The only thing we can say is the before/after states need to be + // either true or false. + if (beforeState !== true && beforeState !== false) { + beforeDiv.lastChild.className = "bad-result"; + } + if (afterState !== true && afterState !== false) { + afterDiv.lastChild.className = "bad-result"; + } + } else { + // The general rule is it must flip the state, unless there's no state + // defined, in which case it should always be false. + beforeDiv.lastChild.className = + afterDiv.lastChild.className = + ("state" in commands[command] && typeof beforeState == "boolean" && typeof afterState == "boolean" && beforeState === !afterState) + || (!("state" in commands[command]) && beforeState === false && afterState === false) + ? "good-result" + : "bad-result"; + } + beforeDiv.lastChild.textContent = "state " + prettyPrint(beforeState); + afterDiv.lastChild.textContent = "state " + prettyPrint(afterState); + + beforeDiv.appendChild(document.createTextNode(", ")); + afterDiv.appendChild(document.createTextNode(", ")); + + beforeDiv.appendChild(document.createElement("span")); + afterDiv.appendChild(document.createElement("span")); + + // Direct equality comparison doesn't make sense in a bunch of cases. + if (command == "backcolor" || command == "forecolor" || command == "hilitecolor") { + if (/^([0-9a-fA-F]{3}){1,2}$/.test(value)) { + value = "#" + value; + } + } else if (command == "fontsize") { + value = normalizeFontSize(value); + if (value !== null) { + value = String(cssSizeToLegacy(value)); + } + } else if (command == "formatblock") { + value = value.replace(/^<(.*)>$/, "$1").toLowerCase(); + } else if (command == "defaultparagraphseparator") { + value = value.toLowerCase(); + if (value != "p" && value != "div") { + value = ""; + } + } + + if (((command == "backcolor" || command == "forecolor" || command == "hilitecolor") && value.toLowerCase() == "currentcolor") + || (command == "fontsize" && value === null) + || (command == "formatblock" && formattableBlockNames.indexOf(value.replace(/^<(.*)>$/, "$1").trim()) == -1) + || (command == "defaultparagraphseparator" && value == "")) { + afterDiv.lastChild.className = beforeValue === afterValue + ? "good-result" + : "bad-result"; + } else if (/^justify(center|full|left|right)$/.test(command)) { + // We know there are only four correct values beforehand, and afterward + // the value has to be the one we set. + if (!/^(center|justify|left|right)$/.test(beforeValue)) { + beforeDiv.lastChild.className = "bad-result"; + } + var expectedValue = command == "justifyfull" + ? "justify" + : command.replace("justify", ""); + afterDiv.lastChild.className = afterValue === expectedValue + ? "good-result" + : "bad-result"; + } else if (!("value" in commands[command])) { + // If it's not defined we want "". + beforeDiv.lastChild.className = beforeValue === "" + ? "good-result" + : "bad-result"; + afterDiv.lastChild.className = afterValue === "" + ? "good-result" + : "bad-result"; + } else { + // And in all other cases, the value afterwards has to be the one we + // set. + afterDiv.lastChild.className = + areEquivalentValues(command, afterValue, value) + ? "good-result" + : "bad-result"; + } + beforeDiv.lastChild.textContent = "value " + prettyPrint(beforeValue); + afterDiv.lastChild.textContent = "value " + prettyPrint(afterValue); + + return frag; +} +//@} + +function normalizeTest(command, test, styleWithCss) { +//@{ + // Our standard format for test processing is: + // [input HTML, + // [command1, value1, optional_name_mod], + // [command2, value2, optional_name_mod], ...] + // Where `optional_name_mod` is an optionally-specified string used when + // generating test names (necessary to ensure uniqueness for command + // sequences that use the same command multiple times). This format is + // verbose, so we actually use three different formats in the tests and + // multiTests arrays: + // + // 1) Plain string giving the input HTML. The command is implicit from the + // key of the tests array. If the command takes values, the value is given + // by defaultValues, otherwise it's "". Has to be converted to + // [input HTML, [command, value]. + // + // 2) Two-element array [value, input HTML]. Has to be converted to + // [input HTML, [command, value]]. + // + // 3) An element of multiTests. This just has to have values filled in. + // + // Optionally, a styleWithCss argument can be passed, either true or false. + // If it is, we'll prepend a styleWithCss invocation. + if (command == "multitest") { + if (typeof test == "string") { + test = JSON.parse(test); + } + for (var i = 1; i < test.length; i++) { + if (typeof test[i] == "string" + && test[i] in defaultValues) { + test[i] = [test[i], defaultValues[test[i]]]; + } else if (typeof test[i] == "string") { + test[i] = [test[i], ""]; + } + } + return test; + } + + if (typeof test == "string") { + if (command in defaultValues) { + test = [test, [command, defaultValues[command]]]; + } else { + test = [test, [command, ""]]; + } + } else if (test.length == 2) { + test = [test[1], [command, String(test[0])]]; + } + + if (styleWithCss !== undefined) { + test.splice(1, 0, ["stylewithcss", String(styleWithCss)]); + } + + return test; +} +//@} + +function doInputCell(tr, test, command) { +//@{ + var testHtml = test[0]; + + var msg = null; + if (command in defaultValues) { + // Single command with a value, possibly with a styleWithCss stuck + // before. We don't need to specify the command itself, since this + // presumably isn't in multiTests, so the command is already given by + // the section header. + msg = 'value: ' + prettyPrint(test[test.length - 1][1]); + } else if (command == "multitest") { + // Uses a different input format + msg = JSON.stringify(test); + } + var inputCell = document.createElement("td"); + inputCell.innerHTML = "<div></div><div></div>"; + inputCell.firstChild.innerHTML = testHtml; + inputCell.lastChild.textContent = inputCell.firstChild.innerHTML; + if (msg !== null) { + inputCell.lastChild.textContent += " (" + msg + ")"; + } + + tr.appendChild(inputCell); +} +//@} + +function doSpecCell(tr, test, command) { +//@{ + var specCell = document.createElement("td"); + tr.appendChild(specCell); + try { + var points = setupCell(specCell, test[0]); + var range = document.createRange(); + range.setStart(points[0], points[1]); + range.setEnd(points[2], points[3]); + // The points might be backwards + if (range.collapsed) { + range.setEnd(points[0], points[1]); + } + specCell.firstChild.contentEditable = "true"; + specCell.firstChild.spellcheck = false; + + if (command != "multitest") { + try { var beforeIndeterm = myQueryCommandIndeterm(command, range) } + catch(e) { beforeIndeterm = "Exception" } + try { var beforeState = myQueryCommandState(command, range) } + catch(e) { beforeState = "Exception" } + try { var beforeValue = myQueryCommandValue(command, range) } + catch(e) { beforeValue = "Exception" } + } + + for (var i = 1; i < test.length; i++) { + myExecCommand(test[i][0], false, test[i][1], range); + } + + if (command != "multitest") { + try { var afterIndeterm = myQueryCommandIndeterm(command, range) } + catch(e) { afterIndeterm = "Exception" } + try { var afterState = myQueryCommandState(command, range) } + catch(e) { afterState = "Exception" } + try { var afterValue = myQueryCommandValue(command, range) } + catch(e) { afterValue = "Exception" } + } + + specCell.firstChild.contentEditable = "inherit"; + specCell.firstChild.removeAttribute("spellcheck"); + var compareDiv1 = specCell.firstChild.cloneNode(true); + + // Now do various sanity checks, and throw if they're violated. First + // just count children: + if (specCell.childNodes.length != 2) { + throw "The cell didn't have two children. Did something spill outside the test div?"; + } + + // Now verify that the DOM serializes. + compareDiv1.normalize(); + var compareDiv2 = compareDiv1.cloneNode(false); + compareDiv2.innerHTML = compareDiv1.innerHTML; + // Oddly, IE9 sometimes produces two nodes that return true for + // isEqualNode but have different innerHTML (omitting closing tags vs. + // not). + if (!compareDiv1.isEqualNode(compareDiv2) + && compareDiv1.innerHTML != compareDiv2.innerHTML) { + throw "DOM does not round-trip through serialization! " + + compareDiv1.innerHTML + " vs. " + compareDiv2.innerHTML; + } + if (!compareDiv1.isEqualNode(compareDiv2)) { + throw "DOM does not round-trip through serialization (although innerHTML is the same)! " + + compareDiv1.innerHTML; + } + + // Check for attributes + if (specCell.firstChild.attributes.length) { + throw "Wrapper div has attributes! " + + specCell.innerHTML.replace(/<div><\/div>$/, ""); + } + + // Final sanity check: make sure everything isAllowedChild() of its + // parent. + getDescendants(specCell.firstChild).forEach(function(descendant) { + if (!isAllowedChild(descendant, descendant.parentNode)) { + throw "Something here is not an allowed child of its parent: " + descendant; + } + }); + + addBrackets(range); + + specCell.lastChild.textContent = specCell.firstChild.innerHTML; + if (command != "multitest") { + specCell.lastChild.appendChild(queryOutputHelper( + beforeIndeterm, beforeState, beforeValue, + afterIndeterm, afterState, afterValue, + command, test[test.length - 1][1])); + if (specCell.querySelector(".bad-result")) { + specCell.parentNode.className = "alert"; + } + } + } catch (e) { + specCell.firstChild.contentEditable = "inherit"; + specCell.firstChild.removeAttribute("spellcheck"); + specCell.lastChild.textContent = "Exception: " + formatException(e); + + specCell.parentNode.className = "alert"; + specCell.lastChild.className = "alert"; + + // Don't bother comparing to localStorage, this is always wrong no + // matter what. + return; + } + + if (command != "multitest") { + // Old storage format + var key = "execcommand-" + command + + "-" + (test.length == 2 || test[1][1] == "false" ? "0" : "1") + + "-" + tr.firstChild.lastChild.textContent; + } else { + var key = "execcommand-" + JSON.stringify(test); + } + + // Use getItem() instead of direct property access to work around Firefox + // bug: https://bugzilla.mozilla.org/show_bug.cgi?id=532062 + var oldValue = localStorage.getItem(key); + var newValue = specCell.lastChild.firstChild.textContent; + + // Ignore differences between {} and []. + if (oldValue === null + || oldValue.replace("{}", "[]") !== newValue.replace("{}", "[]")) { + specCell.parentNode.className = "alert"; + var alertDiv = document.createElement("div"); + specCell.lastChild.appendChild(alertDiv); + alertDiv.className = "alert"; + if (oldValue === null) { + alertDiv.textContent = "Newly added test result"; + } else if (oldValue.replace(/[\[\]{}]/g, "") == newValue.replace(/[\[\]{}]/g, "")) { + alertDiv.textContent = "Last run produced a different selection: " + oldValue; + } else { + alertDiv.textContent = "Last run produced different markup: " + oldValue; + } + + var button = document.createElement("button"); + alertDiv.appendChild(button); + button.textContent = "Store new result"; + button.className = "store-new-result"; + button.onclick = (function(key, val, alertDiv) { return function() { + localStorage[key] = val; + // Make it easier to do mass updates, and also to jump to the next + // new result + var buttons = document.getElementsByClassName("store-new-result"); + for (var i = 0; i < buttons.length; i++) { + if (isDescendant(buttons[i], alertDiv) + && i + 1 < buttons.length) { + buttons[i + 1].focus(); + break; + } + } + var td = alertDiv; + while (td.tagName != "TD") { + td = td.parentNode; + } + alertDiv.parentNode.removeChild(alertDiv); + if (!td.querySelector(".alert")) { + td.parentNode.className = (" " + td.parentNode.className + " ") + .replace(/ alert /g, "") + .replace(/^ | $/g, ""); + } + } })(key, newValue, alertDiv); + } +} +//@} + +function browserCellException(e, testDiv, browserCell) { +//@{ + if (testDiv) { + testDiv.contenteditable = "inherit"; + testDiv.removeAttribute("spellcheck"); + } + browserCell.lastChild.className = "alert"; + browserCell.lastChild.textContent = "Exception: " + formatException(e); + if (testDiv && testDiv.parentNode != browserCell) { + browserCell.insertBefore(testDiv, browserCell.firstChild); + } +} +//@} + +function formatException(e) { +//@{ + if (typeof e == "object" && "stack" in e) { + return e + " (stack: " + e.stack + ")"; + } + return String(e); +} +//@} + +function doSameCell(tr) { +//@{ + tr.className = (" " + tr.className + " ").replace(" active ", "").trim(); + if (tr.className == "") { + tr.removeAttribute("class"); + } + + var sameCell = document.createElement("td"); + if (!document.querySelector("#browser-checkbox").checked) { + sameCell.className = "maybe"; + sameCell.textContent = "?"; + } else { + var exception = false; + try { + // Ad hoc normalization to avoid basically spurious mismatches. For + // now this includes ignoring where the selection goes. + var normalizedSpecCell = tr.childNodes[1].lastChild.firstChild.textContent + .replace(/[[\]{}]/g, "") + .replace(/ style="margin: 0 0 0 40px; border: none; padding: 0px;"/g, '') + .replace(/ style="margin-right: 0px;" dir="ltr"/g, '') + .replace(/ style="margin-left: 0px;" dir="rtl"/g, '') + .replace(/ style="margin-(left|right): 40px;"/g, '') + .replace(/: /g, ":") + .replace(/;? ?"/g, '"') + .replace(/<(\/?)strong/g, '<$1b') + .replace(/<(\/?)strike/g, '<$1s') + .replace(/<(\/?)em/g, '<$1i') + .replace(/#[0-9a-fA-F]{6}/g, function(match) { return match.toUpperCase(); }); + var normalizedBrowserCell = tr.childNodes[2].lastChild.firstChild.textContent + .replace(/[[\]{}]/g, "") + .replace(/ style="margin: 0 0 0 40px; border: none; padding: 0px;"/g, '') + .replace(/ style="margin-right: 0px;" dir="ltr"/g, '') + .replace(/ style="margin-left: 0px;" dir="rtl"/g, '') + .replace(/ style="margin-(left|right): 40px;"/g, '') + .replace(/: /g, ":") + .replace(/;? ?"/g, '"') + .replace(/<(\/?)strong/g, '<$1b') + .replace(/<(\/?)strike/g, '<$1s') + .replace(/<(\/?)em/g, '<$1i') + .replace(/#[0-9a-fA-F]{6}/g, function(match) { return match.toUpperCase(); }) + .replace(/ size="2" width="100%"/g, ''); + if (navigator.userAgent.indexOf("MSIE") != -1) { + // IE produces <font style> instead of <span style>, so let's + // translate all <span>s to <font>s. + normalizedSpecCell = normalizedSpecCell + .replace(/<(\/?)span/g, '<$1font'); + normalizedBrowserCell = normalizedBrowserCell + .replace(/<(\/?)span/g, '<$1font'); + } + } catch (e) { + exception = true; + } + if (!exception && normalizedSpecCell == normalizedBrowserCell) { + sameCell.className = "yes"; + sameCell.textContent = "\u2713"; + } else { + sameCell.className = "no"; + sameCell.textContent = "\u2717"; + } + } + tr.appendChild(sameCell); + + for (var i = 0; i <= 2; i++) { + // Insert <wbr> so IE doesn't stretch the screen. This is considerably + // more complicated than it has to be, thanks to Firefox's lack of + // support for outerHTML. + var div = tr.childNodes[i].lastChild; + if (div.firstChild) { + var text = div.firstChild.textContent; + div.removeChild(div.firstChild); + div.insertBefore(document.createElement("div"), div.firstChild); + div.firstChild.innerHTML = text + .replace(/&/g, "&") + .replace(/</g, "<") + .replace(/>/g, "><wbr>") + .replace(/</g, "<wbr><"); + while (div.firstChild.hasChildNodes()) { + div.insertBefore(div.firstChild.lastChild, div.firstChild.nextSibling); + } + div.removeChild(div.firstChild); + } + + // Add position: absolute span to not affect vertical layout + getDescendants(tr.childNodes[i].firstChild) + .filter(function(node) { + return node.nodeType == Node.TEXT_NODE + && /^(\{\}?|\})$/.test(node.data); + }).forEach(function(node) { + var span = document.createElement("span"); + span.style.position = "absolute"; + span.textContent = node.data; + node.parentNode.insertBefore(span, node); + node.parentNode.removeChild(node); + }); + } +} +//@} + +function doTearDown(command) { +//@{ + getSelection().removeAllRanges(); +} +//@} + +function setupCell(cell, html) { +//@{ + cell.innerHTML = "<div></div><div></div>"; + + return setupDiv(cell.firstChild, html); +} +//@} + +function setupDiv(node, html) { +//@{ + // A variety of checks to avoid simple errors. Not foolproof, of course. + var re = /\{|\[|data-start/g; + var markers = []; + var marker; + while (marker = re.exec(html)) { + markers.push(marker); + } + if (markers.length != 1) { + throw "Need exactly one start marker ([ or { or data-start), found " + markers.length; + } + + var re = /\}|\]|data-end/g; + var markers = []; + var marker; + while (marker = re.exec(html)) { + markers.push(marker); + } + if (markers.length != 1) { + throw "Need exactly one end marker (] or } or data-end), found " + markers.length; + } + + node.innerHTML = html; + + var startNode, startOffset, endNode, endOffset; + + // For braces that don't lie inside text nodes, we can't just set + // innerHTML, because that might disturb the DOM. For instance, if the + // brace is right before a <tr>, it could get moved outside the table + // entirely, which messes everything up pretty badly. So we instead + // allow using data attributes: data-start and data-end on the start and + // end nodes, with a numeric value indicating the offset. This format + // doesn't allow the parent div to be a start or end node, but in that case + // you can always use the curly braces. + if (node.querySelector("[data-start]")) { + startNode = node.querySelector("[data-start]"); + startOffset = startNode.getAttribute("data-start"); + startNode.removeAttribute("data-start"); + } + if (node.querySelector("[data-end]")) { + endNode = node.querySelector("[data-end]"); + endOffset = endNode.getAttribute("data-end"); + endNode.removeAttribute("data-end"); + } + + var cur = node; + while (true) { + if (!cur || (cur != node && !(cur.compareDocumentPosition(node) & Node.DOCUMENT_POSITION_CONTAINS))) { + break; + } + + if (cur.nodeType != Node.TEXT_NODE) { + cur = nextNode(cur); + continue; + } + + var data = cur.data.replace(/\]/g, ""); + var startIdx = data.indexOf("["); + + data = cur.data.replace(/\[/g, ""); + var endIdx = data.indexOf("]"); + + cur.data = cur.data.replace(/[\[\]]/g, ""); + + if (startIdx != -1) { + startNode = cur; + startOffset = startIdx; + } + + if (endIdx != -1) { + endNode = cur; + endOffset = endIdx; + } + + // These are only legal as the first or last + data = cur.data.replace(/\}/g, ""); + var elStartIdx = data.indexOf("{"); + + data = cur.data.replace(/\{/g, ""); + var elEndIdx = data.indexOf("}"); + + if (elStartIdx == 0) { + startNode = cur.parentNode; + startOffset = getNodeIndex(cur); + } else if (elStartIdx != -1) { + startNode = cur.parentNode; + startOffset = getNodeIndex(cur) + 1; + } + if (elEndIdx == 0) { + endNode = cur.parentNode; + endOffset = getNodeIndex(cur); + } else if (elEndIdx != -1) { + endNode = cur.parentNode; + endOffset = getNodeIndex(cur) + 1; + } + + cur.data = cur.data.replace(/[{}]/g, ""); + if (!cur.data.length) { + if (cur == startNode || cur == endNode) { + throw "You put a square bracket where there was no text node . . ."; + } + var oldCur = cur; + cur = nextNode(cur); + oldCur.parentNode.removeChild(oldCur); + } else { + cur = nextNode(cur); + } + } + + return [startNode, startOffset, endNode, endOffset]; +} +//@} + +function setSelection(startNode, startOffset, endNode, endOffset) { +//@{ + if (navigator.userAgent.indexOf("Opera") != -1) { + // Yes, browser sniffing is evil, but I can't be bothered to debug + // Opera. + var range = document.createRange(); + range.setStart(startNode, startOffset); + range.setEnd(endNode, endOffset); + if (range.collapsed) { + range.setEnd(startNode, startOffset); + } + getSelection().removeAllRanges(); + getSelection().addRange(range); + } else if ("extend" in getSelection()) { + // WebKit behaves unreasonably for collapse(), so do that manually. + /* + var range = document.createRange(); + range.setStart(startNode, startOffset); + getSelection().removeAllRanges(); + getSelection().addRange(range); + */ + getSelection().collapse(startNode, startOffset); + getSelection().extend(endNode, endOffset); + } else { + // IE9. Selections have no direction, so we just make the selection + // always forwards. + var range; + if (getSelection().rangeCount) { + range = getSelection().getRangeAt(0); + } else { + range = document.createRange(); + } + range.setStart(startNode, startOffset); + range.setEnd(endNode, endOffset); + if (range.collapsed) { + // Phooey, we got them backwards. + range.setEnd(startNode, startOffset); + } + if (!getSelection().rangeCount) { + getSelection().addRange(range); + } + } +} +//@} + +/** + * Add brackets at the start and end points of the given range, so that they're + * visible. + */ +function addBrackets(range) { +//@{ + // Handle the collapsed case specially, to avoid confusingly getting the + // markers backwards in some cases + if (range.startContainer.nodeType == Node.TEXT_NODE + || range.startContainer.nodeType == Node.COMMENT_NODE) { + if (range.collapsed) { + range.startContainer.insertData(range.startOffset, "[]"); + } else { + range.startContainer.insertData(range.startOffset, "["); + } + } else { + var marker = range.collapsed ? "{}" : "{"; + if (range.startOffset != range.startContainer.childNodes.length + && range.startContainer.childNodes[range.startOffset].nodeType == Node.TEXT_NODE) { + range.startContainer.childNodes[range.startOffset].insertData(0, marker); + } else if (range.startOffset != 0 + && range.startContainer.childNodes[range.startOffset - 1].nodeType == Node.TEXT_NODE) { + range.startContainer.childNodes[range.startOffset - 1].appendData(marker); + } else { + // Seems to serialize as I'd want even for tables . . . IE doesn't + // allow undefined to be passed as the second argument (it throws + // an exception), so we have to explicitly check the number of + // children and pass null. + range.startContainer.insertBefore(document.createTextNode(marker), + range.startContainer.childNodes.length == range.startOffset + ? null + : range.startContainer.childNodes[range.startOffset]); + } + } + if (range.collapsed) { + return; + } + if (range.endContainer.nodeType == Node.TEXT_NODE + || range.endContainer.nodeType == Node.COMMENT_NODE) { + range.endContainer.insertData(range.endOffset, "]"); + } else { + if (range.endOffset != range.endContainer.childNodes.length + && range.endContainer.childNodes[range.endOffset].nodeType == Node.TEXT_NODE) { + range.endContainer.childNodes[range.endOffset].insertData(0, "}"); + } else if (range.endOffset != 0 + && range.endContainer.childNodes[range.endOffset - 1].nodeType == Node.TEXT_NODE) { + range.endContainer.childNodes[range.endOffset - 1].appendData("}"); + } else { + range.endContainer.insertBefore(document.createTextNode("}"), + range.endContainer.childNodes.length == range.endOffset + ? null + : range.endContainer.childNodes[range.endOffset]); + } + } +} +//@} + +function normalizeSerializedStyle(wrapper) { +//@{ + // Inline CSS attribute serialization has terrible interop, so we fix + // things up a bit to avoid spurious mismatches. This needs to be removed + // once CSSOM defines this stuff properly, but for now there's just no + // standard for any of it. This only normalizes descendants of wrapper, + // not wrapper itself. + [].forEach.call(wrapper.querySelectorAll("[style]"), function(node) { + if (node.style.color != "") { + var newColor = normalizeColor(node.style.color); + node.style.color = ""; + node.style.color = newColor; + } + if (node.style.backgroundColor != "") { + var newBackgroundColor = normalizeColor(node.style.backgroundColor); + node.style.backgroundColor = ""; + node.style.backgroundColor = newBackgroundColor; + } + node.setAttribute("style", node.getAttribute("style") + // Random spacing differences + .replace(/; ?$/, "") + .replace(/: /g, ":") + // Gecko likes "transparent" + .replace(/transparent/g, "rgba(0, 0, 0, 0)") + // WebKit likes to look overly precise + .replace(/, 0.496094\)/g, ", 0.5)") + // Gecko converts anything with full alpha to "transparent" which + // then becomes "rgba(0, 0, 0, 0)", so we have to make other + // browsers match + .replace(/rgba\([0-9]+, [0-9]+, [0-9]+, 0\)/g, "rgba(0, 0, 0, 0)") + ); + }); +} +//@} + +/** + * Input is in the following format: + * [input HTML, + * array of commands, + * expected output HTML, + * array of expected execCommand() return values, + * object of expected indeterm/state/value]. + * The array of commands is [[command, value, optionalDesc], [command, value, + * optionalDesc], ...]. optionalDesc is appended to the description of the + * test in the generated test name. + * + * The + * array of expected execCommand() return values is [true|false, true|false, + * ...], where the indices match those in the array of commands. The + * indeterm/state/value object is of the form + * {command: [expected indeterm before, expected state before, + * expected value before, expected indeterm after, + * expected state after, expected value after], + * command: ... } + * null for any of the last six entries means an INVALID_ACCESS_ERR must be + * raised. + */ +function runConformanceTest(browserTest) { +//@{ + document.getElementById("test-container").innerHTML = "<div contenteditable></div><p>test"; + var testName = JSON.stringify(browserTest[1]) + " " + format_value(browserTest[0]); + var testDiv = document.querySelector("div[contenteditable]"); + var originalRootElement, newRootElement; + var exception = null; + var expectedExecCommandReturnValues = browserTest[3]; + var expectedQueryResults = browserTest[4]; + var actualQueryResults = {}; + var actualQueryExceptions = {}; + var subtestName; + + try { + var points = setupDiv(testDiv, browserTest[0]); + + var range = document.createRange(); + range.setStart(points[0], points[1]); + range.setEnd(points[2], points[3]); + // The points might be backwards + if (range.collapsed) { + range.setEnd(points[0], points[1]); + } + getSelection().removeAllRanges(); + getSelection().addRange(range); + + var originalRootElement = document.documentElement.cloneNode(true); + originalRootElement.querySelector("[contenteditable]").parentNode + .removeChild(originalRootElement.querySelector("[contenteditable]")); + originalRootElement.querySelector("#log").parentNode + .removeChild(originalRootElement.querySelector("#log")); + + for (var command in expectedQueryResults) { + var results = []; + var exceptions = {}; + try { results[0] = document.queryCommandIndeterm(command) } + catch(e) { exceptions[0] = e } + try { results[1] = document.queryCommandState(command) } + catch(e) { exceptions[1] = e } + try { results[2] = document.queryCommandValue(command) } + catch(e) { exceptions[2] = e } + actualQueryResults[command] = results; + actualQueryExceptions[command] = exceptions; + } + } catch(e) { + exception = e; + } + + for (var i = 0; i < browserTest[1].length; i++) { + subtestName = testName + ": execCommand(" + + format_value(browserTest[1][i][0]) + ", false, " + + format_value(browserTest[1][i][1]) + ") " + + (browserTest[1][i][2] ? browserTest[1][i][2] + " " : "") + + "return value" + subsetTest(test, function() { + assert_equals(exception, null, "Setup must not throw an exception"); + + assert_equals(document.execCommand(browserTest[1][i][0], false, browserTest[1][i][1]), + expectedExecCommandReturnValues[i]); + }, subtestName); + } + + if (exception === null) { + try { + for (var command in expectedQueryResults) { + var results = actualQueryResults[command]; + var exceptions = actualQueryExceptions[command]; + try { results[3] = document.queryCommandIndeterm(command) } + catch(e) { exceptions[3] = e } + try { results[4] = document.queryCommandState(command) } + catch(e) { exceptions[4] = e } + try { results[5] = document.queryCommandValue(command) } + catch(e) { exceptions[5] = e } + } + + var newRootElement = document.documentElement.cloneNode(true); + newRootElement.querySelector("[contenteditable]").parentNode + .removeChild(newRootElement.querySelector("[contenteditable]")); + newRootElement.querySelector("#log").parentNode + .removeChild(newRootElement.querySelector("#log")); + + normalizeSerializedStyle(testDiv); + } catch(e) { + exception = e; + } + } + + subsetTest(test, function() { + assert_equals(exception, null, "Setup must not throw an exception"); + + // Now test for modifications to non-editable content. First just + // count children: + assert_equals(testDiv.parentNode.childNodes.length, 2, + "The parent div must have two children. Did something spill outside the test div?"); + + // Check for attributes + assert_equals(testDiv.attributes.length, 1, + 'Wrapper div must have only one attribute (<div contenteditable="">), but has more (' + + formatStartTag(testDiv) + ")"); + + assert_equals(document.body.attributes.length, 0, + "Body element must have no attributes (<body>), but has more (" + + formatStartTag(document.body) + ")"); + + // Check that in general, nothing outside the test div was modified. + // TODO: Less verbose error reporting, the way some of the range tests + // do? + assert_equals(newRootElement.innerHTML, originalRootElement.innerHTML, + "Everything outside the editable div must be unchanged, but some change did occur"); + }, testName + " checks for modifications to non-editable content"); + + subsetTest(test, function() { + assert_equals(exception, null, "Setup must not throw an exception"); + + if (Array.isArray(browserTest[2])) { + var expectedInnerHTMLArray = []; + browserTest[2].forEach(function (expectedInnerHTML) { + expectedInnerHTMLArray.push(expectedInnerHTML.replace(/[\[\]{}]/g, "")); + }); + assert_in_array(testDiv.innerHTML, + expectedInnerHTMLArray, + "Unexpected innerHTML (after normalizing inline style)"); + } else { + assert_equals(testDiv.innerHTML, + browserTest[2].replace(/[\[\]{}]/g, ""), + "Unexpected innerHTML (after normalizing inline style)"); + } + }, testName + " compare innerHTML"); + + for (var command in expectedQueryResults) { + var descriptions = [ + 'queryCommandIndeterm("' + command + '") before', + 'queryCommandState("' + command + '") before', + 'queryCommandValue("' + command + '") before', + 'queryCommandIndeterm("' + command + '") after', + 'queryCommandState("' + command + '") after', + 'queryCommandValue("' + command + '") after', + ]; + for (var i = 0; i < 6; i++) { + subsetTest(test, function() { + assert_equals(exception, null, "Setup must not throw an exception"); + + if (expectedQueryResults[command][i] === null) { + // Some ad hoc tests to verify that we have a real + // DOMException. FIXME: This should be made more rigorous, + // with clear steps specified for checking that something + // is really a DOMException. + assert_true(i in actualQueryExceptions[command], + "An exception must be thrown in this case"); + var e = actualQueryExceptions[command][i]; + assert_equals(typeof e, "object", + "typeof thrown object"); + assert_idl_attribute(e, "code", + "Thrown object must be a DOMException"); + assert_idl_attribute(e, "INVALID_ACCESS_ERR", + "Thrown object must be a DOMException"); + assert_equals(e.code, e.INVALID_ACCESS_ERR, + "Thrown object must be an INVALID_ACCESS_ERR, so its .code and .INVALID_ACCESS_ERR attributes must be equal"); + } else if ((i == 2 || i == 5) + && (command == "backcolor" || command == "forecolor" || command == "hilitecolor") + && typeof actualQueryResults[command][i] == "string") { + assert_false(i in actualQueryExceptions[command], + "An exception must not be thrown in this case"); + // We don't return the format that the color should be in: + // that's up to CSSOM. Thus we normalize before comparing. + assert_equals(normalizeColor(actualQueryResults[command][i]), + expectedQueryResults[command][i], + "Wrong result returned (after color normalization)"); + } else { + assert_false(i in actualQueryExceptions[command], + "An exception must not be thrown in this case"); + assert_equals(actualQueryResults[command][i], + expectedQueryResults[command][i], + "Wrong result returned"); + } + }, testName + " " + descriptions[i]); + } + } + + // Silly Firefox + document.body.removeAttribute("bgcolor"); +} +//@} + +/** + * Return a string like '<body bgcolor="#FFFFFF">'. + */ +function formatStartTag(el) { +//@{ + var ret = "<" + el.tagName.toLowerCase(); + for (var i = 0; i < el.attributes.length; i++) { + ret += " " + el.attributes[i].name + '="'; + ret += el.attributes[i].value.replace(/\&/g, "&") + .replace(/"/g, """); + ret += '"'; + } + return ret + ">"; +} +//@} + +// vim: foldmarker=@{,@} foldmethod=marker diff --git a/testing/web-platform/tests/editing/manual/delete-manual.html b/testing/web-platform/tests/editing/manual/delete-manual.html new file mode 100644 index 0000000000..be8c773b1d --- /dev/null +++ b/testing/web-platform/tests/editing/manual/delete-manual.html @@ -0,0 +1,24 @@ +<!doctype html> +<meta charset=utf-8> +<title>Manual delete (backspace) tests</title> +<link rel=stylesheet href=../include/tests.css> + +<p><input type=button value="Clear cached results" onclick="clearCachedResults()"> + +<div id=tests> + <input type=button value="Run tests" onclick="runTests()"> + <table border=1><tr><th>Input<th>Spec<th>Browser<th>Same</table> + <p><label>New test input: <input></label> <input type=button value="Add test" onclick="addTest()"> +</div> + +<div id=overlay>Tap backspace repeatedly until this annoying message +disappears! (But not too quickly. And don't hit any other keys or click with +the mouse anywhere, it will mess it up.<span id=testcount> <span></span> +manual test(s) remain.</span>)</div> + +<script src=../include/implementation.js></script> +<script src=../include/tests.js></script> +<script> +var command = "delete"; +</script> +<script src=../include/manualtest.js></script> diff --git a/testing/web-platform/tests/editing/manual/forwarddelete-manual.html b/testing/web-platform/tests/editing/manual/forwarddelete-manual.html new file mode 100644 index 0000000000..9c42b88f7a --- /dev/null +++ b/testing/web-platform/tests/editing/manual/forwarddelete-manual.html @@ -0,0 +1,24 @@ +<!doctype html> +<meta charset=utf-8> +<title>Manual forwardDelete (delete key) tests</title> +<link rel=stylesheet href=../include/tests.css> + +<p><input type=button value="Clear cached results" onclick="clearCachedResults()"> + +<div id=tests> + <input type=button value="Run tests" onclick="runTests()"> + <table border=1><tr><th>Input<th>Spec<th>Browser<th>Same</table> + <p><label>New test input: <input></label> <input type=button value="Add test" onclick="addTest()"> +</div> + +<div id=overlay>Tap delete repeatedly until this annoying message +disappears! (But not too quickly. And don't hit any other keys or click with +the mouse anywhere, it will mess it up.<span id=testcount> <span></span> +manual test(s) remain.</span>)</div> + +<script src=../include/implementation.js></script> +<script src=../include/tests.js></script> +<script> +var command = "forwarddelete"; +</script> +<script src=../include/manualtest.js></script> diff --git a/testing/web-platform/tests/editing/manual/insertlinebreak-manual.html b/testing/web-platform/tests/editing/manual/insertlinebreak-manual.html new file mode 100644 index 0000000000..631fc04317 --- /dev/null +++ b/testing/web-platform/tests/editing/manual/insertlinebreak-manual.html @@ -0,0 +1,24 @@ +<!doctype html> +<meta charset=utf-8> +<title>Manual insertLineBreak (Shift-Enter) tests</title> +<link rel=stylesheet href=../include/tests.css> + +<p><input type=button value="Clear cached results" onclick="clearCachedResults()"> + +<div id=tests> + <input type=button value="Run tests" onclick="runTests()"> + <table border=1><tr><th>Input<th>Spec<th>Browser<th>Same</table> + <p><label>New test input: <input></label> <input type=button value="Add test" onclick="addTest()"> +</div> + +<div id=overlay>Tap Shift-Enter (or Mac equivalent) repeatedly until this +annoying message disappears! (But not too quickly. And don't hit any other +keys or click with the mouse anywhere, it will mess it up.<span id=testcount> +<span></span> manual test(s) remain.</span>)</div> + +<script src=../include/implementation.js></script> +<script src=../include/tests.js></script> +<script> +var command = "insertlinebreak"; +</script> +<script src=../include/manualtest.js></script> diff --git a/testing/web-platform/tests/editing/manual/insertparagraph-manual.html b/testing/web-platform/tests/editing/manual/insertparagraph-manual.html new file mode 100644 index 0000000000..468a096f03 --- /dev/null +++ b/testing/web-platform/tests/editing/manual/insertparagraph-manual.html @@ -0,0 +1,24 @@ +<!doctype html> +<meta charset=utf-8> +<title>Manual insertParagraph (enter key) tests</title> +<link rel=stylesheet href=../include/tests.css> + +<p><input type=button value="Clear cached results" onclick="clearCachedResults()"> + +<div id=tests> + <input type=button value="Run tests" onclick="runTests()"> + <table border=1><tr><th>Input<th>Spec<th>Browser<th>Same</table> + <p><label>New test input: <input></label> <input type=button value="Add test" onclick="addTest()"> +</div> + +<div id=overlay>Tap enter repeatedly until this annoying message +disappears! (But not too quickly. And don't hit any other keys or click with +the mouse anywhere, it will mess it up.<span id=testcount> <span></span> +manual test(s) remain.</span>)</div> + +<script src=../include/implementation.js></script> +<script src=../include/tests.js></script> +<script> +var command = "insertparagraph"; +</script> +<script src=../include/manualtest.js></script> diff --git a/testing/web-platform/tests/editing/manual/inserttext-manual.html b/testing/web-platform/tests/editing/manual/inserttext-manual.html new file mode 100644 index 0000000000..c796c05747 --- /dev/null +++ b/testing/web-platform/tests/editing/manual/inserttext-manual.html @@ -0,0 +1,24 @@ +<!doctype html> +<meta charset=utf-8> +<title>Manual insertText tests (A key)</title> +<link rel=stylesheet href=../include/tests.css> + +<p><input type=button value="Clear cached results" onclick="clearCachedResults()"> + +<div id=tests> + <input type=button value="Run tests" onclick="runTests()"> + <table border=1><tr><th>Input<th>Spec<th>Browser<th>Same</table> + <p><label>New test input: <input></label> <input type=button value="Add test" onclick="addTest()"> +</div> + +<div id=overlay>Tap the A key repeatedly until this annoying message +disappears! (But not too quickly. And don't hit any other keys or click with +the mouse anywhere, it will mess it up.<span id=testcount> <span></span> +manual test(s) remain.</span>)</div> + +<script src=../include/implementation.js></script> +<script src=../include/tests.js></script> +<script> +var command = "inserttext"; +</script> +<script src=../include/manualtest.js></script> diff --git a/testing/web-platform/tests/editing/manual/inserttext2-manual.html b/testing/web-platform/tests/editing/manual/inserttext2-manual.html new file mode 100644 index 0000000000..43c3d4b2dc --- /dev/null +++ b/testing/web-platform/tests/editing/manual/inserttext2-manual.html @@ -0,0 +1,25 @@ +<!doctype html> +<meta charset=utf-8> +<title>Manual insertText tests (space key)</title> +<link rel=stylesheet href=../include/tests.css> + +<p><input type=button value="Clear cached results" onclick="clearCachedResults()"> + +<div id=tests> + <input type=button value="Run tests" onclick="runTests()"> + <table border=1><tr><th>Input<th>Spec<th>Browser<th>Same</table> + <p><label>New test input: <input></label> <input type=button value="Add test" onclick="addTest()"> +</div> + +<div id=overlay>Tap the space key repeatedly until this annoying message +disappears! (But not too quickly. And don't hit any other keys or click with +the mouse anywhere, it will mess it up.<span id=testcount> <span></span> +manual test(s) remain.</span>)</div> + +<script src=../include/implementation.js></script> +<script src=../include/tests.js></script> +<script> +var command = "inserttext"; +var globalValue = " "; +</script> +<script src=../include/manualtest.js></script> diff --git a/testing/web-platform/tests/editing/other/body-should-not-deleted-even-if-empty.html b/testing/web-platform/tests/editing/other/body-should-not-deleted-even-if-empty.html new file mode 100644 index 0000000000..050e780a26 --- /dev/null +++ b/testing/web-platform/tests/editing/other/body-should-not-deleted-even-if-empty.html @@ -0,0 +1,51 @@ +<html><head> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +</head><body><script> +"use strict" + +document.designMode = "on"; + +test(() => { + document.querySelector("script")?.remove(); + document.head?.remove(); + document.body.firstChild?.remove(); + document.body.appendChild(document.createElement("p")); + getSelection().collapse(document.querySelector("p"), 0); + document.querySelector("p").firstChild?.remove(); + document.execCommand("delete"); + assert_in_array( + document.documentElement?.outerHTML.replace(/\n/g, ""), + [ + "<html><body></body></html>", + "<html><body><br></body></html>", + "<html><body><p></p></body></html>", + "<html><body><p><br></p></body></html>" + ], + "Body element shouldn't be deleted even if it becomes empty" + ); +}, "Delete in empty paragraph shouldn't delete parent body and html elements even if they become empty by Backspace"); + +test(() => { + document.querySelector("script")?.remove(); + document.head?.remove(); + document.body.firstChild?.remove(); + document.body.appendChild(document.createElement("p")); + getSelection().collapse(document.querySelector("p"), 0); + document.querySelector("p").firstChild?.remove(); + document.execCommand("delete"); + assert_in_array( + document.documentElement?.outerHTML.replace(/\n/g, ""), + [ + "<html><body></body></html>", + "<html><body><br></body></html>", + "<html><body><p></p></body></html>", + "<html><body><p><br></p></body></html>" + ], + "Body element shouldn't be deleted even if it becomes empty" + ); + + document.designMode = "off"; +}, "Delete in empty paragraph shouldn't delete parent body and html elements even if they become empty by Delete"); + +</script></body></html>
\ No newline at end of file diff --git a/testing/web-platform/tests/editing/other/cefalse-boundaries-deletion.html b/testing/web-platform/tests/editing/other/cefalse-boundaries-deletion.html new file mode 100644 index 0000000000..de793bd6a3 --- /dev/null +++ b/testing/web-platform/tests/editing/other/cefalse-boundaries-deletion.html @@ -0,0 +1,60 @@ +<!DOCTYPE HTML> +<meta charset=utf-8> +<title>Selecting and deleting all from the cE=true element with cE=false element at the beginning</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="../include/editor-test-utils.js"></script> + +<div contenteditable></div> + +<script> + const utils = new EditorTestUtils( document.querySelector( 'div[contenteditable]' ) ); + + test( () => { + utils.setupEditingHost( `<div contenteditable="false" id="cefalse-beginning"> </div> + <p id="paragraph-beginning">Lorem ipsum dolor sit amet.</p>` ); + + const cefalse = document.querySelector( '#cefalse-beginning' ); + const paragraph = document.querySelector( '#paragraph-beginning' ); + + utils.editingHost.focus(); + document.execCommand( 'selectAll' ); + document.execCommand( 'delete' ); + + assert_false( cefalse.isConnected, 'cE=false element should be removed' ); + assert_false( paragraph.isConnected, 'paragraph should be removed' ); + }, 'cE=false elements can be removed from the beginning of the cE=true elements' ); + + test( () => { + utils.setupEditingHost( `<p id="paragraph-end">Lorem ipsum dolor sit amet.</p> + <div contenteditable="false" id="cefalse-end"> </div>` ); + + const cefalse = document.querySelector( '#cefalse-end' ); + const paragraph = document.querySelector( '#paragraph-end' ); + + utils.editingHost.focus(); + document.execCommand( 'selectAll' ); + document.execCommand( 'delete' ); + + assert_false( cefalse.isConnected, 'cE=false element should be removed' ); + assert_false( paragraph.isConnected, 'paragraph should be removed' ); + }, 'cE=false elements can be removed from the end of the cE=true elements' ); + + test( () => { + utils.setupEditingHost( `<div contenteditable="false" id="cefalse-boundaries-beginning"> </div> + <p id="paragraph-boundaries">Lorem ipsum dolor sit amet.</p> + <div contenteditable="false" id="cefalse-boundaries-end"> </div>` ); + + const cefalseBeginning = document.querySelector( '#cefalse-boundaries-beginning' ); + const cefalseEnd = document.querySelector( '#cefalse-boundaries-end' ); + const paragraph = document.querySelector( '#paragraph-boundaries' ); + + utils.editingHost.focus(); + document.execCommand( 'selectAll' ); + document.execCommand( 'delete' ); + + assert_false( cefalseBeginning.isConnected, 'cE=false element at the beginning should be removed' ); + assert_false( cefalseEnd.isConnected, 'cE=false element at the end should be removed' ); + assert_false( paragraph.isConnected, 'paragraph should be removed' ); + }, 'cE=false elements can be removed from the boundaries of the cE=true elements' ); +</script> diff --git a/testing/web-platform/tests/editing/other/cloning-attributes-at-splitting-element.tentative.html b/testing/web-platform/tests/editing/other/cloning-attributes-at-splitting-element.tentative.html new file mode 100644 index 0000000000..3c0b1c9344 --- /dev/null +++ b/testing/web-platform/tests/editing/other/cloning-attributes-at-splitting-element.tentative.html @@ -0,0 +1,522 @@ +<!doctype html> +<meta chareset="utf-8"> +<meta name="timeout" content="long"> +<title>Cloning attributes at splitting an element in contenteditable</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script src="../include/editor-test-utils.js"></script> +<div contenteditable></div> +<script> +"use strict"; + +document.execCommand("defaultParagraphSeparator", false, "div"); +const utils = + new EditorTestUtils(document.querySelector("div[contenteditable]")); + +// DO NOT USE multi-line comment in this file, then, you can comment out +// unnecessary tests when you need to attach the browser with a debugger. + +// When an element is being split, all attributes except id attribute should be +// cloned to the new element. +promise_test(async t => { + utils.setupEditingHost(`<div id="splittee">abc[]def</div>`); + const splittee = document.getElementById("splittee"); + await utils.sendEnterKey(); + test(() => { + assert_equals( + document.getElementById("splittee"), + splittee, + `The element instance returned by Document.getElementById shouldn't be changed after splitting the element (${t.name})` + ); + }); + test(() => { + assert_equals( + document.querySelectorAll("[id=splittee]").length, + 1, + `The new element created by splitting an element shouldn't have same id attribute value (${t.name})` + ); + }); +}, "Splitting <div id=\"splittee\">"); + +promise_test(async t => { + utils.setupEditingHost(`<div class="splittee">abc[]def</div>`); + await utils.sendEnterKey(); + const leftNode = utils.editingHost.querySelector("div"); + const rightNode = utils.editingHost.querySelector("div + div"); + test(() => { + assert_equals( + leftNode.getAttribute("class"), + "splittee", + `The left element should keep having the class attribute (${t.name})` + ); + }); + test(() => { + assert_equals( + rightNode.getAttribute("class"), + "splittee", + `The right element should keep having the class attribute (${t.name})` + ); + }); +}, "Splitting <div class=\"splittee\">"); + +promise_test(async t => { + utils.setupEditingHost(`<div data-foo="1" data-bar="2">abc[]def</div>`); + await utils.sendEnterKey(); + const leftNode = utils.editingHost.querySelector("div"); + const rightNode = utils.editingHost.querySelector("div + div"); + test(() => { + assert_equals( + leftNode.getAttribute("data-foo"), + "1", + `The left element should keep having the data-foo attribute (${t.name})` + ); + assert_equals( + leftNode.getAttribute("data-bar"), + "2", + `The left element should keep having the data-bar attribute (${t.name})` + ); + }); + test(() => { + assert_equals( + rightNode.getAttribute("data-foo"), + "1", + `The right element should keep having the data-foo attribute (${t.name})` + ); + assert_equals( + rightNode.getAttribute("data-bar"), + "2", + `The right element should keep having the data-bar attribute (${t.name})` + ); + }); +}, "Splitting <div data-foo=\"1\" data-bar=\"2\">"); + +// Same tests for list items since browsers may use different path to handle +// splitting a list item. +promise_test(async t => { + utils.setupEditingHost(`<ul><li id="splittee">abc[]def</li></ul>`); + const splittee = document.getElementById("splittee"); + await utils.sendEnterKey(); + test(() => { + assert_equals( + document.getElementById("splittee"), + splittee, + `The element instance returned by Document.getElementById shouldn't be changed after splitting the element (${t.name})` + ); + }); + test(() => { + assert_equals( + document.querySelectorAll("[id=splittee]").length, + 1, + `The new element created by splitting an element shouldn't have same id attribute value (${t.name})` + ); + }); +}, "Splitting <li id=\"splittee\">"); + +promise_test(async t => { + utils.setupEditingHost(`<ul><li class="splittee">abc[]def</li></ul>`); + await utils.sendEnterKey(); + const leftNode = utils.editingHost.querySelector("li"); + const rightNode = utils.editingHost.querySelector("li + li"); + test(() => { + assert_equals( + leftNode.getAttribute("class"), + "splittee", + `The left element should keep having the class attribute (${t.name})` + ); + }); + test(() => { + assert_equals( + rightNode.getAttribute("class"), + "splittee", + `The right element should keep having the class attribute (${t.name})` + ); + }); +}, "Splitting <li class=\"splittee\">"); + +promise_test(async t => { + utils.setupEditingHost(`<ul><li data-foo="1" data-bar="2">abc[]def</li></ul>`); + await utils.sendEnterKey(); + const leftNode = utils.editingHost.querySelector("li"); + const rightNode = utils.editingHost.querySelector("li + li"); + test(() => { + assert_equals( + leftNode.getAttribute("data-foo"), + "1", + `The left element should keep having the data-foo attribute (${t.name})` + ); + assert_equals( + leftNode.getAttribute("data-bar"), + "2", + `The left element should keep having the data-bar attribute (${t.name})` + ); + }); + test(() => { + assert_equals( + rightNode.getAttribute("data-foo"), + "1", + `The right element should keep having the data-foo attribute (${t.name})` + ); + assert_equals( + rightNode.getAttribute("data-bar"), + "2", + `The right element should keep having the data-bar attribute (${t.name})` + ); + }); +}, "Splitting <li data-foo=\"1\" data-bar=\"2\">"); + +// Same tests for heading since browsers may use different path to handle +// splitting a heading element. +promise_test(async t => { + utils.setupEditingHost(`<h3 id="p">abc[]def</h3>`); + const splittee = document.getElementById("splittee"); + await utils.sendEnterKey(); + test(() => { + assert_equals( + document.getElementById("splittee"), + splittee, + `The element instance returned by Document.getElementById shouldn't be changed after splitting the element (${t.name})` + ); + }); + test(() => { + assert_equals( + document.querySelectorAll("[id=p]").length, + 1, + `The new element created by splitting an element shouldn't have same id attribute value (${t.name})` + ); + }); +}, "Splitting <h3 id=\"p\">"); + +promise_test(async t => { + utils.setupEditingHost(`<h3 class="splittee">abc[]def</h3>`); + await utils.sendEnterKey(); + const leftNode = utils.editingHost.querySelector("h3"); + const rightNode = leftNode.nextSibling; + test(() => { + assert_equals( + leftNode.getAttribute("class"), + "splittee", + `The left element should keep having the class attribute (${t.name})` + ); + }); + test(() => { + assert_equals( + rightNode.getAttribute("class"), + "splittee", + `The right element should keep having the class attribute (${t.name})` + ); + }); +}, "Splitting <h3 class=\"splittee\">"); + +promise_test(async t => { + utils.setupEditingHost(`<h3 data-foo="1" data-bar="2">abc[]def</h3>`); + await utils.sendEnterKey(); + const leftNode = utils.editingHost.querySelector("h3"); + const rightNode = leftNode.nextSibling; + test(() => { + assert_equals( + leftNode.getAttribute("data-foo"), + "1", + `The left element should keep having the data-foo attribute (${t.name})` + ); + assert_equals( + leftNode.getAttribute("data-bar"), + "2", + `The left element should keep having the data-bar attribute (${t.name})` + ); + }); + test(() => { + assert_equals( + rightNode.getAttribute("data-foo"), + "1", + `The right element should keep having the data-foo attribute (${t.name})` + ); + assert_equals( + rightNode.getAttribute("data-bar"), + "2", + `The right element should keep having the data-bar attribute (${t.name})` + ); + }); +}, "Splitting <h3 data-foo=\"1\" data-bar=\"2\">"); + +// Same tests for <dt> since browsers may use different path to handle +// splitting a <dt>. +promise_test(async t => { + utils.setupEditingHost(`<dl><dt id="splittee">abc[]def</dt></dl>`); + const splittee = document.getElementById("splittee"); + await utils.sendEnterKey(); + test(() => { + assert_equals( + document.getElementById("splittee"), + splittee, + `The element instance returned by Document.getElementById shouldn't be changed after splitting the element (${t.name})` + ); + }); + test(() => { + assert_equals( + document.querySelectorAll("[id=splittee]").length, + 1, + `The new element created by splitting an element shouldn't have same id attribute value (${t.name})` + ); + }); +}, "Splitting <dt id=\"splittee\">"); + +promise_test(async t => { + utils.setupEditingHost(`<dl><dt class="splittee">abc[]def</dt></dl>`); + await utils.sendEnterKey(); + const leftNode = utils.editingHost.querySelector("dt"); + const rightNode = leftNode.nextSibling; + test(() => { + assert_equals( + leftNode.getAttribute("class"), + "splittee", + `The left element should keep having the class attribute (${t.name})` + ); + }); + test(() => { + assert_equals( + rightNode.getAttribute("class"), + "splittee", + `The right element should keep having the class attribute (${t.name})` + ); + }); +}, "Splitting <dt class=\"splittee\">"); + +promise_test(async t => { + utils.setupEditingHost(`<dl><dt data-foo="1" data-bar="2">abc[]def</dt></dl>`); + await utils.sendEnterKey(); + const leftNode = utils.editingHost.querySelector("dt"); + const rightNode = leftNode.nextSibling; + test(() => { + assert_equals( + leftNode.getAttribute("data-foo"), + "1", + `The left element should keep having the data-foo attribute (${t.name})` + ); + assert_equals( + leftNode.getAttribute("data-bar"), + "2", + `The left element should keep having the data-bar attribute (${t.name})` + ); + }); + test(() => { + assert_equals( + rightNode.getAttribute("data-foo"), + "1", + `The right element should keep having the data-foo attribute (${t.name})` + ); + assert_equals( + rightNode.getAttribute("data-bar"), + "2", + `The right element should keep having the data-bar attribute (${t.name})` + ); + }); +}, "Splitting <dt data-foo=\"1\" data-bar=\"2\">"); + +// Same tests for <dd> since browsers may use different path to handle +// splitting a <dd>. +promise_test(async t => { + utils.setupEditingHost(`<dl><dd id="splittee">abc[]def</dd></dl>`); + const splittee = document.getElementById("splittee"); + await utils.sendEnterKey(); + test(() => { + assert_equals( + document.getElementById("splittee"), + splittee, + `The element instance returned by Document.getElementById shouldn't be changed after splitting the element (${t.name})` + ); + }); + test(() => { + assert_equals( + document.querySelectorAll("[id=splittee]").length, + 1, + `The new element created by splitting an element shouldn't have same id attribute value (${t.name})` + ); + }); +}, "Splitting <dd id=\"splittee\">"); + +promise_test(async t => { + utils.setupEditingHost(`<dl><dd class="splittee">abc[]def</dd></dl>`); + await utils.sendEnterKey(); + const leftNode = utils.editingHost.querySelector("dd"); + const rightNode = leftNode.nextSibling; + test(() => { + assert_equals( + leftNode.getAttribute("class"), + "splittee", + `The left element should keep having the class attribute (${t.name})` + ); + }); + test(() => { + assert_equals( + rightNode.getAttribute("class"), + "splittee", + `The right element should keep having the class attribute (${t.name})` + ); + }); +}, "Splitting <dd class=\"splittee\">"); + +promise_test(async t => { + utils.setupEditingHost(`<dl><dd data-foo="1" data-bar="2">abc[]def</dd></dl>`); + await utils.sendEnterKey(); + const leftNode = utils.editingHost.querySelector("dd"); + const rightNode = leftNode.nextSibling; + test(() => { + assert_equals( + leftNode.getAttribute("data-foo"), + "1", + `The left element should keep having the data-foo attribute (${t.name})` + ); + assert_equals( + leftNode.getAttribute("data-bar"), + "2", + `The left element should keep having the data-bar attribute (${t.name})` + ); + }); + test(() => { + assert_equals( + rightNode.getAttribute("data-foo"), + "1", + `The right element should keep having the data-foo attribute (${t.name})` + ); + assert_equals( + rightNode.getAttribute("data-bar"), + "2", + `The right element should keep having the data-bar attribute (${t.name})` + ); + }); +}, "Splitting <dd data-foo=\"1\" data-bar=\"2\">"); + +// Same tests for inline elements. +promise_test(async t => { + utils.setupEditingHost(`<div id="splittee-parent"><span id="splittee">abc[]def</span></div>`); + const splittee = document.getElementById("splittee"); + const splitteeParent = document.getElementById("splittee-parent"); + await utils.sendEnterKey(); + test(() => { + assert_equals( + document.getElementById("splittee"), + splittee, + `The element instance returned by Document.getElementById shouldn't be changed after splitting the element (${t.name})` + ); + }); + test(() => { + assert_equals( + document.getElementById("splittee-parent"), + splitteeParent, + `The element instance returned by Document.getElementById shouldn't be changed after splitting the element (splittee-parent) (${t.name})` + ); + }); + test(() => { + assert_equals( + document.querySelectorAll("[id=splittee]").length, + 1, + `The new element created by splitting an element shouldn't have same id attribute value (${t.name})` + ); + }); + test(() => { + assert_equals( + document.querySelectorAll("[id=splittee-parent]").length, + 1, + `The new element created by splitting an element shouldn't have same id attribute value (splittee-parent) (${t.name})` + ); + }); +}, "Splitting <div id=\"splittee-parent\"> and <span id=\"splittee\">"); + +promise_test(async t => { + utils.setupEditingHost(`<div class="splittee-parent"><span class="splittee">abc[]def</span></div>`); + await utils.sendEnterKey(); + const leftParent = utils.editingHost.querySelector("div"); + const leftNode = leftParent.querySelector("span"); + const rightParent = utils.editingHost.querySelector("div + div"); + const rightNode = rightParent.querySelector("span"); + test(() => { + assert_equals( + leftNode.getAttribute("class"), + "splittee", + `The left element should keep having the class attribute (${t.name})` + ); + }); + test(() => { + assert_equals( + leftParent.getAttribute("class"), + "splittee-parent", + `The left element should keep having the class attribute (splittee-parent) (${t.name})` + ); + }); + test(() => { + assert_equals( + rightNode.getAttribute("class"), + "splittee", + `The right element should keep having the class attribute (${t.name})` + ); + }); + test(() => { + assert_equals( + rightParent.getAttribute("class"), + "splittee-parent", + `The right element should keep having the class attribute (splittee-parent) (${t.name})` + ); + }); +}, "Splitting <div class=\"splittee-parent\"> and <span class=\"splittee\">"); + +promise_test(async t => { + utils.setupEditingHost(`<div data-foo="1" data-bar="2"><span data-foo="3" data-bar="4">abc[]def</span></div>`); + await utils.sendEnterKey(); + const leftParent = utils.editingHost.querySelector("div"); + const leftNode = leftParent.querySelector("span"); + const rightParent = utils.editingHost.querySelector("div + div"); + const rightNode = rightParent.querySelector("span"); + test(() => { + assert_equals( + leftNode.getAttribute("data-foo"), + "3", + `The left element should keep having the data-foo attribute (${t.name})` + ); + assert_equals( + leftNode.getAttribute("data-bar"), + "4", + `The left element should keep having the data-bar attribute (${t.name})` + ); + }); + test(() => { + assert_equals( + leftParent.getAttribute("data-foo"), + "1", + `The left element should keep having the data-foo attribute (splittee-parent) (${t.name})` + ); + assert_equals( + leftParent.getAttribute("data-bar"), + "2", + `The left element should keep having the data-bar attribute (splittee-parent) (${t.name})` + ); + }); + test(() => { + assert_equals( + rightNode.getAttribute("data-foo"), + "3", + `The right element should keep having the data-foo attribute (${t.name})` + ); + assert_equals( + rightNode.getAttribute("data-bar"), + "4", + `The right element should keep having the data-bar attribute (${t.name})` + ); + }); + test(() => { + assert_equals( + rightParent.getAttribute("data-foo"), + "1", + `The right element should keep having the data-foo attribute (splittee-parent) (${t.name})` + ); + assert_equals( + rightParent.getAttribute("data-bar"), + "2", + `The right element should keep having the data-bar attribute (splittee-parent) (${t.name})` + ); + }); +}, "Splitting <div data-foo=\"1\" data-bar=\"2\"> and <span data-foo=\"3\" data-bar=\"4\">"); + +</script> diff --git a/testing/web-platform/tests/editing/other/delete-in-child-of-head.tentative.html b/testing/web-platform/tests/editing/other/delete-in-child-of-head.tentative.html new file mode 100644 index 0000000000..978cf83d47 --- /dev/null +++ b/testing/web-platform/tests/editing/other/delete-in-child-of-head.tentative.html @@ -0,0 +1,418 @@ +<!doctype html> +<html> +<head> +<meta chareset="utf-8"> +<meta name="timeout" content="long"> +<meta name="variant" content="?designMode=off&method=backspace"> +<meta name="variant" content="?designMode=off&method=forwarddelete"> +<meta name="variant" content="?designMode=on&method=backspace"> +<meta name="variant" content="?designMode=on&method=forwarddelete"> +<title>Join paragraphs in the head element</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script src="../include/editor-test-utils.js"></script> +</head> +<body> +<iframe srcdoc=""></iframe> +<script> +"use strict"; + +const searchParams = new URLSearchParams(document.location.search); +const testingBackspace = searchParams.get("method") == "backspace"; +const commandName = testingBackspace ? "delete" : "forwarddelete"; +const testingDesignMode = searchParams.get("designMode") == "on"; + +const iframe = document.querySelector("iframe"); +const minimumSrcDoc = + "<html>" + + '<head style="display:block">' + + "<title>iframe</title>" + + "<script src='/resources/testdriver.js'></" + "script>" + + "<script src='/resources/testdriver-vendor.js'></" + "script>" + + "<script src='/resources/testdriver-actions.js'></" + "script>" + + "</head>" + + "<body><br></body>" + + "</html>"; + +async function initializeAndWaitForLoad(iframeElement, srcDocValue) { + const waitForLoad = + new Promise( + resolve => iframeElement.addEventListener("load", resolve, {once: true}) + ); + iframeElement.srcdoc = srcDocValue; + await waitForLoad; + if (testingDesignMode) { + iframeElement.contentDocument.designMode = "on"; + } else { + iframeElement.contentDocument.documentElement.setAttribute("contenteditable", ""); + } + iframeElement.contentWindow.focus(); + iframeElement.contentDocument.execCommand("defaultParagraphSeparator", false, "div"); +} + +function removeResourceScriptElements(node) { + node.querySelectorAll("script").forEach( + element => { + if (element.getAttribute("src")?.startsWith("/resources")) { + element.remove() + } + } + ); +} + +// DO NOT USE multi-line comment in this file, then, you can comment out +// unnecessary tests when you need to attach the browser with a debugger. + +// For backward compatibility, normal block elements in <head> should be +// joined by deletion. +promise_test(async () => { + await initializeAndWaitForLoad(iframe, minimumSrcDoc); + const childDoc = iframe.contentDocument; + const utils = new EditorTestUtils(childDoc.documentElement); + const div1 = childDoc.createElement("div"); + div1.innerHTML = "abc"; + const div2 = childDoc.createElement("div"); + div2.innerHTML = "def"; + childDoc.head.appendChild(div1); + childDoc.head.appendChild(div2); + // Now: <head><title>...</title><div>abc</div><div>def</div></head>... + childDoc.getSelection().collapse( + testingBackspace ? div2.firstChild : div1.firstChild, + testingBackspace ? 0 : div1.firstChild.length + ); + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + removeResourceScriptElements(childDoc); + childDoc.head.removeAttribute("style"); + + assert_in_array( + childDoc.documentElement.innerHTML, + [ + '<head><title>iframe</title><div>abcdef</div></head><body><br></body>', + '<head><title>iframe</title><div>abcdef<br></div></head><body><br></body>', + ], + "The <div> elements should be merged" + ); + assert_equals( + div1.isConnected ^ div2.isConnected, + 1, + "One <div> element should be removed, and the other should stay" + ); +}, `${commandName} in <div> elements in <head> should join them`); + +// The following void elements shouldn't be deleted for avoiding various +// affection to the document. +for (const tag of ["meta", "title", "style", "script", "link", "base", "template"]) { + promise_test(async () => { + await initializeAndWaitForLoad(iframe, minimumSrcDoc); + const childDoc = iframe.contentDocument; + const utils = new EditorTestUtils(childDoc.documentElement); + const div1 = childDoc.createElement("div"); + div1.innerHTML = "abc"; + const div2 = childDoc.createElement("div"); + div2.innerHTML = "def"; + const element = childDoc.createElement(tag); + childDoc.head.appendChild(div1); + childDoc.head.appendChild(element); + childDoc.head.appendChild(div2); + // Now: <head><title>...</title><div>abc</div><tag/><div>def</div></head>... + childDoc.getSelection().collapse( + testingBackspace ? div2.firstChild : div1.firstChild, + testingBackspace ? 0 : div1.firstChild.length + ); + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + removeResourceScriptElements(childDoc); + childDoc.head.removeAttribute("style"); + + if (["title", "style", "script", "template"].includes(tag)) { + assert_in_array( + childDoc.documentElement.innerHTML, + [ + `<head><title>iframe</title><div>abcdef</div><${tag}></${tag}></head><body><br></body>`, + `<head><title>iframe</title><div>abcdef<br></div><${tag}></${tag}></head><body><br></body>`, + `<head><title>iframe</title><${tag}></${tag}><div>abcdef</div></head><body><br></body>`, + `<head><title>iframe</title><${tag}></${tag}><div>abcdef<br></div></head><body><br></body>`, + ], + `The <div> elements should be merged without deleting <${tag}>` + ); + } else { + assert_in_array( + childDoc.documentElement.innerHTML, + [ + `<head><title>iframe</title><div>abcdef</div><${tag}></head><body><br></body>`, + `<head><title>iframe</title><div>abcdef<br></div><${tag}></head><body><br></body>`, + `<head><title>iframe</title><${tag}><div>abcdef</div></head><body><br></body>`, + `<head><title>iframe</title><${tag}><div>abcdef<br></div></head><body><br></body>`, + ], + `The <div> elements should be merged without deleting <${tag}>` + ); + } + }, `${commandName} around invisible <${tag}> should not delete it at joining paragraphs`); +} + +// Visible <script>, <style>, <title> elements shouldn't be joined +promise_test(async () => { + await initializeAndWaitForLoad(iframe, minimumSrcDoc); + const childDoc = iframe.contentDocument; + const utils = new EditorTestUtils(childDoc.documentElement); + const script1 = childDoc.createElement("script"); + script1.innerHTML = "// abc"; + script1.setAttribute("style", "display:block"); + const script2 = childDoc.createElement("script"); + script2.innerHTML = "// def"; + script2.setAttribute("style", "display:block"); + childDoc.head.appendChild(script1); + childDoc.head.appendChild(script2); + // Now: <head><title>...</title><script>// abc</ script><script>// def</ script></head>... + childDoc.getSelection().collapse( + testingBackspace ? script2.firstChild : script1.firstChild, + testingBackspace ? 0 : script1.firstChild.length + ); + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + removeResourceScriptElements(childDoc); + childDoc.head.removeAttribute("style"); + script1.removeAttribute("style"); + script2.removeAttribute("style"); + + assert_equals( + childDoc.documentElement.innerHTML, + "<head><title>iframe</title><script>// abc</" + "script><script>// def</" + "script></head><body><br></body>", + "Visible <script> elements shouldn't be merged" + ); +}, `${commandName} in visible <script> elements in <head> should not join them`); + +promise_test(async () => { + await initializeAndWaitForLoad(iframe, minimumSrcDoc); + const childDoc = iframe.contentDocument; + const utils = new EditorTestUtils(childDoc.documentElement); + const style1 = childDoc.createElement("style"); + style1.innerHTML = "abc"; + style1.setAttribute("style", "display:block"); + const style2 = childDoc.createElement("style"); + style2.innerHTML = "def"; + style2.setAttribute("style", "display:block"); + childDoc.head.appendChild(style1); + childDoc.head.appendChild(style2); + // Now: <head><title>...</title><style>abc</style><style>def</style></head>... + childDoc.getSelection().collapse( + testingBackspace ? style2.firstChild : style1.firstChild, + testingBackspace ? 0 : style1.firstChild.length + ); + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + removeResourceScriptElements(childDoc); + childDoc.head.removeAttribute("style"); + style1.removeAttribute("style"); + style2.removeAttribute("style"); + + assert_equals( + childDoc.documentElement.innerHTML, + "<head><title>iframe</title><style>abc</style><style>def</style></head><body><br></body>", + "Visible <style> elements shouldn't be merged" + ); +}, `${commandName} in visible <style> elements in <head> should not join them`); + +promise_test(async () => { + await initializeAndWaitForLoad(iframe, minimumSrcDoc); + const childDoc = iframe.contentDocument; + const utils = new EditorTestUtils(childDoc.documentElement); + const title1 = childDoc.createElement("title"); + title1.innerHTML = "abc"; + title1.setAttribute("style", "display:block"); + const title2 = childDoc.createElement("title"); + title2.innerHTML = "def"; + title2.setAttribute("style", "display:block"); + childDoc.head.appendChild(title1); + childDoc.head.appendChild(title2); + // Now: <head><title>...</title><title>abc</title><title>def</title></head>... + childDoc.getSelection().collapse( + testingBackspace ? title2.firstChild : title1.firstChild, + testingBackspace ? 0 : title1.firstChild.length + ); + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + removeResourceScriptElements(childDoc); + childDoc.head.removeAttribute("style"); + title1.removeAttribute("style"); + title2.removeAttribute("style"); + + assert_equals( + childDoc.documentElement.innerHTML, + "<head><title>iframe</title><title>abc</title><title>def</title></head><body><br></body>", + "Visible <title> elements shouldn't be merged" + ); +}, `${commandName} in visible <title> elements in <head> should not join them`); + +// Visible <script>, <style>, <title> shouldn't be joined with following <div> +promise_test(async () => { + await initializeAndWaitForLoad(iframe, minimumSrcDoc); + const childDoc = iframe.contentDocument; + const utils = new EditorTestUtils(childDoc.documentElement); + const script = childDoc.createElement("script"); + script.innerHTML = "// abc"; + script.setAttribute("style", "display:block"); + const div = childDoc.createElement("div"); + div.innerHTML = "// def"; + childDoc.head.appendChild(script); + childDoc.head.appendChild(div); + // Now: <head><title>...</title><script>// abc</ script><div>// def</div></head>... + childDoc.getSelection().collapse( + testingBackspace ? div.firstChild : script.firstChild, + testingBackspace ? 0 : script.firstChild.length + ); + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + removeResourceScriptElements(childDoc); + childDoc.head.removeAttribute("style"); + script.removeAttribute("style"); + + assert_equals( + childDoc.documentElement.innerHTML, + "<head><title>iframe</title><script>// abc</" + "script><div>// def</div></head><body><br></body>", + "Visible <script> and <div> shouldn't be merged" + ); +}, `${commandName} at boundary of <script> and <div> in <head> should not join them`); + +promise_test(async () => { + await initializeAndWaitForLoad(iframe, minimumSrcDoc); + const childDoc = iframe.contentDocument; + const utils = new EditorTestUtils(childDoc.documentElement); + const style = childDoc.createElement("style"); + style.innerHTML = "abc"; + style.setAttribute("style", "display:block"); + const div = childDoc.createElement("div"); + div.innerHTML = "def"; + childDoc.head.appendChild(style); + childDoc.head.appendChild(div); + // Now: <head><title>...</title><style>abc</style><div>def</div></head>... + childDoc.getSelection().collapse( + testingBackspace ? div.firstChild : style.firstChild, + testingBackspace ? 0 : style.firstChild.length + ); + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + removeResourceScriptElements(childDoc); + childDoc.head.removeAttribute("style"); + style.removeAttribute("style"); + + assert_equals( + childDoc.documentElement.innerHTML, + "<head><title>iframe</title><style>abc</style><div>def</div></head><body><br></body>", + "Visible <style> and <div> shouldn't be merged" + ); +}, `${commandName} at boundary of <style> and <div> in <head> should not join them`); + +promise_test(async () => { + await initializeAndWaitForLoad(iframe, minimumSrcDoc); + const childDoc = iframe.contentDocument; + const utils = new EditorTestUtils(childDoc.documentElement); + const title = childDoc.createElement("title"); + title.innerHTML = "abc"; + title.setAttribute("title", "display:block"); + const div = childDoc.createElement("div"); + div.innerHTML = "def"; + childDoc.head.appendChild(title); + childDoc.head.appendChild(div); + // Now: <head><title>...</title><title>abc</title><div>def</div></head>... + childDoc.getSelection().collapse( + testingBackspace ? div.firstChild : title.firstChild, + testingBackspace ? 0 : title.firstChild.length + ); + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + removeResourceScriptElements(childDoc); + childDoc.head.removeAttribute("style"); + title.removeAttribute("style"); + + assert_equals( + childDoc.documentElement.innerHTML, + "<head><title>iframe</title><title>abc</title><div>def</div></head><body><br></body>", + "Visible <title> and <div> shouldn't be merged" + ); +}, `${commandName} at boundary of <title> and <div> in <head> should not join them`); + +// Visible <script>, <style>, <title> shouldn't be joined with preceding <div> +promise_test(async () => { + await initializeAndWaitForLoad(iframe, minimumSrcDoc); + const childDoc = iframe.contentDocument; + const utils = new EditorTestUtils(childDoc.documentElement); + const div = childDoc.createElement("div"); + div.innerHTML = "// abc"; + const script = childDoc.createElement("script"); + script.innerHTML = "// def"; + script.setAttribute("style", "display:block"); + childDoc.head.appendChild(div); + childDoc.head.appendChild(script); + // Now: <head><title>...</title><div>// abc</div><script>// def</ script></head>... + childDoc.getSelection().collapse( + testingBackspace ? script.firstChild : div.firstChild, + testingBackspace ? 0 : div.firstChild.length + ); + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + removeResourceScriptElements(childDoc); + childDoc.head.removeAttribute("style"); + script.removeAttribute("style"); + + assert_equals( + childDoc.documentElement.innerHTML, + "<head><title>iframe</title><div>// abc</div><script>// def</" + "script></head><body><br></body>", + "<div> and visible <script> shouldn't be merged" + ); +}, `${commandName} at boundary of <div> and <script> in <head> should not join them`); + +promise_test(async () => { + await initializeAndWaitForLoad(iframe, minimumSrcDoc); + const childDoc = iframe.contentDocument; + const utils = new EditorTestUtils(childDoc.documentElement); + const div = childDoc.createElement("div"); + div.innerHTML = "abc"; + const style = childDoc.createElement("style"); + style.innerHTML = "def"; + style.setAttribute("style", "display:block"); + childDoc.head.appendChild(div); + childDoc.head.appendChild(style); + // Now: <head><title>...</title><div>abc</div><style>def</style></head>... + childDoc.getSelection().collapse( + testingBackspace ? style.firstChild : div.firstChild, + testingBackspace ? 0 : div.firstChild.length + ); + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + removeResourceScriptElements(childDoc); + childDoc.head.removeAttribute("style"); + style.removeAttribute("style"); + + assert_equals( + childDoc.documentElement.innerHTML, + "<head><title>iframe</title><div>abc</div><style>def</style></head><body><br></body>", + "<div> and visible <style> shouldn't be merged" + ); +}, `${commandName} at boundary of <div> and <style> in <head> should not join them`); + +promise_test(async () => { + await initializeAndWaitForLoad(iframe, minimumSrcDoc); + const childDoc = iframe.contentDocument; + const utils = new EditorTestUtils(childDoc.documentElement); + const div = childDoc.createElement("div"); + div.innerHTML = "abc"; + const title = childDoc.createElement("title"); + title.innerHTML = "def"; + title.setAttribute("style", "display:block"); + childDoc.head.appendChild(div); + childDoc.head.appendChild(title); + // Now: <head><title>...</title><div>abc</div><title>def</title></head>... + childDoc.getSelection().collapse( + testingBackspace ? title.firstChild : div.firstChild, + testingBackspace ? 0 : div.firstChild.length + ); + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + removeResourceScriptElements(childDoc); + childDoc.head.removeAttribute("style"); + title.removeAttribute("style"); + + assert_equals( + childDoc.documentElement.innerHTML, + "<head><title>iframe</title><div>abc</div><title>def</title></head><body><br></body>", + "<div> and visible <title> shouldn't be merged" + ); +}, `${commandName} at boundary of <div> and <title> in <head> should not join them`); + +</script> +</body> +</html> diff --git a/testing/web-platform/tests/editing/other/delete-in-child-of-html.tentative.html b/testing/web-platform/tests/editing/other/delete-in-child-of-html.tentative.html new file mode 100644 index 0000000000..4ae5446d1b --- /dev/null +++ b/testing/web-platform/tests/editing/other/delete-in-child-of-html.tentative.html @@ -0,0 +1,449 @@ +<!doctype html> +<html> +<head> +<meta chareset="utf-8"> +<meta name="timeout" content="long"> +<meta name="variant" content="?designMode=off&method=backspace"> +<meta name="variant" content="?designMode=off&method=forwarddelete"> +<meta name="variant" content="?designMode=on&method=backspace"> +<meta name="variant" content="?designMode=on&method=forwarddelete"> +<title>Join paragraphs outside the body</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script src="../include/editor-test-utils.js"></script> +</head> +<body> +<iframe srcdoc=""></iframe> +<script> +"use strict"; + +const searchParams = new URLSearchParams(document.location.search); +const testingBackspace = searchParams.get("method") == "backspace"; +const commandName = testingBackspace ? "delete" : "forwarddelete"; +const testingDesignMode = searchParams.get("designMode") == "on"; + +const iframe = document.querySelector("iframe"); +const minimumSrcDoc = + "<html>" + + "<head>" + + "<title>iframe</title>" + + "<script src='/resources/testdriver.js'></" + "script>" + + "<script src='/resources/testdriver-vendor.js'></" + "script>" + + "<script src='/resources/testdriver-actions.js'></" + "script>" + + "</head>" + + "<body><br></body>" + + "</html>"; + +async function initializeAndWaitForLoad(iframeElement, srcDocValue) { + const waitForLoad = + new Promise( + resolve => iframeElement.addEventListener("load", resolve, {once: true}) + ); + iframeElement.srcdoc = srcDocValue; + await waitForLoad; + if (testingDesignMode) { + iframeElement.contentDocument.designMode = "on"; + } else { + iframeElement.contentDocument.documentElement.setAttribute("contenteditable", ""); + } + iframeElement.contentWindow.focus(); + iframeElement.contentDocument.execCommand("defaultParagraphSeparator", false, "div"); +} + +function removeResourceScriptElements(node) { + node.querySelectorAll("script").forEach( + element => { + if (element.getAttribute("src")?.startsWith("/resources")) { + element.remove() + } + } + ); +} + +// DO NOT USE multi-line comment in this file, then, you can comment out +// unnecessary tests when you need to attach the browser with a debugger. + +// For backward compatibility, normal block elements outside <body> should be +// joined by deletion. +promise_test(async () => { + await initializeAndWaitForLoad(iframe, minimumSrcDoc); + const childDoc = iframe.contentDocument; + const utils = new EditorTestUtils(childDoc.documentElement); + const div1 = childDoc.createElement("div"); + div1.innerHTML = "abc"; + const div2 = childDoc.createElement("div"); + div2.innerHTML = "def"; + childDoc.documentElement.appendChild(div1); + childDoc.documentElement.appendChild(div2); + // Now: </head><body><br></body><div>abc</div><div>def</div> + childDoc.getSelection().collapse( + testingBackspace ? div2.firstChild : div1.firstChild, + testingBackspace ? 0 : div1.firstChild.length + ); + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + removeResourceScriptElements(childDoc); + assert_in_array( + childDoc.documentElement.innerHTML, + [ + '<head><title>iframe</title></head><body><br></body><div>abcdef</div>', + '<head><title>iframe</title></head><body><br></body><div>abcdef<br></div>', + ], + "The <div> elements should be merged" + ); + assert_equals( + div1.isConnected ^ div2.isConnected, + 1, + "One <div> element should be removed, and the other should stay" + ); +}, `${commandName} in <div> elements after <body> should join them`); + +// Deleting around end of the <body> should merge the element after the +// <body> into the <body>. +promise_test(async () => { + await initializeAndWaitForLoad(iframe, minimumSrcDoc); + const childDoc = iframe.contentDocument; + const utils = new EditorTestUtils(childDoc.documentElement); + childDoc.body.innerHTML = "abc"; + const div = childDoc.createElement("div"); + div.innerHTML = "def"; + childDoc.documentElement.appendChild(div); + // Now: </head><body>abc</body><div>def</div> + childDoc.getSelection().collapse( + testingBackspace ? div.firstChild : childDoc.body.firstChild, + testingBackspace ? 0 : childDoc.body.firstChild.length + ); + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + removeResourceScriptElements(childDoc); + assert_in_array( + childDoc.documentElement.innerHTML, + [ + '<head><title>iframe</title></head><body>abcdef</body>', + '<head><title>iframe</title></head><body>abcdef<br></body>', + ], + "The text should be merged" + ); + assert_false( + div.isConnected, + "The <div> following <body> should be removed" + ); +}, `${commandName} should merge <div> after <body> into the <body>`); + +promise_test(async () => { + await initializeAndWaitForLoad(iframe, minimumSrcDoc); + const childDoc = iframe.contentDocument; + const utils = new EditorTestUtils(childDoc.documentElement); + const div1 = childDoc.createElement("div"); + div1.innerHTML = "abc"; + const div2 = childDoc.createElement("div"); + div2.innerHTML = "def"; + childDoc.body.innerHTML = ""; + childDoc.body.appendChild(div1); + childDoc.documentElement.appendChild(div2); + // Now: </head><body><div>abc</div></body><div>def</div> + childDoc.getSelection().collapse( + testingBackspace ? div2.firstChild : div1.firstChild, + testingBackspace ? 0 : div1.firstChild.length + ); + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + removeResourceScriptElements(childDoc); + assert_in_array( + childDoc.documentElement.innerHTML, + [ + '<head><title>iframe</title></head><body><div>abcdef</div></body>', + '<head><title>iframe</title></head><body><div>abcdef<br></div></body>', + ], + "The <div> elements should be merged" + ); + assert_true( + !div2.isConnected || (div2.isConnected && div2.parentNode == childDoc.body), + "The <div> following <body> should be removed or moved into the <body>" + ); +}, `${commandName} should merge <div> after <body> into the <div> in the <body>`); + +promise_test(async () => { + await initializeAndWaitForLoad(iframe, minimumSrcDoc); + const childDoc = iframe.contentDocument; + const utils = new EditorTestUtils(childDoc.documentElement); + const div = childDoc.createElement("div"); + div.innerHTML = "abc"; + childDoc.documentElement.appendChild(div); + // Now: </head><body><br></body><div>abc</div> + childDoc.getSelection().collapse( + testingBackspace ? div.firstChild : childDoc.body, + 0 + ); + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + removeResourceScriptElements(childDoc); + assert_in_array( + childDoc.documentElement.innerHTML, + [ + '<head><title>iframe</title></head><body>abc</body>', + '<head><title>iframe</title></head><body>abc<br></body>', + ], + "The <div> element should be merged into the <body>" + ); + assert_false( + div.isConnected, + "The <div> element should be removed" + ); +}, `${commandName} should merge <div> after <body> into the empty <body>`); + +// Deleting around start of the <body> should merge the element before the +// <body> into the <body>. +promise_test(async () => { + await initializeAndWaitForLoad(iframe, minimumSrcDoc); + const childDoc = iframe.contentDocument; + const utils = new EditorTestUtils(childDoc.documentElement); + const div = childDoc.createElement("div"); + div.innerHTML = "abc"; + childDoc.body.innerHTML = "def"; + childDoc.documentElement.insertBefore(div, childDoc.body); + // Now: </head><div>abc</div><body>def</body> + childDoc.getSelection().collapse( + testingBackspace ? childDoc.body.firstChild : div.firstChild, + testingBackspace ? 0 : div.firstChild.length + ); + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + removeResourceScriptElements(childDoc); + assert_in_array( + childDoc.documentElement.innerHTML, + [ + '<head><title>iframe</title></head><body>abcdef</body>', + '<head><title>iframe</title></head><body>abcdef<br></body>', + ], + "The text should be merged" + ); + assert_false( + div.isConnected, + "The <div> following <body> should be removed" + ); +}, `${commandName} should merge <div> before <body> into the <body>`); + +promise_test(async () => { + await initializeAndWaitForLoad(iframe, minimumSrcDoc); + const childDoc = iframe.contentDocument; + const utils = new EditorTestUtils(childDoc.documentElement); + const div1 = childDoc.createElement("div"); + div1.innerHTML = "abc"; + const div2 = childDoc.createElement("div"); + div2.innerHTML = "def"; + childDoc.documentElement.insertBefore(div1, childDoc.body); + childDoc.body.innerHTML = ""; + childDoc.body.appendChild(div2); + // Now: </head><div>abc</div><body><div>def</div></body> + childDoc.getSelection().collapse( + testingBackspace ? div2.firstChild : div1.firstChild, + testingBackspace ? 0 : div1.firstChild.length + ); + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + removeResourceScriptElements(childDoc); + assert_in_array( + childDoc.documentElement.innerHTML, + [ + '<head><title>iframe</title></head><body><div>abcdef</div></body>', + '<head><title>iframe</title></head><body><div>abcdef<br></div></body>', + ], + "The <div> elements should be merged" + ); + assert_true( + !div2.isConnected || (div2.isConnected && div2.parentNode == childDoc.body), + "The <div> following <body> should be removed or moved into the <body>" + ); +}, `${commandName} should merge <div> before <body> into the <div> in the <body>`); + +promise_test(async () => { + await initializeAndWaitForLoad(iframe, minimumSrcDoc); + const childDoc = iframe.contentDocument; + const utils = new EditorTestUtils(childDoc.documentElement); + const div = childDoc.createElement("div"); + div.innerHTML = "abc"; + childDoc.documentElement.insertBefore(div, childDoc.body); + // Now: </head><div>abc</div><body><br></body> + childDoc.getSelection().collapse( + testingBackspace ? childDoc.body : div.firstChild, + testingBackspace ? 0: div.firstChild.length + ); + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + removeResourceScriptElements(childDoc); + assert_in_array( + childDoc.documentElement.innerHTML, + [ + '<head><title>iframe</title></head><body>abc</body>', + '<head><title>iframe</title></head><body>abc<br></body>', + ], + "The <div> element should be merged into the <body>" + ); + assert_false( + div.isConnected, + "The <div> element should be removed" + ); +}, `${commandName} should merge <div> before <body> into the empty <body>`); + +// Deleting around end of the <head> should not delete the <head> element. +if (testingBackspace) { + promise_test(async () => { + await initializeAndWaitForLoad(iframe, minimumSrcDoc); + const childDoc = iframe.contentDocument; + const utils = new EditorTestUtils(childDoc.documentElement); + const div = childDoc.createElement("div"); + div.innerHTML = "abc"; + childDoc.body.innerHTML = "def"; + childDoc.documentElement.insertBefore(div, childDoc.body); + // Now: </head><div>abc</div><body>def</body> + childDoc.getSelection().collapse(div.firstChild, 0); + await utils.sendBackspaceKey(); + removeResourceScriptElements(childDoc); + assert_equals( + childDoc.documentElement.innerHTML, + '<head><title>iframe</title></head><div>abc</div><body>def</body>', + "The <div> element should be merged into the <body>" + ); + assert_true( + div.isConnected, + "The <div> element should not be removed" + ); + }, `delete from <div> following invisible <head> element shouldn't delete the <head> element`); +} + +// Joining elements around <head> element should not delete the <head> element. +promise_test(async () => { + await initializeAndWaitForLoad(iframe, minimumSrcDoc); + const childDoc = iframe.contentDocument; + const utils = new EditorTestUtils(childDoc.documentElement); + const div1 = childDoc.createElement("div"); + div1.innerHTML = "abc"; + const div2 = childDoc.createElement("div"); + div2.innerHTML = "def"; + childDoc.documentElement.insertBefore(div1, childDoc.head); + childDoc.documentElement.insertBefore(div2, childDoc.body); + // Now: <div>abc</div><head>...</head><div>def</div><body><br></body> + childDoc.getSelection().collapse( + testingBackspace ? div2.firstChild : div1.firstChild, + testingBackspace ? 0 : div1.firstChild.length + ); + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + removeResourceScriptElements(childDoc); + assert_in_array( + childDoc.documentElement.innerHTML, + [ + '<div>abcdef</div><head><title>iframe</title></head><body><br></body>', + '<div>abcdef<br></div><head><title>iframe</title></head><body><br></body>', + '<head><title>iframe</title></head><div>abcdef</div><body><br></body>', + '<head><title>iframe</title></head><div>abcdef<br></div><body><br></body>', + ], + "The <div> element should be merged into the left <div> without deleting the <head>" + ); + assert_true( + div1.isConnected ^ div2.isConnected, + "One <div> element should be removed, but the other should stay" + ); +}, `${commandName} from <div> around invisible <head> element should not delete the <head>`); + + +// Same as <body> element boundary, allow joining across <head> elements if +// and only if both elements are normal elements. +promise_test(async () => { + await initializeAndWaitForLoad(iframe, minimumSrcDoc); + const childDoc = iframe.contentDocument; + childDoc.head.setAttribute("style", "display:block"); + const utils = new EditorTestUtils(childDoc.documentElement); + const div1 = childDoc.createElement("div"); + div1.innerHTML = "abc"; + const div2 = childDoc.createElement("div"); + div2.innerHTML = "def"; + childDoc.head.appendChild(div1); + childDoc.documentElement.insertBefore(div2, childDoc.body); + // Now: <div>abc</div></head><div>def</div><body><br></body> + childDoc.getSelection().collapse( + testingBackspace ? div2.firstChild : div1.firstChild, + testingBackspace ? 0 : div1.firstChild.length + ); + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + removeResourceScriptElements(childDoc); + childDoc.head.removeAttribute("style"); + assert_in_array( + childDoc.documentElement.innerHTML, + [ + '<head><title>iframe</title><div>abcdef</div></head><body><br></body>', + '<head><title>iframe</title><div>abcdef<br></div></head><body><br></body>', + ], + "The <div> element should be merged into the <div> in the <head>" + ); + assert_false( + div2.isConnected, + "The <div> element should be removed" + ); +}, `${commandName} from <div> following visible <head> element should be merged with the <div> in the <head>`); + +// However, don't allow to join with <script> and <style> elements because +// changing them may not be safe. +promise_test(async () => { + await initializeAndWaitForLoad(iframe, minimumSrcDoc); + const childDoc = iframe.contentDocument; + childDoc.head.setAttribute("style", "display:block"); + const utils = new EditorTestUtils(childDoc.documentElement); + const style = childDoc.createElement("style"); + style.setAttribute("style", "display:block;white-space:pre"); + style.innerHTML = "abc"; + const div = childDoc.createElement("div"); + div.innerHTML = "def"; + childDoc.head.appendChild(style); + childDoc.documentElement.insertBefore(div, childDoc.body); + // Now: <style>abc</style></head><div>def</div><body><br></body> + childDoc.getSelection().collapse( + testingBackspace ? div.firstChild : style.firstChild, + testingBackspace ? 0 : style.firstChild.length + ); + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + removeResourceScriptElements(childDoc); + childDoc.head.removeAttribute("style"); + style.removeAttribute("style"); + assert_equals( + childDoc.documentElement.innerHTML, + '<head><title>iframe</title><style>abc</style></head><div>def</div><body><br></body>', + "The <div> element should not be merged with the <style> in the <head>" + ); + assert_true( + div.isConnected, + "The <div> element should not be removed" + ); +}, `${commandName} from <div> following visible <head> element should be merged with the visible <style> in the <head>`); + +promise_test(async () => { + await initializeAndWaitForLoad(iframe, minimumSrcDoc); + const childDoc = iframe.contentDocument; + childDoc.head.setAttribute("style", "display:block"); + const utils = new EditorTestUtils(childDoc.documentElement); + const script = childDoc.createElement("script"); + script.setAttribute("style", "display:block;white-space:pre"); + script.innerHTML = "// abc"; + const div = childDoc.createElement("div"); + div.innerHTML = "def"; + childDoc.head.appendChild(script); + childDoc.documentElement.insertBefore(div, childDoc.body); + // Now: <script>// abc</ script></head><div>def</div><body><br></body> + childDoc.getSelection().collapse( + testingBackspace ? div.firstChild : script.firstChild, + testingBackspace ? 0 : script.firstChild.length + ); + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + removeResourceScriptElements(childDoc); + childDoc.head.removeAttribute("style"); + script.removeAttribute("style"); + assert_equals( + childDoc.documentElement.innerHTML, + '<head><title>iframe</title><script>// abc</' + 'script></head><div>def</div><body><br></body>', + "The <div> element should not be merged with the <script> in the <head>" + ); + assert_true( + div.isConnected, + "The <div> element should not be removed" + ); +}, `${commandName} from <div> following visible <script> element should be merged with the visible <script> in the <head>`); + +</script> +</body> +</html> diff --git a/testing/web-platform/tests/editing/other/delete-in-last-definition-list-item-when-parent-list-is-editing-host.html b/testing/web-platform/tests/editing/other/delete-in-last-definition-list-item-when-parent-list-is-editing-host.html new file mode 100644 index 0000000000..e068f9bcd2 --- /dev/null +++ b/testing/web-platform/tests/editing/other/delete-in-last-definition-list-item-when-parent-list-is-editing-host.html @@ -0,0 +1,88 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<meta name="timeout" content="long"> +<meta name="variant" content="?action=Backspace"> +<meta name="variant" content="?action=Delete"> +<title>Delete in last list item should not delete parent list if it's editing host</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script src="../include/editor-test-utils.js"></script> +<script> +"use strict"; + +const params = new URLSearchParams(location.search.substring(1)); +const backspace = params.get("action") == "Backspace"; + +addEventListener("load", () => { + document.body.innerHTML ="<dl contenteditable></dl>"; + const editingHost = document.querySelector("dl[contenteditable]"); + const utils = new EditorTestUtils(editingHost); + + function addPromiseTest(aTest) { + promise_test(async () => { + editingHost.focus(); + utils.setupEditingHost(aTest.innerHTML); + await (backspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + utils.normalizeStyleAttributeValues(); + if (Array.isArray(aTest.expectedResult)) { + assert_in_array(editingHost.innerHTML, aTest.expectedResult); + } else { + assert_equals(editingHost.innerHTML, aTest.expectedResult); + } + assert_equals( + document.body.childNodes.length, + 1, + `The editing host should be the only child of <body> (got: "${document.body.innerHTML}")` + ); + assert_equals( + document.body.firstChild, + editingHost, + `The editing host should be the only child of <body> (got: "${document.body.innerHTML}")` + ); + }, `${backspace ? "Backspace" : "Delete"} in "<dl contenteditable>${aTest.innerHTML}</dl>"`); + } + + addPromiseTest({ + innerHTML: "<dt>{}</dt>", + expectedResult: ["<dt></dt>", "<dt><br></dt>"], + }); + addPromiseTest({ + innerHTML: "<dd>{}</dd>", + expectedResult: ["<dd></dd>", "<dd><br></dd>"], + }); + addPromiseTest({ + innerHTML: "<dd><ul><li>{}</li></ul></dd>", + expectedResult: ["<dd></dd>", "<dd><br></dd>"], + }); + addPromiseTest({ + innerHTML: "<dd><ol><li>{}</li></ol></dd>", + expectedResult: ["<dd></dd>", "<dd><br></dd>"], + }); + // If only sub-list in the editing host list element, the sub-list should be + // replaced with a list item. + addPromiseTest({ + innerHTML: "<ul><li>{}</li></ul>", + expectedResult: ["<dd></dd>", "<dd><br></dd>"], + }); + addPromiseTest({ + innerHTML: "<ol><li>{}</li></ol>", + expectedResult: ["<dd></dd>", "<dd><br></dd>"], + }); + addPromiseTest({ + innerHTML: "<dl><dt>{}</dt></dl>", + expectedResult: ["<dd></dd>", "<dd><br></dd>"], + }); + addPromiseTest({ + innerHTML: "<dl><dd>{}</dd></dl>", + expectedResult: ["<dd></dd>", "<dd><br></dd>"], + }); +}, {once:true}); +</script> +</head> +<body></body> +</html> diff --git a/testing/web-platform/tests/editing/other/delete-in-last-list-item-when-parent-list-is-editing-host.html b/testing/web-platform/tests/editing/other/delete-in-last-list-item-when-parent-list-is-editing-host.html new file mode 100644 index 0000000000..7d15943935 --- /dev/null +++ b/testing/web-platform/tests/editing/other/delete-in-last-list-item-when-parent-list-is-editing-host.html @@ -0,0 +1,87 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<meta name="timeout" content="long"> +<meta name="variant" content="?list=ul&action=Backspace"> +<meta name="variant" content="?list=ul&action=Delete"> +<meta name="variant" content="?list=ol&action=Backspace"> +<meta name="variant" content="?list=ol&action=Delete"> +<title>Delete in last list item should not delete parent list if it's editing host</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script src="../include/editor-test-utils.js"></script> +<script> +"use strict"; + +const params = new URLSearchParams(location.search.substring(1)); +const backspace = params.get("action") == "Backspace"; +const list = params.get("list"); + +addEventListener("load", () => { + document.body.innerHTML =`<${list} contenteditable></${list}>`; + const editingHost = document.querySelector("[contenteditable]"); + const utils = new EditorTestUtils(editingHost); + + function addPromiseTest(aTest) { + promise_test(async () => { + editingHost.focus(); + utils.setupEditingHost(aTest.innerHTML); + await (backspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + utils.normalizeStyleAttributeValues(); + if (Array.isArray(aTest.expectedResult)) { + assert_in_array(editingHost.innerHTML, aTest.expectedResult); + } else { + assert_equals(editingHost.innerHTML, aTest.expectedResult); + } + assert_equals( + document.body.childNodes.length, + 1, + `The editing host should be the only child of <body> (got: "${document.body.innerHTML}")` + ); + assert_equals( + document.body.firstChild, + editingHost, + `The editing host should be the only child of <body> (got: "${document.body.innerHTML}")` + ); + }, `${backspace ? "Backspace" : "Delete"} in "<${list} contenteditable>${aTest.innerHTML}</${list}>"`); + } + + addPromiseTest({ + innerHTML: "<li>{}</li>", + expectedResult: ["<li></li>", "<li><br></li>"], + }); + addPromiseTest({ + innerHTML: "<li><ul><li>{}</li></ul></li>", + expectedResult: ["<li></li>", "<li><br></li>"], + }); + addPromiseTest({ + innerHTML: "<li><ol><li>{}</li></ol></li>", + expectedResult: ["<li></li>", "<li><br></li>"], + }); + // If only sub-list in the editing host list element, the sub-list should be + // replaced with a list item. + addPromiseTest({ + innerHTML: "<ul><li>{}</li></ul>", + expectedResult: ["<li></li>", "<li><br></li>"], + }); + addPromiseTest({ + innerHTML: "<ol><li>{}</li></ol>", + expectedResult: ["<li></li>", "<li><br></li>"], + }); + addPromiseTest({ + innerHTML: "<dl><dt>{}</dt></dl>", + expectedResult: ["<li></li>", "<li><br></li>"], + }); + addPromiseTest({ + innerHTML: "<dl><dd>{}</dd></dl>", + expectedResult: ["<li></li>", "<li><br></li>"], + }); +}, {once:true}); +</script> +</head> +<body></body> +</html> diff --git a/testing/web-platform/tests/editing/other/delete.html b/testing/web-platform/tests/editing/other/delete.html new file mode 100644 index 0000000000..b9bd1437e3 --- /dev/null +++ b/testing/web-platform/tests/editing/other/delete.html @@ -0,0 +1,149 @@ +<!doctype html> +<meta charset=utf-8> +<title>Deletion tests</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<div contenteditable></div> +<script> +var div = document.querySelector("div"); + +// Format: [start html, start pos, expected html, expected pos, command] +// Positions are a sequence of offsets starting from div, e.g., "1,2,0" +// translates to node = div.childNodes[1].childNodes[2], offset = 0. For a +// non-collapsed selection, use a hyphen, like "0,0-1,0". The selections are +// created with collapse() followed by extend() to allow reverse selections, so +// order is significant. +// +// Expected values can be arrays, in which case any is acceptable. +var tests = [ + ["<p><br></p><p><br></p>", "1,0", "<p><br></p>", "0,0", "delete"], + ["<p><br></p><p><br></p>", "0,0", "<p><br></p>", "0,0", "forwarddelete"], + + // Range + ["<p><br></p><p><br></p>", "0,0-1,0", "<p><br></p>", "0,0", "delete"], + ["<p><br></p><p><br></p>", "0,0-1,0", "<p><br></p>", "0,0", "forwarddelete"], + ["<p><br></p><p><br></p>", "1,0-0,0", "<p><br></p>", "0,0", "delete"], + ["<p><br></p><p><br></p>", "1,0-0,0", "<p><br></p>", "0,0", "forwarddelete"], + + // Different start values + ["<p>x<br></p><p><br></p>", "1,0", + // WebKit/Blink like to get rid of the extra <br> + ["<p>x<br></p>", "<p>x</p>"], + // The selection should really be collapsed inside the text node, but in the + // parent is close enough. + ["0,0,1", "0,1"], "delete"], + ["<p><br><br></p><p><br></p>", "1,0", "<p><br><br></p>", "0,1", "delete"], + ["<p><br></p><p><br><br></p>", "1,1", + "<p><br></p><p><br></p>", "1,0", "delete"], + ["<p><br><br><br></p>", "0,2", "<p><br><br></p>", "0,1", "delete"], + ["<p><br></p><p><br><br><br></p>", "1,2", + "<p><br></p><p><br><br></p>", "1,1", "delete"], + ["<p><br><br></p><p><br><br></p>", "1,1", + "<p><br><br></p><p><br></p>", "1,0", "delete"], + ["<p><br></p><br>", "1", "<p><br></p>", "0,0", "delete"], + + // The trailing \n in these cases is actually significant, because it was + // necessary to trigger an actual Gecko bug (somehow!). + ["<p><br></p><p><br></p>\n", "1,0", "<p><br></p>\n", "0,0", "delete"], + ["<p><br></p><p><br></p>\n", "0,0", "<p><br></p>\n", "0,0", "forwarddelete"], + ["\n<p><tt>x</tt></p><p><tt><br></tt></p><p><tt><br></tt></p>\n", "3,0,0", + "\n<p><tt>x</tt></p><p><tt><br></tt></p>\n", "2,0,0", "delete"], +]; + +div.focus(); + +for (var i = 0; i < tests.length; i++) { + test(function() { + var test = tests[i]; + div.innerHTML = test[0]; + setSelection(test[1]); + + document.execCommand(test[4], false, ""); + + if (typeof test[2] == "string") { + assert_equals(div.innerHTML, test[2], "innerHTML"); + } else { + assert_in_array(div.innerHTML, test[2], "innerHTML"); + } + + var actualSel = recordSelection(); + var expectedSel = []; + if (typeof test[3] == "string") { + test[3] = [test[3]]; + } + for (var j = 0; j < test[3].length; j++) { + setSelection(test[3][j]); + expectedSel.push(recordSelection()); + } + assertSelectionEquals(actualSel, expectedSel, test[2]); + }, i + ": " + format_value(tests[i][0]) + " " + tests[i][1] + + " " + tests[i][4]); +} + +function setSelection(selstr) { + var parts = selstr.split("-"); + var collapsePoint = getPointFromArray(parts[0].split(",")); + getSelection().collapse(collapsePoint[0], collapsePoint[1]); + + if (parts[1]) { + var extendPoint = getPointFromArray(parts[1].split(",")); + getSelection().extend(extendPoint[0], extendPoint[1]); + } +} + +function getPointFromArray(offsets) { + var retNode = div, retOffset; + var offset; + while (offset = offsets.shift()) { + if (!offsets.length) { + retOffset = offset; + } else { + retNode = retNode.childNodes[offset]; + } + } + return [retNode, retOffset]; +} + +function recordSelection() { + return [getSelection().anchorNode, getSelection().anchorOffset, + getSelection().focusNode, getSelection().focusOffset]; +} + +function assertSelectionEquals(actual, expected, html) { + if (typeof expected == "string") { + expected = [expected]; + } + var pass = false; + for (var i = 0; i < expected.length; i++) { + if (expected[i][0] === actual[0] && + expected[i][1] === actual[1] && + expected[i][2] === actual[2] && + expected[i][3] === actual[3]) { + pass = true; + break; + } + } + + assert_true(pass, "Wrong selection, expected " + formatSel(expected) + + ", got " + formatSel(actual) + + " (in HTML " + format_value(html) + ")"); +} + +function formatSel(arr) { + if (arr.length == 1) { + arr = arr[0]; + } + if (Array.isArray(arr[0])) { + var ret = []; + for (var i = 0; i < arr.length; i++) { + ret.push(formatSel(arr[i])); + } + return ret.join(" or "); + } + if (arr[0] == arr[2] && arr[1] == arr[3]) { + return "collapsed (" + format_value(arr[0]) + ", " + arr[1] + ")"; + } + return "(" + format_value(arr[0]) + ", " + arr[1] + + ")-(" + format_value(arr[2]) + ", " + arr[3] + ")"; +} +</script> diff --git a/testing/web-platform/tests/editing/other/design-mode-textarea-crash.html b/testing/web-platform/tests/editing/other/design-mode-textarea-crash.html new file mode 100644 index 0000000000..d9f01e4165 --- /dev/null +++ b/testing/web-platform/tests/editing/other/design-mode-textarea-crash.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<script> +onload = function() { + let x2 = document.getElementById("x2"); + x2.select(); + x2.placeholder = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; + document.designMode = "on"; +} +</script> +<textarea id="x2" inputmode="text" spellcheck="false" rows="32" readonly=""> +<data id="x56" part="part1" accesskey="" translate="no"> +Baa1101 11 +</data> +</textarea> diff --git a/testing/web-platform/tests/editing/other/edit-in-textcontrol-immediately-after-hidden.tentative.html b/testing/web-platform/tests/editing/other/edit-in-textcontrol-immediately-after-hidden.tentative.html new file mode 100644 index 0000000000..2cdffd6e2c --- /dev/null +++ b/testing/web-platform/tests/editing/other/edit-in-textcontrol-immediately-after-hidden.tentative.html @@ -0,0 +1,138 @@ +<!doctype html> +<meta charset=utf-8> +<meta name="variant" content="?editor=input&hide-target=editor"> +<meta name="variant" content="?editor=textarea&hide-target=editor"> +<meta name="variant" content="?editor=input&hide-target=parent"> +<meta name="variant" content="?editor=textarea&hide-target=parent"> +<title>Testing edit action in zombie editor</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<body> +<script> +"use strict"; + +const params = new URLSearchParams(location.search); + +/** + * The expected results is based on Chrome 93. + * The behavior is reasonable because JS API which requires focus and user input + * does not work if it's hidden. + */ + +function init() { + const div = document.createElement("div"); + const editor = document.createElement(params.get("editor")); + const hideTarget = params.get("hide-target") == "editor" ? editor : div; + editor.value = "default value"; + div.appendChild(editor); + document.body.appendChild(div); + return [ hideTarget, editor ]; +} + +function finalize(editor) { + editor.blur(); + editor.parentNode.remove(); + document.body.getBoundingClientRect(); +} + +promise_test(async () => { + await new Promise(resolve => addEventListener("load", resolve, {once: true})); +}, "Wait for load event"); + +promise_test(async () => { + const [hideTarget, editor] = init(); + try { + editor.select(); + hideTarget.style.display = "none"; + document.execCommand("insertText", false, "typed value"); + assert_equals(editor.value, "default value", "The value shouldn't be modified by \"insertText\" command"); + } finally { + finalize(editor); + } +}, `execCommand("insertText", false, "typed value") in <${params.get("editor")}>`); + +promise_test(async () => { + const [hideTarget, editor] = init(); + try { + editor.select(); + hideTarget.style.display = "none"; + document.execCommand("delete"); + assert_equals(editor.value, "default value", "The value shouldn't be modified by \"delete\" command"); + } finally { + finalize(editor); + } +}, `execCommand("delete") in <${params.get("editor")}>`); + +promise_test(async () => { + const [hideTarget, editor] = init(); + try { + editor.select(); + const waitForKeyDown = new Promise(resolve => { + editor.addEventListener("keydown", () => { + hideTarget.style.display = "none"; + resolve(); + }); + }); + await new test_driver.Actions() + .keyDown("a").keyUp("a") + .send(); + assert_equals( + editor.value, + "default value", + "The value shouldn't be modified by user input if \"keydown\" event listener destroyed the editor" + ); + } finally { + finalize(editor); + } +}, `<${params.get("editor")}> is hidden by "keydown" event listener`); + +promise_test(async () => { + const [hideTarget, editor] = init(); + try { + editor.select(); + const waitForKeyDown = new Promise(resolve => { + editor.addEventListener("keypress", () => { + hideTarget.style.display = "none"; + resolve(); + }); + }); + await new test_driver.Actions() + .keyDown("a").keyUp("a") + .send(); + assert_equals( + editor.value, + "default value", + "The value shouldn't be modified by user input if \"keypress\" event listener destroyed the editor" + ); + } finally { + finalize(editor); + } +}, `<${params.get("editor")}> is hidden by "keypress" event listener`); + +promise_test(async () => { + const [hideTarget, editor] = init(); + try { + editor.select(); + const waitForKeyDown = new Promise(resolve => { + editor.addEventListener("beforeinput", () => { + hideTarget.style.display = "none"; + resolve(); + }); + }); + await new test_driver.Actions() + .keyDown("a").keyUp("a") + .send(); + assert_equals( + editor.value, + "default value", + "The value shouldn't be modified by user input if \"beforeinput\" event listener destroyed the editor" + ); + } finally { + finalize(editor); + } +}, `<${params.get("editor")}> is hidden by "beforeinput" event listener`); +</script> +</body> diff --git a/testing/web-platform/tests/editing/other/editable-state-and-focus-in-assigned-slot-dom.tentative.html b/testing/web-platform/tests/editing/other/editable-state-and-focus-in-assigned-slot-dom.tentative.html new file mode 100644 index 0000000000..ae8b145283 --- /dev/null +++ b/testing/web-platform/tests/editing/other/editable-state-and-focus-in-assigned-slot-dom.tentative.html @@ -0,0 +1,31 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<title>Testing editable state and focus in slotted editable element</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +</head> +<body> +<div id="host"> +<div contenteditable></div> +</div> +<script> +const text = 'A'; +test(() => { + const host = document.querySelector('#host'); + const shadowRoot = host.attachShadow({ mode: "open" }); + const slot = document.createElement("slot"); + shadowRoot.appendChild(slot); + const editable = document.querySelector('div[contenteditable]'); + editable.focus(); + document.execCommand('insertText', false, text); + editable.blur(); + assert_equals(editable.innerText, text); + editable.focus(); + document.execCommand('insertText', false, text); + assert_equals(editable.innerText, text + text); +}); +</script> +</body> +</html>
\ No newline at end of file diff --git a/testing/web-platform/tests/editing/other/editable-state-and-focus-in-shadow-dom-in-designMode.tentative.html b/testing/web-platform/tests/editing/other/editable-state-and-focus-in-shadow-dom-in-designMode.tentative.html new file mode 100644 index 0000000000..88e6d29129 --- /dev/null +++ b/testing/web-platform/tests/editing/other/editable-state-and-focus-in-shadow-dom-in-designMode.tentative.html @@ -0,0 +1,252 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<title>Testing editable state and focus in shadow DOM in design mode</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script src="../include/editor-test-utils.js"></script> +</head> +<body> +<h3>open</h3> +<my-shadow data-mode="open"></my-shadow> +<h3>closed</h3> +<my-shadow data-mode="closed"></my-shadow> + +<script> +"use strict"; + +document.designMode = "on"; +const utils = new EditorTestUtils(document.body); + +class MyShadow extends HTMLElement { + #defaultInnerHTML = + "<style>:focus { outline: 3px red solid; }</style>" + + "<div>text" + + "<div contenteditable=\"\">editable</div>" + + "<object tabindex=\"0\">object</object>" + + "<p tabindex=\"0\">paragraph</p>" + + "</div>"; + #shadowRoot; + + constructor() { + super(); + this.#shadowRoot = this.attachShadow({mode: this.getAttribute("data-mode")}); + this.#shadowRoot.innerHTML = this.#defaultInnerHTML; + } + + reset() { + this.#shadowRoot.innerHTML = this.#defaultInnerHTML; + this.#shadowRoot.querySelector("div").getBoundingClientRect(); + } + + focusText() { + this.focus(); + const div = this.#shadowRoot.querySelector("div"); + getSelection().collapse(div.firstChild || div, 0); + } + + focusContentEditable() { + this.focus(); + const contenteditable = this.#shadowRoot.querySelector("div[contenteditable]"); + contenteditable.focus(); + getSelection().collapse(contenteditable.firstChild || contenteditable, 0); + } + + focusObject() { + this.focus(); + this.#shadowRoot.querySelector("object[tabindex]").focus(); + } + + focusParagraph() { + this.focus(); + const tabbableP = this.#shadowRoot.querySelector("p[tabindex]"); + tabbableP.focus(); + getSelection().collapse(tabbableP.firstChild || tabbableP, 0); + } + + getInnerHTML() { + return this.#shadowRoot.innerHTML; + } + + getDefaultInnerHTML() { + return this.#defaultInnerHTML; + } + + getFocusedElementName() { + return this.#shadowRoot.querySelector(":focus")?.tagName.toLocaleLowerCase() || ""; + } + + getSelectedRange() { + // XXX There is no standardized way to retrieve selected ranges in + // shadow trees, therefore, we use non-standardized API for now + // since the main purpose of this test is checking the behavior of + // selection changes in shadow trees, not checking the selection API. + const selection = + this.#shadowRoot.getSelection !== undefined + ? this.#shadowRoot.getSelection() + : getSelection(); + return selection.getRangeAt(0); + } +} + +customElements.define("my-shadow", MyShadow); + +function getRangeDescription(range) { + function getNodeDescription(node) { + if (!node) { + return "null"; + } + switch (node.nodeType) { + case Node.TEXT_NODE: + case Node.COMMENT_NODE: + case Node.CDATA_SECTION_NODE: + return `${node.nodeName} "${node.data}"`; + case Node.ELEMENT_NODE: + return `<${node.nodeName.toLowerCase()}>`; + default: + return `${node.nodeName}`; + } + } + if (range === null) { + return "null"; + } + if (range === undefined) { + return "undefined"; + } + return range.startContainer == range.endContainer && + range.startOffset == range.endOffset + ? `(${getNodeDescription(range.startContainer)}, ${range.startOffset})` + : `(${getNodeDescription(range.startContainer)}, ${ + range.startOffset + }) - (${getNodeDescription(range.endContainer)}, ${range.endOffset})`; +} + +promise_test(async () => { + await new Promise(resolve => addEventListener("load", resolve, {once: true})); + assert_true(true, "Load event is fired"); +}, "Waiting for load"); + +/** + * The expected result of this test is based on Blink and Gecko's behavior. + */ + +for (const mode of ["open", "closed"]) { + const host = document.querySelector(`my-shadow[data-mode=${mode}]`); + promise_test(async (t) => { + host.reset(); + host.focusText(); + test(() => { + assert_equals( + host.getFocusedElementName(), + "", + `No element should have focus after ${t.name}` + ); + }, `Focus after ${t.name}`); + await utils.sendKey("A"); + test(() => { + assert_equals( + host.getInnerHTML(), + host.getDefaultInnerHTML(), + `The shadow DOM shouldn't be modified after ${t.name}` + ); + }, `Typing "A" after ${t.name}`); + }, `Collapse selection into text in the ${mode} shadow DOM`); + + promise_test(async (t) => { + host.reset(); + host.focusContentEditable(); + test(() => { + assert_equals( + host.getFocusedElementName(), + "div", + `<div contenteditable> should have focus after ${t.name}` + ); + }, `Focus after ${t.name}`); + await utils.sendKey("A"); + test(() => { + assert_equals( + host.getInnerHTML(), + host.getDefaultInnerHTML().replace("<div contenteditable=\"\">", "<div contenteditable=\"\">A"), + `The shadow DOM shouldn't be modified after ${t.name}` + ); + }, `Typing "A" after ${t.name}`); + }, `Collapse selection into text in <div contenteditable> in the ${mode} shadow DOM`); + + promise_test(async (t) => { + host.reset(); + host.focusObject(); + test(() => { + assert_equals( + host.getFocusedElementName(), + "object", + `The <object> element should have focus after ${t.name}` + ); + }, `Focus after ${t.name}`); + await utils.sendKey("A"); + test(() => { + assert_equals( + host.getInnerHTML(), + host.getDefaultInnerHTML(), + `The shadow DOM shouldn't be modified after ${t.name}` + ); + }, `Typing "A" after ${t.name}`); + }, `Set focus to <object> in the ${mode} shadow DOM`); + + promise_test(async (t) => { + host.reset(); + host.focusParagraph(); + test(() => { + assert_equals( + host.getFocusedElementName(), + "p", + `The <p tabindex="0"> element should have focus after ${t.name}` + ); + }, `Focus after ${t.name}`); + await utils.sendKey("A"); + test(() => { + assert_equals( + host.getInnerHTML(), + host.getDefaultInnerHTML(), + `The shadow DOM shouldn't be modified after ${t.name}` + ); + }, `Typing "A" after ${t.name}`); + }, `Set focus to <p tabindex="0"> in the ${mode} shadow DOM`); + + promise_test(async (t) => { + host.reset(); + host.focusParagraph(); + await utils.sendSelectAllShortcutKey(); + assert_in_array( + getRangeDescription(host.getSelectedRange()), + [ + // Feel free to add reasonable select all result in the <my-shadow>. + "(#document-fragment, 0) - (#document-fragment, 2)", + "(#text \"text\", 0) - (#text \"paragraph\", 9)", + ], + `Only all children of the ${mode} shadow DOM should be selected` + ); + getSelection().collapse(document.body, 0); + }, `SelectAll in the ${mode} shadow DOM`); + + promise_test(async (t) => { + host.reset(); + host.focusContentEditable(); + await utils.sendSelectAllShortcutKey(); + assert_in_array( + getRangeDescription(host.getSelectedRange()), + [ + // Feel free to add reasonable select all result in the <div contenteditable>. + "(<div>, 0) - (<div>, 1)", + "(#text \"editable\", 0) - (#text \"editable\", 8)", + ] + ); + getSelection().collapse(document.body, 0); + }, `SelectAll in the <div contenteditable> in the ${mode} shadow DOM`); +} +</script> +</body> +</html> diff --git a/testing/web-platform/tests/editing/other/editing-around-select-element.tentative.html b/testing/web-platform/tests/editing/other/editing-around-select-element.tentative.html new file mode 100644 index 0000000000..9182216efd --- /dev/null +++ b/testing/web-platform/tests/editing/other/editing-around-select-element.tentative.html @@ -0,0 +1,310 @@ +<!doctype html> +<meta charset=utf-8> +<title>Test execCommand with selection around select element</title> +<meta name="timeout" content="long"> +<meta name="variant" content="?delete"> +<meta name="variant" content="?forwardDelete"> +<meta name="variant" content="?insertText"> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script> +"use strict"; + +const command = document.location.search.substring(1); +const insertText = command === "insertText" ? "XYZ" : ""; + +/** + * Typically, browsers do not allow to move caret or select part of <select>, + * <option> and <optgroup>, but Selection API can do it (but browsers don't + * show the result). In this case, any elements under `<select>` element + * shouldn't be modified (deleted) for avoiding unexpected data loss for the + * users. + */ + +promise_test(async () => { + await new Promise(resolve => { + addEventListener("load", resolve, {once: true}); + }); +}); + +function addPromiseTest(desc, initFunc, expectedResults) { + promise_test(async () => { + initFunc(); + document.execCommand(command, false, insertText); + if (Array.isArray(expectedResults)) { + assert_in_array(document.body.innerHTML.replace(/(=""|<br>)/g, ""), expectedResults); + } else { + assert_equals(document.body.innerHTML.replace(/(=""|<br>)/g, ""), expectedResults); + } + }, `execCommand(${command}, false, "${insertText}") in ${desc}`); +} + +for (const multiple of ["", " multiple"]) { + addPromiseTest( + `<div contenteditable><p>ab[c</p><select${multiple}><option>d]ef</option></select></div>: shouldn't modify in <option>`, + () => { + document.body.innerHTML = + `<div contenteditable><p>abc</p><select${multiple}><option>def</option></select></div>`; + getSelection().setBaseAndExtent( + document.querySelector("p").firstChild, + 2, + document.querySelector("option").firstChild, + 1 + ); + }, + [ + `<div contenteditable><p>abc</p><select${multiple}><option>def</option></select></div>`, + `<div contenteditable><p>ab${insertText}</p><select${multiple}><option>def</option></select></div>`, + ] + ); + + addPromiseTest( + `<div contenteditable><p>abc</p><select${multiple}><option>d[]ef</option></select></div>: shouldn't modify in <option>`, + () => { + document.body.innerHTML = + `<div contenteditable><p>abc</p><select${multiple}><option>def</option></select></div>`; + getSelection().collapse( + document.querySelector("option").firstChild, + 1 + ); + }, + `<div contenteditable><p>abc</p><select${multiple}><option>def</option></select></div>`, + ); + + addPromiseTest( + `<div contenteditable><select${multiple}><option>ab[c</option></select><p>d]ef</p></div>: shouldn't modify in <option>`, + () => { + document.body.innerHTML = + `<div contenteditable><select${multiple}><option>abc</option></select><p>def</p></div>`; + getSelection().setBaseAndExtent( + document.querySelector("option").firstChild, + 2, + document.querySelector("p").firstChild, + 1 + ); + }, + [ + `<div contenteditable><select${multiple}><option>abc</option></select><p>def</p></div>`, + `<div contenteditable><select${multiple}><option>abc</option></select><p>${insertText}ef</p></div>`, + ] + ); + + addPromiseTest( + `<div contenteditable><p>abc</p><select${multiple}><option>{}def</option></select><p>ghi</p></div>: shouldn't modify in <option>`, + () => { + document.body.innerHTML = + `<div contenteditable><p>abc</p><select${multiple}><option>def</option></select><p>ghi</p></div>`; + getSelection().collapse( + document.querySelector("option"), + 0 + ); + }, + `<div contenteditable><p>abc</p><select${multiple}><option>def</option></select><p>ghi</p></div>` + ); + + addPromiseTest( + `<div contenteditable><p>abc</p><select${multiple}><option>def{}</option></select><p>ghi</p></div>: shouldn't modify in <option>`, + () => { + document.body.innerHTML = + `<div contenteditable><p>abc</p><select${multiple}><option>def</option></select><p>ghi</p></div>`; + getSelection().collapse( + document.querySelector("option"), + 1 + ); + }, + `<div contenteditable><p>abc</p><select${multiple}><option>def</option></select><p>ghi</p></div>` + ); + + addPromiseTest( + `<div contenteditable><p>abc</p><select${multiple}><option>{def}</option></select><p>ghi</p></div>: shouldn't modify in <option>`, + () => { + document.body.innerHTML = + `<div contenteditable><p>abc</p><select${multiple}><option>def</option></select><p>ghi</p></div>`; + getSelection().selectAllChildren( + document.querySelector("option") + ); + }, + `<div contenteditable><p>abc</p><select${multiple}><option>def</option></select><p>ghi</p></div>` + ); + + addPromiseTest( + `<div contenteditable><p>abc</p><select${multiple}><option>{def</option><option>ghi}</option></select><p>jkl</p></div>: shouldn't join <option>s`, + () => { + document.body.innerHTML = + `<div contenteditable><p>abc</p><select${multiple}><option>def</option><option>ghi</option></select><p>jkl</p></div>`; + getSelection().setBaseAndExtent( + document.querySelector("option"), + 0, + document.querySelector("option + option"), + 1, + ); + }, + `<div contenteditable><p>abc</p><select${multiple}><option>def</option><option>ghi</option></select><p>jkl</p></div>` + ); + + addPromiseTest( + `<div contenteditable><p>abc</p><select${multiple}>{<option>def</option>}<option>ghi</option></select><p>jkl</p></div>: shouldn't delete <option>`, + () => { + document.body.innerHTML = + `<div contenteditable><p>abc</p><select${multiple}><option>def</option><option>ghi</option></select><p>jkl</p></div>`; + getSelection().setBaseAndExtent( + document.querySelector("select"), + 0, + document.querySelector("select"), + 1, + ); + }, + `<div contenteditable><p>abc</p><select${multiple}><option>def</option><option>ghi</option></select><p>jkl</p></div>` + ); + + addPromiseTest( + `<div contenteditable><p>abc</p><select${multiple}><option>def</option>{<option>ghi</option>}</select><p>jkl</p></div>: shouldn't delete <option>`, + () => { + document.body.innerHTML = + `<div contenteditable><p>abc</p><select${multiple}><option>def</option><option>ghi</option></select><p>jkl</p></div>`; + getSelection().setBaseAndExtent( + document.querySelector("select"), + 1, + document.querySelector("select"), + 2, + ); + }, + `<div contenteditable><p>abc</p><select${multiple}><option>def</option><option>ghi</option></select><p>jkl</p></div>` + ); + + addPromiseTest( + `<div contenteditable><p>abc</p><select${multiple}>{<option>def</option><option>ghi</option>}</select><p>jkl</p></div>: shouldn't delete <option>s nor <select${multiple}>`, + () => { + document.body.innerHTML = + `<div contenteditable><p>abc</p><select${multiple}><option>def</option><option>ghi</option></select><p>jkl</p></div>`; + getSelection().selectAllChildren( + document.querySelector("select") + ); + }, + `<div contenteditable><p>abc</p><select${multiple}><option>def</option><option>ghi</option></select><p>jkl</p></div>` + ); + + addPromiseTest( + `<div contenteditable><p>abc</p><select${multiple}><optgroup>{<option>def</option><option>ghi</option>}</optgroup></select><p>jkl</p></div>: shouldn't delete <option>, <optgroup> nor <select${multiple}>`, + () => { + document.body.innerHTML = + `<div contenteditable><p>abc</p><select${multiple}><optgroup><option>def</option><option>ghi</option></optgroup></select><p>jkl</p></div>`; + getSelection().selectAllChildren( + document.querySelector("optgroup") + ); + }, + `<div contenteditable><p>abc</p><select${multiple}><optgroup><option>def</option><option>ghi</option></optgroup></select><p>jkl</p></div>` + ); + + addPromiseTest( + `<div contenteditable><p>abc</p>{<select${multiple}><option>def</option><option>ghi</option></select>}<p>jkl</p></div>: <select${multiple}> element itself should be removable`, + () => { + document.body.innerHTML = + `<div contenteditable><p>abc</p><select${multiple}><option>def</option><option>ghi</option></select><p>jkl</p></div>`; + getSelection().setBaseAndExtent( + document.querySelector("div"), + 1, + document.querySelector("div"), + 2, + ); + }, + [ + `<div contenteditable><p>abc</p>${insertText}<p>jkl</p></div>`, + `<div contenteditable><p>abc${insertText}</p><p>jkl</p></div>`, + `<div contenteditable><p>abc</p><p>${insertText}jkl</p></div>`, + ] + ); + + addPromiseTest( + `<div contenteditable><p>abc</p>{<select${multiple}><optgroup><option>def</option><option>ghi</option></optgroup></select>}<p>jkl</p></div>: <select${multiple}> element itself should be removable`, + () => { + document.body.innerHTML = + `<div contenteditable><p>abc</p><select${multiple}><option>def</option><option>ghi</option></select><p>jkl</p></div>`; + getSelection().setBaseAndExtent( + document.querySelector("div"), + 1, + document.querySelector("div"), + 2, + ); + }, + [ + `<div contenteditable><p>abc</p>${insertText}<p>jkl</p></div>`, + `<div contenteditable><p>abc${insertText}</p><p>jkl</p></div>`, + `<div contenteditable><p>abc</p><p>${insertText}jkl</p></div>`, + ] + ); + + addPromiseTest( + `<select${multiple} contenteditable>{<option>abc</option><option>def</option>}</select>: shouldn't delete <option>s`, + () => { + document.body.innerHTML = + `<select${multiple} contenteditable><option>abc</option><option>def</option></select>`; + getSelection().selectAllChildren( + document.querySelector("select") + ); + }, + `<select${multiple} contenteditable><option>abc</option><option>def</option></select>` + ); + + addPromiseTest( + `<select${multiple}><option contenteditable>{abc}</option><option>def</option></select>: shouldn't modify <option>`, + () => { + document.body.innerHTML = + `<select${multiple}><option contenteditable>abc</option><option>def</option></select>`; + getSelection().selectAllChildren( + document.querySelector("option") + ); + }, + `<select${multiple}><option contenteditable>abc</option><option>def</option></select>` + ); + + addPromiseTest( + `<select${multiple}><optgroup contenteditable>{<option>abc</option><option>def</option>}</optgroup></select>: shouldn't delete <option>s`, + () => { + document.body.innerHTML = + `<select${multiple}><optgroup contenteditable><option>abc</option><option>def</option></optgroup></select>`; + getSelection().selectAllChildren( + document.querySelector("optgroup") + ); + }, + `<select${multiple}><optgroup contenteditable><option>abc</option><option>def</option></optgroup></select>` + ); + + addPromiseTest( + `<select${multiple}><optgroup contenteditable><option>{abc}</option><option>def</option></optgroup></select>: shouldn't delete <option>s nor optgroup`, + () => { + document.body.innerHTML = + `<select${multiple}><optgroup contenteditable><option>abc</option><option>def</option></optgroup></select>`; + getSelection().selectAllChildren( + document.querySelector("option") + ); + }, + `<select${multiple}><optgroup contenteditable><option>abc</option><option>def</option></optgroup></select>` + ); +} + +addPromiseTest( + "<optgroup contenteditable><option>{abc}</option><option>def</option></optgroup>: shouldn't delete <option>s nor optgroup", + () => { + document.body.innerHTML = + "<optgroup contenteditable><option>abc</option><option>def</option></optgroup>"; + getSelection().selectAllChildren( + document.querySelector("option") + ); + }, + `<optgroup contenteditable><option>abc</option><option>def</option></optgroup>` +); + +addPromiseTest( + "<option contenteditable>{abc}</option>: shouldn't modify <option>", + () => { + document.body.innerHTML = + "<option contenteditable>abc</option>"; + getSelection().selectAllChildren( + document.querySelector("option") + ); + }, + `<option contenteditable>abc</option>` +); +</script> +<body></body>
\ No newline at end of file diff --git a/testing/web-platform/tests/editing/other/editing-div-outside-body.html b/testing/web-platform/tests/editing/other/editing-div-outside-body.html new file mode 100644 index 0000000000..03064eb612 --- /dev/null +++ b/testing/web-platform/tests/editing/other/editing-div-outside-body.html @@ -0,0 +1,163 @@ +<!doctype html> +<html> +<meta charset=utf-8> +<meta name="variant" content="?designMode"> +<meta name="variant" content="?body"> +<meta name="variant" content="?html"> +<meta name="variant" content="?div-in-body"> +<meta name="variant" content="?nothing"> +<title>Test editing outside of body element</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script src="../include/editor-test-utils.js"></script> +<script> +"use strict"; + +// This test creates an editable <div> element, append it to the <html>, +// i.e., after the <body>, and do something in it. + +const tests = [ + { + command: "insertText", + arg: "abc", + initial: "<div>[]<br></div>", + expected: ["<div>abc</div>", "<div>abc<br></div>"], + }, + { + command: "delete", + initial: "<div>abc[]</div>", + expected: ["<div>ab</div>", "<div>ab<br></div>"], + }, + { + command: "forwardDelete", + initial: "<div>[]abc</div>", + expected: ["<div>bc</div>", "<div>bc<br></div>"], + }, + { + command: "insertParagraph", + initial: "<div>ab[]c</div>", + expected: [ + "<div>ab</div><div>c</div>", + "<div>ab<br></div><div>c</div>", + "<div>ab</div><div>c<br></div>", + "<div>ab<br></div><div>c<br></div>", + ], + }, + { + command: "insertLineBreak", + initial: "<div>ab[]c</div>", + expected: ["<div>ab<br>c</div>", "<div>ab<br>c<br></div>"], + }, + { + command: "bold", + initial: "<div>a[b]c</div>", + expected: ["<div>a<b>b</b>c</div>", "<div>a<b>b</b>c<br></div>"], + }, + { + command: "italic", + initial: "<div>a[b]c</div>", + expected: ["<div>a<i>b</i>c</div>", "<div>a<i>b</i>c<br></div>"], + }, + { + command: "createLink", + arg: "another.html", + initial: "<div>a[b]c</div>", + expected: [ + "<div>a<a href=\"another.html\">b</a>c</div>", + "<div>a<a href=\"another.html\">b</a>c<br></div>", + ], + }, + { + command: "unlink", + initial: "<div>a[<a href=\"another.html\">b</a>]c</div>", + expected: ["<div>abc</div>", "<div>abc<br></div>"], + }, + { + command: "insertHTML", + arg: "<hr>", + initial: "<div>a[b]c</div>", + expected: [ + "<div>a<hr>c</div>", + "<div>a<br><hr>c</div>", + "<div>a<hr>c<br></div>", + "<div>a<br><hr>c<br></div>", + ], + }, + // TODO: Add more commands. +]; + +let editingHost = () => { + switch (document.location.search) { + case "?designMode": + document.designMode = "on"; + return document.documentElement; + case "?body": + document.body.setAttribute("contenteditable", "true"); + return document.body; + case "?html": + document.documentElement.setAttribute("contenteditable", "true"); + return document.documentElement; + case "?div-in-body": + return document.querySelector("div[contenteditable]"); + case "?nothing": + return null; + } +}; + +let div; + +promise_test(async () => { + await new Promise(resolve => { + addEventListener( + "load", + () => { + assert_true(true, "load event is fired"); + resolve(); + }, + { once: true } + ); + }); + + div = document.createElement("div"); + if (editingHost != document.documentElement) { + div.setAttribute("contenteditable", "true"); + editingHost = div; + } + document.documentElement.appendChild(div); + assert_equals(document.documentElement.lastChild, div, + "The test target should be last child of the <html>"); +}, "Waiting for load event"); + +function addPromiseTest(testName, testFunc) { + promise_test(async () => { + editingHost.focus(); + await testFunc(new EditorTestUtils(div)); + }, testName); +} + +for (const test of tests) { + addPromiseTest( + `Test for execCommand("${test.command}", false, ${ + typeof test.arg == "string" ? `"${test.arg}"` : test.arg + }) in "${test.initial}"`, + async (utils) => { + utils.setupEditingHost(test.initial); + await new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve))); + document.execCommand(test.command, false, test.arg); + if (Array.isArray(test.expected)) { + assert_in_array(div.innerHTML, test.expected, + "The editing result is different from expected one"); + } else { + assert_equals(div.innerHTML, test.expected, + "The editing result is different from expected one"); + } + } + ); +} +</script> +</head> +<body></body> +</html> diff --git a/testing/web-platform/tests/editing/other/editing-style-of-range-around-void-element-child.tentative.html b/testing/web-platform/tests/editing/other/editing-style-of-range-around-void-element-child.tentative.html new file mode 100644 index 0000000000..864074c1a6 --- /dev/null +++ b/testing/web-platform/tests/editing/other/editing-style-of-range-around-void-element-child.tentative.html @@ -0,0 +1,157 @@ +<!doctype html> +<html> +<meta charset=utf-8> +<title>Test toggling style a range which starts from or ends by a child of a void element</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<body> +<div contenteditable></div> +<script> +"use strict"; + +/** + * The expected behavior is based on Chromium, but this is edge case tests. + * So, failures of this are not important unless crash. + */ + +const editor = document.querySelector("div[contenteditable]"); + +promise_test(async () => { + await new Promise(resolve => { + addEventListener("load", () => { + assert_true(true, "The document is loaded"); + resolve(); + }, { once: true }); + }); +}, "Waiting for load..."); + +promise_test(async () => { + editor.innerHTML = "<meta>bar"; + const meta = editor.querySelector("meta"); + const text = document.createTextNode("foo"); + meta.append(text); + assert_equals(meta.firstChild, text); + getSelection().setBaseAndExtent(meta.firstChild, 1, meta.nextSibling, 1); + document.execCommand("bold"); + assert_in_array( + editor.innerHTML, + [ + "<meta><b>b</b>ar", + "<meta><b>b</b>ar<br>", + ] + ); +}, "Try to apply style from void element child"); + +promise_test(async () => { + editor.innerHTML = "foo<meta>"; + const meta = editor.querySelector("meta"); + const text = document.createTextNode("bar"); + meta.append(text); + assert_equals(meta.firstChild, text); + getSelection().setBaseAndExtent(editor.firstChild, 1, meta.firstChild, 2); + document.execCommand("bold"); + assert_in_array( + editor.innerHTML, + [ + "f<b>oo</b><meta>", + "f<b>oo</b><meta><br>", + ] + ); +}, "Try to apply style by void element child"); + +promise_test(async () => { + editor.innerHTML = "<meta>"; + const meta = editor.querySelector("meta"); + const text = document.createTextNode("foo"); + meta.append(text); + assert_equals(meta.firstChild, text); + getSelection().setBaseAndExtent(meta.firstChild, 1, meta.firstChild, 2); + document.execCommand("bold"); + assert_in_array( + editor.innerHTML, + [ + "<meta>", + "<meta><br>", + ] + ); +}, "Try to apply style in void element child"); + +promise_test(async () => { + editor.innerHTML = "<meta>bar"; + const meta = editor.querySelector("meta"); + meta.setAttribute("style", "font-weight: bold"); + const text = document.createTextNode("foo"); + meta.append(text); + assert_equals(meta.firstChild, text); + getSelection().setBaseAndExtent(meta.firstChild, 1, meta.nextSibling, 1); + document.execCommand("bold"); + assert_in_array( + editor.innerHTML, + [ + "<meta><b>b</b>ar", + "<meta><b>b</b>ar<br>", + "<meta style=\"\"><b>b</b>ar", + "<meta style=\"\"><b>b</b>ar<br>", + ] + ); +}, "Try to remove style from void element child"); + +promise_test(async () => { + editor.innerHTML = "<meta>bar"; + const meta = editor.querySelector("meta"); + meta.setAttribute("style", "font-weight: bold"); + const text = document.createTextNode("foo"); + meta.append(text); + assert_equals(meta.firstChild, text); + getSelection().setBaseAndExtent(meta.firstChild, meta.firstChild.length, meta.nextSibling, 1); + document.execCommand("bold"); + assert_in_array( + editor.innerHTML, + [ + "<meta><b>b</b>ar", + "<meta><b>b</b>ar<br>", + "<meta style=\"\"><b>b</b>ar", + "<meta style=\"\"><b>b</b>ar<br>", + ] + ); +}, "Try to remove style from end of void element child"); + +promise_test(async () => { + editor.innerHTML = "foo<meta>"; + const meta = editor.querySelector("meta"); + const text = document.createTextNode("bar"); + meta.append(text); + assert_equals(meta.firstChild, text); + getSelection().setBaseAndExtent(editor.firstChild, 1, meta.firstChild, 2); + document.execCommand("bold"); + assert_in_array( + editor.innerHTML, + [ + "f<b>oo</b><meta>", + "f<b>oo</b><meta><br>", + "f<b>oo</b><meta style=\"\">", + "f<b>oo</b><meta style=\"\"><br>", + ] + ); +}, "Try to remove style by void element child"); + +promise_test(async () => { + editor.innerHTML = "foo<meta>"; + const meta = editor.querySelector("meta"); + const text = document.createTextNode("bar"); + meta.append(text); + assert_equals(meta.firstChild, text); + getSelection().setBaseAndExtent(editor.firstChild, 1, meta.firstChild, 0); + document.execCommand("bold"); + assert_in_array( + editor.innerHTML, + [ + "f<b>oo</b><meta>", + "f<b>oo</b><meta><br>", + "f<b>oo</b><meta style=\"\">", + "f<b>oo</b><meta style=\"\"><br>", + ] + ); +}, "Try to remove style by start of void element child"); +</script> +</body>
\ No newline at end of file diff --git a/testing/web-platform/tests/editing/other/empty-elements-insertion.html b/testing/web-platform/tests/editing/other/empty-elements-insertion.html new file mode 100644 index 0000000000..c654521354 --- /dev/null +++ b/testing/web-platform/tests/editing/other/empty-elements-insertion.html @@ -0,0 +1,118 @@ +<!DOCTYPE HTML> +<meta charset=utf-8> +<title>Placing selection and typing inside empty elements</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script src="../include/editor-test-utils.js"></script> +<style> + #border { + display: inline-block; + border: 2px red solid; + } + + #padding { + display: inline-block; + padding: 1em; + } + + #unstyled-before::before, + #unstyled-after::after, + #unstyled-both::before, + #unstyled-both::after { + content: ''; + display: inline-block; + border: 2px red solid; + } +</style> +<div contenteditable></div> + +<script> + const utils = new EditorTestUtils( document.querySelector( 'div[contenteditable]' ) ); + + promise_test( async () => { + utils.setupEditingHost( `<p><strong id="border"></strong></p>` ); + + const target = document.querySelector( '#border' ); + const actions = new test_driver.Actions(); + await actions + .pointerMove( 0, 0, { origin: target } ) + .pointerDown( { button: actions.ButtonType.LEFT } ) + .pointerUp( { button: actions.ButtonType.LEFT } ) + .send(); + document.execCommand( 'insertText', false, 'a' ); + assert_greater_than( target.innerHTML.length, 0, 'The text should be inserted into the styled <strong> element' ); + }, 'Insert text into the inline element styled with border' ); + + promise_test( async () => { + utils.setupEditingHost( `<p><strong id="padding"></strong></p>` ); + + const target = document.querySelector( '#padding' ); + const actions = new test_driver.Actions(); + await actions + .pointerMove( 0, 0, { origin: target } ) + .pointerDown( { button: actions.ButtonType.LEFT } ) + .pointerUp( { button: actions.ButtonType.LEFT } ) + .send(); + document.execCommand( 'insertText', false, 'a' ); + assert_greater_than( target.innerHTML.length, 0, 'The text should be inserted into the styled <strong> element' ); + }, 'Insert text into the inline element styled with padding' ); + + promise_test( async () => { + utils.setupEditingHost( `<p><strong id="unstyled"></strong></p>` ); + + const target = document.querySelector( '#unstyled' ); + const actions = new test_driver.Actions(); + await actions + .pointerMove( 0, 0, { origin: target } ) + .pointerDown( { button: actions.ButtonType.LEFT } ) + .pointerUp( { button: actions.ButtonType.LEFT } ) + .send(); + document.execCommand( 'insertText', false, 'a' ); + assert_greater_than( target.innerHTML.length, 0, 'The text should be inserted into the unstyled <strong> element' ); + }, 'Insert text into the unstyled inline element' ); + + promise_test( async () => { + utils.setupEditingHost( `<p><strong id="unstyled-before"></strong></p>` ); + + const target = document.querySelector( '#unstyled-before' ); + const actions = new test_driver.Actions(); + await actions + .pointerMove( 0, 0, { origin: target } ) + .pointerDown( { button: actions.ButtonType.LEFT } ) + .pointerUp( { button: actions.ButtonType.LEFT } ) + .send(); + document.execCommand( 'insertText', false, 'a' ); + assert_greater_than( target.innerHTML.length, 0, 'The text should be inserted into the <strong> element' ); + }, 'Insert text into the unstyled inline element with the styled ::before pseudoelement' ); + + promise_test( async () => { + utils.setupEditingHost( `<p><strong id="unstyled-after"></strong></p>` ); + + const target = document.querySelector( '#unstyled-after' ); + const actions = new test_driver.Actions(); + await actions + .pointerMove( 0, 0, { origin: target } ) + .pointerDown( { button: actions.ButtonType.LEFT } ) + .pointerUp( { button: actions.ButtonType.LEFT } ) + .send(); + document.execCommand( 'insertText', false, 'a' ); + assert_greater_than( target.innerHTML.length, 0, 'The text should be inserted into the <strong> element' ); + }, 'Insert text into the unstyled inline element with the styled ::after pseudoelement' ); + + promise_test( async () => { + utils.setupEditingHost( `<p><strong id="unstyled-both"></strong></p>` ); + + const target = document.querySelector( '#unstyled-both' ); + const actions = new test_driver.Actions(); + await actions + .pointerMove( 0, 0, { origin: target } ) + .pointerDown( { button: actions.ButtonType.LEFT } ) + .pointerUp( { button: actions.ButtonType.LEFT } ) + .send(); + document.execCommand( 'insertText', false, 'a' ); + assert_greater_than( target.innerHTML.length, 0, 'The text should be inserted into the <strong> element' ); + }, 'Insert text into the unstyled inline element with the styled ::before and ::after pseudoelements' ); +</script> diff --git a/testing/web-platform/tests/editing/other/exec-command-never-throw-exceptions.tentative.html b/testing/web-platform/tests/editing/other/exec-command-never-throw-exceptions.tentative.html new file mode 100644 index 0000000000..1b77b15ab0 --- /dev/null +++ b/testing/web-platform/tests/editing/other/exec-command-never-throw-exceptions.tentative.html @@ -0,0 +1,89 @@ +<!doctype html> +<meta charset=utf-8> +<title>Test that execCommand and related methods never throw exceptions if HTML or XHTML document</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<div contenteditable=""></div> +<script> +"use strict"; + +const editor = document.querySelector("div[contenteditable]"); + +test(function execCommand_with_unknown_command() { + editor.innerHTML = "abc"; + editor.focus(); + try { + let done = document.execCommand("unknown-command", false, "foo"); + assert_equals(done, false, + "Should return false without throwing exception"); + } catch (e) { + assert_true(false, + "Shouldn't throw exception for unknown command"); + } +}, "Testing execCommand with unknown command"); + +test(function queryCommandEnabled_with_unknown_command() { + editor.innerHTML = "abc"; + editor.focus(); + try { + let enabled = document.queryCommandEnabled("unknown-command"); + assert_equals(enabled, false, + "Should return false without throwing exception"); + } catch (e) { + assert_true(false, + "Shouldn't throw exception for unknown command"); + } +}, "Testing queryCommandEnabled with unknown command"); + +test(function queryCommandIndeterm_with_unknown_command() { + editor.innerHTML = "abc"; + editor.focus(); + try { + let indeterminate = document.queryCommandIndeterm("unknown-command"); + assert_equals(indeterminate, false, + "Should return false without throwing exception"); + } catch (e) { + assert_true(false, + "Shouldn't throw exception for unknown command"); + } +}, "Testing queryCommandIndeterm with unknown command"); + +test(function queryCommandState_with_unknown_command() { + editor.innerHTML = "abc"; + editor.focus(); + try { + let state = document.queryCommandState("unknown-command"); + assert_equals(state, false, + "Should return false without throwing exception"); + } catch (e) { + assert_true(false, + "Shouldn't throw exception for unknown command"); + } +}, "Testing queryCommandState with unknown command"); + +test(function queryCommandSupported_with_unknown_command() { + editor.innerHTML = "abc"; + editor.focus(); + try { + let supported = document.queryCommandSupported("unknown-command"); + assert_equals(supported, false, + "Should return false without throwing exception"); + } catch (e) { + assert_true(false, + "Shouldn't throw exception for unknown command"); + } +}, "Testing queryCommandSupported with unknown command"); + +test(function queryCommandValue_with_unknown_command() { + editor.innerHTML = "abc"; + editor.focus(); + try { + let value = document.queryCommandValue("unknown-command"); + assert_equals(value, "", + "Should return empty string without throwing exception"); + } catch (e) { + assert_true(false, + "Shouldn't throw exception for unknown command"); + } +}, "Testing queryCommandValue with unknown command"); +</script> diff --git a/testing/web-platform/tests/editing/other/exec-command-with-text-editor.tentative.html b/testing/web-platform/tests/editing/other/exec-command-with-text-editor.tentative.html new file mode 100644 index 0000000000..e3b0931f16 --- /dev/null +++ b/testing/web-platform/tests/editing/other/exec-command-with-text-editor.tentative.html @@ -0,0 +1,655 @@ +<!doctype html> +<meta charset=utf-8> +<title>Test that execCommand with <input> or <textarea></title> +<meta name="variant" content="?type=text"> +<meta name="variant" content="?type=textarea"> +<meta name="variant" content="?type=password"> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<div id="container"></div> +<script> +"use strict"; + +setup({explicit_done: true}); +const testingType = new URLSearchParams(document.location.search).get("type"); + +/** + * This test checks whether document.execCommand() does something expected or + * not in <input> and <textarea> with/without contenteditable parent. Although + * this is not standardized even by any drafts. So, this test uses expected + * values which may be expected by web developers. + */ +function runTests() { + let container = document.getElementById("container"); + switch (testingType) { + case "text": + case "password": + container.innerHTML = `Here <b>is</b> Text: <input id="target" type="${testingType}">`; + runTest(document.getElementById("target"), `In <input type="${testingType}">`); + container.setAttribute("contenteditable", "true"); + container.innerHTML = `Here <b>is</b> Text: <input id="target" type="${testingType}">`; + runTest(document.getElementById("target"), `In <input type="${testingType}"> in contenteditable`); + break; + case "textarea": + container.innerHTML = "Here <b>is</b> Text: <textarea id=\"target\"></textarea>"; + runTest(document.getElementById("target"), "In <textarea>"); + container.setAttribute("contenteditable", "true"); + container.innerHTML = "Here <b>is</b> Text: <textarea id=\"target\"></textarea>"; + runTest(document.getElementById("target"), "In <textarea> in contenteditable"); + break; + } + done(); +} + +function runTest(aTarget, aDescription) { + const kIsTextArea = testingType == "textarea"; + const kTests = [ + /** + * command: command name of execCommand(). + * param: param for the command. i.e., the 3rd param of execCommand(). + * value: initial value of <input> or <textarea>. must have a pair of + * "[" and "]" for specifying selection range. + * expectedValue: expected value of <input> or <textarea> after calling + * execCommand() with command and param. must have a + * pair of "[" and "]" for specifying selection range. + * expectedExecCommandResult: expected bool result of execCommand(). + * expectedCommandSupported: expected bool result of queryCommandSupported(). + * expectedCommandEnabled: expected bool result of queryCommandEnabled(). + * beforeinputExpected: if "beforeinput" event shouldn't be fired, set + * null. otherwise, expected inputType value and + * target element. + * inputExpected: if "input" event shouldn't be fired, set null. + * otherwise, expected inputType value and target element. + */ + {command: "getHTML", param: null, + value: "a[b]c", expectedValue: "a[b]c", + expectedExecCommandResult: false, + expectedCommandSupported: false, + expectedCommandEnabled: false, + beforeinputExpected: null, inputExpected: null, + }, + {command: "bold", param: "bold", + value: "a[b]c", expectedValue: "a[b]c", + expectedExecCommandResult: false, + expectedCommandSupported: true, + expectedCommandEnabled: false, + beforeinputExpected: null, inputExpected: null, + }, + {command: "italic", param: null, + value: "a[b]c", expectedValue: "a[b]c", + expectedExecCommandResult: false, + expectedCommandSupported: true, + expectedCommandEnabled: false, + beforeinputExpected: null, inputExpected: null, + }, + {command: "underline", param: null, + value: "a[b]c", expectedValue: "a[b]c", + expectedExecCommandResult: false, + expectedCommandSupported: true, + expectedCommandEnabled: false, + beforeinputExpected: null, inputExpected: null, + }, + {command: "strikethrough", param: null, + value: "a[b]c", expectedValue: "a[b]c", + expectedExecCommandResult: false, + expectedCommandSupported: true, + expectedCommandEnabled: false, + beforeinputExpected: null, inputExpected: null, + }, + {command: "superscript", param: null, + value: "a[b]c", expectedValue: "a[b]c", + expectedExecCommandResult: false, + expectedCommandSupported: true, + expectedCommandEnabled: false, + beforeinputExpected: null, inputExpected: null, + }, + // Should return true for web apps implementing custom editor. + {command: "cut", param: null, + value: "ab[]c", expectedValue: "ab[]c", + expectedExecCommandResult: false, + expectedCommandSupported: true, + expectedCommandEnabled: false, + beforeinputExpected: null, inputExpected: null, + }, + {command: "cut", param: null, + value: "a[b]c", expectedValue: "a[]c", + expectedExecCommandResult: true, + expectedCommandSupported: true, + expectedCommandEnabled: true, + beforeinputExpected: null, + inputExpected: { inputType: "deleteByCut", target: aTarget }, + }, + // Should return true for web apps implementing custom editor. + {command: "copy", param: null, + value: "abc[]d", expectedValue: "abc[]d", + expectedExecCommandResult: false, + expectedCommandSupported: true, + expectedCommandEnabled: false, + beforeinputExpected: null, inputExpected: null, + }, + {command: "copy", param: null, + value: "a[bc]d", expectedValue: "a[bc]d", + expectedExecCommandResult: true, + expectedCommandSupported: true, + expectedCommandEnabled: true, + beforeinputExpected: null, inputExpected: null, + }, + {command: "paste", param: null, + value: "a[]c", expectedValue: "a[bc]c", + expectedExecCommandResult: true, + expectedCommandSupported: true, + expectedCommandEnabled: true, + beforeinputExpected: null, + inputExpected: { inputType: "insertFromPaste", target: aTarget }, + }, + {command: "delete", param: null, + value: "ab[]c", expectedValue: "a[]c", + expectedExecCommandResult: true, + expectedCommandSupported: true, + expectedCommandEnabled: true, + beforeinputExpected: null, + inputExpected: { inputType: "deleteContentBackward", target: aTarget }, + }, + {command: "delete", param: null, + value: "a[b]c", expectedValue: "a[]c", + expectedExecCommandResult: true, + expectedCommandSupported: true, + expectedCommandEnabled: true, + beforeinputExpected: null, + inputExpected: { inputType: "deleteContentBackward", target: aTarget }, + }, + {command: "forwarddelete", param: null, + value: "a[b]c", expectedValue: "a[]c", + expectedExecCommandResult: true, + expectedCommandSupported: true, + expectedCommandEnabled: true, + beforeinputExpected: null, + inputExpected: { inputType: "deleteContentForward", target: aTarget }, + }, + {command: "forwarddelete", param: null, + value: "a[]bc", expectedValue: "a[]c", + expectedExecCommandResult: true, + expectedCommandSupported: true, + expectedCommandEnabled: true, + beforeinputExpected: null, + inputExpected: { inputType: "deleteContentForward", target: aTarget }, + }, + {command: "selectall", param: null, + value: "a[b]c", expectedValue: "[abc]", + expectedExecCommandResult: true, + expectedCommandSupported: true, + expectedCommandEnabled: true, + beforeinputExpected: null, inputExpected: null, + }, + // Setting value should forget any transactions. + {command: "undo", param: null, + value: "[a]bc", expectedValue: "[a]bc", + expectedExecCommandResult: false, + expectedCommandSupported: true, + expectedCommandEnabled: false, + beforeinputExpected: null, inputExpected: null, + }, + {command: "undo", param: null, + value: "a[b]c", expectedValue: "a[b]c", + initFunc: () => { + document.execCommand("delete", false, null); + }, + expectedExecCommandResult: true, + expectedCommandSupported: true, + expectedCommandEnabled: true, + beforeinputExpected: null, + inputExpected: { inputType: "historyUndo", target: aTarget }, + }, + // Setting value should forget any transactions. + {command: "redo", param: null, + value: "[a]bc", expectedValue: "[a]bc", + expectedExecCommandResult: false, + expectedCommandSupported: true, + expectedCommandEnabled: false, + beforeinputExpected: null, inputExpected: null, + }, + {command: "redo", param: null, + value: "a[b]c", expectedValue: "a[]c", + initFunc: () => { + document.execCommand("delete", false, null); + document.execCommand("undo", false, null); + }, + expectedExecCommandResult: true, + expectedCommandSupported: true, + expectedCommandEnabled: true, + beforeinputExpected: null, + inputExpected: { inputType: "historyRedo", target: aTarget }, + }, + {command: "indent", param: null, + value: "a[b]c", expectedValue: "a[b]c", + expectedExecCommandResult: false, + expectedCommandSupported: true, + expectedCommandEnabled: false, + beforeinputExpected: null, inputExpected: null, + }, + {command: "outdent", param: null, + value: "a[b]c", expectedValue: "a[b]c", + expectedExecCommandResult: false, + expectedCommandSupported: true, + expectedCommandEnabled: false, + beforeinputExpected: null, inputExpected: null, + }, + {command: "backcolor", param: "#000000", + value: "a[b]c", expectedValue: "a[b]c", + expectedExecCommandResult: false, + expectedCommandSupported: true, + expectedCommandEnabled: false, + beforeinputExpected: null, inputExpected: null, + }, + {command: "forecolor", param: "#000000", + value: "a[b]c", expectedValue: "a[b]c", + expectedExecCommandResult: false, + expectedCommandSupported: true, + expectedCommandEnabled: false, + beforeinputExpected: null, inputExpected: null, + }, + {command: "hilitecolor", param: "#000000", + value: "a[b]c", expectedValue: "a[b]c", + expectedExecCommandResult: false, + expectedCommandSupported: true, + expectedCommandEnabled: false, + beforeinputExpected: null, inputExpected: null, + }, + {command: "fontname", param: "DummyFont", + value: "a[b]c", expectedValue: "a[b]c", + expectedExecCommandResult: false, + expectedCommandSupported: true, + expectedCommandEnabled: false, + beforeinputExpected: null, inputExpected: null, + }, + {command: "fontsize", param: "5", + value: "a[b]c", expectedValue: "a[b]c", + expectedExecCommandResult: false, + expectedCommandSupported: true, + expectedCommandEnabled: false, + beforeinputExpected: null, inputExpected: null, + }, + {command: "increasefontsize", param: null, + value: "a[b]c", expectedValue: "a[b]c", + expectedExecCommandResult: false, + expectedCommandSupported: false, + expectedCommandEnabled: false, + beforeinputExpected: null, inputExpected: null, + }, + {command: "decreasefontsize", param: null, + value: "a[b]c", expectedValue: "a[b]c", + expectedExecCommandResult: false, + expectedCommandSupported: false, + expectedCommandEnabled: false, + beforeinputExpected: null, inputExpected: null, + }, + {command: "inserthorizontalrule", param: null, + value: "a[b]c", expectedValue: "a[b]c", + expectedExecCommandResult: false, + expectedCommandSupported: true, + expectedCommandEnabled: false, + beforeinputExpected: null, inputExpected: null, + }, + {command: "createlink", param: "foo.html", + value: "a[b]c", expectedValue: "a[b]c", + expectedExecCommandResult: false, + expectedCommandSupported: true, + expectedCommandEnabled: false, + beforeinputExpected: null, inputExpected: null, + }, + {command: "insertimage", param: "no-image.png", + value: "a[b]c", expectedValue: "a[b]c", + expectedExecCommandResult: false, + expectedCommandSupported: true, + expectedCommandEnabled: false, + beforeinputExpected: null, inputExpected: null, + }, + {command: "inserthtml", param: "<b>inserted</b>", + value: "a[b]c", expectedValue: "ainserted[]c", + expectedExecCommandResult: true, + expectedCommandSupported: true, + expectedCommandEnabled: true, + beforeinputExpected: null, + inputExpected: { inputType: "insertText", target: aTarget }, + }, + {command: "inserttext", param: "**inserted**", + value: "a[b]c", expectedValue: "a**inserted**[]c", + expectedExecCommandResult: true, + expectedCommandSupported: true, + expectedCommandEnabled: true, + beforeinputExpected: null, + inputExpected: { inputType: "insertText", target: aTarget }, + }, + {command: "inserttext", param: "", + value: "a[b]c", expectedValue: "a[]c", + expectedExecCommandResult: true, + expectedCommandSupported: true, + expectedCommandEnabled: true, + beforeinputExpected: null, + inputExpected: { inputType: "insertText", target: aTarget }, + }, + {command: "justifyleft", param: null, + value: "a[b]c", expectedValue: "a[b]c", + expectedExecCommandResult: false, + expectedCommandSupported: true, + expectedCommandEnabled: false, + beforeinputExpected: null, inputExpected: null, + }, + {command: "justifyright", param: null, + value: "a[b]c", expectedValue: "a[b]c", + expectedExecCommandResult: false, + expectedCommandSupported: true, + expectedCommandEnabled: false, + beforeinputExpected: null, inputExpected: null, + }, + {command: "justifycenter", param: null, + value: "a[b]c", expectedValue: "a[b]c", + expectedExecCommandResult: false, + expectedCommandSupported: true, + expectedCommandEnabled: false, + beforeinputExpected: null, inputExpected: null, + }, + {command: "justifyfull", param: null, + value: "a[b]c", expectedValue: "a[b]c", + expectedExecCommandResult: false, + expectedCommandSupported: true, + expectedCommandEnabled: false, + beforeinputExpected: null, inputExpected: null, + }, + {command: "removeformat", param: null, + value: "a[b]c", expectedValue: "a[b]c", + expectedExecCommandResult: false, + expectedCommandSupported: true, + expectedCommandEnabled: false, + beforeinputExpected: null, inputExpected: null, + }, + {command: "unlink", param: null, + value: "a[b]c", expectedValue: "a[b]c", + expectedExecCommandResult: false, + expectedCommandSupported: true, + expectedCommandEnabled: false, + beforeinputExpected: null, inputExpected: null, + }, + {command: "insertorderedlist", param: null, + value: "a[b]c", expectedValue: "a[b]c", + expectedExecCommandResult: false, + expectedCommandSupported: true, + expectedCommandEnabled: false, + beforeinputExpected: null, inputExpected: null, + }, + {command: "insertunorderedlist", param: null, + value: "a[b]c", expectedValue: "a[b]c", + expectedExecCommandResult: false, + expectedCommandSupported: true, + expectedCommandEnabled: false, + beforeinputExpected: null, inputExpected: null, + }, + {command: "insertparagraph", param: null, + value: "a[b]c", expectedValue: kIsTextArea ? "a\n[]c" : "a[b]c", + expectedExecCommandResult: kIsTextArea, + expectedCommandSupported: true, + expectedCommandEnabled: kIsTextArea, + beforeinputExpected: null, + inputExpected: kIsTextArea ? { inputType: "insertParagraph", target: aTarget } : null, + }, + {command: "insertlinebreak", param: null, + value: "a[b]c", expectedValue: kIsTextArea ? "a\n[]c" : "a[b]c", + expectedExecCommandResult: kIsTextArea, + expectedCommandSupported: true, + expectedCommandEnabled: kIsTextArea, + beforeinputExpected: null, + inputExpected: kIsTextArea ? { inputType: "insertLineBreak", target: aTarget } : null, + }, + {command: "formatblock", param: "div", + value: "a[b]c", expectedValue: "a[b]c", + expectedExecCommandResult: false, + expectedCommandSupported: true, + expectedCommandEnabled: false, + beforeinputExpected: null, inputExpected: null, + }, + {command: "heading", param: "h1", + value: "a[b]c", expectedValue: "a[b]c", + expectedExecCommandResult: false, + expectedCommandSupported: false, + expectedCommandEnabled: false, + beforeinputExpected: null, inputExpected: null, + }, + {command: "styleWithCSS", param: "true", + value: "a[b]c", expectedValue: "a[b]c", + expectedExecCommandResult: container.isContentEditable, + expectedCommandSupported: true, + expectedCommandEnabled: container.isContentEditable, + beforeinputExpected: null, inputExpected: null, + additionalCheckFunc: aDescription => { + test( + () => assert_equals(document.queryCommandState("styleWithCSS"), container.isContentEditable), + `${aDescription}: styleWithCSS state should be ${container.isContentEditable} when ${ + kIsTextArea ? "<textarea>" : "<input>" + } has focus` + ); + aTarget.blur(); + container.focus(); + getSelection().collapse(container, 0); + test( + () => assert_equals(document.queryCommandState("styleWithCSS"), container.isContentEditable), + `${aDescription}: styleWithCSS state should be ${container.isContentEditable} when ${ + kIsTextArea ? "<textarea>" : "<input>" + } does not have focus` + ); + }, + }, + {command: "styleWithCSS", param: "false", + value: "a[b]c", expectedValue: "a[b]c", + expectedExecCommandResult: container.isContentEditable, + expectedCommandSupported: true, + expectedCommandEnabled: container.isContentEditable, + beforeinputExpected: null, inputExpected: null, + additionalCheckFunc: aDescription => { + test( + () => assert_equals(document.queryCommandState("styleWithCSS"), false), + `${aDescription}: styleWithCSS state should be false when ${ + kIsTextArea ? "<textarea>" : "<input>" + } has focus` + ); + aTarget.blur(); + container.focus(); + getSelection().collapse(container, 0); + test( + () => assert_equals(document.queryCommandState("styleWithCSS"), false), + `${aDescription}: styleWithCSS state should be false when ${ + kIsTextArea ? "<textarea>" : "<input>" + } does not have focus` + ); + }, + }, + {command: "contentReadOnly", param: "true", + value: "a[b]c", expectedValue: "a[b]c", + expectedExecCommandResult: false, + expectedCommandSupported: false, + expectedCommandEnabled: false, + beforeinputExpected: null, inputExpected: null, + additionalCheckFunc: aDescription => { + test( + () => assert_equals(document.queryCommandState("contentReadOnly"), false), + `${aDescription}: contentReadOnly state should be true when ${ + kIsTextArea ? "<textarea>" : "<input>" + } has focus` + ); + test( + () => assert_equals(aTarget.readOnly, false), + `${aDescription}: readonly property should be true` + ); + aTarget.blur(); + container.focus(); + getSelection().collapse(container, 0); + test( + () => assert_equals(document.queryCommandState("contentReadOnly"), false), + `${aDescription}: contentReadOnly state should be false when ${ + kIsTextArea ? "<textarea>" : "<input>" + } does not have focus` + ); + }, + }, + {command: "contentReadOnly", param: "false", + value: "a[b]c", expectedValue: "a[b]c", + expectedExecCommandResult: false, + expectedCommandSupported: false, + expectedCommandEnabled: false, + beforeinputExpected: null, inputExpected: null, + additionalCheckFunc: aDescription => { + test( + () => assert_equals(document.queryCommandState("contentReadOnly"), false), + `${aDescription}: contentReadOnly state should be false when ${ + kIsTextArea ? "<textarea>" : "<input>" + } has focus` + ); + test( + () => assert_equals(aTarget.readOnly, false), + `${aDescription}: readonly property should be false` + ); + aTarget.blur(); + container.focus(); + getSelection().collapse(container, 0); + test( + () => assert_equals(document.queryCommandState("contentReadOnly"), false), + `${aDescription}: contentReadOnly state should be false when ${ + kIsTextArea ? "<textarea>" : "<input>" + } does not have focus` + ); + }, + }, + {command: "defaultParagraphSeparator", param: "p", + value: "a[b]c", expectedValue: "a[b]c", + expectedExecCommandResult: container.isContentEditable, + expectedCommandSupported: true, + expectedCommandEnabled: container.isContentEditable, + beforeinputExpected: null, inputExpected: null, + additionalCheckFunc: aDescription => { + test( + () => + assert_equals( + document.queryCommandValue("defaultParagraphSeparator"), + container.isContentEditable ? "p" : "div" + ) + , + `${aDescription}: defaultParagraphSeparator value should be "p" when ${ + kIsTextArea ? "<textarea>" : "<input>" + } has focus` + ); + aTarget.blur(); + container.focus(); + getSelection().collapse(container, 0); + test( + () => + assert_equals( + document.queryCommandValue("defaultParagraphSeparator"), + container.isContentEditable ? "p" : "div" + ), + `${aDescription}: defaultParagraphSeparator value should be "p" when ${ + kIsTextArea ? "<textarea>" : "<input>" + } does not have focus` + ); + }, + }, + {command: "defaultParagraphSeparator", param: "div", + value: "a[b]c", expectedValue: "a[b]c", + expectedExecCommandResult: container.isContentEditable, + expectedCommandSupported: true, + expectedCommandEnabled: container.isContentEditable, + beforeinputExpected: null, inputExpected: null, + additionalCheckFunc: aDescription => { + test( + () => assert_equals(document.queryCommandValue("defaultParagraphSeparator"), "div"), + `${aDescription}: defaultParagraphSeparator value should be "div" when ${ + kIsTextArea ? "<textarea>" : "<input>" + } has focus` + ); + aTarget.blur(); + container.focus(); + getSelection().collapse(container, 0); + test( + () => assert_equals(document.queryCommandValue("defaultParagraphSeparator"), "div"), + `${aDescription}: defaultParagraphSeparator value should be "div" when ${ + kIsTextArea ? "<textarea>" : "<input>" + } does not have focus` + ); + }, + }, + ]; + + for (const kTest of kTests) { + const kDescription = + `${aDescription}, execCommand("${kTest.command}", false, ${kTest.param}), ${kTest.value})`; + aTarget.value = "dummy value to ensure the following value setting clear the undo history"; + let value = kTest.value.replace(/[\[\]]/g, ""); + aTarget.value = value; + aTarget.focus(); + aTarget.selectionStart = kTest.value.indexOf("["); + aTarget.selectionEnd = kTest.value.indexOf("]") - 1; + + test( + () => assert_equals(document.queryCommandSupported(kTest.command), kTest.expectedCommandSupported), + `${kDescription}: The command should ${ + kTest.expectedCommandSupported ? "be" : "not be" + } supported` + ); + test( + () => assert_equals(document.queryCommandEnabled(kTest.command), kTest.expectedCommandEnabled), + `${kDescription}: The command should ${ + kTest.expectedCommandEnabled ? "be" : "not be" + } enabled` + ); + + if (!document.queryCommandSupported(kTest.command) || !kTest.expectedCommandSupported) { + continue; + } + + if (kTest.initFunc) { + kTest.initFunc(); + } + + let beforeinput = null; + function onBeforeinput(event) { + beforeinput = event; + } + window.addEventListener("beforeinput", onBeforeinput, {capture: true}); + let input = null; + function onInput(event) { + input = event; + } + window.addEventListener("input", onInput, {capture: true}); + let ret; + test(function () { + ret = document.execCommand(kTest.command, false, kTest.param); + assert_equals(ret, kTest.expectedExecCommandResult); + }, `${kDescription}: execCommand() should return ${kTest.expectedExecCommandResult}`); + test(function () { + let value = aTarget.value.substring(0, aTarget.selectionStart) + + "[" + + aTarget.value.substring(aTarget.selectionStart, aTarget.selectionEnd) + + "]" + + aTarget.value.substring(aTarget.selectionEnd); + assert_equals(value, kTest.expectedValue); + }, `${kDescription}: ${kIsTextArea ? "<textarea>" : "<input>"}.value should be "${kTest.expectedValue}"`); + test(function () { + assert_equals(beforeinput?.inputType, kTest.beforeinputExpected?.inputType); + }, `${kDescription}: beforeinput.inputType should be ${kTest.beforeinputExpected?.inputType}`); + test(function () { + assert_equals(beforeinput?.target, kTest.beforeinputExpected?.target); + }, `${kDescription}: beforeinput.target should be ${kTest.beforeinputExpected?.target}`); + test(function () { + assert_equals(input?.inputType, kTest.inputExpected?.inputType); + }, `${kDescription}: input.inputType should be ${kTest.inputExpected?.inputType}`); + test(function () { + assert_equals(input?.target, kTest.inputExpected?.target); + }, `${kDescription}: input.target should be ${kTest.inputExpected?.target}`); + if (kTest.additionalCheckFunc) { + kTest.additionalCheckFunc(kDescription); + } + window.removeEventListener("beforeinput", onBeforeinput, {capture: true}); + window.removeEventListener("input", onInput, {capture: true}); + } +} + +window.addEventListener("load", runTests, {once: true}); +</script> diff --git a/testing/web-platform/tests/editing/other/exec-command-without-editable-element.tentative.html b/testing/web-platform/tests/editing/other/exec-command-without-editable-element.tentative.html new file mode 100644 index 0000000000..0547140306 --- /dev/null +++ b/testing/web-platform/tests/editing/other/exec-command-without-editable-element.tentative.html @@ -0,0 +1,526 @@ +<!doctype html> +<meta charset=utf-8> +<title>Test that execCommand without editable element</title> +<script src=../include/implementation.js></script> +<script>var testsJsLibraryOnly = true</script> +<script src=../include/tests.js></script> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script> +"use strict"; + +setup({explicit_done: true}); + +// This test calls execCommand() without editable element in the document, +// but its parent or child document has editable element and it has focus. +// In most cases, execCommand() should do nothing and return false. However, +// "cut", "copy", "paste" and "selectall" commands should work without DOM tree +// modification for making web apps can implement their own editor without +// editable element. +async function runTests() { + let parentWindow = window; + let parentDocument = document; + let parentSelection = parentDocument.getSelection(); + let parentEditor = parentDocument.getElementById("editor"); + parentEditor.focus(); + let iframe = document.getElementsByTagName("iframe")[0]; + let childWindow = iframe.contentWindow; + let childDocument = iframe.contentDocument; + let childSelection = childDocument.getSelection(); + let childEditor = childDocument.getElementById("editor"); + childEditor.focus(); + + // execCommand() in child document shouldn't affect to focused parent + // document. + await doTest(parentWindow, parentDocument, parentSelection, parentEditor, + childWindow, childDocument, childSelection, childEditor, false); + // execCommand() in parent document shouldn't affect to focused child + // document but "cut" and "copy" may affect the focused child document. + await doTest(childWindow, childDocument, childSelection, childEditor, + parentWindow, parentDocument, parentSelection, parentEditor, true); + + done(); +} + +async function doTest(aFocusWindow, aFocusDocument, aFocusSelection, aFocusEditor, + aExecWindow, aExecDocument, aExecSelection, aExecEditor, + aExecInParent) { + const kTests = [ + /** + * command: The command which you test. + * focusContent: Will be set to innerHTML of div#editor element in focused + * document. + * execContent: Will be set to innerHTML of div#editor element in the + * document whose execCommand() will be called. + * initFunc: [optional] If you need to do something before running the + * test, you can do it with a function. + * expectedFocusContent: Expected content and selection in div#editor in + * focused document after calling execCommand(). + * expectedExecContent: Expected content and selection in div#editor in + * the document whose execCommand() is called. + * event: The event which you need to check whether it's fired or not. + * expectedFiredInFocus: true if the event should be fired on the focused + * document node. + * expectedFiredInExec: true if the event should be fired on the document + * node whose execCommand() is called. + * expectedResult: Expected result of execCommand(). + */ + {command: "bold", value: "bold", + focusContent: "a[b]c", execContent: "a[b]c", + expectedFocusContent: "a[b]c", expectedExecContent: "a[b]c", + event: "input", expectedFiredInFocus: false, expectedFiredInExec: false, + expectedResult: false, + }, + {command: "italic", value: null, + focusContent: "a[b]c", execContent: "a[b]c", + expectedFocusContent: "a[b]c", expectedExecContent: "a[b]c", + event: "input", expectedFiredInFocus: false, expectedFiredInExec: false, + expectedResult: false, + }, + {command: "underline", value: null, + focusContent: "a[b]c", execContent: "a[b]c", + expectedFocusContent: "a[b]c", expectedExecContent: "a[b]c", + event: "input", expectedFiredInFocus: false, expectedFiredInExec: false, + expectedResult: false, + }, + {command: "strikethrough", value: null, + focusContent: "a[b]c", execContent: "a[b]c", + expectedFocusContent: "a[b]c", expectedExecContent: "a[b]c", + event: "input", expectedFiredInFocus: false, expectedFiredInExec: false, + expectedResult: false, + }, + {command: "subscript", value: null, + focusContent: "a[b]c", execContent: "a[b]c", + expectedFocusContent: "a[b]c", expectedExecContent: "a[b]c", + event: "input", expectedFiredInFocus: false, expectedFiredInExec: false, + expectedResult: false, + }, + {command: "superscript", value: null, + focusContent: "a[b]c", execContent: "a[b]c", + expectedFocusContent: "a[b]c", expectedExecContent: "a[b]c", + event: "input", expectedFiredInFocus: false, expectedFiredInExec: false, + expectedResult: false, + }, + // "cut", "copy" and "paste" command should cause firing corresponding + // events to make web apps be able to implement their own editor even + // if there is no editor and selection is collapsed. + {command: "cut", value: null, + focusContent: "a[b]c", execContent: "ab[]c", + expectedFocusContent: "a[b]c", expectedExecContent: "ab[]c", + event: "cut", expectedFiredInFocus: false, expectedFiredInExec: true, + expectedResult: false, + }, + {command: "cut", value: null, + focusContent: "a[b]c", execContent: "a[b]c", + expectedFocusContent: "a[b]c", expectedExecContent: "a[b]c", + event: "cut", expectedFiredInFocus: false, expectedFiredInExec: true, + expectedResult: false, + }, + {command: "copy", value: null, + focusContent: "a[b]c", execContent: "ab[]c", + expectedFocusContent: "a[b]c", expectedExecContent: "ab[]c", + event: "copy", expectedFiredInFocus: false, expectedFiredInExec: true, + expectedResult: false, + }, + {command: "copy", value: null, + focusContent: "a[b]c", execContent: "a[b]c", + expectedFocusContent: "a[b]c", expectedExecContent: "a[b]c", + event: "copy", expectedFiredInFocus: false, expectedFiredInExec: true, + expectedResult: false, + }, + {command: "paste", value: null, + focusContent: "a[b]c", execContent: "a[b]c", + expectedFocusContent: "a[b]c", expectedExecContent: "a[b]c", + initFunc: () => { aFocusDocument.execCommand("copy", false, "b"); }, + event: "paste", expectedFiredInFocus: false, expectedFiredInExec: true, + expectedResult: false, + }, + {command: "delete", value: null, + focusContent: "a[b]c", execContent: "a[b]c", + expectedFocusContent: "a[b]c", expectedExecContent: "a[b]c", + event: "input", expectedFiredInFocus: false, expectedFiredInExec: false, + expectedResult: false, + }, + {command: "forwarddelete", value: null, + focusContent: "a[b]c", execContent: "a[b]c", + expectedFocusContent: "a[b]c", expectedExecContent: "a[b]c", + event: "input", expectedFiredInFocus: false, expectedFiredInExec: false, + expectedResult: false, + }, + // "selectall" command should be available without editable content. + {command: "selectall", value: null, + focusContent: "a[b]c", execContent: "a[b]c", + expectedFocusContent: "a[b]c", expectedExecContent: undefined, + event: "selectionchange", expectedFiredInFocus: false, expectedFiredInExec: true, + expectedResult: true, + }, + {command: "undo", value: null, + focusContent: "a[]c", execContent: "a[b]c", + initFunc: () => { aFocusDocument.execCommand("insertText", false, "b"); }, + expectedFocusContent: "ab[]c", expectedExecContent: "a[b]c", + event: "input", expectedFiredInFocus: false, expectedFiredInExec: false, + expectedResult: false, + }, + {command: "redo", value: null, + focusContent: "a[]c", execContent: "a[b]c", + initFunc: () => { + aFocusDocument.execCommand("insertText", false, "b"); + aFocusDocument.execCommand("undo", false, null); + }, + expectedFocusContent: "a[]c", expectedExecContent: "a[b]c", + event: "input", expectedFiredInFocus: false, expectedFiredInExec: false, + expectedResult: false, + }, + {command: "indent", value: null, + focusContent: "a[b]c", execContent: "a[b]c", + expectedFocusContent: "a[b]c", expectedExecContent: "a[b]c", + event: "input", expectedFiredInFocus: false, expectedFiredInExec: false, + expectedResult: false, + }, + {command: "outdent", value: null, + focusContent: "a[b]c", execContent: "a[b]c", + expectedFocusContent: "a[b]c", expectedExecContent: "a[b]c", + event: "input", expectedFiredInFocus: false, expectedFiredInExec: false, + expectedResult: false, + }, + {command: "backcolor", value: "#000000", + focusContent: "a[b]c", execContent: "a[b]c", + expectedFocusContent: "a[b]c", expectedExecContent: "a[b]c", + event: "input", expectedFiredInFocus: false, expectedFiredInExec: false, + expectedResult: false, + }, + {command: "forecolor", value: "#F0F0F0", + focusContent: "a[b]c", execContent: "a[b]c", + expectedFocusContent: "a[b]c", expectedExecContent: "a[b]c", + event: "input", expectedFiredInFocus: false, expectedFiredInExec: false, + expectedResult: false, + }, + {command: "hilitecolor", value: "#FFFF00", + focusContent: "a[b]c", execContent: "a[b]c", + expectedFocusContent: "a[b]c", expectedExecContent: "a[b]c", + event: "input", expectedFiredInFocus: false, expectedFiredInExec: false, + expectedResult: false, + }, + {command: "fontname", value: "DummyFont", + focusContent: "a[b]c", execContent: "a[b]c", + expectedFocusContent: "a[b]c", expectedExecContent: "a[b]c", + event: "input", expectedFiredInFocus: false, expectedFiredInExec: false, + expectedResult: false, + }, + {command: "fontsize", value: "5", + focusContent: "a[b]c", execContent: "a[b]c", + expectedFocusContent: "a[b]c", expectedExecContent: "a[b]c", + event: "input", expectedFiredInFocus: false, expectedFiredInExec: false, + expectedResult: false, + }, + {command: "increasefontsize", value: null, + focusContent: "a[b]c", execContent: "a[b]c", + expectedFocusContent: "a[b]c", expectedExecContent: "a[b]c", + event: "input", expectedFiredInFocus: false, expectedFiredInExec: false, + expectedResult: false, + }, + {command: "decreasefontsize", value: null, + focusContent: "a[b]c", execContent: "a[b]c", + expectedFocusContent: "a[b]c", expectedExecContent: "a[b]c", + event: "input", expectedFiredInFocus: false, expectedFiredInExec: false, + expectedResult: false, + }, + {command: "inserthorizontalrule", value: null, + focusContent: "a[]bc", execContent: "a[]bc", + expectedFocusContent: "a[]bc", expectedExecContent: "a[]bc", + event: "input", expectedFiredInFocus: false, expectedFiredInExec: false, + expectedResult: false, + }, + {command: "createlink", value: "foo.html", + focusContent: "a[b]c", execContent: "a[b]c", + expectedFocusContent: "a[b]c", expectedExecContent: "a[b]c", + event: "input", expectedFiredInFocus: false, expectedFiredInExec: false, + expectedResult: false, + }, + {command: "insertimage", value: "no-image.png", + focusContent: "a[b]c", execContent: "a[b]c", + expectedFocusContent: "a[b]c", expectedExecContent: "a[b]c", + event: "input", expectedFiredInFocus: false, expectedFiredInExec: false, + expectedResult: false, + }, + {command: "inserthtml", value: "<b>inserted</b>", + focusContent: "a[b]c", execContent: "a[b]c", + expectedFocusContent: "a[b]c", expectedExecContent: "a[b]c", + event: "input", expectedFiredInFocus: false, expectedFiredInExec: false, + expectedResult: false, + }, + {command: "inserttext", value: "**inserted**", + focusContent: "a[b]c", execContent: "a[b]c", + expectedFocusContent: "a[b]c", expectedExecContent: "a[b]c", + event: "input", expectedFiredInFocus: false, expectedFiredInExec: false, + expectedResult: false, + }, + {command: "justifyleft", value: null, + focusContent: "a[b]c", execContent: "a[b]c", + expectedFocusContent: "a[b]c", expectedExecContent: "a[b]c", + event: "input", expectedFiredInFocus: false, expectedFiredInExec: false, + expectedResult: false, + }, + {command: "justifyright", value: null, + focusContent: "a[b]c", execContent: "a[b]c", + expectedFocusContent: "a[b]c", expectedExecContent: "a[b]c", + event: "input", expectedFiredInFocus: false, expectedFiredInExec: false, + expectedResult: false, + }, + {command: "justifycenter", value: null, + focusContent: "a[b]c", execContent: "a[b]c", + expectedFocusContent: "a[b]c", expectedExecContent: "a[b]c", + event: "input", expectedFiredInFocus: false, expectedFiredInExec: false, + expectedResult: false, + }, + {command: "justifyfull", value: null, + focusContent: "a[b]c", execContent: "a[b]c", + expectedFocusContent: "a[b]c", expectedExecContent: "a[b]c", + event: "input", expectedFiredInFocus: false, expectedFiredInExec: false, + expectedResult: false, + }, + {command: "removeformat", value: null, + focusContent: "<b>a[b]c</b>", execContent: "<b>a[b]c</b>", + expectedFocusContent: "<b>a[b]c</b>", expectedExecContent: "<b>a[b]c</b>", + event: "input", expectedFiredInFocus: false, expectedFiredInExec: false, + expectedResult: false, + }, + {command: "unlink", value: null, + focusContent: "<a href=\"foo.html\">a[b]c</a>", execContent: "<a href=\"foo.html\">a[b]c</a>", + expectedFocusContent: "<a href=\"foo.html\">a[b]c</a>", expectedExecContent: "<a href=\"foo.html\">a[b]c</a>", + event: "input", expectedFiredInFocus: false, expectedFiredInExec: false, + expectedResult: false, + }, + {command: "insertorderedlist", value: null, + focusContent: "a[b]c", execContent: "a[b]c", + expectedFocusContent: "a[b]c", expectedExecContent: "a[b]c", + event: "input", expectedFiredInFocus: false, expectedFiredInExec: false, + expectedResult: false, + }, + {command: "insertunorderedlist", value: null, + focusContent: "a[b]c", execContent: "a[b]c", + expectedFocusContent: "a[b]c", expectedExecContent: "a[b]c", + event: "input", expectedFiredInFocus: false, expectedFiredInExec: false, + expectedResult: false, + }, + {command: "insertparagraph", value: null, + focusContent: "a[b]c", execContent: "a[b]c", + expectedFocusContent: "a[b]c", expectedExecContent: "a[b]c", + event: "input", expectedFiredInFocus: false, expectedFiredInExec: false, + expectedResult: false, + }, + {command: "insertlinebreak", value: null, + focusContent: "a[b]c", execContent: "a[b]c", + expectedFocusContent: "a[b]c", expectedExecContent: "a[b]c", + event: "input", expectedFiredInFocus: false, expectedFiredInExec: false, + expectedResult: false, + }, + {command: "formatblock", value: "div", + focusContent: "a[b]c", execContent: "a[b]c", + expectedFocusContent: "a[b]c", expectedExecContent: "a[b]c", + event: "input", expectedFiredInFocus: false, expectedFiredInExec: false, + expectedResult: false, + }, + {command: "heading", value: "h1", + focusContent: "a[b]c", execContent: "a[b]c", + expectedFocusContent: "a[b]c", expectedExecContent: "a[b]c", + event: "input", expectedFiredInFocus: false, expectedFiredInExec: false, + expectedResult: false, + }, + /** + * command: The command which you test. + * state: The state which is used with execCommand(). + * initState: The state which should be set with execCommand() first. + * focusContent: Will be set to innerHTML of div#editor element in focused + * document. + * execContent: Will be set to innerHTML of div#editor element in the + * document whose execCommand() will be called. + * initFunc: [optional] If you need to do something before running the + * test, you can do it with a function. + * expectedSetStateInFocus: Expected queryCommandState() result in focused + * document. + * expectedSetStateInExec: Expected queryCommandState() result in document + * whose execCommand() is called. + * expectedResult: Expected result of execCommand(). + */ + {command: "styleWithCSS", state: "true", initState: "false", + focusContent: "a[b]c", execContent: "a[b]c", + expectedSetStateInFocus: false, expectedSetStateInExec: false, + expectedResult: false, + }, + {command: "contentReadOnly", state: "true", initState: "false", + focusContent: "a[b]c", execContent: "a[b]c", + expectedSetStateInFocus: false, expectedSetStateInExec: false, + expectedResult: false, + }, + {command: "insertBrOnReturn", state: "true", initState: "false", + focusContent: "a[b]c", execContent: "a[b]c", + expectedSetStateInFocus: false, expectedSetStateInExec: false, + expectedResult: false, + }, + {command: "defaultParagraphSeparator", state: "div", initState: "p", + focusContent: "a[b]c", execContent: "a[b]c", + expectedSetStateInFocus: false, expectedSetStateInExec: false, + expectedResult: false, + }, + {command: "defaultParagraphSeparator", state: "p", initState: "div", + focusContent: "a[b]c", execContent: "a[b]c", + expectedSetStateInFocus: false, expectedSetStateInExec: false, + expectedResult: false, + }, + {command: "enableObjectResizing", state: "true", initState: "false", + focusContent: "a[b]c", execContent: "a[b]c", + expectedSetStateInFocus: false, expectedSetStateInExec: false, + expectedResult: false, + }, + {command: "enableInlineTableEditing", state: "true", initState: "false", + focusContent: "a[b]c", execContent: "a[b]c", + expectedSetStateInFocus: false, expectedSetStateInExec: false, + expectedResult: false, + }, + {command: "enableAbsolutePositionEditing", state: "true", initState: "false", + focusContent: "a[b]c", execContent: "a[b]c", + expectedSetStateInFocus: false, expectedSetStateInExec: false, + expectedResult: false, + }, + ]; + + async function waitForCondition(aCheckFunc) { + let retry = 60; + while (retry--) { + if (aCheckFunc()) { + return; + } + await new Promise(resolve => requestAnimationFrame(resolve)); + } + } + + for (const kTest of kTests) { + // Skip unsupported command since it's not purpose of this tests whether + // each command is supported on the browser. + if (!aExecDocument.queryCommandSupported(kTest.command)) { + continue; + } + aExecEditor.removeAttribute("contenteditable"); // Disable commands in the exec document. + let points = setupDiv(aFocusEditor, kTest.focusContent); + aFocusSelection.setBaseAndExtent(points[0], points[1], points[2], points[3]); + points = setupDiv(aExecEditor, kTest.execContent); + aExecSelection.setBaseAndExtent(points[0], points[1], points[2], points[3]); + aFocusWindow.focus(); + aFocusEditor.focus(); + if (kTest.initFunc) { + kTest.initFunc(); + } + if (kTest.state === undefined) { + let eventFiredOnFocusDocument = false; + function handlerOnFocusDocument() { + eventFiredOnFocusDocument = true; + } + aFocusDocument.addEventListener(kTest.event, handlerOnFocusDocument, {capture: true}); + let eventFiredOnExecDocument = false; + function handlerOnExecDocument() { + eventFiredOnExecDocument = true; + } + aExecDocument.addEventListener(kTest.event, handlerOnExecDocument, {capture: true}); + const kDescription = `${aExecInParent ? "Parent" : "Child"}Document.execCommand(${kTest.command}, false, ${kTest.value}) with ${kTest.execContent}`; + test(function () { + let ret = aExecDocument.execCommand(kTest.command, false, kTest.value); + assert_equals(ret, kTest.expectedResult, `execCommand should return ${kTest.expectedResult}`); + }, `${kDescription}: calling execCommand`); + if (kTest.event === "selectionchange") { + test(function () { + assert_false(eventFiredOnFocusDocument, + `"${kTest.event}" event should not be fired synchronously on focused document`); + assert_false(eventFiredOnExecDocument, + `"${kTest.event}" event should not be fired synchronously on executed document`); + }, `${kDescription}: checking unexpected synchronous event`); + await waitForCondition(() => eventFiredOnFocusDocument && eventFiredOnExecDocument); + // TODO: Whether select all changes selection in the focused document depends on the + // implementation of "Select All". + } else { + test(function () { + assert_equals(eventFiredOnFocusDocument, kTest.expectedFiredInFocus, + `"${kTest.event}" event should${kTest.expectedFiredInFocus ? "" : " not"} be fired`); + }, `${kDescription}: checking event on focused document`); + } + test(function () { + assert_equals(eventFiredOnExecDocument, kTest.expectedFiredInExec, + `"${kTest.event}" event should${kTest.expectedFiredInExec ? "" : " not"} be fired`); + }, `${kDescription}: checking event on executed document`); + test(function () { + if (aFocusSelection.rangeCount) { + addBrackets(aFocusSelection.getRangeAt(0)); + } + assert_equals(aFocusEditor.innerHTML, kTest.expectedFocusContent); + }, `${kDescription}: checking result content in focused document`); + test(function () { + if (kTest.command === "selectall") { + assert_true(aExecSelection.rangeCount > 0); + assert_equals( + aExecSelection.toString().replace(/[\r\n]/g, ""), + aExecDocument.body.textContent.replace(/[\r\n]/g, "") + ); + } else { + if (aExecSelection.rangeCount) { + addBrackets(aExecSelection.getRangeAt(0)); + } + assert_equals(aExecEditor.innerHTML, kTest.expectedExecContent); + } + }, `${kDescription}: checking result content in executed document`); + aFocusDocument.removeEventListener(kTest.event, handlerOnFocusDocument, {capture: true}); + aExecDocument.removeEventListener(kTest.event, handlerOnExecDocument, {capture: true}); + aExecEditor.setAttribute("contenteditable", ""); + } else { + const kDescription = `${aExecInParent ? "Parent" : "Child"}Document.execCommand(${kTest.command}, false, ${kTest.state})`; + test(function () { + let ret = aExecDocument.execCommand(kTest.command, false, kTest.initState); + assert_equals(ret, kTest.expectedResult, `execCommand should return ${kTest.expectedResult}`); + }, `${kDescription}: calling execCommand to initialize`); + let hasSetState = false; + test(function () { + hasSetState = aExecDocument.queryCommandState(kTest.command); + assert_equals(hasSetState, kTest.expectedSetStateInExec, `queryCommandState on executed document should return ${kTest.expectedSetState}`); + }, `${kDescription}: calling queryCommandState on executed document after initializing`); + test(function () { + let ret = aFocusDocument.queryCommandState(kTest.command); + assert_equals(ret, kTest.expectedSetStateInFocus, `queryCommandState on focus document should return ${kTest.expectedSetState}`); + }, `${kDescription}: calling queryCommandState on focus document after initializing`); + if (hasSetState) { + test(function () { + let ret = aExecDocument.queryCommandValue(kTest.command); + assert_equals(ret, kTest.initState, `queryCommandValue on executed document should return ${kTest.initState}`); + }, `${kDescription}: calling queryCommandValue on executed document after initializing`); + } + test(function () { + let ret = aExecDocument.execCommand(kTest.command, false, kTest.state); + assert_equals(ret, kTest.expectedResult, `execCommand should return ${kTest.expectedResult}`); + }, `${kDescription}: calling execCommand to set state`); + test(function () { + hasSetState = aExecDocument.queryCommandState(kTest.command); + assert_equals(hasSetState, kTest.expectedSetStateInExec, `queryCommandState should return ${kTest.expectedSetState}`); + }, `${kDescription}: calling queryCommandState on executed document`); + test(function () { + let ret = aFocusDocument.queryCommandState(kTest.command); + assert_equals(ret, kTest.expectedSetStateInFocus, `queryCommandState should return ${kTest.expectedSetState}`); + }, `${kDescription}: calling queryCommandState on focused document`); + if (hasSetState) { + test(function () { + let ret = aExecDocument.queryCommandValue(kTest.command); + assert_equals(ret, kTest.state, `queryCommandValue should return ${kTest.initState}`); + }, `${kDescription}: calling queryCommandValue on executed document`); + } + aExecEditor.setAttribute("contenteditable", ""); + test(function () { + let ret = aExecDocument.queryCommandState(kTest.command); + assert_equals(ret, kTest.expectedSetStateInExec, `queryCommandState should return ${kTest.expectedSetState}`); + }, `${kDescription}: calling queryCommandState on executed document after making executed document editable`); + } + } +} + +window.addEventListener("load", runTests, {once: true}); +</script> +<body> +<div contenteditable id="editor">abc</div> +<iframe srcdoc="<div contenteditable id='editor'>def</div><span>ghi</span>"></iframe> +</body> diff --git a/testing/web-platform/tests/editing/other/extra-text-nodes.html b/testing/web-platform/tests/editing/other/extra-text-nodes.html new file mode 100644 index 0000000000..2cd1232d00 --- /dev/null +++ b/testing/web-platform/tests/editing/other/extra-text-nodes.html @@ -0,0 +1,43 @@ +<!doctype html> +<meta charset=utf-8> +<title>Editor should not create unnecessary text nodes</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<div contenteditable></div> +<script> +var div = document.querySelector("div"); +var walker = document.createTreeWalker(div, NodeFilter.SHOW_TEXT); +function testInput(html, callback, desc) { + test(() => { + div.innerHTML = html; + div.focus(); + callback(); + + walker.currentNode = walker.root; + var node; + while (node = walker.nextNode()) { + if (node.nextSibling) { + assert_not_equals(node.nextSibling.nodeType, Node.TEXT_NODE, + 'text node "' + node.nodeValue + '" is next to "' + + node.nextSibling.nodeValue + '"'); + } + } + }, desc); +} + +[ + ['<img src="#">foo<img src="#">', + () => { + getSelection().collapse(div, 1); + document.execCommand("inserttext", false, "x"); + }, + "Simple insertText"], + ['<p>editor</p>', + () => { + getSelection().collapse(div.firstChild.firstChild, 3); + document.execCommand("insertlinebreak", false, ""); + document.execCommand("inserttext", false, "x"); + }, + "insertText after insertLineBreak"], +].forEach(([a, b, c]) => testInput(a, b, c)); +</script> diff --git a/testing/web-platform/tests/editing/other/formatblock-preserving-selection.tentative.html b/testing/web-platform/tests/editing/other/formatblock-preserving-selection.tentative.html new file mode 100644 index 0000000000..d10e80b4ea --- /dev/null +++ b/testing/web-platform/tests/editing/other/formatblock-preserving-selection.tentative.html @@ -0,0 +1,136 @@ +<!doctype html> +<html> +<head> +<meta chareset="utf-8"> +<meta name="timeout" content="long"> +<meta name="variant" content="?styleWithCSS=false&block=address"> +<meta name="variant" content="?styleWithCSS=false&block=article"> +<meta name="variant" content="?styleWithCSS=false&block=blockquote"> +<meta name="variant" content="?styleWithCSS=false&block=dd"> +<meta name="variant" content="?styleWithCSS=false&block=div"> +<meta name="variant" content="?styleWithCSS=false&block=dt"> +<meta name="variant" content="?styleWithCSS=false&block=h1"> +<meta name="variant" content="?styleWithCSS=false&block=li"> +<meta name="variant" content="?styleWithCSS=false&block=pre"> +<meta name="variant" content="?styleWithCSS=true&block=address"> +<meta name="variant" content="?styleWithCSS=true&block=article"> +<meta name="variant" content="?styleWithCSS=true&block=blockquote"> +<meta name="variant" content="?styleWithCSS=true&block=dd"> +<meta name="variant" content="?styleWithCSS=true&block=div"> +<meta name="variant" content="?styleWithCSS=true&block=dt"> +<meta name="variant" content="?styleWithCSS=true&block=h1"> +<meta name="variant" content="?styleWithCSS=true&block=li"> +<meta name="variant" content="?styleWithCSS=true&block=pre"> +<title>Test preserving selection after formatBlock</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script src="../include/editor-test-utils.js"></script> +</head> +<body> +<div contenteditable></div> +<script> +"use strict"; + +const editor = document.querySelector("div[contenteditable]"); +const utils = new EditorTestUtils(editor); +const searchParams = new URLSearchParams(document.location.search); +const styleWithCSS = searchParams.get("styleWithCSS"); +const block = searchParams.get("block"); +document.execCommand("styleWithCSS", false, styleWithCSS); + +// Note that it's not scope of this test how browsers to convert the selected +// content to a block. + +// html: Initial HTML which will be set editor.innerHTML, it should contain +// selection range with a pair of "[" or "{" and "]" or "}". +// expectedSelectedString: After executing "outdent", compared with +// getSelection().toString().replace(/[ \n\r\t]+/g, "") +const tests = [ + { + html: "a[b]c", + expectedSelectedString: "b", + }, + { + html: "a[bc<br>de]f", + expectedSelectedString: "bcde", + }, + { + html: "<div>a[b]c</div>", + expectedSelectedString: "b", + }, + { + html: "<div>a[bc</div><div>de]f</div>", + expectedSelectedString: "bcde", + }, + { + html: "<div>a[bc<br>de]f</div>", + expectedSelectedString: "bcde", + }, + { + html: "<ul><li>a[b]c</li></ul>", + expectedSelectedString: "b", + }, + { + html: "<ul><li>a[bc</li><li>de]f</li></ul>", + expectedSelectedString: "bcde", + }, + { + html: "<ul><li>a[bc</li><li>de]f</li><li>ghi</li></ul>", + expectedSelectedString: "bcde", + }, + { + html: "<ul><li>abc</li><li>d[ef</li><li>gh]i</li></ul>", + expectedSelectedString: "efgh", + }, + { + html: "<ul><li>abc</li><li>d[ef</li></ul>" + + "<div>gh]i</div>", + expectedSelectedString: "efgh", + }, + { + html: "<div>a[bc</div>" + + "<ul><li>de]f</li><li>ghi</li></ul>", + expectedSelectedString: "bcde", + }, + { + html: "<table><tr><td>a[b]c</td></tr></table>", + expectedSelectedString: "b", + }, + { + html: "<table><tr><td>a[bc</td><td>de]f</td></tr></table>", + expectedSelectedString: "bcde", + }, + { + html: "<table><tr><td>a[bc</td></tr><tr><td>de]f</td></tr></table>", + expectedSelectedString: "bcde", + }, + { + html: "<div>a[bc</div>" + + "<table><tr><td>de]f</td></tr></table>", + expectedSelectedString: "bcde", + }, + { + html: "<table><tr><td>a[bc</td></tr></table>" + + "<div>de]f</div>", + expectedSelectedString: "bcde", + }, +]; + +for (const t of tests) { + test(() => { + utils.setupEditingHost(t.html); + document.execCommand("formatblock", false, block); + assert_equals( + getSelection().toString().replace(/[ \n\r\t]+/g, ""), + t.expectedSelectedString, + `Result: ${editor.innerHTML}` + ); + }, `Preserve selection after formatBlock with ${block} at ${t.html}`); +} + +</script> +</body> +</html> diff --git a/testing/web-platform/tests/editing/other/indent-preserving-selection.tentative.html b/testing/web-platform/tests/editing/other/indent-preserving-selection.tentative.html new file mode 100644 index 0000000000..b3fae41faf --- /dev/null +++ b/testing/web-platform/tests/editing/other/indent-preserving-selection.tentative.html @@ -0,0 +1,103 @@ +<!doctype html> +<html> +<head> +<meta chareset="utf-8"> +<meta name="timeout" content="long"> +<meta name="variant" content="?styleWithCSS=false"> +<meta name="variant" content="?styleWithCSS=true"> +<title>Test preserving selection after indent</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script src="../include/editor-test-utils.js"></script> +</head> +<body> +<div contenteditable></div> +<script> +"use strict"; + +const editor = document.querySelector("div[contenteditable]"); +const utils = new EditorTestUtils(editor); +const styleWithCSS = + new URLSearchParams(document.location.search).get("styleWithCSS"); +document.execCommand("styleWithCSS", false, styleWithCSS); + +// Note that it's not scope of this test how browsers to indent the selected +// content. + +// html: Initial HTML which will be set editor.innerHTML, it should contain +// selection range with a pair of "[" or "{" and "]" or "}". +// expectedSelectedString: After executing "indent", compared with +// getSelection().toString().replace(/[ \n\r]+/g, "") +const tests = [ + { + html: "<div>a[b]c</div>", + expectedSelectedString: "b", + }, + { + html: "<div>a[bc</div><div>de]f</div>", + expectedSelectedString: "bcde", + }, + { + html: "<ul><li>a[b]c</li></ul>", + expectedSelectedString: "b", + }, + { + html: "<ul><li>a[bc</li><li>de]f</li></ul>", + expectedSelectedString: "bcde", + }, + { + html: "<div>a[bc</div>" + + "<ul><li>de]f</li></ul>", + expectedSelectedString: "bcde", + }, + { + html: "<ul><li>a[bc</li></ul>" + + "<ul><li>de]f</li></ul>", + expectedSelectedString: "bcde", + }, + { + html: "<ul><li>abc</li><li>d[ef</li></ul>" + + "<ul><li>gh]i</li></ul>", + expectedSelectedString: "efgh", + }, + { + html: "<ul><li>abc</li><li>d[ef</li></ul>" + + "<ul><li>gh]i</li><li>jkl</li></ul>", + expectedSelectedString: "efgh", + }, + { + html: "<ul><ul><li>a[bc</li></ul><li>de]f</li></ul>", + expectedSelectedString: "bcde", + }, + { + html: "<ol><ul><li>a[bc</li></ul><li>de]f</li></ol>", + expectedSelectedString: "bcde", + }, + { + html: "<ul><li>a[bc</li><ul><li>de]f</li></ul></ul>", + expectedSelectedString: "bcde", + }, + { + html: "<ol><li>a[bc</li><ul><li>de]f</li></ul></ol>", + expectedSelectedString: "bcde", + }, +]; + +for (const t of tests) { + test(() => { + utils.setupEditingHost(t.html); + document.execCommand("indent"); + assert_equals( + getSelection().toString().replace(/[ \n\r]+/g, ""), + t.expectedSelectedString, + `Result: ${editor.innerHTML}` + ); + }, `Preserve selection after indent at ${t.html}`); +} + +</script> +</body> +</html> diff --git a/testing/web-platform/tests/editing/other/input-in-text-control-which-is-also-editing-host.tentative.html b/testing/web-platform/tests/editing/other/input-in-text-control-which-is-also-editing-host.tentative.html new file mode 100644 index 0000000000..1ca22b6730 --- /dev/null +++ b/testing/web-platform/tests/editing/other/input-in-text-control-which-is-also-editing-host.tentative.html @@ -0,0 +1,184 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<meta name="timeout" content="long"> +<meta name="variant" content="?textcontrol=text"> +<meta name="variant" content="?textcontrol=password"> +<meta name="variant" content="?textcontrol=textarea"> +<title>Check whether a text control element handles user input when it's an editing host</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/resources/testdriver-actions.js"></script> +</head> +<body> +<div></div> +<script> +const searchParams = new URLSearchParams(document.location.search); +const textControlType = searchParams.get("textcontrol"); +const textControlDescription = + textControlType == "textarea" + ? "<textarea contenteditable>" + : `<input type="${textControlType}" contenteditable>`; +const div = document.querySelector("div"); + +function createTextControl() { + const textControl = document.createElement( + textControlType == "textarea" ? "textarea" : "input" + ); + if (textControlType != "textarea") { + textControl.type = textControlType; + } + return textControl; +} + +promise_test(async t => { + const textControl = createTextControl(); + div.appendChild(textControl); + textControl.setAttribute("contenteditable", ""); + textControl.focus(); + await (new test_driver.Actions() + .keyDown("a") + .keyUp("a") + .keyDown("b") + .keyUp("b") + .keyDown("c") + .keyUp("c") + .send()); + assert_equals( + textControl.value, + "abc", + `${t.name}: The text control value should be updated` + ); + assert_equals( + document.querySelector("div").textContent.trim(), + "", + `${t.name}: No text should be inserted as a child of the text control` + ); + textControl.remove(); +}, `User typing in ${textControlDescription} should update the value`); + +promise_test(async t => { + const textControl = createTextControl(); + div.appendChild(textControl); + textControl.setAttribute("contenteditable", ""); + textControl.focus(); + document.execCommand("insertText", false, "abc"); + assert_equals( + textControl.value, + "abc", + `${t.name}: The text control value should be updated` + ); + assert_equals( + div.textContent.trim(), + "", + `${t.name}: No text should be inserted as a child of the text control` + ); + textControl.remove(); +}, `execCommand("insertText") in ${textControlDescription} should update the value`); + +promise_test(async t => { + const textControl = createTextControl(); + div.appendChild(textControl); + textControl.focus(); + textControl.setAttribute("contenteditable", ""); + await (new test_driver.Actions() + .keyDown("a") + .keyUp("a") + .keyDown("b") + .keyUp("b") + .keyDown("c") + .keyUp("c") + .send()); + assert_equals( + textControl.value, + "abc", + `${t.name}: The text control value should be updated` + ); + assert_equals( + div.textContent.trim(), + "", + `${t.name}: No text should be inserted as a child of the text control` + ); + textControl.remove(); +}, `User typing in ${textControlDescription} should update the value (became an editing host during focused)`); + +promise_test(async t => { + const textControl = createTextControl(); + div.appendChild(textControl); + textControl.focus(); + textControl.setAttribute("contenteditable", ""); + document.execCommand("insertText", false, "abc"); + assert_equals( + textControl.value, + "abc", + `${t.name}: The text control value should be updated` + ); + assert_equals( + div.textContent.trim(), + "", + `${t.name}: No text should be inserted as a child of the text control` + ); + textControl.remove(); +}, `execCommand("insertText") in ${textControlDescription} should update the value (became an editing host during focused)`); + +if (textControlType != "textarea") { + promise_test(async t => { + const textControl = createTextControl(); + textControl.type = "button"; + div.appendChild(textControl); + textControl.setAttribute("contenteditable", ""); + textControl.focus(); + textControl.type = textControlType; + await (new test_driver.Actions() + .keyDown("a") + .keyUp("a") + .keyDown("b") + .keyUp("b") + .keyDown("c") + .keyUp("c") + .send()); + assert_equals( + textControl.value, + "abc", + `${t.name}: The text control value should be updated` + ); + assert_equals( + document.querySelector("div").textContent.trim(), + "", + `${t.name}: No text should be inserted as a child of the text control` + ); + textControl.remove(); + }, `User typing in ${ + textControlDescription + } should update the value (became an editing host during focused and different type)`); + + promise_test(async t => { + const textControl = createTextControl(); + textControl.type = "button"; + div.appendChild(textControl); + textControl.setAttribute("contenteditable", ""); + textControl.focus(); + textControl.type = textControlType; + document.execCommand("insertText", false, "abc"); + assert_equals( + textControl.value, + "abc", + `${t.name}: The text control value should be updated` + ); + assert_equals( + div.textContent.trim(), + "", + `${t.name}: No text should be inserted as a child of the text control` + ); + textControl.remove(); + }, `execCommand("insertText") in ${ + textControlDescription + } should update the value (became an editing host during focused and different type)`); +} + +</script> +</body> +</html> diff --git a/testing/web-platform/tests/editing/other/insert-list-preserving-selection.tentative.html b/testing/web-platform/tests/editing/other/insert-list-preserving-selection.tentative.html new file mode 100644 index 0000000000..b7faf4f27a --- /dev/null +++ b/testing/web-platform/tests/editing/other/insert-list-preserving-selection.tentative.html @@ -0,0 +1,155 @@ +<!doctype html> +<html> +<head> +<meta chareset="utf-8"> +<meta name="timeout" content="long"> +<meta name="variant" content="?styleWithCSS=false&command=insertOrderedList"> +<meta name="variant" content="?styleWithCSS=false&command=insertUnorderedList"> +<meta name="variant" content="?styleWithCSS=true&command=insertOrderedList"> +<meta name="variant" content="?styleWithCSS=true&command=insertUnorderedList"> +<title>Test preserving selection after insert*List</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script src="../include/editor-test-utils.js"></script> +</head> +<body> +<div contenteditable></div> +<script> +"use strict"; + +const editor = document.querySelector("div[contenteditable]"); +const utils = new EditorTestUtils(editor); +const searchParams = new URLSearchParams(document.location.search); +const styleWithCSS = searchParams.get("styleWithCSS"); +const command = searchParams.get("command"); +document.execCommand("styleWithCSS", false, styleWithCSS); + +// Note that it's not scope of this test how browsers to convert the selected +// content to a list. + +// html: Initial HTML which will be set editor.innerHTML, it should contain +// selection range with a pair of "[" or "{" and "]" or "}". +// expectedSelectedString: After executing "outdent", compared with +// getSelection().toString().replace(/[ \n\r\t]+/g, "") +const tests = [ + { + html: "<div>a[b]c</div>", + expectedSelectedString: "b", + }, + { + html: "<div>a[bc</div><div>de]f</div>", + expectedSelectedString: "bcde", + }, + { + html: "<div>a[bc<br>de]f</div>", + expectedSelectedString: "bcde", + }, + { + html: "<ul><li>a[b]c</li></ul>", + expectedSelectedString: "b", + }, + { + html: "<ul><li>a[bc</li><li>de]f</li></ul>", + expectedSelectedString: "bcde", + }, + { + html: "<ul><li>a[bc</li><li>de]f</li><li>ghi</li></ul>", + expectedSelectedString: "bcde", + }, + { + html: "<ul><li>abc</li><li>d[ef</li><li>gh]i</li></ul>", + expectedSelectedString: "efgh", + }, + { + html: "<ol><li>a[b]c</li></ol>", + expectedSelectedString: "b", + }, + { + html: "<ol><li>a[bc</li><li>de]f</li></ol>", + expectedSelectedString: "bcde", + }, + { + html: "<ol><li>a[bc</li><li>de]f</li><li>ghi</li></ol>", + expectedSelectedString: "bcde", + }, + { + html: "<ol><li>abc</li><li>d[ef</li><li>gh]i</li></ol>", + expectedSelectedString: "efgh", + }, + { + html: "<ul><li>a[bc</li></ul>" + + "<ul><li>de]f</li></ul>", + expectedSelectedString: "bcde", + }, + { + html: "<ol><li>a[bc</li></ol>" + + "<ul><li>de]f</li></ul>", + expectedSelectedString: "bcde", + }, + { + html: "<ul><li>a[bc</li></ul>" + + "<ol><li>de]f</li></ol>", + expectedSelectedString: "bcde", + }, + { + html: "<div>a[bc</div>" + + "<ul><li>de]f</li><li>ghi</li></ul>", + expectedSelectedString: "bcde", + }, + { + html: "<ul><li>abc</li><li>d[ef</li></ul>" + + "<div>gh]i</div>", + expectedSelectedString: "efgh", + }, + { + html: "<div>a[bc</div>" + + "<ol><li>de]f</li><li>ghi</li></ol>", + expectedSelectedString: "bcde", + }, + { + html: "<ol><li>abc</li><li>d[ef</li></ol>" + + "<div>gh]i</div>", + expectedSelectedString: "efgh", + }, + { + html: "<table><tr><td>a[b]c</td></tr></table>", + expectedSelectedString: "b", + }, + { + html: "<table><tr><td>a[bc</td><td>de]f</td></tr></table>", + expectedSelectedString: "bcde", + }, + { + html: "<table><tr><td>a[bc</td></tr><tr><td>de]f</td></tr></table>", + expectedSelectedString: "bcde", + }, + { + html: "<div>a[bc</div>" + + "<table><tr><td>de]f</td></tr></table>", + expectedSelectedString: "bcde", + }, + { + html: "<table><tr><td>a[bc</td></tr></table>" + + "<div>de]f</div>", + expectedSelectedString: "bcde", + }, +]; + +for (const t of tests) { + test(() => { + utils.setupEditingHost(t.html); + document.execCommand(command); + assert_equals( + getSelection().toString().replace(/[ \n\r\t]+/g, ""), + t.expectedSelectedString, + `Result: ${editor.innerHTML}` + ); + }, `Preserve selection after ${command} at ${t.html}`); +} + +</script> +</body> +</html> diff --git a/testing/web-platform/tests/editing/other/insert-paragraph-in-void-element.tentative.html b/testing/web-platform/tests/editing/other/insert-paragraph-in-void-element.tentative.html new file mode 100644 index 0000000000..c4f788a550 --- /dev/null +++ b/testing/web-platform/tests/editing/other/insert-paragraph-in-void-element.tentative.html @@ -0,0 +1,206 @@ +<!doctype html> +<meta charset=utf-8> +<title>Test insertParagraph when selection collapsed in void element</title> +<meta name="timeout" content="long"> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<div contenteditable></div> +<script> +"use strict"; + +const voidElements = [ + "br", + "embed", + "hr", + "img", + "input", + "wbr", +]; + +// This test tests whether the inserted text is inserted into, when selection +// is collapsed in the void element. The expected results are based on Blink, +// but the results of <hr>, <embed> and <wbr> elements are not consistent with +// the other elements'. Therefore, Blink also does not pass some of the +// following tests. +// FYI: This cannot be tested by editing/run because there is no way to collapse +// selection into a void element with the framework. + +const editor = document.querySelector("div[contenteditable]"); +for (const container of ["div", "h1", "li"]) { + const openTagOfContainer = (() => { + if (container == "li") { + return "<ol><li>"; + } + return `<${container}>`; + })(); + const closeTagOfContainer = (() => { + if (container == "li") { + return "</li></ol>"; + } + return `</${container}>`; + })(); + const closeAndOpenTagsOfSplitPoint = (() => { + if (container == "li") { + return "</li><li>"; + } + return `</${container}><${container}>`; + })(); + for (const tag of voidElements) { + const visibleTag = tag == "hr" || tag == "img" || tag == "input"; + test(() => { + editor.innerHTML = `${openTagOfContainer}<${tag}>${closeTagOfContainer}`; + const element = editor.querySelector(tag); + editor.focus(); + const selection = getSelection(); + selection.collapse(element, 0); + document.execCommand("insertParagraph"); + if (tag == "br") { + if (!visibleTag && container == "h1") { + assert_in_array( + editor.innerHTML, + `${openTagOfContainer}<br>${closeTagOfContainer}<div><br></div>`, + `The paragraph should be inserted before the <${tag}> element` + ); + } else { + assert_in_array( + editor.innerHTML, + `${openTagOfContainer}<br>${closeAndOpenTagsOfSplitPoint}<br>${closeTagOfContainer}`, + `The paragraph should be inserted before the <${tag}> element` + ); + } + } else if (!visibleTag && container == "h1") { + assert_in_array( + editor.innerHTML, + [ + `${openTagOfContainer}<br>${closeTagOfContainer}<div><${tag}></div>`, + `${openTagOfContainer}<br>${closeTagOfContainer}<div><${tag}><br></div>`, + ], + `The paragraph should be inserted before the <${tag}> element` + ); + } else { + assert_in_array( + editor.innerHTML, + [ + `${openTagOfContainer}<br>${closeAndOpenTagsOfSplitPoint}<${tag}>${closeTagOfContainer}`, + `${openTagOfContainer}<br>${closeAndOpenTagsOfSplitPoint}<${tag}><br>${closeTagOfContainer}`, + ], + `The paragraph should be inserted before the <${tag}> element` + ); + } + }, `Inserting paragraph when selection is collapsed in <${tag}> in <${container}> which is only child`); + + test(() => { + editor.innerHTML = `${openTagOfContainer}<${tag}>${closeTagOfContainer}`; + const element = editor.querySelector(tag); + editor.focus(); + const selection = getSelection(); + selection.collapse(element, 0); + element.getBoundingClientRect(); + document.execCommand("insertParagraph"); + if (tag == "br") { + if (!visibleTag && container == "h1") { + assert_in_array( + editor.innerHTML, + `${openTagOfContainer}<br>${closeTagOfContainer}<div><br></div>`, + `The paragraph should be inserted before the <${tag}> element` + ); + } else { + assert_in_array( + editor.innerHTML, + `${openTagOfContainer}<br>${closeAndOpenTagsOfSplitPoint}<br>${closeTagOfContainer}`, + `The paragraph should be inserted before the <${tag}> element` + ); + } + } else if (!visibleTag && container == "h1") { + assert_in_array( + editor.innerHTML, + [ + `${openTagOfContainer}<br>${closeTagOfContainer}<div><${tag}></div>`, + `${openTagOfContainer}<br>${closeTagOfContainer}<div><${tag}><br></div>`, + ], + `The paragraph should be inserted before the <${tag}> element` + ); + } else { + assert_in_array( + editor.innerHTML, + [ + `${openTagOfContainer}<br>${closeAndOpenTagsOfSplitPoint}<${tag}>${closeTagOfContainer}`, + `${openTagOfContainer}<br>${closeAndOpenTagsOfSplitPoint}<${tag}><br>${closeTagOfContainer}`, + ], + `The paragraph should be inserted before the <${tag}> element` + ); + } + }, `Inserting paragraph when selection is collapsed in <${tag}> in <${container}> which is only child (explicitly flushes maybe pending layout)`); + + test(() => { + editor.innerHTML = `${openTagOfContainer}abc<${tag}>${closeTagOfContainer}`; + const element = editor.querySelector(tag); + editor.focus(); + const selection = getSelection(); + selection.collapse(element, 0); + document.execCommand("insertParagraph"); + if (tag == "br") { + if (!visibleTag && container == "h1") { + assert_in_array( + editor.innerHTML, + [ + `${openTagOfContainer}abc${closeTagOfContainer}<div><br></div>`, + `${openTagOfContainer}abc<br>${closeTagOfContainer}<div><br></div>`, + ], + `The paragraph should be split before the <${tag}> element` + ); + } else { + assert_in_array( + editor.innerHTML, + [ + `${openTagOfContainer}abc${closeAndOpenTagsOfSplitPoint}<br>${closeTagOfContainer}`, + `${openTagOfContainer}abc<br>${closeAndOpenTagsOfSplitPoint}<br>${closeTagOfContainer}`, + ], + `The paragraph should be split before the <${tag}> element` + ); + } + } else if (!visibleTag && container == "h1") { + assert_in_array( + editor.innerHTML, + [ + `${openTagOfContainer}abc${closeTagOfContainer}<div><${tag}></div>`, + `${openTagOfContainer}abc<br>${closeTagOfContainer}<div><${tag}></div>`, + `${openTagOfContainer}abc${closeTagOfContainer}<div><${tag}><br></div>`, + `${openTagOfContainer}abc<br>${closeTagOfContainer}<div><${tag}><br></div>`, + ], + `The paragraph should be split before the <${tag}> element` + ); + } else { + assert_in_array( + editor.innerHTML, + [ + `${openTagOfContainer}abc${closeAndOpenTagsOfSplitPoint}<${tag}>${closeTagOfContainer}`, + `${openTagOfContainer}abc<br>${closeAndOpenTagsOfSplitPoint}<${tag}>${closeTagOfContainer}`, + `${openTagOfContainer}abc${closeAndOpenTagsOfSplitPoint}<${tag}><br>${closeTagOfContainer}`, + `${openTagOfContainer}abc<br>${closeAndOpenTagsOfSplitPoint}<${tag}><br>${closeTagOfContainer}`, + ], + `The paragraph should be split before the <${tag}> element` + ); + } + }, `Inserting paragraph when selection is collapsed in <${tag}> which follows a text node in <${container}>`); + + test(() => { + editor.innerHTML = `${openTagOfContainer}<${tag}>abc${closeTagOfContainer}`; + const element = editor.querySelector(tag); + editor.focus(); + const selection = getSelection(); + selection.collapse(element, 0); + document.execCommand("insertParagraph"); + assert_in_array( + editor.innerHTML, + [ + `${openTagOfContainer}<br>${closeAndOpenTagsOfSplitPoint}<${tag}>abc${closeTagOfContainer}`, + `${openTagOfContainer}<br>${closeAndOpenTagsOfSplitPoint}<${tag}>abc<br>${closeTagOfContainer}`, + ], + `The paragraph should be inserted before the <${tag}> element` + ); + }, `Inserting paragraph when selection is collapsed in <${tag}> which is followed by a text node in <${container}>`); + } +} + +</script> diff --git a/testing/web-platform/tests/editing/other/insert-text-in-void-element.tentative.html b/testing/web-platform/tests/editing/other/insert-text-in-void-element.tentative.html new file mode 100644 index 0000000000..f84d3fce03 --- /dev/null +++ b/testing/web-platform/tests/editing/other/insert-text-in-void-element.tentative.html @@ -0,0 +1,322 @@ +<!doctype html> +<meta charset=utf-8> +<title>Test insertText when selection collapsed in void element</title> +<meta name="timeout" content="long"> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<div contenteditable></div> +<script> +"use strict"; + +const voidElements = [ + "br", + "embed", + "hr", + "img", + "input", + "wbr", +]; + +// This test tests whether the inserted text is inserted into, when selection +// is collapsed in the void element. The expected results are based on Blink, +// but the results of <embed> and <wbr> elements are not consistent with the +// other elements'. Therefore, Blink also does not pass some of the following +// tests. +// FYI: This cannot be tested by editing/run because there is no way to collapse +// selection into a void element with the framework. + +const editor = document.querySelector("div[contenteditable]"); +for (const tag of voidElements) { + test(() => { + editor.innerHTML = `<div></div>`; + const element = document.createElement(tag); + editor.firstChild.appendChild(element); + editor.focus(); + const selection = getSelection(); + selection.collapse(element, 0); + document.execCommand("insertText", false, "abc"); + if (tag == "br") { + assert_in_array( + editor.innerHTML, + [ + "<div>abc</div>", + "<div>abc<br></div>", + ], + `The text should be inserted before the <br> element` + ); + } else { + assert_in_array( + editor.innerHTML, + [ + `<div>abc<${tag}></div>`, + `<div>abc<${tag}><br></div>`, + ], + `The text should be inserted before the <${tag}> element` + ); + } + }, `Inserting text when selection is collapsed in <${tag}> which is only child`); + + test(() => { + editor.innerHTML = `<div></div>`; + const element = document.createElement(tag); + editor.firstChild.appendChild(element); + editor.focus(); + const selection = getSelection(); + selection.collapse(element, 0); + element.getBoundingClientRect(); + document.execCommand("insertText", false, "abc"); + if (tag == "br") { + assert_in_array( + editor.innerHTML, + [ + "<div>abc</div>", + "<div>abc<br></div>", + ], + `The text should be inserted before the <br> element` + ); + } else { + assert_in_array( + editor.innerHTML, + [ + `<div>abc<${tag}></div>`, + `<div>abc<${tag}><br></div>`, + ], + `The text should be inserted before the <${tag}> element` + ); + } + }, `Inserting text when selection is collapsed in <${tag}> which is only child (explicitly flushes maybe pending layout)`); + + test(() => { + editor.innerHTML = `<div>abc</div>`; + const element = document.createElement(tag); + editor.firstChild.appendChild(element); + editor.focus(); + const selection = getSelection(); + selection.collapse(element, 0); + document.execCommand("insertText", false, "def"); + if (tag == "br") { + assert_in_array( + editor.innerHTML, + [ + "<div>abcdef</div>", + "<div>abcdef<br></div>", + ], + `The text should be inserted before the <br> element` + ); + } else { + assert_in_array( + editor.innerHTML, + [ + `<div>abcdef<${tag}></div>`, + `<div>abcdef<${tag}><br></div>`, + ], + `The text should be inserted before the <${tag}> element` + ); + } + }, `Inserting text when selection is collapsed in <${tag}> which follows a text node`); + + test(() => { + editor.innerHTML = `<div>def</div>`; + const element = document.createElement(tag); + editor.firstChild.insertBefore(element, editor.firstChild.firstChild); + editor.focus(); + const selection = getSelection(); + selection.collapse(element, 0); + document.execCommand("insertText", false, "abc"); + if (tag == "br") { + assert_in_array( + editor.innerHTML, + [ + "<div>abc<br>def</div>", + "<div>abc<br>def<br></div>", + ], + `The text should be inserted before the <br> element` + ); + } else { + assert_in_array( + editor.innerHTML, + [ + `<div>abc<${tag}>def</div>`, + `<div>abc<${tag}>def<br></div>`, + ], + `The text should be inserted before the <${tag}> element` + ); + } + }, `Inserting text when selection is collapsed in <${tag}> which is followed by a text node`); + + test(() => { + editor.innerHTML = `<div><span></span></div>`; + const element = document.createElement(tag); + editor.firstChild.appendChild(element); + editor.focus(); + const selection = getSelection(); + selection.collapse(element, 0); + document.execCommand("insertText", false, "abc"); + if (tag == "br") { + assert_in_array( + editor.innerHTML, + [ + "<div><span></span>abc</div>", + "<div><span></span>abc<br></div>", + ], + `The text should be inserted after the previous empty inline element of <br>` + ); + } else if (tag == "input") { // visible inline? + assert_in_array( + editor.innerHTML, + [ + `<div><span></span>abc<${tag}></div>`, + `<div><span></span>abc<${tag}><br></div>`, + ], + `The text should be inserted after the previous empty inline element of <${tag}>` + ); + } else if (tag == "hr") { // block + assert_in_array( + editor.innerHTML, + [ + `<div><span></span>abc<${tag}></div>`, + `<div><span></span>abc<br><${tag}></div>`, + ], + `The text should be inserted after the previous empty inline element of <${tag}>` + ); + } else { + assert_in_array( + editor.innerHTML, + [ + `<div>abc<span></span><${tag}></div>`, + `<div>abc<span></span><${tag}><br></div>`, + ], + `The text should be inserted before the previous empty inline element of <${tag}>` + ); + } + }, `Inserting text when selection is collapsed in <${tag}> which follows an empty <span> element`); + + test(() => { + editor.innerHTML = `<div>abc<span></span></div>`; + const element = document.createElement(tag); + editor.firstChild.appendChild(element); + editor.focus(); + const selection = getSelection(); + selection.collapse(element, 0); + document.execCommand("insertText", false, "def"); + if (tag == "br") { + assert_in_array( + editor.innerHTML, + [ + "<div>abcdef<span></span></div>", + "<div>abcdef<span></span><br></div>", + ], + `The text should be inserted at end of the first text node before empty <span> and <br>` + ); + } else if (tag == "hr") { // block + assert_in_array( + editor.innerHTML, + [ + `<div>abc<span></span>def<${tag}></div>`, + `<div>abc<span></span>def<br><${tag}></div>`, + ], + `The text should be inserted after the previous empty inline element of <${tag}> even if the empty element follows a text node` + ); + } else { + assert_in_array( + editor.innerHTML, + [ + `<div>abcdef<span></span><${tag}></div>`, + `<div>abcdef<span></span><${tag}><br></div>`, + ], + `The text should be inserted before the previous empty inline element of <${tag}>` + ); + } + }, `Inserting text when selection is collapsed in <${tag}> which follows a text node and an empty <span> element`); + + test(() => { + editor.innerHTML = `<div><span>abc</span></div>`; + const element = document.createElement(tag); + editor.firstChild.appendChild(element); + editor.focus(); + const selection = getSelection(); + selection.collapse(element, 0); + document.execCommand("insertText", false, "def"); + if (tag == "br") { + assert_in_array( + editor.innerHTML, + [ + "<div><span>abcdef</span></div>", + "<div><span>abcdef</span><br></div>", + ], + `The text should be inserted at end of the text node in <span>` + ); + } else if (tag == "hr") { // block + assert_in_array( + editor.innerHTML, + [ + `<div><span>abc</span>def<${tag}></div>`, + `<div><span>abc</span>def<br><${tag}></div>`, + ], + `The text should be inserted at after the span and before <${tag}>` + ); + } else { + assert_in_array( + editor.innerHTML, + [ + `<div><span>abcdef</span><${tag}></div>`, + `<div><span>abcdef</span><${tag}><br></div>`, + ], + `The text should be inserted at end of the text node in <span> before <${tag}>` + ); + } + }, `Inserting text when selection is collapsed in <${tag}> which follows a non-empty <span> element`); + + test(() => { + editor.innerHTML = `<div>abc<span></span>\n</div>`; + const element = document.createElement(tag); + editor.firstChild.appendChild(element); + editor.focus(); + const selection = getSelection(); + selection.collapse(element, 0); + document.execCommand("insertText", false, "def"); + if (tag == "br") { + assert_in_array( + editor.innerHTML.replace(/\n/g, " "), + [ + "<div>abcdef<span></span></div>", + "<div>abcdef<span></span><br></div>", + "<div>abcdef<span></span> </div>", + "<div>abcdef<span></span> <br></div>", + ], + `The text should be inserted at end of the first text node with ignoring the empty <span> and invisible text node before <br>` + ); + } else if (tag == "img" || tag == "input") { // visible inline + assert_in_array( + editor.innerHTML.replace(/\n/g, " "), + [ + `<div>abc<span></span> def<${tag}></div>`, + `<div>abc<span></span> def<${tag}><br></div>`, + `<div>abc<span></span> def<${tag}></div>`, + `<div>abc<span></span> def<${tag}><br></div>`, + ], + `The text should be inserted at end of the last visible text node` + ); + } else if (tag == "hr") { // block + assert_in_array( + editor.innerHTML, + [ + `<div>abc<span></span>def<${tag}></div>`, + `<div>abc<span></span>def<br><${tag}></div>`, + ], + `The text should be inserted after the previous empty inline element` + ); + } else { + assert_in_array( + editor.innerHTML.replace(/\n/g, " "), + [ + `<div>abcdef<span></span> <${tag}></div>`, + `<div>abcdef<span></span> <${tag}><br></div>`, + ], + `The text should be inserted before the previous empty inline element` + ); + } + }, `Inserting text when selection is collapsed in <${tag}> which follows a text node, an empty <span> element and white-space only text node`); +} + +</script>
\ No newline at end of file diff --git a/testing/web-platform/tests/editing/other/inserthtml-do-not-preserve-inline-styles.html b/testing/web-platform/tests/editing/other/inserthtml-do-not-preserve-inline-styles.html new file mode 100644 index 0000000000..3483f8f995 --- /dev/null +++ b/testing/web-platform/tests/editing/other/inserthtml-do-not-preserve-inline-styles.html @@ -0,0 +1,176 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<meta name="timeout" content="long"> +<meta name="variant" content="?stylesAtInsertionPoint=bold&stylesInserting=italic"> +<meta name="variant" content="?stylesAtInsertionPoint=bold&stylesInserting=strikethrough"> +<meta name="variant" content="?stylesAtInsertionPoint=bold&stylesInserting=subscript"> +<meta name="variant" content="?stylesAtInsertionPoint=bold&stylesInserting=superscript"> +<meta name="variant" content="?stylesAtInsertionPoint=bold&stylesInserting=underline"> +<meta name="variant" content="?stylesAtInsertionPoint=bold&stylesInserting=fontname"> +<meta name="variant" content="?stylesAtInsertionPoint=bold&stylesInserting=fontsize"> +<meta name="variant" content="?stylesAtInsertionPoint=bold&stylesInserting=forecolor"> +<meta name="variant" content="?stylesAtInsertionPoint=bold&stylesInserting=hilitecolor"> +<meta name="variant" content="?stylesAtInsertionPoint=italic&stylesInserting=bold"> +<meta name="variant" content="?stylesAtInsertionPoint=strikethrough&stylesInserting=bold"> +<meta name="variant" content="?stylesAtInsertionPoint=subscript&stylesInserting=bold"> +<meta name="variant" content="?stylesAtInsertionPoint=superscript&stylesInserting=bold"> +<meta name="variant" content="?stylesAtInsertionPoint=underline&stylesInserting=bold"> +<meta name="variant" content="?stylesAtInsertionPoint=fontname&stylesInserting=bold"> +<meta name="variant" content="?stylesAtInsertionPoint=forecolor&stylesInserting=bold"> +<meta name="variant" content="?stylesAtInsertionPoint=hilitecolor&stylesInserting=bold"> +<meta name="variant" content="?stylesAtInsertionPoint=bold,italic&stylesInserting=strikethrough,underline"> +<title>insertHTML should not preserve inline styles at insertion point</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="../include/editor-test-utils.js"></script> +</head> +<body><div contenteditable></div> +<script> +"use strict"; + +const params = new URLSearchParams(location.search.substring(1)); +const stylesAtInsertionPoint = params.get("stylesAtInsertionPoint").split(","); +const stylesInserting = params.get("stylesInserting").split(","); + +function getOpenTagForStyle(style) { + switch (style.toLowerCase()) { + case "bold": + return "<b>"; + case "italic": + return "<i>"; + case "strikethrough": + return "<s>"; + case "subscript": + return "<sub>"; + case "superscript": + return "<sup>"; + case "underline": + return "<u>"; + case "fontname": + return "<font face=\"monospace\">"; + case "fontsize": + return "<font size=\"5\">"; + case "forecolor": + return "<font color=\"#0000FF\">"; + case "hilitecolor": + return "<span style=\"background-color:rgb(0, 255, 255)\">"; + } +} + +function getClosedTagForStyle(style) { + switch (style.toLowerCase()) { + case "bold": + return "</b>"; + case "italic": + return "</i>"; + case "strikethrough": + return "</s>"; + case "subscript": + return "</sub>"; + case "superscript": + return "</sup>"; + case "underline": + return "</u>"; + case "fontname": + case "fontsize": + case "forecolor": + return "</font>"; + case "hilitecolor": + return "</span>"; + } +} + +function openTags(styles) { + let openTags = ""; + for (const style of styles) { + openTags = getOpenTagForStyle(style) + openTags; + } + return openTags; +} + +function closedTags(styles) { + let closedTags = ""; + for (const style of styles) { + closedTags += getClosedTagForStyle(style); + } + return closedTags; +} + +const editingHost = document.querySelector("div[contenteditable]"); +const utils = new EditorTestUtils(editingHost); + +function addTest(aTest) { + test(() => { + utils.setupEditingHost(aTest.innerHTML); + document.execCommand("insertHTML", false, aTest.newContent); + utils.normalizeStyleAttributeValues(); + assert_equals(editingHost.innerHTML, aTest.expectedResult, aTest.description); + for (const style of stylesInserting) { + switch (style.toLocaleLowerCase()) { + case "fontsize": + assert_equals( + document.queryCommandValue(style), + "5", + `document.queryCommandValue("${style}")` + ); + break; + case "fontname": + assert_equals( + document.queryCommandValue(style), + "monospace", + `document.queryCommandValue("${style}")` + ); + break; + case "forecolor": + assert_equals( + document.queryCommandValue(style), + "rgb(0, 0, 255)", + `document.queryCommandValue("${style}")` + ); + break; + case "hilitecolor": + assert_equals( + document.queryCommandValue(style), + "rgb(0, 255, 255))", + `document.queryCommandValue("${style}")` + ); + break; + default: + assert_true( + document.queryCommandState(style), + `document.queryCommandState("${style}")` + ); + break; + } + } + }, `insertHTML with "${aTest.newContent}" into ${aTest.innerHTML}`); +} + +addTest({ + innerHTML: `${openTags(stylesAtInsertionPoint)}[]def${closedTags(stylesAtInsertionPoint)}`, + newContent: `${openTags(stylesInserting)}abc${closedTags(stylesInserting)}`, + expectedResult: `${openTags(stylesInserting)}abc${closedTags(stylesInserting)}` + + `${openTags(stylesAtInsertionPoint)}def${closedTags(stylesAtInsertionPoint)}`, + description: "New content should be inserted before the inline containers", +}); +addTest({ + innerHTML: `${openTags(stylesAtInsertionPoint)}abc[]${closedTags(stylesAtInsertionPoint)}`, + newContent: `${openTags(stylesInserting)}def${closedTags(stylesInserting)}`, + expectedResult: `${openTags(stylesAtInsertionPoint)}abc${closedTags(stylesAtInsertionPoint)}` + + `${openTags(stylesInserting)}def${closedTags(stylesInserting)}`, + description: "New content should be appended after the inline containers", +}); +addTest({ + innerHTML: `${openTags(stylesAtInsertionPoint)}a[]c${closedTags(stylesAtInsertionPoint)}`, + newContent: `${openTags(stylesInserting)}b${closedTags(stylesInserting)}`, + expectedResult: `${openTags(stylesAtInsertionPoint)}a${closedTags(stylesAtInsertionPoint)}` + + `${openTags(stylesInserting)}b${closedTags(stylesInserting)}` + + `${openTags(stylesAtInsertionPoint)}c${closedTags(stylesAtInsertionPoint)}`, + description: "The inline containers should be split and new content inserted between them", +}); + +</script> +</body> +</html> diff --git a/testing/web-platform/tests/editing/other/insertlinebreak-with-white-space-style.tentative.html b/testing/web-platform/tests/editing/other/insertlinebreak-with-white-space-style.tentative.html new file mode 100644 index 0000000000..7e362c3571 --- /dev/null +++ b/testing/web-platform/tests/editing/other/insertlinebreak-with-white-space-style.tentative.html @@ -0,0 +1,426 @@ +<!doctype html> +<meta charset=utf-8> +<meta name="timeout" content="long"> +<meta name="variant" content="?pre"> +<meta name="variant" content="?pre-wrap"> +<meta name="variant" content="?pre-line"> +<meta name="variant" content="?nowrap"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="../include/editor-test-utils.js"></script> +<link rel=stylesheet href=../include/reset.css> +<title>insertlinebreak in white-space specified element</title> +<body><div contenteditable></div></body> +<script> +/** + * The expected behavior is based on Chrome 91. + */ +const style = location.search.substr(1); +const isNewLineSignificant = style == "pre" || style == "pre-wrap" || style == "pre-line"; +const editingHost = document.querySelector("div[contenteditable]"); +for (const defaultParagraphSeparator of ["div", "p"]) { + document.execCommand("defaultparagraphseparator", false, defaultParagraphSeparator); + for (const display of ["block", "inline", "inline-block"]) { + // insertlinebreak at direct child of editing host. + test(() => { + editingHost.style.whiteSpace = style; + editingHost.style.display = display; + const utils = new EditorTestUtils(editingHost); + utils.setupEditingHost(`abc[]`); + editingHost.getBoundingClientRect(); + document.execCommand("insertlinebreak"); + if (isNewLineSignificant) { + assert_in_array( + editingHost.innerHTML, + [ + `abc\n\n`, + `abc\n<br>`, + ], + "A linefeed should be inserted at end" + ); + } else { + assert_equals( + editingHost.innerHTML, + `abc<br><br>`, + "A <br> should be inserted at end" + ); + } + }, `<div contenteditable style="white-space:${style}; display:${display}">abc[]</div> (defaultparagraphseparator: ${defaultParagraphSeparator})`); + + test(() => { + editingHost.style.whiteSpace = style; + editingHost.style.display = display; + const utils = new EditorTestUtils(editingHost); + utils.setupEditingHost(`[]abc`); + editingHost.getBoundingClientRect(); + document.execCommand("insertlinebreak"); + if (isNewLineSignificant) { + assert_in_array( + editingHost.innerHTML, + [ + `\nabc`, + `\nabc<br>`, + ], + "A linefeed should be inserted at start" + ); + } else { + assert_in_array( + editingHost.innerHTML, + [ + `<br>abc`, + `<br>abc<br>`, + ], + "A <br> should be inserted at start" + ); + } + }, `<div contenteditable style="white-space:${style}; display:${display}">[]abc</div> (defaultparagraphseparator: ${defaultParagraphSeparator})`); + + test(() => { + editingHost.style.whiteSpace = style; + editingHost.style.display = display; + const utils = new EditorTestUtils(editingHost); + utils.setupEditingHost(`a[]bc`); + editingHost.getBoundingClientRect(); + document.execCommand("insertlinebreak"); + if (isNewLineSignificant) { + assert_in_array( + editingHost.innerHTML, + [ + `a\nbc`, + `a\nbc<br>`, + ], + "A linefeed should be inserted" + ); + } else { + assert_in_array( + editingHost.innerHTML, + [ + `a<br>bc`, + `a<br>bc<br>`, + ], + "A <br> should be inserted" + ); + } + }, `<div contenteditable style="white-space:${style}; display:${display}">a[]bc</div> (defaultparagraphseparator: ${defaultParagraphSeparator})`); + + // inline styles should be preserved. + test(() => { + editingHost.style.whiteSpace = style; + editingHost.style.display = display; + const utils = new EditorTestUtils(editingHost); + utils.setupEditingHost(`abc[]`); + editingHost.getBoundingClientRect(); + document.execCommand("italic"); + document.execCommand("insertlinebreak"); + document.execCommand("inserttext", false, "def"); + if (isNewLineSignificant) { + assert_in_array( + editingHost.innerHTML, + [ + `abc\n<i>def</i>`, + `abc\n<i>def\n</i>`, + `abc\n<i>def<br></i>`, + `abc\n<i>def</i>\n`, + `abc\n<i>def</i><br>`, + ], + "The temporary inline style should be applied to next line" + ); + } else { + assert_in_array( + editingHost.innerHTML, + [ + `abc<br><i>def</i>`, + `abc<br><i>def<br></i>`, + `abc<br><i>def</i><br>`, + ], + "The temporary inline style should be applied to next line" + ); + } + }, `<div contenteditable style="white-space:${style}; display:${display}">abc[]</div> (defaultparagraphseparator: ${defaultParagraphSeparator}) (preserving temporary inline style test)`); + + test(() => { + editingHost.style.whiteSpace = style; + editingHost.style.display = display; + const utils = new EditorTestUtils(editingHost); + utils.setupEditingHost(`<b>abc[]</b>`); + editingHost.getBoundingClientRect(); + document.execCommand("insertlinebreak"); + document.execCommand("inserttext", false, "def"); + if (isNewLineSignificant) { + assert_in_array( + editingHost.innerHTML, + [ + `<b>abc\ndef</b>`, + `<b>abc\ndef\n</b>`, + `<b>abc\ndef<br></b>`, + `<b>abc\ndef</b>\n`, + `<b>abc\ndef</b><br>`, + ], + "The inline style should be applied to next line" + ); + } else { + assert_in_array( + editingHost.innerHTML, + [ + `<b>abc<br>def</b>`, + `<b>abc<br>def<br></b>`, + `<b>abc<br>def</b><br>`, + ], + "The inline style should be applied to next line" + ); + } + }, `<div contenteditable style="white-space:${style}; display:${display}"><b>abc[]</b></div> (defaultparagraphseparator: ${defaultParagraphSeparator}) (preserving inline style test)`); + + for (const paragraph of ["div", "p"]) { + // insertlinebreak in existing paragraph whose `white-space` is specified. + test(() => { + editingHost.style.whiteSpace = "normal"; + editingHost.style.display = display; + const utils = new EditorTestUtils(editingHost); + utils.setupEditingHost(`<${paragraph} style="white-space:${style}">abc[]</${paragraph}>`); + editingHost.getBoundingClientRect(); + document.execCommand("insertlinebreak"); + if (isNewLineSignificant) { + assert_in_array( + editingHost.innerHTML, + [ + `<${paragraph} style="white-space:${style}">abc\n\n</${paragraph}>`, + `<${paragraph} style="white-space:${style}">abc\n<br></${paragraph}>`, + ], + "A linefeed should be inserted at end of the paragraph" + ); + } else { + assert_equals( + editingHost.innerHTML, + `<${paragraph} style="white-space:${style}">abc<br><br></${paragraph}>`, + "A <br> should be inserted at end of the paragraph" + ); + } + }, `<div contenteditable style="display:${display}"><${paragraph} style="white-space:${style}">abc[]</${paragraph}></div> (defaultparagraphseparator: ${defaultParagraphSeparator})`); + + test(() => { + editingHost.style.whiteSpace = "normal"; + editingHost.style.display = display; + const utils = new EditorTestUtils(editingHost); + utils.setupEditingHost(`<${paragraph} style="white-space:${style}">[]abc</${paragraph}>`); + editingHost.getBoundingClientRect(); + document.execCommand("insertlinebreak"); + if (isNewLineSignificant) { + assert_in_array( + editingHost.innerHTML, + [ + `<${paragraph} style="white-space:${style}">\nabc</${paragraph}>`, + `<${paragraph} style="white-space:${style}">\nabc<br></${paragraph}>`, + ], + "A linefeed should be inserted at start" + ); + } else { + assert_in_array( + editingHost.innerHTML, + [ + `<${paragraph} style="white-space:${style}"><br>abc</${paragraph}>`, + `<${paragraph} style="white-space:${style}"><br>abc<br></${paragraph}>`, + ], + "A <br> should be inserted at start" + ); + } + }, `<div contenteditable style="display:${display}"><${paragraph} style="white-space:${style}">[]abc</${paragraph}></div> (defaultparagraphseparator: ${defaultParagraphSeparator})`); + + test(() => { + editingHost.style.whiteSpace = "normal"; + editingHost.style.display = display; + const utils = new EditorTestUtils(editingHost); + utils.setupEditingHost(`<${paragraph} style="white-space:${style}">a[]bc</${paragraph}>`); + editingHost.getBoundingClientRect(); + document.execCommand("insertlinebreak"); + if (isNewLineSignificant) { + assert_in_array( + editingHost.innerHTML, + [ + `<${paragraph} style="white-space:${style}">a\nbc</${paragraph}>`, + `<${paragraph} style="white-space:${style}">a\nbc<br></${paragraph}>`, + ], + "A linefeed should be inserted" + ); + } else { + assert_in_array( + editingHost.innerHTML, + [ + `<${paragraph} style="white-space:${style}">a<br>bc</${paragraph}>`, + `<${paragraph} style="white-space:${style}">a<br>bc<br></${paragraph}>`, + ], + "A <br> should be inserted" + ); + } + }, `<div contenteditable style="display:${display}"><${paragraph} style="white-space:${style}">a[]bc</${paragraph}></div> (defaultparagraphseparator: ${defaultParagraphSeparator})`); + + // insertlinebreak in existing paragraph. + test(() => { + editingHost.style.whiteSpace = style; + editingHost.style.display = display; + const utils = new EditorTestUtils(editingHost); + utils.setupEditingHost(`<${paragraph}>abc[]</${paragraph}>`); + editingHost.getBoundingClientRect(); + document.execCommand("insertlinebreak"); + if (isNewLineSignificant) { + assert_in_array( + editingHost.innerHTML, + [ + `<${paragraph}>abc\n\n</${paragraph}>`, + `<${paragraph}>abc\n<br></${paragraph}>`, + ], + "A linefeed should be inserted at end of the paragraph" + ); + } else { + assert_equals( + editingHost.innerHTML, + `<${paragraph}>abc<br><br></${paragraph}>`, + "A <br> should be inserted at end of the paragraph" + ); + } + }, `<div contenteditable style="display:${display}; white-space:${style}"><${paragraph}>abc[]</${paragraph}></div> (defaultparagraphseparator: ${defaultParagraphSeparator})`); + + test(() => { + editingHost.style.whiteSpace = style; + editingHost.style.display = display; + const utils = new EditorTestUtils(editingHost); + utils.setupEditingHost(`<${paragraph}>[]abc</${paragraph}>`); + editingHost.getBoundingClientRect(); + document.execCommand("insertlinebreak"); + if (isNewLineSignificant) { + assert_in_array( + editingHost.innerHTML, + [ + `<${paragraph}>\nabc</${paragraph}>`, + `<${paragraph}>\nabc<br></${paragraph}>`, + ], + "A linefeed should be inserted at start" + ); + } else { + assert_in_array( + editingHost.innerHTML, + [ + `<${paragraph}><br>abc</${paragraph}>`, + `<${paragraph}><br>abc<br></${paragraph}>`, + ], + "A <br> should be inserted at start" + ); + } + }, `<div contenteditable style="display:${display}; white-space:${style}"><${paragraph}>[]abc</${paragraph}></div> (defaultparagraphseparator: ${defaultParagraphSeparator})`); + + test(() => { + editingHost.style.whiteSpace = style; + editingHost.style.display = display; + const utils = new EditorTestUtils(editingHost); + utils.setupEditingHost(`<${paragraph}>a[]bc</${paragraph}>`); + editingHost.getBoundingClientRect(); + document.execCommand("insertlinebreak"); + if (isNewLineSignificant) { + assert_in_array( + editingHost.innerHTML, + [ + `<${paragraph}>a\nbc</${paragraph}>`, + `<${paragraph}>a\nbc<br></${paragraph}>`, + ], + "A linefeed should be inserted" + ); + } else { + assert_in_array( + editingHost.innerHTML, + [ + `<${paragraph}>a<br>bc</${paragraph}>`, + `<${paragraph}>a<br>bc<br></${paragraph}>`, + ], + "A <br> should be inserted" + ); + } + }, `<div contenteditable style="display:${display}; white-space:${style}"><${paragraph}>a[]bc</${paragraph}></div> (defaultparagraphseparator: ${defaultParagraphSeparator})`); + + // Styling the existing paragraph instead of editing host. + test(() => { + editingHost.style.whiteSpace = "normal"; + editingHost.style.display = "block"; + const utils = new EditorTestUtils(editingHost); + const styleAttr = `style="display:${display}; white-space:${style}"`; + utils.setupEditingHost(`<${paragraph} ${styleAttr}>abc[]</${paragraph}>`); + editingHost.getBoundingClientRect(); + document.execCommand("insertlinebreak"); + if (isNewLineSignificant) { + assert_in_array( + editingHost.innerHTML, + [ + `<${paragraph} ${styleAttr}>abc\n\n</${paragraph}>`, + `<${paragraph} ${styleAttr}>abc\n<br></${paragraph}>`, + ], + "A linefeed should be inserted at end of the paragraph" + ); + } else { + assert_equals( + editingHost.innerHTML, + `<${paragraph} ${styleAttr}>abc<br><br></${paragraph}>`, + "A <br> should be inserted at end of the paragraph" + ); + } + }, `<div contenteditable><${paragraph} style="display:${display}; white-space:${style}">abc[]</${paragraph}></div> (defaultparagraphseparator: ${defaultParagraphSeparator})`); + + test(() => { + editingHost.style.whiteSpace = "normal"; + editingHost.style.display = "block"; + const utils = new EditorTestUtils(editingHost); + const styleAttr = `style="display:${display}; white-space:${style}"`; + utils.setupEditingHost(`<${paragraph} ${styleAttr}>[]abc</${paragraph}>`); + editingHost.getBoundingClientRect(); + document.execCommand("insertlinebreak"); + if (isNewLineSignificant) { + assert_in_array( + editingHost.innerHTML, + [ + `<${paragraph} ${styleAttr}>\nabc</${paragraph}>`, + `<${paragraph} ${styleAttr}>\nabc<br></${paragraph}>`, + ], + "A linefeed should be inserted at start" + ); + } else { + assert_in_array( + editingHost.innerHTML, + [ + `<${paragraph} ${styleAttr}><br>abc</${paragraph}>`, + `<${paragraph} ${styleAttr}><br>abc<br></${paragraph}>`, + ], + "A <br> should be inserted at start" + ); + } + }, `<div contenteditable><${paragraph} style="display:${display}; white-space:${style}">[]abc</${paragraph}></div> (defaultparagraphseparator: ${defaultParagraphSeparator})`); + + test(() => { + editingHost.style.whiteSpace = "normal"; + editingHost.style.display = "block"; + const utils = new EditorTestUtils(editingHost); + const styleAttr = `style="display:${display}; white-space:${style}"`; + utils.setupEditingHost(`<${paragraph} ${styleAttr}>a[]bc</${paragraph}>`); + editingHost.getBoundingClientRect(); + document.execCommand("insertlinebreak"); + if (isNewLineSignificant) { + assert_in_array( + editingHost.innerHTML, + [ + `<${paragraph} ${styleAttr}>a\nbc</${paragraph}>`, + `<${paragraph} ${styleAttr}>a\nbc<br></${paragraph}>`, + ], + "A linefeed should be inserted" + ); + } else { + assert_in_array( + editingHost.innerHTML, + [ + `<${paragraph} ${styleAttr}>a<br>bc</${paragraph}>`, + `<${paragraph} ${styleAttr}>a<br>bc<br></${paragraph}>`, + ], + "A <br> should be inserted" + ); + } + }, `<div contenteditable><${paragraph} style="display:${display}; white-space:${style}">a[]bc</${paragraph}></div> (defaultparagraphseparator: ${defaultParagraphSeparator})`); + } + } +} +</script> diff --git a/testing/web-platform/tests/editing/other/insertparagraph-in-child-of-head.tentative.html b/testing/web-platform/tests/editing/other/insertparagraph-in-child-of-head.tentative.html new file mode 100644 index 0000000000..2ee8a4b33b --- /dev/null +++ b/testing/web-platform/tests/editing/other/insertparagraph-in-child-of-head.tentative.html @@ -0,0 +1,367 @@ +<!doctype html> +<html> +<head> +<meta chareset="utf-8"> +<meta name="timeout" content="long"> +<meta name="variant" content="?designMode=off&white-space=normal"> +<meta name="variant" content="?designMode=off&white-space=pre"> +<meta name="variant" content="?designMode=off&white-space=pre-line"> +<meta name="variant" content="?designMode=off&white-space=pre-wrap"> +<meta name="variant" content="?designMode=on&white-space=normal"> +<meta name="variant" content="?designMode=on&white-space=pre"> +<meta name="variant" content="?designMode=on&white-space=pre-line"> +<meta name="variant" content="?designMode=on&white-space=pre-wrap"> +<title>Insert paragraph in a block element in the head element</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script src="../include/editor-test-utils.js"></script> +</head> +<body> +<iframe srcdoc=""></iframe> +<script> +"use strict"; + +const searchParams = new URLSearchParams(document.location.search); +const whiteSpace = searchParams.get("white-space"); +const testingDesignMode = searchParams.get("designMode") == "on"; + +const isPreformatted = + whiteSpace == "pre" || whiteSpace == "pre-line" || whiteSpace == "pre-wrap"; + +const iframe = document.querySelector("iframe"); +const minimumSrcDoc = + "<html>" + + "<head style='display:block'>" + + "<title>iframe</title>" + + "<script src='/resources/testdriver.js'></" + "script>" + + "<script src='/resources/testdriver-vendor.js'></" + "script>" + + "<script src='/resources/testdriver-actions.js'></" + "script>" + + "</head>" + + "<body><br></body>" + + "</html>"; + +async function initializeAndWaitForLoad(iframeElement, srcDocValue) { + const waitForLoad = + new Promise( + resolve => iframeElement.addEventListener("load", resolve, {once: true}) + ); + iframeElement.srcdoc = srcDocValue; + await waitForLoad; + if (testingDesignMode) { + iframeElement.contentDocument.designMode = "on"; + } else { + iframeElement.contentDocument.documentElement.setAttribute("contenteditable", ""); + } + iframeElement.contentWindow.focus(); + iframeElement.contentDocument.execCommand("defaultParagraphSeparator", false, "div"); +} + +function removeResourceScriptElements(node) { + node.querySelectorAll("script").forEach( + element => { + if (element.getAttribute("src")?.startsWith("/resources")) { + element.remove() + } + } + ); +} + +// DO NOT USE multi-line comment in this file, then, you can comment out +// unnecessary tests when you need to attach the browser with a debugger. + +// <title>, <style> and <script> cannot have <br> element. Therefore, it's +// hard to think what is the best if linefeeds are not preformatted. +promise_test(async () => { + await initializeAndWaitForLoad(iframe, minimumSrcDoc); + const childDoc = iframe.contentDocument; + const title = childDoc.querySelector("title"); + title.setAttribute("style", `display:block;white-space:${whiteSpace}`); + const utils = new EditorTestUtils(title); + utils.setupEditingHost("{}"); + await utils.sendEnterKey(); + removeResourceScriptElements(childDoc); + title.removeAttribute("style"); + childDoc.head.removeAttribute("style"); + + if (!isPreformatted) { + assert_in_array( + childDoc.documentElement.innerHTML, + [ + "<head><title></title></head><body><br></body>", // noop + "<head><title>\n</title></head><body><br></body>", // (collapse white-space) + "<head><title>\n\n</title></head><body><br></body>", // (collapse white-spaces) + ], + "0-2 collapsible linefeed(s) should be inserted" + ); + } else { + // The second linefeed is required to make the last line visible + assert_equals( + childDoc.documentElement.innerHTML, + "<head><title>\n\n</title></head><body><br></body>", + "2 preformatted linefeeds should be inserted" + ); + } +}, `insertParagraph in empty <title style="display:block;white-space:${whiteSpace}"> should not split it`); + +promise_test(async () => { + await initializeAndWaitForLoad(iframe, minimumSrcDoc); + const childDoc = iframe.contentDocument; + const title = childDoc.querySelector("title"); + title.setAttribute("style", `display:block;white-space:${whiteSpace}`); + const utils = new EditorTestUtils(title); + utils.setupEditingHost("ab[]cd"); + await utils.sendEnterKey(); + removeResourceScriptElements(childDoc); + title.removeAttribute("style"); + childDoc.head.removeAttribute("style"); + + if (!isPreformatted) { + assert_in_array( + childDoc.documentElement.innerHTML, + [ + "<head><title>abcd</title></head><body><br></body>", // noop + "<head><title>ab\ncd</title></head><body><br></body>", // (collapsible white-space) + ], + "0-1 collapsible linefeed should be inserted" + ); + } else { + assert_equals( + childDoc.documentElement.innerHTML, + "<head><title>ab\ncd</title></head><body><br></body>", + "1 preformatted linefeed should be inserted" + ); + } +}, `insertParagraph in <title style="display:block;white-space:${whiteSpace}"> containing text should not split it`); + +promise_test(async () => { + await initializeAndWaitForLoad(iframe, minimumSrcDoc); + const childDoc = iframe.contentDocument; + const style = childDoc.createElement("style"); + style.setAttribute("style", `display:block;white-space:${whiteSpace}`); + childDoc.head.appendChild(style); + const utils = new EditorTestUtils(style); + utils.setupEditingHost("{}"); + await utils.sendEnterKey(); + removeResourceScriptElements(childDoc); + style.removeAttribute("style"); + childDoc.head.removeAttribute("style"); + + if (!isPreformatted) { + assert_in_array( + childDoc.documentElement.innerHTML, + [ + "<head><title>iframe</title><style></style></head><body><br></body>", // noop + "<head><title>iframe</title><style>\n</style></head><body><br></body>", // (collapsible white-space) + "<head><title>iframe</title><style>\n\n</style></head><body><br></body>", // (collapsible white-spaces) + ], + "0-2 collapsible linefeeds should be inserted" + ); + } else { + // The second linefeed is required to make the last line visible + assert_equals( + childDoc.documentElement.innerHTML, + "<head><title>iframe</title><style>\n\n</style></head><body><br></body>", + "2 preformatted linefeeds should be inserted" + ); + } +}, `insertParagraph in empty <style style="display:block;white-space:${whiteSpace}"> should not split it`); + +promise_test(async () => { + await initializeAndWaitForLoad(iframe, minimumSrcDoc); + const childDoc = iframe.contentDocument; + const style = childDoc.createElement("style"); + style.setAttribute("style", `display:block;white-space:${whiteSpace}`); + childDoc.head.appendChild(style); + const utils = new EditorTestUtils(style); + utils.setupEditingHost("ab[]cd"); + await utils.sendEnterKey(); + removeResourceScriptElements(childDoc); + style.removeAttribute("style"); + childDoc.head.removeAttribute("style"); + + if (!isPreformatted) { + assert_in_array( + childDoc.documentElement.innerHTML, + [ + "<head><title>iframe</title><style>abcd</style></head><body><br></body>", // noop + "<head><title>iframe</title><style>ab\ncd</style></head><body><br></body>", // (collapsible white-space) + ], + "0-1 collapsible linefeed should be inserted" + ); + } else { + assert_equals( + childDoc.documentElement.innerHTML, + "<head><title>iframe</title><style>ab\ncd</style></head><body><br></body>", + "1 preformatted linefeed should be inserted" + ); + } +}, `insertParagraph in <style style="display:block;white-space:${whiteSpace}"> containing text should not split it`); + +promise_test(async () => { + await initializeAndWaitForLoad(iframe, minimumSrcDoc); + const childDoc = iframe.contentDocument; + const script = childDoc.createElement("script"); + script.setAttribute("style", `display:block;white-space:${whiteSpace}`); + childDoc.head.appendChild(script); + // Setting <script>.innerHTML causes throwing exception because it runs + // setting script, so we cannot use EditorTestUtils.setupEditingHost. + childDoc.getSelection().collapse(script, 0); + const utils = new EditorTestUtils(childDoc.documentElement); + await utils.sendEnterKey(); + removeResourceScriptElements(childDoc); + script.removeAttribute("style"); + childDoc.head.removeAttribute("style"); + + if (!isPreformatted) { + assert_in_array( + childDoc.documentElement.innerHTML, + [ + "<head><title>iframe</title><script></" + "script></head><body><br></body>", // noop + "<head><title>iframe</title><script>\n</" + "script></head><body><br></body>", // (collapsible white-space) + "<head><title>iframe</title><script>\n\n</" + "script></head><body><br></body>", // (collapsible white-spaces) + ], + "0-2 collapsible linefeeds should be inserted" + ); + } else { + // The second linefeed is required to make the last line visible + assert_equals( + childDoc.documentElement.innerHTML, + "<head><title>iframe</title><script>\n\n</" + "script></head><body><br></body>", + "2 preformatted linefeeds should be inserted" + ); + } +}, `insertParagraph in empty <script style="display:block;white-space:${whiteSpace}"> should not split it`); + +promise_test(async () => { + await initializeAndWaitForLoad(iframe, minimumSrcDoc); + const childDoc = iframe.contentDocument; + const script = childDoc.createElement("script"); + script.setAttribute("style", `display:block;white-space:${whiteSpace}`); + childDoc.head.appendChild(script); + // Setting <script>.innerHTML causes throwing exception because it runs + // setting script, so we cannot use EditorTestUtils.setupEditingHost. + script.innerText = "// ab// cd"; + childDoc.getSelection().collapse(script.firstChild, "// ab".length); + const utils = new EditorTestUtils(childDoc.documentElement); + await utils.sendEnterKey(); + removeResourceScriptElements(childDoc); + script.removeAttribute("style"); + childDoc.head.removeAttribute("style"); + + if (!isPreformatted) { + assert_in_array( + childDoc.documentElement.innerHTML, + [ + "<head><title>iframe</title><script>// ab// cd</" + "script></head><body><br></body>", // noop + "<head><title>iframe</title><script>// ab\n// cd</" + "script></head><body><br></body>", // (collapsible white-space) + ], + "0-1 linefeed should be inserted" + ); + } else { + assert_equals( + childDoc.documentElement.innerHTML, + "<head><title>iframe</title><script>// ab\n// cd</" + "script></head><body><br></body>", + "1 preformatted linefeed should be inserted" + ); + } +}, `insertParagraph in <script style="display:block;white-space:${whiteSpace}"> containing text should not split it`); + +// <div> element in the <head> should be same behavior as the following result. +// See insertparagraph-in-child-of-html.tentative.html for the detail. +promise_test(async () => { + await initializeAndWaitForLoad(iframe, minimumSrcDoc); + const childDoc = iframe.contentDocument; + const div = childDoc.createElement("div"); + div.setAttribute("style", `white-space:${whiteSpace}`); + childDoc.head.appendChild(div); + const utils = new EditorTestUtils(div); + utils.setupEditingHost("{}"); + await utils.sendEnterKey(); + removeResourceScriptElements(childDoc); + childDoc.head.removeAttribute("style"); + + if (!isPreformatted) { + assert_equals( + childDoc.documentElement.innerHTML, + `<head><title>iframe</title><div style="white-space:${whiteSpace}"><br></div><div style="white-space:${whiteSpace}"><br></div></head><body><br></body>`, + "The <div> should be split" + ); + } else { + assert_in_array( + childDoc.documentElement.innerHTML, + [ + `<head><title>iframe</title><div style="white-space:${whiteSpace}">\n</div><div style="white-space:${whiteSpace}">\n</div></head><body><br></body>`, + `<head><title>iframe</title><div style="white-space:${whiteSpace}"><br></div><div style="white-space:${whiteSpace}"><br></div></head><body><br></body>`, + ], + "The <div> should be split" + ); + } +}, `insertParagraph in empty <div style="white-space:${ + whiteSpace +}"> in the <head> should split the <div>`); + +promise_test(async () => { + await initializeAndWaitForLoad(iframe, minimumSrcDoc); + const childDoc = iframe.contentDocument; + const div = childDoc.createElement("div"); + div.setAttribute("style", `white-space:${whiteSpace}`); + childDoc.head.appendChild(div); + const utils = new EditorTestUtils(div); + utils.setupEditingHost("{}<br>"); + await utils.sendEnterKey(); + removeResourceScriptElements(childDoc); + childDoc.head.removeAttribute("style"); + + if (!isPreformatted) { + assert_equals( + childDoc.documentElement.innerHTML, + `<head><title>iframe</title><div style="white-space:${whiteSpace}"><br></div><div style="white-space:${whiteSpace}"><br></div></head><body><br></body>`, + "The <div> should be split" + ); + } else { + assert_in_array( + childDoc.documentElement.innerHTML, + [ + `<head><title>iframe</title><div style="white-space:${whiteSpace}">\n</div><div style="white-space:${whiteSpace}">\n</div></head><body><br></body>`, + `<head><title>iframe</title><div style="white-space:${whiteSpace}"><br></div><div style="white-space:${whiteSpace}">\n</div></head><body><br></body>`, + `<head><title>iframe</title><div style="white-space:${whiteSpace}">\n</div><div style="white-space:${whiteSpace}"><br></div></head><body><br></body>`, + `<head><title>iframe</title><div style="white-space:${whiteSpace}"><br></div><div style="white-space:${whiteSpace}"><br></div></head><body><br></body>`, + ], + "The <div> should be split" + ); + } +}, `insertParagraph in <div style="white-space:${ + whiteSpace +}"> (containing only a <br>) in the <head> should split the <div> element`); + +promise_test(async () => { + await initializeAndWaitForLoad(iframe, minimumSrcDoc); + const childDoc = iframe.contentDocument; + const div = childDoc.createElement("div"); + div.setAttribute("style", `white-space:${whiteSpace}`); + childDoc.head.appendChild(div); + const utils = new EditorTestUtils(div); + utils.setupEditingHost("ab[]cd"); + await utils.sendEnterKey(); + removeResourceScriptElements(childDoc); + childDoc.head.removeAttribute("style"); + + assert_in_array( + childDoc.documentElement.innerHTML, + [ + `<head><title>iframe</title><div style="white-space:${whiteSpace}">ab</div><div style="white-space:${whiteSpace}">cd</div></head><body><br></body>`, + `<head><title>iframe</title><div style="white-space:${whiteSpace}">ab</div><div style="white-space:${whiteSpace}">cd<br></div></head><body><br></body>`, + `<head><title>iframe</title><div style="white-space:${whiteSpace}">ab<br></div><div style="white-space:${whiteSpace}">cd</div></head><body><br></body>`, + `<head><title>iframe</title><div style="white-space:${whiteSpace}">ab<br></div><div style="white-space:${whiteSpace}">cd<br></div></head><body><br></body>`, + ], + "The <div> should be split" + ); +}, `insertParagraph in <div style="white-space:${ + whiteSpace +}"> (containing text) in the <head> should split the <div> element`); +</script> +</body> +</html> diff --git a/testing/web-platform/tests/editing/other/insertparagraph-in-child-of-html.tentative.html b/testing/web-platform/tests/editing/other/insertparagraph-in-child-of-html.tentative.html new file mode 100644 index 0000000000..a82da32df1 --- /dev/null +++ b/testing/web-platform/tests/editing/other/insertparagraph-in-child-of-html.tentative.html @@ -0,0 +1,344 @@ +<!doctype html> +<html><head> +<meta chareset="utf-8"> +<meta name="timeout" content="long"> +<meta name="variant" content="?designMode=off&white-space=normal"> +<meta name="variant" content="?designMode=off&white-space=pre"> +<meta name="variant" content="?designMode=off&white-space=pre-line"> +<meta name="variant" content="?designMode=off&white-space=pre-wrap"> +<meta name="variant" content="?designMode=on&white-space=normal"> +<meta name="variant" content="?designMode=on&white-space=pre"> +<meta name="variant" content="?designMode=on&white-space=pre-line"> +<meta name="variant" content="?designMode=on&white-space=pre-wrap"> +<title>Insert paragraph in a child of the html element</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script src="../include/editor-test-utils.js"></script> +</head><body> +<iframe srcdoc=""></iframe> +<script> +"use strict"; + +const searchParams = new URLSearchParams(document.location.search); +const whiteSpace = searchParams.get("white-space"); +const testingDesignMode = searchParams.get("designMode") == "on"; + +const isPreformatted = + whiteSpace == "pre" || whiteSpace == "pre-line" || whiteSpace == "pre-wrap"; + +const iframe = document.querySelector("iframe"); +const minimumSrcDoc = + "<html>" + + "<head>" + + "<title>iframe</title>" + + "<script src='/resources/testdriver.js'></" + "script>" + + "<script src='/resources/testdriver-vendor.js'></" + "script>" + + "<script src='/resources/testdriver-actions.js'></" + "script>" + + "</head>" + + "<body><br></body>" + + "</html>"; + +async function initializeAndWaitForLoad(iframeElement, srcDocValue) { + const waitForLoad = + new Promise( + resolve => iframeElement.addEventListener("load", resolve, {once: true}) + ); + iframeElement.srcdoc = srcDocValue; + await waitForLoad; + if (testingDesignMode) { + iframeElement.contentDocument.designMode = "on"; + } else { + iframeElement.contentDocument.documentElement.setAttribute("contenteditable", ""); + } + iframeElement.contentWindow.focus(); + iframeElement.contentDocument.execCommand("defaultParagraphSeparator", false, "div"); +} + +function removeResourceScriptElements(node) { + node.querySelectorAll("script").forEach( + element => { + if (element.getAttribute("src")?.startsWith("/resources")) { + element.remove() + } + } + ); +} + +// DO NOT USE multi-line comment in this file, then, you can comment out +// unnecessary tests when you need to attach the browser with a debugger. + +// For backward compatibility, <div> elements outside <body> should be split +// by insertParagraph. However, should not unwrap existing <div> in any case +// to avoid its child to become children of the <html>. +promise_test(async () => { + await initializeAndWaitForLoad(iframe, minimumSrcDoc); + const childDoc = iframe.contentDocument; + const div = childDoc.createElement("div"); + div.setAttribute("style", `white-space:${whiteSpace}`); + childDoc.documentElement.appendChild(div); + const utils = new EditorTestUtils(div); + utils.setupEditingHost("{}"); + await utils.sendEnterKey(); + removeResourceScriptElements(childDoc); + + if (!isPreformatted) { + assert_equals( + childDoc.documentElement.innerHTML, + `<head><title>iframe</title></head><body><br></body><div style="white-space:${whiteSpace}"><br></div><div style="white-space:${whiteSpace}"><br></div>`, + "The <div> should be split" + ); + } else { + assert_in_array( + childDoc.documentElement.innerHTML, + [ + `<head><title>iframe</title></head><body><br></body><div style="white-space:${whiteSpace}">\n</div><div style="white-space:${whiteSpace}">\n</div>`, + `<head><title>iframe</title></head><body><br></body><div style="white-space:${whiteSpace}"><br></div><div style="white-space:${whiteSpace}"><br></div>`, + ], + "The <div> should be split" + ); + } +}, `insertParagraph in empty <div style="white-space:${ + whiteSpace +}"> after <body> should split the <div>`); + +promise_test(async () => { + await initializeAndWaitForLoad(iframe, minimumSrcDoc); + const childDoc = iframe.contentDocument; + const div = childDoc.createElement("div"); + div.setAttribute("style", `white-space:${whiteSpace}`); + childDoc.documentElement.appendChild(div); + const utils = new EditorTestUtils(div); + utils.setupEditingHost("{}<br>"); + await utils.sendEnterKey(); + removeResourceScriptElements(childDoc); + + if (!isPreformatted) { + assert_equals( + childDoc.documentElement.innerHTML, + `<head><title>iframe</title></head><body><br></body><div style="white-space:${whiteSpace}"><br></div><div style="white-space:${whiteSpace}"><br></div>`, + "The <div> should be split" + ); + } else { + assert_in_array( + childDoc.documentElement.innerHTML, + [ + `<head><title>iframe</title></head><body><br></body><div style="white-space:${whiteSpace}">\n</div><div style="white-space:${whiteSpace}">\n</div>`, + `<head><title>iframe</title></head><body><br></body><div style="white-space:${whiteSpace}"><br></div><div style="white-space:${whiteSpace}">\n</div>`, + `<head><title>iframe</title></head><body><br></body><div style="white-space:${whiteSpace}">\n</div><div style="white-space:${whiteSpace}"><br></div>`, + `<head><title>iframe</title></head><body><br></body><div style="white-space:${whiteSpace}"><br></div><div style="white-space:${whiteSpace}"><br></div>`, + ], + "The <div> should be split" + ); + } +}, `insertParagraph in <div style="white-space:${ + whiteSpace +}"> (containing only a <br>) after <body> should split the <div>`); + +promise_test(async () => { + await initializeAndWaitForLoad(iframe, minimumSrcDoc); + const childDoc = iframe.contentDocument; + const div = childDoc.createElement("div"); + div.setAttribute("style", `white-space:${whiteSpace}`); + childDoc.documentElement.appendChild(div); + const utils = new EditorTestUtils(div); + utils.setupEditingHost("ab[]cd"); + await utils.sendEnterKey(); + removeResourceScriptElements(childDoc); + + assert_in_array( + childDoc.documentElement.innerHTML, + [ + `<head><title>iframe</title></head><body><br></body><div style="white-space:${whiteSpace}">ab</div><div style="white-space:${whiteSpace}">cd</div>`, + `<head><title>iframe</title></head><body><br></body><div style="white-space:${whiteSpace}">ab<br></div><div style="white-space:${whiteSpace}">cd</div>`, + `<head><title>iframe</title></head><body><br></body><div style="white-space:${whiteSpace}">ab</div><div style="white-space:${whiteSpace}">cd<br></div>`, + `<head><title>iframe</title></head><body><br></body><div style="white-space:${whiteSpace}">ab<br></div><div style="white-space:${whiteSpace}">cd<br></div>`, + ], + "The <div> should be split" + ); +}, `insertParagraph in <div style="white-space:${ + whiteSpace +}"> (containing text) after <body> should not create another <div> element`); + +promise_test(async () => { + await initializeAndWaitForLoad(iframe, minimumSrcDoc); + const childDoc = iframe.contentDocument; + const div = childDoc.createElement("div"); + div.setAttribute("style", `white-space:${whiteSpace}`); + childDoc.documentElement.insertBefore(div, childDoc.body); + const utils = new EditorTestUtils(div); + utils.setupEditingHost("{}"); + await utils.sendEnterKey(); + removeResourceScriptElements(childDoc); + + if (!isPreformatted) { + assert_equals( + childDoc.documentElement.innerHTML, + `<head><title>iframe</title></head><div style="white-space:${whiteSpace}"><br></div><div style="white-space:${whiteSpace}"><br></div><body><br></body>`, + "The <div> should be split" + ); + } else { + assert_in_array( + childDoc.documentElement.innerHTML, + [ + `<head><title>iframe</title></head><div style="white-space:${whiteSpace}">\n</div><div style="white-space:${whiteSpace}">\n</div><body><br></body>`, + `<head><title>iframe</title></head><div style="white-space:${whiteSpace}"><br></div><div style="white-space:${whiteSpace}"><br></div><body><br></body>`, + ], + "The <div> should be split" + ); + } +}, `insertParagraph in empty <div style="white-space:${ + whiteSpace +}"> before <body> should split the <div>`); + +promise_test(async () => { + await initializeAndWaitForLoad(iframe, minimumSrcDoc); + const childDoc = iframe.contentDocument; + const div = childDoc.createElement("div"); + div.setAttribute("style", `white-space:${whiteSpace}`); + childDoc.documentElement.insertBefore(div, childDoc.body); + const utils = new EditorTestUtils(div); + utils.setupEditingHost("{}<br>"); + await utils.sendEnterKey(); + removeResourceScriptElements(childDoc); + + if (!isPreformatted) { + assert_equals( + childDoc.documentElement.innerHTML, + `<head><title>iframe</title></head><div style="white-space:${whiteSpace}"><br></div><div style="white-space:${whiteSpace}"><br></div><body><br></body>`, + "The <div> should be split" + ); + } else { + assert_in_array( + childDoc.documentElement.innerHTML, + [ + `<head><title>iframe</title></head><div style="white-space:${whiteSpace}">\n</div><div style="white-space:${whiteSpace}">\n</div><body><br></body>`, + `<head><title>iframe</title></head><div style="white-space:${whiteSpace}"><br></div><div style="white-space:${whiteSpace}">\n</div><body><br></body>`, + `<head><title>iframe</title></head><div style="white-space:${whiteSpace}">\n</div><div style="white-space:${whiteSpace}"><br></div><body><br></body>`, + `<head><title>iframe</title></head><div style="white-space:${whiteSpace}"><br></div><div style="white-space:${whiteSpace}"><br></div><body><br></body>`, + ], + "The <div> should be split" + ); + } +}, `insertParagraph in <div style="white-space:${ + whiteSpace +}"> (containing only a <br>) before <body> should split the <div>`); + +promise_test(async () => { + await initializeAndWaitForLoad(iframe, minimumSrcDoc); + const childDoc = iframe.contentDocument; + const div = childDoc.createElement("div"); + div.setAttribute("style", `white-space:${whiteSpace}`); + childDoc.documentElement.insertBefore(div, childDoc.body); + const utils = new EditorTestUtils(div); + utils.setupEditingHost("ab[]cd"); + await utils.sendEnterKey(); + removeResourceScriptElements(childDoc); + + assert_in_array( + childDoc.documentElement.innerHTML, + [ + `<head><title>iframe</title></head><div style="white-space:${whiteSpace}">ab</div><div style="white-space:${whiteSpace}">cd</div><body><br></body>`, + `<head><title>iframe</title></head><div style="white-space:${whiteSpace}">ab<br></div><div style="white-space:${whiteSpace}">cd</div><body><br></body>`, + `<head><title>iframe</title></head><div style="white-space:${whiteSpace}">ab</div><div style="white-space:${whiteSpace}">cd<br></div><body><br></body>`, + `<head><title>iframe</title></head><div style="white-space:${whiteSpace}">ab<br></div><div style="white-space:${whiteSpace}">cd<br></div><body><br></body>`, + ], + "The <div> should be split" + ); +}, `insertParagraph in <div style="white-space:${ + whiteSpace +}"> (containing text) before <body> should split the <div>`); + +promise_test(async () => { + await initializeAndWaitForLoad(iframe, minimumSrcDoc); + const childDoc = iframe.contentDocument; + const div = document.createElement("div"); + div.setAttribute("style", `white-space:${whiteSpace}`); + childDoc.documentElement.insertBefore(div, childDoc.head); + const utils = new EditorTestUtils(div); + utils.setupEditingHost("{}"); + await utils.sendEnterKey(); + removeResourceScriptElements(childDoc); + + if (!isPreformatted) { + assert_equals( + childDoc.documentElement.innerHTML, + `<div style="white-space:${whiteSpace}"><br></div><div style="white-space:${whiteSpace}"><br></div><head><title>iframe</title></head><body><br></body>`, + "The <div> should be split" + ); + } else { + assert_in_array( + childDoc.documentElement.innerHTML, + [ + `<div style="white-space:${whiteSpace}">\n</div><div style="white-space:${whiteSpace}">\n</div><head><title>iframe</title></head><body><br></body>`, + `<div style="white-space:${whiteSpace}"><br></div><div style="white-space:${whiteSpace}"><br></div><head><title>iframe</title></head><body><br></body>`, + ], + "The <div> should be split" + ); + } +}, `insertParagraph in empty <div style="white-space:${ + whiteSpace +}"> before <head> should split the <div>`); + +promise_test(async () => { + await initializeAndWaitForLoad(iframe, minimumSrcDoc); + const childDoc = iframe.contentDocument; + const div = childDoc.createElement("div"); + div.setAttribute("style", `white-space:${whiteSpace}`); + childDoc.documentElement.insertBefore(div, childDoc.head); + const utils = new EditorTestUtils(div); + utils.setupEditingHost("{}<br>"); + await utils.sendEnterKey(); + removeResourceScriptElements(childDoc); + + if (!isPreformatted) { + assert_equals( + childDoc.documentElement.innerHTML, + `<div style="white-space:${whiteSpace}"><br></div><div style="white-space:${whiteSpace}"><br></div><head><title>iframe</title></head><body><br></body>`, + "The <div> should be split" + ); + } else { + assert_in_array( + childDoc.documentElement.innerHTML, + [ + `<div style="white-space:${whiteSpace}">\n</div><div style="white-space:${whiteSpace}">\n</div><head><title>iframe</title></head><body><br></body>`, + `<div style="white-space:${whiteSpace}"><br></div><div style="white-space:${whiteSpace}">\n</div><head><title>iframe</title></head><body><br></body>`, + `<div style="white-space:${whiteSpace}">\n</div><div style="white-space:${whiteSpace}"><br></div><head><title>iframe</title></head><body><br></body>`, + `<div style="white-space:${whiteSpace}"><br></div><div style="white-space:${whiteSpace}"><br></div><head><title>iframe</title></head><body><br></body>`, + ], + "The <div> should be split" + ); + } +}, `insertParagraph in <div style="white-space:${ + whiteSpace +}"> (containing only a <br>) before <head> should split the <div>`); + +promise_test(async () => { + await initializeAndWaitForLoad(iframe, minimumSrcDoc); + const childDoc = iframe.contentDocument; + const div = childDoc.createElement("div"); + div.setAttribute("style", `white-space:${whiteSpace}`); + childDoc.documentElement.insertBefore(div, childDoc.head); + const utils = new EditorTestUtils(div); + utils.setupEditingHost("ab[]cd"); + await utils.sendEnterKey(); + removeResourceScriptElements(childDoc); + + assert_in_array( + childDoc.documentElement.innerHTML, + [ + `<div style="white-space:${whiteSpace}">ab</div><div style="white-space:${whiteSpace}">cd</div><head><title>iframe</title></head><body><br></body>`, + `<div style="white-space:${whiteSpace}">ab<br></div><div style="white-space:${whiteSpace}">cd</div><head><title>iframe</title></head><body><br></body>`, + `<div style="white-space:${whiteSpace}">ab</div><div style="white-space:${whiteSpace}">cd<br></div><head><title>iframe</title></head><body><br></body>`, + `<div style="white-space:${whiteSpace}">ab<br></div><div style="white-space:${whiteSpace}">cd<br></div><head><title>iframe</title></head><body><br></body>`, + ], + "The <div> should be split" + ); +}, `insertParagraph in <div style="white-space:${ + whiteSpace +}"> (containing text) before <head> should split the <div>`); + +</script> +</body></html> diff --git a/testing/web-platform/tests/editing/other/insertparagraph-in-editing-host-cannot-have-div.tentative.html b/testing/web-platform/tests/editing/other/insertparagraph-in-editing-host-cannot-have-div.tentative.html new file mode 100644 index 0000000000..fe6ea2c183 --- /dev/null +++ b/testing/web-platform/tests/editing/other/insertparagraph-in-editing-host-cannot-have-div.tentative.html @@ -0,0 +1,182 @@ +<!doctype html> +<meta charset=utf-8> +<meta name="timeout" content="long"> + +<meta name="variant" content="?host=span&white-space=normal&display=block&command=insertParagraph"> +<meta name="variant" content="?host=span&white-space=pre&display=block&command=insertParagraph"> +<meta name="variant" content="?host=span&white-space=pre-wrap&display=block&command=insertParagraph"> +<meta name="variant" content="?host=span&white-space=pre-line&display=block&command=insertParagraph"> +<meta name="variant" content="?host=span&white-space=normal&display=block&command=insertText"> +<meta name="variant" content="?host=span&white-space=pre&display=block&command=insertText"> +<meta name="variant" content="?host=span&white-space=pre-wrap&display=block&command=insertText"> +<meta name="variant" content="?host=span&white-space=pre-line&display=block&command=insertText"> + +<meta name="variant" content="?host=span&white-space=normal&display=inline&command=insertParagraph"> +<meta name="variant" content="?host=span&white-space=pre&display=inline&command=insertParagraph"> +<meta name="variant" content="?host=span&white-space=pre-wrap&display=inline&command=insertParagraph"> +<meta name="variant" content="?host=span&white-space=pre-line&display=inline&command=insertParagraph"> +<meta name="variant" content="?host=span&white-space=normal&display=inline&command=insertText"> +<meta name="variant" content="?host=span&white-space=pre&display=inline&command=insertText"> +<meta name="variant" content="?host=span&white-space=pre-wrap&display=inline&command=insertText"> +<meta name="variant" content="?host=span&white-space=pre-line&display=inline&command=insertText"> + +<meta name="variant" content="?host=span&white-space=normal&display=inline-block&command=insertParagraph"> +<meta name="variant" content="?host=span&white-space=pre&display=inline-block&command=insertParagraph"> +<meta name="variant" content="?host=span&white-space=pre-wrap&display=inline-block&command=insertParagraph"> +<meta name="variant" content="?host=span&white-space=pre-line&display=inline-block&command=insertParagraph"> +<meta name="variant" content="?host=span&white-space=normal&display=inline-block&command=insertText"> +<meta name="variant" content="?host=span&white-space=pre&display=inline-block&command=insertText"> +<meta name="variant" content="?host=span&white-space=pre-wrap&display=inline-block&command=insertText"> +<meta name="variant" content="?host=span&white-space=pre-line&display=inline-block&command=insertText"> + +<meta name="variant" content="?host=p&white-space=normal&display=block&command=insertParagraph"> +<meta name="variant" content="?host=p&white-space=pre&display=block&command=insertParagraph"> +<meta name="variant" content="?host=p&white-space=pre-wrap&display=block&command=insertParagraph"> +<meta name="variant" content="?host=p&white-space=pre-line&display=block&command=insertParagraph"> +<meta name="variant" content="?host=p&white-space=normal&display=block&command=insertText"> +<meta name="variant" content="?host=p&white-space=pre&display=block&command=insertText"> +<meta name="variant" content="?host=p&white-space=pre-wrap&display=block&command=insertText"> +<meta name="variant" content="?host=p&white-space=pre-line&display=block&command=insertText"> + +<meta name="variant" content="?host=p&white-space=normal&display=inline&command=insertParagraph"> +<meta name="variant" content="?host=p&white-space=pre&display=inline&command=insertParagraph"> +<meta name="variant" content="?host=p&white-space=pre-wrap&display=inline&command=insertParagraph"> +<meta name="variant" content="?host=p&white-space=pre-line&display=inline&command=insertParagraph"> +<meta name="variant" content="?host=p&white-space=normal&display=inline&command=insertText"> +<meta name="variant" content="?host=p&white-space=pre&display=inline&command=insertText"> +<meta name="variant" content="?host=p&white-space=pre-wrap&display=inline&command=insertText"> +<meta name="variant" content="?host=p&white-space=pre-line&display=inline&command=insertText"> + +<meta name="variant" content="?host=p&white-space=normal&display=inline-block&command=insertParagraph"> +<meta name="variant" content="?host=p&white-space=pre&display=inline-block&command=insertParagraph"> +<meta name="variant" content="?host=p&white-space=pre-wrap&display=inline-block&command=insertParagraph"> +<meta name="variant" content="?host=p&white-space=pre-line&display=inline-block&command=insertParagraph"> +<meta name="variant" content="?host=p&white-space=normal&display=inline-block&command=insertText"> +<meta name="variant" content="?host=p&white-space=pre&display=inline-block&command=insertText"> +<meta name="variant" content="?host=p&white-space=pre-wrap&display=inline-block&command=insertText"> +<meta name="variant" content="?host=p&white-space=pre-line&display=inline-block&command=insertText"> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="../include/editor-test-utils.js"></script> +<link rel=stylesheet href=../include/reset.css> +<title>Tests for inserting paragraph in editing host which cannot have <div> element as child</title> +<body></body> +<script> +const params = new URLSearchParams(location.search); +const tag = params.get("host"); +const whiteSpace = params.get("white-space"); +const isNewLineSignificant = whiteSpace == "pre" || whiteSpace == "pre-line" || whiteSpace == "pre-wrap"; +const display = params.get("display"); +const command = params.get("command"); +const editingHost = document.createElement(tag); +editingHost.contentEditable = true; +editingHost.style.whiteSpace = whiteSpace; +editingHost.style.display = display; +document.body.appendChild(editingHost); + +function execInsertTextOrParagraphCommand() { + if (command == "insertParagraph") { + document.execCommand(command); + } else { + // Inserting a linefeed by insertText command should be equivalent of insertParagraph. + document.execCommand(command, false, "\n"); + } +} + +const editingHostOpenTagAttrs = `contenteditable style="display:${display}; white-space:${whiteSpace}"`; +test(() => { + const utils = new EditorTestUtils(editingHost); + utils.setupEditingHost(`a[]b`); + editingHost.getBoundingClientRect(); + execInsertTextOrParagraphCommand(); + // A linefeed should be inserted if it's significant. Otherwise, <br>. + assert_equals( + editingHost.innerHTML, + isNewLineSignificant ? "a\nb" : "a<br>b" + ); +}, `<${tag} ${editingHostOpenTagAttrs}>a[]b</${tag}>`); + +test(() => { + const utils = new EditorTestUtils(editingHost); + utils.setupEditingHost(`<span style="white-space:normal">a[]b</span>`); + editingHost.getBoundingClientRect(); + execInsertTextOrParagraphCommand(); + // A <br> element should be inserted if another <span> makes the linebreaks not significant. + assert_equals(editingHost.innerHTML, `<span style="white-space:normal">a<br>b</span>`); +}, `<${tag} ${editingHostOpenTagAttrs}><span style="white-space:normal">a[]b</span></${tag}>`); + +if (isNewLineSignificant) { + test(() => { + const utils = new EditorTestUtils(editingHost); + utils.setupEditingHost(`<span style="white-space:normal"><span style="white-space:${whiteSpace}">a[]b</span></span>`); + editingHost.getBoundingClientRect(); + execInsertTextOrParagraphCommand(); + // A linefeed should be inserted even if `white-space` is changed by ancestor, but it's back to preformatted. + assert_equals(editingHost.innerHTML, `<span style="white-space:normal"><span style="white-space:${whiteSpace}">a\nb</span></span>`); + }, `<${tag} ${editingHostOpenTagAttrs}><span style="white-space:normal"><span style="white-space:${whiteSpace}">a[]b</span></span></${tag}>`); +} + +test(() => { + const utils = new EditorTestUtils(editingHost); + utils.setupEditingHost(`<span style="display:block">a[]b</span>`); + editingHost.getBoundingClientRect(); + execInsertTextOrParagraphCommand(); + // Split the internal <span> which is styled as block. + assert_equals( + editingHost.innerHTML, + `<span style="display:block">a</span><span style="display:block">b</span>` + ); +}, `<${tag} ${editingHostOpenTagAttrs}><span style="display:block;white-space:normal">a[]b</span></${tag}>`); + +test(() => { + const utils = new EditorTestUtils(editingHost); + utils.setupEditingHost(`<div>a[]b</div>`); + editingHost.getBoundingClientRect(); + execInsertTextOrParagraphCommand(); + // Although neither <span> nor <p> can have <div>, but if the insertion point is in the invalid <div>, + // browsers should just split the <div>. + assert_equals(editingHost.innerHTML, `<div>a</div><div>b</div>`); +}, `<${tag} ${editingHostOpenTagAttrs}><div>a[]b</div></${tag}>`); + +test(() => { + const utils = new EditorTestUtils(editingHost); + utils.setupEditingHost(`<div style="display:inline">a[]b</div>`); + editingHost.getBoundingClientRect(); + execInsertTextOrParagraphCommand(); + // If <div> is styled as inline, it should be treated like <span>. + assert_equals(editingHost.innerHTML, `<div style="display:inline">a\nb</div>`); +}, `<${tag} ${editingHostOpenTagAttrs}><div style="display:inline">a[]b</div></${tag}>`); + +test(() => { + const utils = new EditorTestUtils(editingHost); + utils.setupEditingHost(`<div style="display:inline-block">a[]b</div>`); + editingHost.getBoundingClientRect(); + execInsertTextOrParagraphCommand(); + // If <div> is styled as inline-block, it should be treated like <span>. + assert_equals( + editingHost.innerHTML, + isNewLineSignificant + ? `<div style="display:inline-block">a\nb</div>` + : `<div style="display:inline-block">a<br>b</div>` + ); +}, `<${tag} ${editingHostOpenTagAttrs}><div style="display:inline-block">a[]b</div></${tag}>`); + +test(() => { + const utils = new EditorTestUtils(editingHost); + utils.setupEditingHost(`<div style="display:inline;white-space:normal">a[]b</div>`); + editingHost.getBoundingClientRect(); + execInsertTextOrParagraphCommand(); + // If <div> is styled as inline, it should be treated like <span>. + assert_equals(editingHost.innerHTML, `<div style="display:inline;white-space:normal">a<br>b</div>`); +}, `<${tag} ${editingHostOpenTagAttrs}><div style="display:inline;white-space:normal">a[]b</div></${tag}>`); + +test(() => { + const utils = new EditorTestUtils(editingHost); + utils.setupEditingHost(`<div style="display:inline-block;white-space:normal">a[]b</div>`); + editingHost.getBoundingClientRect(); + execInsertTextOrParagraphCommand(); + // If <div> is styled as inline-block, it should be treated like <span>. + assert_equals(editingHost.innerHTML, `<div style="display:inline-block;white-space:normal">a<br>b</div>`); +}, `<${tag} ${editingHostOpenTagAttrs}><div style="display:inline-block;white-space:normal">a[]b</div></${tag}>`); +</script> diff --git a/testing/web-platform/tests/editing/other/insertparagraph-in-inline-editing-host.tentative.html b/testing/web-platform/tests/editing/other/insertparagraph-in-inline-editing-host.tentative.html new file mode 100644 index 0000000000..9baed3f7fa --- /dev/null +++ b/testing/web-platform/tests/editing/other/insertparagraph-in-inline-editing-host.tentative.html @@ -0,0 +1,502 @@ +<!doctype html> +<meta chareset="utf-8"> +<meta name="timeout" content="long"> + +<meta name="variant" content="?white-space=normal&display=inline&method=enter"> +<meta name="variant" content="?white-space=normal&display=inline&method=shift-enter"> +<meta name="variant" content="?white-space=normal&display=inline-block&method=enter"> +<meta name="variant" content="?white-space=normal&display=inline-block&method=shift-enter"> +<meta name="variant" content="?white-space=normal&display=block&method=enter"> +<meta name="variant" content="?white-space=normal&display=block&method=shift-enter"> +<meta name="variant" content="?white-space=normal&display=list-item&method=enter"> +<meta name="variant" content="?white-space=normal&display=list-item&method=shift-enter"> +<meta name="variant" content="?white-space=normal&display=table-cell&method=enter"> +<meta name="variant" content="?white-space=normal&display=table-cell&method=shift-enter"> + +<meta name="variant" content="?white-space=pre&display=inline&method=enter"> +<meta name="variant" content="?white-space=pre&display=inline&method=shift-enter"> +<meta name="variant" content="?white-space=pre&display=inline-block&method=enter"> +<meta name="variant" content="?white-space=pre&display=inline-block&method=shift-enter"> +<meta name="variant" content="?white-space=pre&display=block&method=enter"> +<meta name="variant" content="?white-space=pre&display=block&method=shift-enter"> +<meta name="variant" content="?white-space=pre&display=list-item&method=enter"> +<meta name="variant" content="?white-space=pre&display=list-item&method=shift-enter"> +<meta name="variant" content="?white-space=pre&display=table-cell&method=enter"> +<meta name="variant" content="?white-space=pre&display=table-cell&method=shift-enter"> + +<meta name="variant" content="?white-space=pre-line&display=inline&method=enter"> +<meta name="variant" content="?white-space=pre-line&display=inline&method=shift-enter"> +<meta name="variant" content="?white-space=pre-line&display=inline-block&method=enter"> +<meta name="variant" content="?white-space=pre-line&display=inline-block&method=shift-enter"> +<meta name="variant" content="?white-space=pre-line&display=block&method=enter"> +<meta name="variant" content="?white-space=pre-line&display=block&method=shift-enter"> +<meta name="variant" content="?white-space=pre-line&display=list-item&method=enter"> +<meta name="variant" content="?white-space=pre-line&display=list-item&method=shift-enter"> +<meta name="variant" content="?white-space=pre-line&display=table-cell&method=enter"> +<meta name="variant" content="?white-space=pre-line&display=table-cell&method=shift-enter"> + +<meta name="variant" content="?white-space=pre-wrap&display=inline&method=enter"> +<meta name="variant" content="?white-space=pre-wrap&display=inline&method=shift-enter"> +<meta name="variant" content="?white-space=pre-wrap&display=inline-block&method=enter"> +<meta name="variant" content="?white-space=pre-wrap&display=inline-block&method=shift-enter"> +<meta name="variant" content="?white-space=pre-wrap&display=block&method=enter"> +<meta name="variant" content="?white-space=pre-wrap&display=block&method=shift-enter"> +<meta name="variant" content="?white-space=pre-wrap&display=list-item&method=enter"> +<meta name="variant" content="?white-space=pre-wrap&display=list-item&method=shift-enter"> +<meta name="variant" content="?white-space=pre-wrap&display=table-cell&method=enter"> +<meta name="variant" content="?white-space=pre-wrap&display=table-cell&method=shift-enter"> + +<title>Line breaking in inline editing host</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script src="../include/editor-test-utils.js"></script> +<div><span contenteditable></span></div> +<script> +"use strict"; + +const searchParams = new URLSearchParams(document.location.search); +const testingInsertParagraph = searchParams.get("method") == "enter"; +const whiteSpace = searchParams.get("white-space"); +const display = searchParams.get("display"); + +const isPreformatted = + whiteSpace == "pre" || whiteSpace == "pre-line" || whiteSpace == "pre-wrap"; + +const editingHost = document.querySelector("span[contenteditable]"); +const container = editingHost.parentElement; +const utils = new EditorTestUtils(editingHost); +const modifiers = (() => { + if (testingInsertParagraph) { + return null; + } + // Only Safari treats `Ctrl+Enter` as insertLineBreak + if (navigator.platform.includes("Mac") && + navigator.userAgent.includes("Safari") && + !navigator.userAgent.includes("Chrom")) { + return utils.kControl; + } + // The others including WebKitGTK treat `Shift+Enter` as it. + return utils.kShift; +})(); + +for (const defaultParagraphSeparator of ["div", "p"]) { + document.execCommand( + "defaultParagraphSeparator", + false, + defaultParagraphSeparator + ); + + promise_test(async t => { + editingHost.setAttribute( + "style", + `display:${display};white-space:${whiteSpace}` + ); + utils.setupEditingHost("{}"); + await utils.sendEnterKey(modifiers); + editingHost.removeAttribute("style"); + // In this case, the inserting line break is the last visible thing in the + // block. Therefore, additional <br> or a preformatted linefeed is also + // required to make the new line visible. + if (!isPreformatted) { + assert_equals( + container.innerHTML, + '<span contenteditable=""><br><br></span>', + `A <br> and additional <br> should be inserted when ${t.name}` + ); + } else { + assert_in_array( + container.innerHTML, + [ + '<span contenteditable="">\n<br></span>', + '<span contenteditable="">\n\n</span>', + ], + `A linefeed and additional line breaker should be inserted when ${t.name}` + ); + } + }, `${ + testingInsertParagraph ? "insertParagraph" : "insertLineBreak" + } in <span contenteditable style="display:${ + display + };white-space:${whiteSpace}">{}</span> (defaultParagraphSeparator=${ + defaultParagraphSeparator + })`); + + promise_test(async t => { + editingHost.setAttribute( + "style", + `display:${display};white-space:${whiteSpace}` + ); + const brElement = document.createElement("br"); + try { + container.appendChild(brElement); + utils.setupEditingHost("{}"); + await utils.sendEnterKey(modifiers); + editingHost.removeAttribute("style"); + // Even if the <span> element is followed by an invisible <br>, it does + // not make the new line in the <span> element visible. Therefore, + // inserting additional line break is required in this case too. + if (!isPreformatted) { + assert_equals( + container.innerHTML, + '<span contenteditable=""><br><br></span><br>', + `A <br> and additional <br> should be inserted when ${t.name}` + ); + } else { + assert_in_array( + container.innerHTML, + [ + `<span contenteditable="">\n\n</span><br>`, + `<span contenteditable="">\n<br></span><br>`, + ], + `A linefeed and additional line break should be inserted when ${t.name}` + ); + } + } finally { + brElement.remove(); + } + }, `${ + testingInsertParagraph ? "insertParagraph" : "insertLineBreak" + } in <span contenteditable style="display:${ + display + };white-space:${ + whiteSpace + }">{}</span> followed by a <br> (defaultParagraphSeparator=${ + defaultParagraphSeparator + })`); + + promise_test(async t => { + editingHost.setAttribute( + "style", + `display:${display};white-space:${whiteSpace}` + ); + const divElement = document.createElement("div"); + divElement.textContent = "efg"; + try { + container.appendChild(divElement); + utils.setupEditingHost("{}"); + await utils.sendEnterKey(modifiers); + editingHost.removeAttribute("style"); + // When the <span> element is followed by a <div>, making empty last + // line visible requires an invisible <br> after a line break. + if (!isPreformatted) { + assert_equals( + container.innerHTML, + '<span contenteditable=""><br><br></span><div>efg</div>', + `A <br> and additional <br> should be inserted when ${t.name}` + ); + } else { + assert_in_array( + container.innerHTML, + [ + `<span contenteditable="">\n\n</span><div>efg</div>`, + `<span contenteditable="">\n<br></span><div>efg</div>`, + ], + `A linefeed and additional line break should be inserted when ${t.name}` + ); + } + } finally { + divElement.remove(); + } + }, `${ + testingInsertParagraph ? "insertParagraph" : "insertLineBreak" + } in <span contenteditable style="display:${ + display + };white-space:${ + whiteSpace + }">{}</span> followed by a <div> (defaultParagraphSeparator=${ + defaultParagraphSeparator + })`); + + promise_test(async t => { + editingHost.setAttribute( + "style", + `display:${display};white-space:${whiteSpace}` + ); + const text = document.createTextNode("abc"); + try { + container.appendChild(text); + utils.setupEditingHost("{}"); + await utils.sendEnterKey(modifiers); + editingHost.removeAttribute("style"); + // Even if the <span> element is followed by visible text, it does + // not make the new line in the <span> element visible. Therefore, + // inserting additional line break is required in this case too. + if (!isPreformatted) { + assert_equals( + container.innerHTML, + '<span contenteditable=""><br><br></span>abc', + `A <br> and additional <br> should be inserted when ${t.name}` + ); + } else { + assert_in_array( + container.innerHTML, + [ + `<span contenteditable="">\n\n</span>abc`, + `<span contenteditable="">\n<br></span>abc`, + ], + `A linefeed and additional line break should be inserted when ${t.name}` + ); + } + } finally { + text.remove(); + } + }, `${ + testingInsertParagraph ? "insertParagraph" : "insertLineBreak" + } in <span contenteditable style="display:${ + display + };white-space:${ + whiteSpace + }">{}</span> followed by text (defaultParagraphSeparator=${ + defaultParagraphSeparator + })`); + + promise_test(async t => { + editingHost.setAttribute( + "style", + `display:${display};white-space:${whiteSpace}` + ); + utils.setupEditingHost("{}<br>"); + await utils.sendEnterKey(modifiers); + editingHost.removeAttribute("style"); + // In this case, there is a <br> element which makes the new line (last + // line) visible. Therefore, only a line break should be inserted. + if (!isPreformatted) { + assert_equals( + container.innerHTML, + `<span contenteditable=""><br><br></span>`, + `A <br> should be inserted when ${t.name}` + ); + } else { + assert_equals( + container.innerHTML, + `<span contenteditable="">\n<br></span>`, + `A <br> should be inserted when ${t.name}` + ); + } + }, `${ + testingInsertParagraph ? "insertParagraph" : "insertLineBreak" + } in <span contenteditable style="display:${ + display + };white-space:${whiteSpace}">{}<br></span> (defaultParagraphSeparator=${ + defaultParagraphSeparator + })`); + + promise_test(async t => { + editingHost.setAttribute( + "style", + `display:${display};white-space:${whiteSpace}` + ); + utils.setupEditingHost("[]abcd"); + await utils.sendEnterKey(modifiers); + editingHost.removeAttribute("style"); + assert_equals( + container.innerHTML, + `<span contenteditable="">${ + isPreformatted ? "\n" : "<br>" + }abcd</span>`, + `${ + isPreformatted ? "A linefeed" : "A <br>" + } should be inserted when ${t.name}` + ); + }, `${ + testingInsertParagraph ? "insertParagraph" : "insertLineBreak" + } in <span contenteditable style="display:${ + display + };white-space:${whiteSpace}">[]abcd</span> (defaultParagraphSeparator=${ + defaultParagraphSeparator + })`); + + promise_test(async t => { + editingHost.setAttribute( + "style", + `display:${display};white-space:${whiteSpace}` + ); + utils.setupEditingHost("ab[]cd"); + await utils.sendEnterKey(modifiers); + editingHost.removeAttribute("style"); + assert_equals( + container.innerHTML, + `<span contenteditable="">ab${ + isPreformatted ? "\n" : "<br>" + }cd</span>`, + `${ + isPreformatted ? "A linefeed" : "A <br>" + } should be inserted when ${t.name}` + ); + }, `${ + testingInsertParagraph ? "insertParagraph" : "insertLineBreak" + } in <span contenteditable style="display:${ + display + };white-space:${whiteSpace}">ab[]cd</span> (defaultParagraphSeparator=${ + defaultParagraphSeparator + })`); + + promise_test(async t => { + editingHost.setAttribute( + "style", + `display:${display};white-space:${whiteSpace}` + ); + utils.setupEditingHost("abcd[]"); + await utils.sendEnterKey(modifiers); + editingHost.removeAttribute("style"); + // In this case, the inserting line break is the last visible thing in the + // block. Therefore, additional line break is also required to make the + // new line visible. + if (!isPreformatted) { + assert_equals( + container.innerHTML, + `<span contenteditable="">abcd<br><br></span>`, + `A <br> and additional <br> should be inserted when ${t.name}` + ); + } else { + assert_in_array( + container.innerHTML, + [ + `<span contenteditable="">abcd\n<br></span>`, + `<span contenteditable="">abcd\n\n</span>`, + ], + `A linefeed and additional line break should be inserted when ${t.name}` + ); + } + }, `${ + testingInsertParagraph ? "insertParagraph" : "insertLineBreak" + } in <span contenteditable style="display:${ + display + };white-space:${whiteSpace}">abcd[]</span> (defaultParagraphSeparator=${ + defaultParagraphSeparator + })`); + + promise_test(async t => { + editingHost.setAttribute( + "style", + `display:${display};white-space:${whiteSpace}` + ); + const brElement = document.createElement("br"); + try { + container.appendChild(brElement); + utils.setupEditingHost("abcd[]"); + await utils.sendEnterKey(modifiers); + editingHost.removeAttribute("style"); + // Even if the <span> element is followed by an invisible <br>, it does + // not make the new line in the <span> element visible. Therefore, + // inserting additional line break is required in this case too. + if (!isPreformatted) { + assert_equals( + container.innerHTML, + '<span contenteditable="">abcd<br><br></span><br>', + `A <br> and additional <br> should be inserted when ${t.name}` + ); + } else { + assert_in_array( + container.innerHTML, + [ + `<span contenteditable="">abcd\n<br></span><br>`, + `<span contenteditable="">abcd\n\n</span><br>`, + ], + `A linefeed and additional line break should be inserted when ${t.name}` + ); + } + } finally { + brElement.remove(); + } + }, `${ + testingInsertParagraph ? "insertParagraph" : "insertLineBreak" + } in <span contenteditable style="display:${ + display + };white-space:${ + whiteSpace + }">abcd[]</span> followed by a <br> element (defaultParagraphSeparator=${ + defaultParagraphSeparator + })`); + + promise_test(async t => { + editingHost.setAttribute( + "style", + `display:${display};white-space:${whiteSpace}` + ); + const divElement = document.createElement("div"); + divElement.textContent = "efg"; + try { + container.appendChild(divElement); + utils.setupEditingHost("abcd[]"); + await utils.sendEnterKey(modifiers); + editingHost.removeAttribute("style"); + // When the <span> element is followed by a <div>, making empty last + // line visible requires an invisible <br> after a line break. + if (!isPreformatted) { + assert_equals( + container.innerHTML, + '<span contenteditable="">abcd<br><br></span><div>efg</div>', + `A <br> and additional <br> should be inserted when ${t.name}` + ); + } else { + assert_in_array( + container.innerHTML, + [ + `<span contenteditable="">abcd\n<br></span><div>efg</div>`, + `<span contenteditable="">abcd\n\n</span><div>efg</div>`, + ], + `A linefeed and additional line break should be inserted when ${t.name}` + ); + } + } finally { + divElement.remove(); + } + }, `${ + testingInsertParagraph ? "insertParagraph" : "insertLineBreak" + } in <span contenteditable style="display:${ + display + };white-space:${ + whiteSpace + }">abcd[]</span> followed by a <div> element (defaultParagraphSeparator=${ + defaultParagraphSeparator + })`); + + promise_test(async t => { + editingHost.setAttribute( + "style", + `display:${display};white-space:${whiteSpace}` + ); + const text = document.createTextNode("efg"); + try { + container.appendChild(text); + utils.setupEditingHost("abcd[]"); + await utils.sendEnterKey(modifiers); + editingHost.removeAttribute("style"); + // Even if the <span> element is followed by visible text, it does + // not make the new line in the <span> element visible. Therefore, + // inserting additional line break is required in this case too. + if (!isPreformatted) { + assert_equals( + container.innerHTML, + '<span contenteditable="">abcd<br><br></span>efg', + `A <br> and additional <br> should be inserted when ${t.name}` + ); + } else { + assert_in_array( + container.innerHTML, + [ + `<span contenteditable="">abcd\n<br></span>efg`, + `<span contenteditable="">abcd\n\n</span>efg`, + ], + `A linefeed and additional line break should be inserted when ${t.name}` + ); + } + } finally { + text.remove(); + } + }, `${ + testingInsertParagraph ? "insertParagraph" : "insertLineBreak" + } in <span contenteditable style="display:${ + display + };white-space:${ + whiteSpace + }">abcd[]</span> followed by text (defaultParagraphSeparator=${ + defaultParagraphSeparator + })`); +} + +</script> diff --git a/testing/web-platform/tests/editing/other/insertparagraph-in-non-splittable-element.html b/testing/web-platform/tests/editing/other/insertparagraph-in-non-splittable-element.html new file mode 100644 index 0000000000..c77862fecb --- /dev/null +++ b/testing/web-platform/tests/editing/other/insertparagraph-in-non-splittable-element.html @@ -0,0 +1,142 @@ +<!doctype html> +<meta charset="utf-8"> +<meta name="timeout" content="long"> +<title>Test for inserting paragraph in non-splittable elements</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script src="../include/editor-test-utils.js"></script> +<div contenteditable></div> +<script> +"use strict"; + +const editingHost = document.querySelector("div[contenteditable]"); +const utils = new EditorTestUtils(editingHost); + +const tests = [ + { + selector: "button", + initial: "<div><button>abc</button></div>", + // <button> can have <br> so that it should be handled as insertLineBreak. + expected: "<div><button><br>abc</button></div>", + }, + { + selector: "caption", + initial: "<div><table><caption>abc</caption><tbody><tr><td>abc</td></tr></tbody></table></div>", + // <caption> can have paragraphs so that it should be handled as in a block. + expected: "<div><table><caption><br>abc</caption><tbody><tr><td>abc</td></tr></tbody></table></div>", + }, + { + selector: "col", + initial: "<div><table><colgroup><col></colgroup><tbody><tr><td>abc</td></tr></tbody></table></div>", + // <col> and its table parents cannot have paragraphs nor <br>, therefore, + // it should be handled outside <table> or the first cell in the table. + expected: [ + "<div><table><colgroup><col></colgroup><tbody><tr><td><br>abc</td></tr></tbody></table></div>", // handled with the first cell case + "<div><br></div><div><table><colgroup><col></colgroup><tbody><tr><td>abc</td></tr></tbody></table></div>", // handled outside the table case + ], + }, + { + selector: "colgroup", + initial: "<div><table><colgroup><col></colgroup><tbody><tr><td>abc</td></tr></tbody></table></div>", + // <colgroup> and its table parents cannot have paragraphs nor <br>, + // therefore, it should be handled outside <table> or the the first cell + // in the table. + expected: [ + "<div><table><colgroup><col></colgroup><tbody><tr><td><br>abc</td></tr></tbody></table></div>", // handled with the first cell case + "<div><br></div><div><table><colgroup><col></colgroup><tbody><tr><td>abc</td></tr></tbody></table></div>", // handled outside the table case + ], + }, + { + selector: "iframe", + initial: "<div><iframe srcdoc=\"abc\"></iframe></div>", + // <iframe> is a replaced element so that it should be handled outside of it. + expected: "<div><br></div><div><iframe srcdoc=\"abc\"></iframe></div>", + }, + { + selector: "legend", + initial: "<div><fieldset><legend>abc</legend></fieldset></div>", + // <fieldset> cannot have multiple <legend> elements so that it should not + // be split, and it cannot have paragraphs so that <br> element should be + // inserted instead. + expected: "<div><fieldset><legend><br>abc</legend></fieldset></div>", + }, + { + selector: "meter", + initial: "<div><meter max=\"100\" value=\"50\">abc</meter></div>", + // <meter> is a replaced element so that it should be handled outside of it. + expected: "<div><br></div><div><meter max=\"100\" value=\"50\">abc</meter></div>", + }, + { + selector: "optgroup", + initial: "<div><select><optgroup><option>abc</option></optgroup></select></div>", + // <optgroup> is a part of <select> and they are replaced so that it should + // be handled outside of it. + expected: "<div><br></div><div><select><optgroup><option>abc</option></optgroup></select></div>", + }, + { + selector: "option", + initial: "<div><select><option>abc</option></select></div>", + // <option> is a part of <select> and they are replaced so that it should + // be handled outside of it. + expected: "<div><select><option>abc</option></select></div>", + }, + { + selector: "progress", + initial: "<div><progress max=\"100\" value=\"50\">abc</progress></div>", + // <meter> is a replaced element so that it should be handled outside of it. + expected: "<div><br></div><div><progress max=\"100\" value=\"50\">abc</progress></div>", + }, + { + selector: "select", + initial: "<div><select><option>abc</option></select></div>", + // <select> is a replaced element so that it should be handled outside of it. + expected: "<div><br></div><div><select><option>abc</option></select></div>", + }, + { + selector: "table", + initial: "<div><table><tbody><tr><td>abc</td></tr></tbody></table></div>", + // <table> cannot have paragraphs nor <br>, therefore, it should be handled + // outside or in the first cell in the table. + expected: [ + "<div><table><tbody><tr><td><br>abc</td></tr></tbody></table></div>", // handled in the first cell case + "<div><br></div><div><table><tbody><tr><td>abc</td></tr></tbody></table></div>", // handled outside the table case + ], + }, + { + selector: "tbody", + initial: "<div><table><tbody><tr><td>abc</td></tr></tbody></table></div>", + // <tbody> and its parent cannot have paragraphs nor <br>, therefore, + // it should be handled outside <table> or the first cell in the table. + expected: [ + "<div><table><tbody><tr><td><br>abc</td></tr></tbody></table></div>", // handled in the next cell case + "<div><br></div><div><table><tbody><tr><td>abc</td></tr></tbody></table></div>", // handled outside the table case + ], + }, + { + selector: "tr", + initial: "<div><table><tbody><tr><td>abc</td></tr></tbody></table></div>", + // <tr> and its table parents cannot have paragraphs nor <br>, therefore, + // it should be handled outside <table> or the first cell in the table. + expected: [ + "<div><table><tbody><tr><td><br>abc</td></tr></tbody></table></div>", // handled in the next cell case + "<div><br></div><div><table><tbody><tr><td>abc</td></tr></tbody></table></div>", // handled outside the table case + ], + }, +]; + +for (const currentTest of tests) { + promise_test(async t => { + editingHost.innerHTML = currentTest.initial; + getSelection().collapse(editingHost.querySelector(currentTest.selector), 0); + await utils.sendEnterKey(); + if (Array.isArray(currentTest.expected)) { + assert_in_array(editingHost.innerHTML, currentTest.expected); + } else { + assert_equals(editingHost.innerHTML, currentTest.expected); + } + }, `insertParagraph in ${currentTest.selector} of ${currentTest.initial}`); +} +</script> diff --git a/testing/web-platform/tests/editing/other/insertparagraph-with-white-space-style.tentative.html b/testing/web-platform/tests/editing/other/insertparagraph-with-white-space-style.tentative.html new file mode 100644 index 0000000000..3c9f1848f5 --- /dev/null +++ b/testing/web-platform/tests/editing/other/insertparagraph-with-white-space-style.tentative.html @@ -0,0 +1,475 @@ +<!doctype html> +<meta charset=utf-8> +<meta name="timeout" content="long"> +<meta name="variant" content="?white-space=pre&command=insertParagraph"> +<meta name="variant" content="?white-space=pre-wrap&command=insertParagraph"> +<meta name="variant" content="?white-space=pre-line&command=insertParagraph"> +<meta name="variant" content="?white-space=nowrap&command=insertParagraph"> +<meta name="variant" content="?white-space=pre&command=insertText"> +<meta name="variant" content="?white-space=pre-wrap&command=insertText"> +<meta name="variant" content="?white-space=pre-line&command=insertText"> +<meta name="variant" content="?white-space=nowrap&command=insertText"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="../include/editor-test-utils.js"></script> +<link rel=stylesheet href=../include/reset.css> +<title>insertparagraph in white-space specified element</title> +<body><div contenteditable></div></body> +<script> +/** + * This test checks how insertParagraph command and insertText of "\n" works + * in valid styles of parent (editing host itself or in an splittable element). + */ +const params = new URLSearchParams(location.search); +const style = params.get("white-space"); +const isNewLineSignificant = style == "pre" || style == "pre-wrap" || style == "pre-line"; +const command = params.get("command"); +const editingHost = document.querySelector("div[contenteditable]"); +function execInsertTextOrParagraphCommand() { + if (command == "insertParagraph") { + document.execCommand(command); + } else { + // Inserting a linefeed by insertText command should be equivalent of insertParagraph + document.execCommand(command, false, "\n"); + } +} +for (const defaultParagraphSeparator of ["div", "p"]) { + document.execCommand("defaultParagraphSeparator", false, defaultParagraphSeparator); + for (const display of ["block", "inline", "inline-block"]) { + // Inserting paragraph or inserting a linefeed in a text node which is + // a direct child of the editing host. + test(() => { + editingHost.style.whiteSpace = style; + editingHost.style.display = display; + const utils = new EditorTestUtils(editingHost); + utils.setupEditingHost(`abc[]`); + editingHost.getBoundingClientRect(); + execInsertTextOrParagraphCommand(); + // If the editing host is a block, at least the new paragraph should be + // the default paragraph separator element. + if (display == "block") { + assert_in_array( + editingHost.innerHTML, + [ + `abc<${defaultParagraphSeparator}><br></${defaultParagraphSeparator}>`, + `<${defaultParagraphSeparator}>abc</${defaultParagraphSeparator}><${defaultParagraphSeparator}><br></${defaultParagraphSeparator}>`, + ], + "New paragraph should be inserted at end of the editing host" + ); + } + // Otherwise, i.e., the editing host is inline, insert a line break (a + // linefeed or <br>) should be inserted instead because it's better + // look for the users. + // Note that an extra line break is required for making the last line + // visible because the editing host is the last visible inline in the + // parent block (<body>). + else if (isNewLineSignificant) { + assert_in_array( + editingHost.innerHTML, + [ + `abc\n\n`, + `abc\n<br>`, + ], + "A linefeed should be inserted at end" + ); + } else { + assert_equals( + editingHost.innerHTML, + `abc<br><br>`, + "A <br> should be inserted at end" + ); + } + }, `<div contenteditable style="white-space:${style}; display:${display}">abc[]</div> (defaultParagraphSeparator: ${defaultParagraphSeparator})`); + + // Same as above test except the caret position. + test(() => { + editingHost.style.whiteSpace = style; + editingHost.style.display = display; + const utils = new EditorTestUtils(editingHost); + utils.setupEditingHost(`[]abc`); + editingHost.getBoundingClientRect(); + execInsertTextOrParagraphCommand(); + if (display == "block") { + assert_in_array( + editingHost.innerHTML, + [ + `<${defaultParagraphSeparator}><br></${defaultParagraphSeparator}>abc`, + `<${defaultParagraphSeparator}><br></${defaultParagraphSeparator}><${defaultParagraphSeparator}>abc</${defaultParagraphSeparator}>`, + ], + "New paragraph should be inserted at start of the editing host" + ); + } else if (isNewLineSignificant) { + assert_in_array( + editingHost.innerHTML, + [ + `\nabc`, + `\nabc<br>`, + ], + "A linefeed should be inserted at start" + ); + } else { + assert_in_array( + editingHost.innerHTML, + [ + `<br>abc`, + `<br>abc<br>`, + ], + "A <br> should be inserted at start" + ); + } + }, `<div contenteditable style="white-space:${style}; display:${display}">[]abc</div> (defaultParagraphSeparator: ${defaultParagraphSeparator})`); + + // Same as above test except the caret position. + test(() => { + editingHost.style.whiteSpace = style; + editingHost.style.display = display; + const utils = new EditorTestUtils(editingHost); + utils.setupEditingHost(`a[]bc`); + editingHost.getBoundingClientRect(); + execInsertTextOrParagraphCommand(); + if (display == "block") { + assert_in_array( + editingHost.innerHTML, + [ + `a<${defaultParagraphSeparator}>bc</${defaultParagraphSeparator}>`, + `<${defaultParagraphSeparator}>a</${defaultParagraphSeparator}><${defaultParagraphSeparator}>bc</${defaultParagraphSeparator}>`, + ], + "New paragraph should split the text" + ); + } else if (isNewLineSignificant) { + assert_in_array( + editingHost.innerHTML, + [ + `a\nbc`, + `a\nbc<br>`, + ], + "A linefeed should be inserted" + ); + } else { + assert_in_array( + editingHost.innerHTML, + [ + `a<br>bc`, + `a<br>bc<br>`, + ], + "A <br> should be inserted" + ); + } + }, `<div contenteditable style="white-space:${style}; display:${display}">a[]bc</div> (defaultParagraphSeparator: ${defaultParagraphSeparator})`); + + // Inserting paragraph or inserting a linefeed in a text node after + // executing the "italic" command. The paragraph or line break result + // should be same as above, but the text in the new paragraph or new line + // should be wrapped in <i>. + test(() => { + editingHost.style.whiteSpace = style; + editingHost.style.display = display; + const utils = new EditorTestUtils(editingHost); + utils.setupEditingHost(`abc[]`); + editingHost.getBoundingClientRect(); + document.execCommand("italic"); + execInsertTextOrParagraphCommand(); + document.execCommand("inserttext", false, "def"); + if (display == "block") { + assert_in_array( + editingHost.innerHTML, + [ + `abc<${defaultParagraphSeparator}><i>def</i></${defaultParagraphSeparator}>`, + `<${defaultParagraphSeparator}>abc</${defaultParagraphSeparator}><${defaultParagraphSeparator}><i>def</i></${defaultParagraphSeparator}>`, + `<${defaultParagraphSeparator}>abc</${defaultParagraphSeparator}><${defaultParagraphSeparator}><i>def<br></i></${defaultParagraphSeparator}>`, + `<${defaultParagraphSeparator}>abc</${defaultParagraphSeparator}><${defaultParagraphSeparator}><i>def</i><br></${defaultParagraphSeparator}>`, + ], + "New paragraph should be inserted at end of the editing host whose text should be italic" + ); + } else if (isNewLineSignificant) { + assert_in_array( + editingHost.innerHTML, + [ + `abc\n<i>def</i>`, + `abc\n<i>def\n</i>`, + `abc\n<i>def<br></i>`, + `abc\n<i>def</i>\n`, + `abc\n<i>def</i><br>`, + ], + "The new line should be italic" + ); + } else { + assert_in_array( + editingHost.innerHTML, + [ + `abc<br><i>def</i>`, + `abc<br><i>def<br></i>`, + `abc<br><i>def</i><br>`, + ], + "The new line should be italic" + ); + } + }, `<div contenteditable style="white-space:${style}; display:${display}">abc[]</div> (defaultParagraphSeparator: ${defaultParagraphSeparator}) (preserving temporary inline style test)`); + + // Inserting paragraph or inserting a linefeed in a text node which is + // wrapped in a <b>. The paragraph or line break result should be same as + // above, but the <b> element should be duplicated in the new paragraph + // or shouldn't be split if inserting a line break. + test(() => { + editingHost.style.whiteSpace = style; + editingHost.style.display = display; + const utils = new EditorTestUtils(editingHost); + utils.setupEditingHost(`<b>abc[]</b>`); + editingHost.getBoundingClientRect(); + execInsertTextOrParagraphCommand(); + document.execCommand("inserttext", false, "def"); + if (display == "block") { + assert_in_array( + editingHost.innerHTML, + [ + `<b>abc</b><${defaultParagraphSeparator}><b>def</b></${defaultParagraphSeparator}>`, + `<${defaultParagraphSeparator}><b>abc</b></${defaultParagraphSeparator}><${defaultParagraphSeparator}><b>def</b></${defaultParagraphSeparator}>`, + `<${defaultParagraphSeparator}><b>abc</b></${defaultParagraphSeparator}><${defaultParagraphSeparator}><b>def<br></b></${defaultParagraphSeparator}>`, + `<${defaultParagraphSeparator}><b>abc</b></${defaultParagraphSeparator}><${defaultParagraphSeparator}><b>def</b><br></${defaultParagraphSeparator}>`, + ], + "New paragraph should be inserted at end of the editing host whose text should be bold" + ); + } else if (isNewLineSignificant) { + assert_in_array( + editingHost.innerHTML, + [ + `<b>abc\ndef</b>`, + `<b>abc\ndef\n</b>`, + `<b>abc\ndef<br></b>`, + `<b>abc\ndef</b>\n`, + `<b>abc\ndef</b><br>`, + ], + "The new line should be bold" + ); + } else { + assert_in_array( + editingHost.innerHTML, + [ + `<b>abc<br>def</b>`, + `<b>abc<br>def<br></b>`, + `<b>abc<br>def</b><br>`, + ], + "The new line should be bold" + ); + } + }, `<div contenteditable style="white-space:${style}; display:${display}"><b>abc[]</b></div> (defaultParagraphSeparator: ${defaultParagraphSeparator}) (preserving inline style test)`); + + for (const paragraph of ["div", "p"]) { + // Inserting paragraph or inserting a linefeed in a splittable paragraph + // (<p> or <div>) whose `white-space` is specified. + test(() => { + editingHost.style.whiteSpace = "normal"; + editingHost.style.display = display; + const utils = new EditorTestUtils(editingHost); + utils.setupEditingHost(`<${paragraph} style="white-space:${style}">abc[]</${paragraph}>`); + editingHost.getBoundingClientRect(); + execInsertTextOrParagraphCommand(); + // Even if the editing host is inline, the command should be handled + // with in the splittable paragraph. Therefore, the paragraph should + // be just split and the style attribute should be cloned to keep same + // style in the new paragraph. + assert_equals( + editingHost.innerHTML, + `<${paragraph} style="white-space:${style}">abc</${paragraph}><${paragraph} style="white-space:${style}"><br></${paragraph}>`, + "New paragraph should be inserted at end of the paragraph" + ); + }, `<div contenteditable style="display:${display}"><${paragraph} style="white-space:${style}">abc[]</${paragraph}></div> (defaultParagraphSeparator: ${defaultParagraphSeparator})`); + + // Same as above test except the caret position. + test(() => { + editingHost.style.whiteSpace = "normal"; + editingHost.style.display = display; + const utils = new EditorTestUtils(editingHost); + utils.setupEditingHost(`<${paragraph} style="white-space:${style}">[]abc</${paragraph}>`); + editingHost.getBoundingClientRect(); + execInsertTextOrParagraphCommand(); + assert_in_array( + editingHost.innerHTML, + [ + `<${paragraph} style="white-space:${style}"><br></${paragraph}><${paragraph} style="white-space:${style}">abc</${paragraph}>`, + `<${paragraph} style="white-space:${style}"><br></${paragraph}><${paragraph} style="white-space:${style}">abc<br></${paragraph}>`, + ], + "New paragraph should be inserted at start of the paragraph" + ); + }, `<div contenteditable style="display:${display}"><${paragraph} style="white-space:${style}">[]abc</${paragraph}></div> (defaultParagraphSeparator: ${defaultParagraphSeparator})`); + + // Same as above test except the caret position. + test(() => { + editingHost.style.whiteSpace = "normal"; + editingHost.style.display = display; + const utils = new EditorTestUtils(editingHost); + utils.setupEditingHost(`<${paragraph} style="white-space:${style}">a[]bc</${paragraph}>`); + editingHost.getBoundingClientRect(); + execInsertTextOrParagraphCommand(); + assert_in_array( + editingHost.innerHTML, + [ + `<${paragraph} style="white-space:${style}">a</${paragraph}><${paragraph} style="white-space:${style}">bc</${paragraph}>`, + `<${paragraph} style="white-space:${style}">a</${paragraph}><${paragraph} style="white-space:${style}">bc<br></${paragraph}>`, + ], + "The paragraph should be split" + ); + }, `<div contenteditable style="display:${display}"><${paragraph} style="white-space:${style}">a[]bc</${paragraph}></div> (defaultParagraphSeparator: ${defaultParagraphSeparator})`); + + // Inserting paragraph or inserting a linefeed in a splittable paragraph + // in the editing host whose `white-space` is specified. + test(() => { + editingHost.style.whiteSpace = style; + editingHost.style.display = display; + const utils = new EditorTestUtils(editingHost); + utils.setupEditingHost(`<${paragraph}>abc[]</${paragraph}>`); + editingHost.getBoundingClientRect(); + execInsertTextOrParagraphCommand(); + // Same as previous tests, the splittable paragraph should be split. + // The `white-space` style of the ancestor block or the inline editing + // host should not affect to the behavior because we can just split + // the paragraph. + assert_equals( + editingHost.innerHTML, + `<${paragraph}>abc</${paragraph}><${paragraph}><br></${paragraph}>`, + "New paragraph should be inserted at end of the paragraph" + ); + }, `<div contenteditable style="display:${display}; white-space:${style}"><${paragraph}>abc[]</${paragraph}></div> (defaultParagraphSeparator: ${defaultParagraphSeparator})`); + + // Same as above test except the caret position. + test(() => { + editingHost.style.whiteSpace = style; + editingHost.style.display = display; + const utils = new EditorTestUtils(editingHost); + utils.setupEditingHost(`<${paragraph}>[]abc</${paragraph}>`); + editingHost.getBoundingClientRect(); + execInsertTextOrParagraphCommand(); + assert_in_array( + editingHost.innerHTML, + [ + `<${paragraph}><br></${paragraph}><${paragraph}>abc</${paragraph}>`, + `<${paragraph}><br></${paragraph}><${paragraph}>abc<br></${paragraph}>`, + ], + "New paragraph should be inserted at start of the paragraph" + ); + }, `<div contenteditable style="display:${display}; white-space:${style}"><${paragraph}>[]abc</${paragraph}></div> (defaultParagraphSeparator: ${defaultParagraphSeparator})`); + + // Same as above test except the caret position. + test(() => { + editingHost.style.whiteSpace = style; + editingHost.style.display = display; + const utils = new EditorTestUtils(editingHost); + utils.setupEditingHost(`<${paragraph}>a[]bc</${paragraph}>`); + editingHost.getBoundingClientRect(); + execInsertTextOrParagraphCommand(); + assert_in_array( + editingHost.innerHTML, + [ + `<${paragraph}>a</${paragraph}><${paragraph}>bc</${paragraph}>`, + `<${paragraph}>a</${paragraph}><${paragraph}>bc<br></${paragraph}>`, + ], + "The paragraph should be split" + ); + }, `<div contenteditable style="display:${display}; white-space:${style}"><${paragraph}>a[]bc</${paragraph}></div> (defaultParagraphSeparator: ${defaultParagraphSeparator})`); + + // Inserting paragraph or inserting a linefeed in a splittable paragraph + // element whose `display` and `white-space` are specified. + test(() => { + editingHost.style.whiteSpace = "normal"; + editingHost.style.display = "block"; + const utils = new EditorTestUtils(editingHost); + const styleAttr = `style="display:${display}; white-space:${style}"`; + utils.setupEditingHost(`<${paragraph} ${styleAttr}>abc[]</${paragraph}>`); + editingHost.getBoundingClientRect(); + execInsertTextOrParagraphCommand(); + // If the paragraph is a normal block, we can just split the paragraph. + if (display == "block") { + assert_equals( + editingHost.innerHTML, + `<${paragraph} ${styleAttr}>abc</${paragraph}><${paragraph} ${styleAttr}><br></${paragraph}>`, + "New paragraph should be inserted at end of the paragraph" + ); + } + // Otherwise, the paragraph is an inline, splitting the paragraph + // element does not look like inserting paragraph for the users + // because it would just duplicate the inlined element. + // Therefore, the split paragraph should be wrapped into the new + // paragraph (considered with the default paragraph separator) at + // least. However, <p> cannot contain <p> nor <div> which may be + // styled as inline. Therefore, <div> should be used for the new + // paragraph even if the default paragraph separator is <p>. + else { + assert_in_array( + editingHost.innerHTML, + [ + `<${paragraph} ${styleAttr}>abc</${paragraph}><div><${paragraph} ${styleAttr}><br></${paragraph}></div>`, + `<div><${paragraph} ${styleAttr}>abc</${paragraph}></div><div><${paragraph} ${styleAttr}><br></${paragraph}></div>`, + ], + "New paragraph should be inserted at end of the paragraph which is wrapped by a new <div>" + ); + } + }, `<div contenteditable><${paragraph} style="display:${display}; white-space:${style}">abc[]</${paragraph}></div> (defaultParagraphSeparator: ${defaultParagraphSeparator})`); + + // Same as above test except the caret position. + test(() => { + editingHost.style.whiteSpace = "normal"; + editingHost.style.display = "block"; + const utils = new EditorTestUtils(editingHost); + const styleAttr = `style="display:${display}; white-space:${style}"`; + utils.setupEditingHost(`<${paragraph} ${styleAttr}>[]abc</${paragraph}>`); + editingHost.getBoundingClientRect(); + execInsertTextOrParagraphCommand(); + if (display == "block") { + assert_in_array( + editingHost.innerHTML, + [ + `<${paragraph} ${styleAttr}><br></${paragraph}><${paragraph} ${styleAttr}>abc</${paragraph}>`, + `<${paragraph} ${styleAttr}><br></${paragraph}><${paragraph} ${styleAttr}>abc<br></${paragraph}>`, + ], + "New paragraph should be inserted at start of the paragraph" + ); + } else { + assert_in_array( + editingHost.innerHTML, + [ + `<div><${paragraph} ${styleAttr}><br></${paragraph}></div><${paragraph} ${styleAttr}>abc</${paragraph}>`, + `<div><${paragraph} ${styleAttr}><br></${paragraph}></div><${paragraph} ${styleAttr}>abc<br></${paragraph}>`, + `<div><${paragraph} ${styleAttr}><br></${paragraph}></div><div><${paragraph} ${styleAttr}>abc</${paragraph}></div>`, + `<div><${paragraph} ${styleAttr}><br></${paragraph}></div><div><${paragraph} ${styleAttr}>abc<br></${paragraph}></div>`, + ], + "New paragraph should be inserted at start of the paragraph which is wrapped by a new <div>" + ); + } + + }, `<div contenteditable><${paragraph} style="display:${display}; white-space:${style}">[]abc</${paragraph}></div> (defaultParagraphSeparator: ${defaultParagraphSeparator})`); + + // Same as above test except the caret position. + test(() => { + editingHost.style.whiteSpace = "normal"; + editingHost.style.display = "block"; + const styleAttr = `style="display:${display}; white-space:${style}"`; + const utils = new EditorTestUtils(editingHost); + utils.setupEditingHost(`<${paragraph} ${styleAttr}>a[]bc</${paragraph}>`); + editingHost.getBoundingClientRect(); + execInsertTextOrParagraphCommand(); + if (display == "block") { + assert_in_array( + editingHost.innerHTML, + [ + `<${paragraph} ${styleAttr}>a</${paragraph}><${paragraph} ${styleAttr}>bc</${paragraph}>`, + `<${paragraph} ${styleAttr}>a</${paragraph}><${paragraph} ${styleAttr}>bc<br></${paragraph}>`, + ], + "The paragraph should be split" + ); + } else { + assert_in_array( + editingHost.innerHTML, + [ + `<${paragraph} ${styleAttr}>a</${paragraph}><div><${paragraph} ${styleAttr}>bc</${paragraph}></div>`, + `<${paragraph} ${styleAttr}>a</${paragraph}><div><${paragraph} ${styleAttr}>bc<br></${paragraph}></div>`, + `<div><${paragraph} ${styleAttr}>a</${paragraph}></div><div><${paragraph} ${styleAttr}>bc</${paragraph}></div>`, + `<div><${paragraph} ${styleAttr}>a</${paragraph}></div><div><${paragraph} ${styleAttr}>bc<br></${paragraph}></div>`, + ], + "The paragraph should be split and the latter one should be wrapped by a new <div>" + ); + } + }, `<div contenteditable><${paragraph} style="display:${display}; white-space:${style}">a[]bc</${paragraph}></div> (defaultParagraphSeparator: ${defaultParagraphSeparator})`); + } + } +} +</script> diff --git a/testing/web-platform/tests/editing/other/inserttext-after-bold-in-font-face-monospace.html b/testing/web-platform/tests/editing/other/inserttext-after-bold-in-font-face-monospace.html new file mode 100644 index 0000000000..cc937f28f8 --- /dev/null +++ b/testing/web-platform/tests/editing/other/inserttext-after-bold-in-font-face-monospace.html @@ -0,0 +1,32 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +</head> +<body> +<div contenteditable><div><br></div></div> +<script> +"use strict"; + +const editingHost = document.querySelector("div[contenteditable]"); +test(() => { + editingHost.focus(); + document.execCommand("fontName", false, "monospace"); + document.execCommand("insertText", false, "abc"); + document.execCommand("insertParagraph"); + document.execCommand("insertText", false, "def "); + document.execCommand("bold"); + document.execCommand("insertText", false, "g"); + assert_in_array( + editingHost.querySelector("div + div").innerHTML, + [ + '<font face="monospace">def <b>g</b></font>', + '<font face="monospace">def <b>g<br></b></font>', + ] + ); +}, ""); +</script> +</body> +</html> diff --git a/testing/web-platform/tests/editing/other/inserttext-at-end-of-block-when-br-always-block.html b/testing/web-platform/tests/editing/other/inserttext-at-end-of-block-when-br-always-block.html new file mode 100644 index 0000000000..922b8bd1c8 --- /dev/null +++ b/testing/web-platform/tests/editing/other/inserttext-at-end-of-block-when-br-always-block.html @@ -0,0 +1,36 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<title>Typing white-space and another character at end of a block should preserve the white-space when br element is always block</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> +br { display: block; } +</style> +<script> +"use strict"; + +addEventListener("load", () => { + test( + () => { + const editingHost = document.querySelector("div[contenteditable]"); + editingHost.focus(); + getSelection().collapse(editingHost.firstChild, "abc".length); + document.execCommand("insertText", false, " "); + document.execCommand("insertText", false, "d"); + assert_in_array( + editingHost.innerHTML, + [ + "abc d", + "abc d<br>", + ] + ); + }, + "Inserting white-space and a character at block end should keep the white-space even before block <br> element" + ); +}, {once: true}); +</script> +</head> +<body><div contenteditable>abc</div></body> +</html> diff --git a/testing/web-platform/tests/editing/other/join-different-white-space-style-left-line-and-right-paragraph.html b/testing/web-platform/tests/editing/other/join-different-white-space-style-left-line-and-right-paragraph.html new file mode 100644 index 0000000000..48fa581115 --- /dev/null +++ b/testing/web-platform/tests/editing/other/join-different-white-space-style-left-line-and-right-paragraph.html @@ -0,0 +1,899 @@ +<!doctype html> +<head> +<meta charset="utf-8"> +<meta name="timeout" content="long"> +<meta name="variant" content="?method=backspace&left-white-space=normal&right-white-space=pre"> +<meta name="variant" content="?method=backspace&left-white-space=normal&right-white-space=pre-wrap"> +<meta name="variant" content="?method=backspace&left-white-space=normal&right-white-space=pre-line"> +<meta name="variant" content="?method=backspace&left-white-space=normal&right-white-space=nowrap"> +<meta name="variant" content="?method=backspace&left-white-space=pre&right-white-space=normal"> +<meta name="variant" content="?method=backspace&left-white-space=pre&right-white-space=pre-wrap"> +<meta name="variant" content="?method=backspace&left-white-space=pre&right-white-space=pre-line"> +<meta name="variant" content="?method=backspace&left-white-space=pre&right-white-space=nowrap"> +<meta name="variant" content="?method=backspace&left-white-space=pre-wrap&right-white-space=normal"> +<meta name="variant" content="?method=backspace&left-white-space=pre-wrap&right-white-space=pre"> +<meta name="variant" content="?method=backspace&left-white-space=pre-wrap&right-white-space=pre-line"> +<meta name="variant" content="?method=backspace&left-white-space=pre-wrap&right-white-space=nowrap"> +<meta name="variant" content="?method=backspace&left-white-space=pre-line&right-white-space=normal"> +<meta name="variant" content="?method=backspace&left-white-space=pre-line&right-white-space=pre"> +<meta name="variant" content="?method=backspace&left-white-space=pre-line&right-white-space=pre-wrap"> +<meta name="variant" content="?method=backspace&left-white-space=pre-line&right-white-space=nowrap"> +<meta name="variant" content="?method=backspace&left-white-space=nowrap&right-white-space=normal"> +<meta name="variant" content="?method=backspace&left-white-space=nowrap&right-white-space=pre"> +<meta name="variant" content="?method=backspace&left-white-space=nowrap&right-white-space=pre-wrap"> +<meta name="variant" content="?method=backspace&left-white-space=nowrap&right-white-space=pre-line"> + +<meta name="variant" content="?method=forwarddelete&left-white-space=normal&right-white-space=pre"> +<meta name="variant" content="?method=forwarddelete&left-white-space=normal&right-white-space=pre-wrap"> +<meta name="variant" content="?method=forwarddelete&left-white-space=normal&right-white-space=pre-line"> +<meta name="variant" content="?method=forwarddelete&left-white-space=normal&right-white-space=nowrap"> +<meta name="variant" content="?method=forwarddelete&left-white-space=pre&right-white-space=normal"> +<meta name="variant" content="?method=forwarddelete&left-white-space=pre&right-white-space=pre-wrap"> +<meta name="variant" content="?method=forwarddelete&left-white-space=pre&right-white-space=pre-line"> +<meta name="variant" content="?method=forwarddelete&left-white-space=pre&right-white-space=nowrap"> +<meta name="variant" content="?method=forwarddelete&left-white-space=pre-wrap&right-white-space=normal"> +<meta name="variant" content="?method=forwarddelete&left-white-space=pre-wrap&right-white-space=pre"> +<meta name="variant" content="?method=forwarddelete&left-white-space=pre-wrap&right-white-space=pre-line"> +<meta name="variant" content="?method=forwarddelete&left-white-space=pre-wrap&right-white-space=nowrap"> +<meta name="variant" content="?method=forwarddelete&left-white-space=pre-line&right-white-space=normal"> +<meta name="variant" content="?method=forwarddelete&left-white-space=pre-line&right-white-space=pre"> +<meta name="variant" content="?method=forwarddelete&left-white-space=pre-line&right-white-space=pre-wrap"> +<meta name="variant" content="?method=forwarddelete&left-white-space=pre-line&right-white-space=nowrap"> +<meta name="variant" content="?method=forwarddelete&left-white-space=nowrap&right-white-space=normal"> +<meta name="variant" content="?method=forwarddelete&left-white-space=nowrap&right-white-space=pre"> +<meta name="variant" content="?method=forwarddelete&left-white-space=nowrap&right-white-space=pre-wrap"> +<meta name="variant" content="?method=forwarddelete&left-white-space=nowrap&right-white-space=pre-line"> + +<meta name="variant" content="?method=select-boundary&left-white-space=normal&right-white-space=pre"> +<meta name="variant" content="?method=select-boundary&left-white-space=normal&right-white-space=pre-wrap"> +<meta name="variant" content="?method=select-boundary&left-white-space=normal&right-white-space=pre-line"> +<meta name="variant" content="?method=select-boundary&left-white-space=normal&right-white-space=nowrap"> +<meta name="variant" content="?method=select-boundary&left-white-space=pre&right-white-space=normal"> +<meta name="variant" content="?method=select-boundary&left-white-space=pre&right-white-space=pre-wrap"> +<meta name="variant" content="?method=select-boundary&left-white-space=pre&right-white-space=pre-line"> +<meta name="variant" content="?method=select-boundary&left-white-space=pre&right-white-space=nowrap"> +<meta name="variant" content="?method=select-boundary&left-white-space=pre-wrap&right-white-space=normal"> +<meta name="variant" content="?method=select-boundary&left-white-space=pre-wrap&right-white-space=pre"> +<meta name="variant" content="?method=select-boundary&left-white-space=pre-wrap&right-white-space=pre-line"> +<meta name="variant" content="?method=select-boundary&left-white-space=pre-wrap&right-white-space=nowrap"> +<meta name="variant" content="?method=select-boundary&left-white-space=pre-line&right-white-space=normal"> +<meta name="variant" content="?method=select-boundary&left-white-space=pre-line&right-white-space=pre"> +<meta name="variant" content="?method=select-boundary&left-white-space=pre-line&right-white-space=pre-wrap"> +<meta name="variant" content="?method=select-boundary&left-white-space=pre-line&right-white-space=nowrap"> +<meta name="variant" content="?method=select-boundary&left-white-space=nowrap&right-white-space=normal"> +<meta name="variant" content="?method=select-boundary&left-white-space=nowrap&right-white-space=pre"> +<meta name="variant" content="?method=select-boundary&left-white-space=nowrap&right-white-space=pre-wrap"> +<meta name="variant" content="?method=select-boundary&left-white-space=nowrap&right-white-space=pre-line"> +<title>Tests for joining first line of right paragraph with its preceding line</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script src="../include/editor-test-utils.js"></script> +<style> +.pre { + white-space: pre; +} +.preWrap { + white-space: pre-wrap; +} +.preLine { + white-space: pre-line; +} +.nowrap { + white-space: nowrap; +} +</style> +</head> +<body> +<div contenteditable></div> +<script> +"use strict"; + +const searchParams = new URLSearchParams(document.location.search); +const testingBackspace = searchParams.get("method") == "backspace"; +const testingSelectBoundary = searchParams.get("method") == "select-boundary"; +const commandName = + testingBackspace || testingSelectBoundary ? "delete" : "forwarddelete"; +const editingHost = document.querySelector("div[contenteditable]"); +const caretInLeft = (() => { + if (testingSelectBoundary) { + return "["; + } + return testingBackspace ? "" : "[]"; +})(); +const caretInRight = (() => { + if (testingSelectBoundary) { + return "]"; + } + return testingBackspace ? "[]" : ""; +})(); +const leftWhiteSpace = `white-space:${searchParams.get("left-white-space")}`; +const rightWhiteSpace = `white-space:${searchParams.get("right-white-space")}`; +const leftWhiteSpacePreserveLineBreaks = + searchParams.get("left-white-space") == "pre" || + searchParams.get("left-white-space") == "pre-wrap" || + searchParams.get("left-white-space") == "pre-line"; +const rightWhiteSpacePreserveLineBreaks = + searchParams.get("right-white-space") == "pre" || + searchParams.get("right-white-space") == "pre-wrap" || + searchParams.get("right-white-space") == "pre-line"; +const leftWhiteSpaceIsNormal = + searchParams.get("left-white-space") == "normal"; +const rightWhiteSpaceIsNormal = + searchParams.get("right-white-space") == "normal"; +const leftWhiteSpaceClass = (() => { + switch (searchParams.get("left-white-space")) { + case "pre": + return "pre"; + case "pre-wrap": + return "preWrap"; + case "pre-line": + return "preLine"; + case "nowrap": + return "nowrap"; + default: + return null; + } +})(); +const rightWhiteSpaceClass = (() => { + switch (searchParams.get("right-white-space")) { + case "pre": + return "pre"; + case "pre-wrap": + return "preWrap"; + case "pre-line": + return "preLine"; + case "nowrap": + return "nowrap"; + default: + return null; + } +})(); +const utils = new EditorTestUtils(editingHost); + +const tests = [ + // The cases that the preceding line is a child of parent block whose + // white-space is normal. + { + initialHTML: + `abc${caretInLeft}` + + `<div style="${rightWhiteSpace}">${caretInRight}def\nghi</div>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `abc<span ${aAttrsInLeftBlock}>def</span>` + + `<div style="${rightWhiteSpace}">ghi</div>`, + ]; + }, + skip: !rightWhiteSpacePreserveLineBreaks || !leftWhiteSpaceIsNormal, + }, + { + initialHTML: + `abc${caretInLeft}` + + `<div style="${rightWhiteSpace}">${caretInRight}def<br>ghi</div>`, + expectedHTML: aAttrsInLeftBlock => { + if (rightWhiteSpaceIsNormal) { + return [ + "abcdef" + + `<div style="${rightWhiteSpace}">ghi</div>`, + ]; + } + return [ + `abc<span ${aAttrsInLeftBlock}>def</span>` + + `<div style="${rightWhiteSpace}">ghi</div>`, + ]; + }, + skip: !leftWhiteSpaceIsNormal, + }, + { + initialHTML: + `abc${caretInLeft}` + + `<div style="${rightWhiteSpace}"><b>${caretInRight}def\nghi</b></div>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `abc<b ${aAttrsInLeftBlock}>def</b>` + + `<div style="${rightWhiteSpace}"><b>ghi</b></div>`, + `abc<span ${aAttrsInLeftBlock}><b>def</b></span>` + + `<div style="${rightWhiteSpace}"><b>ghi</b></div>`, + ]; + }, + skip: !rightWhiteSpacePreserveLineBreaks || !leftWhiteSpaceIsNormal, + }, + { + initialHTML: + `abc${caretInLeft}` + + `<div style="${rightWhiteSpace}"><b>${caretInRight}def<br>ghi</b></div>`, + expectedHTML: aAttrsInLeftBlock => { + if (rightWhiteSpaceIsNormal) { + return [ + "abcdef" + + `<div style="${rightWhiteSpace}"><b>ghi</b></div>`, + ]; + } + return [ + `abc<b ${aAttrsInLeftBlock}>def</b>` + + `<div style="${rightWhiteSpace}"><b>ghi</b></div>`, + `abc<span ${aAttrsInLeftBlock}><b>def</b></span>` + + `<div style="${rightWhiteSpace}"><b>ghi</b></div>`, + ]; + }, + skip: !leftWhiteSpaceIsNormal, + }, + { + initialHTML: + `abc${caretInLeft}` + + `<div style="${rightWhiteSpace}"><b>${caretInRight}def</b>ghi\njkl</div>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `abc<b ${aAttrsInLeftBlock}>def</b><span ${aAttrsInLeftBlock}>ghi</span>` + + `<div style="${rightWhiteSpace}">jkl</div>`, + `abc<span ${aAttrsInLeftBlock}><b>def</b>ghi</span>` + + `<div style="${rightWhiteSpace}">jkl</div>`, + ]; + }, + skip: !rightWhiteSpacePreserveLineBreaks || !leftWhiteSpaceIsNormal, + }, + { + initialHTML: + `abc${caretInLeft}` + + `<div style="${rightWhiteSpace}"><b>${caretInRight}def</b>ghi<br>jkl</div>`, + expectedHTML: aAttrsInLeftBlock => { + if (rightWhiteSpaceIsNormal) { + return [ + "abc<b>def</b>ghi" + + `<div style="${rightWhiteSpace}">jkl</div>`, + ]; + } + return [ + `abc<b ${aAttrsInLeftBlock}>def</b><span ${aAttrsInLeftBlock}>ghi</span>` + + `<div style="${rightWhiteSpace}">jkl</div>`, + `abc<span ${aAttrsInLeftBlock}><b>def</b>ghi</span>` + + `<div style="${rightWhiteSpace}">jkl</div>`, + ]; + }, + skip: !leftWhiteSpaceIsNormal, + }, + { + initialHTML: + `abc${caretInLeft}` + + `<div style="${rightWhiteSpace}"><b>${caretInRight}def</b>\nghi</div>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `abc<b ${aAttrsInLeftBlock}>def</b>` + + `<div style="${rightWhiteSpace}">ghi</div>`, + `abc<span ${aAttrsInLeftBlock}><b>def</b></span>` + + `<div style="${rightWhiteSpace}">ghi</div>`, + ]; + }, + skip: !rightWhiteSpacePreserveLineBreaks || !leftWhiteSpaceIsNormal, + }, + { + initialHTML: + `abc${caretInLeft}` + + `<div style="${rightWhiteSpace}"><b>${caretInRight}def</b><br>ghi</div>`, + expectedHTML: aAttrsInLeftBlock => { + if (rightWhiteSpaceIsNormal) { + return [ + "abc<b>def</b>" + + `<div style="${rightWhiteSpace}">ghi</div>`, + ]; + } + return [ + `abc<b ${aAttrsInLeftBlock}>def</b>` + + `<div style="${rightWhiteSpace}">ghi</div>`, + `abc<span ${aAttrsInLeftBlock}><b>def</b></span>` + + `<div style="${rightWhiteSpace}">ghi</div>`, + ]; + }, + skip: !leftWhiteSpaceIsNormal, + }, + { + initialHTML: + `abc${caretInLeft}` + + `<div style="${rightWhiteSpace}"><b>${caretInRight}def\n</b>ghi</div>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `abc<b ${aAttrsInLeftBlock}>def</b>` + + `<div style="${rightWhiteSpace}">ghi</div>`, + `abc<span ${aAttrsInLeftBlock}><b>def</b></span>` + + `<div style="${rightWhiteSpace}">ghi</div>`, + ]; + }, + skip: !rightWhiteSpacePreserveLineBreaks || !leftWhiteSpaceIsNormal, + }, + { + initialHTML: + `abc${caretInLeft}` + + `<div style="${rightWhiteSpace}"><b>${caretInRight}def<br></b>ghi</div>`, + expectedHTML: aAttrsInLeftBlock => { + if (rightWhiteSpaceIsNormal) { + return [ + "abc<b>def</b>" + + `<div style="${rightWhiteSpace}">ghi</div>`, + ]; + } + return [ + `abc<b ${aAttrsInLeftBlock}>def</b>` + + `<div style="${rightWhiteSpace}">ghi</div>`, + `abc<span ${aAttrsInLeftBlock}><b>def</b></span>` + + `<div style="${rightWhiteSpace}">ghi</div>`, + ]; + }, + skip: !leftWhiteSpaceIsNormal, + }, + { + initialHTML: + `abc${caretInLeft}` + + `<div style="${rightWhiteSpace}"><div>${caretInRight}def</div>ghi</div>`, + expectedHTML: aAttrsInLeftBlock => { + if (rightWhiteSpaceIsNormal) { + return [ + "abcdef" + + `<div style="${rightWhiteSpace}">ghi</div>`, + ]; + } + return [ + `abc<span ${aAttrsInLeftBlock}>def</span>` + + `<div style="${rightWhiteSpace}">ghi</div>`, + ]; + }, + skip: !leftWhiteSpaceIsNormal, + }, + { + initialHTML: + `abc${caretInLeft}` + + `<div style="${rightWhiteSpace}">${caretInRight}def<div>ghi</div></div>`, + expectedHTML: aAttrsInLeftBlock => { + if (rightWhiteSpaceIsNormal) { + return [ + "abcdef" + + `<div style="${rightWhiteSpace}"><div>ghi</div></div>`, + ]; + } + return [ + `abc<span ${aAttrsInLeftBlock}>def</span>` + + `<div style="${rightWhiteSpace}"><div>ghi</div></div>`, + ]; + }, + skip: !leftWhiteSpaceIsNormal, + }, + { + initialHTML: + `abc${caretInLeft}` + + `<div style="${rightWhiteSpace}"><div>${caretInRight}def</div>ghi\njkl</div>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `abc<span ${aAttrsInLeftBlock}>def</span>` + + `<div style="${rightWhiteSpace}">ghi\njkl</div>`, + ]; + }, + skip: !rightWhiteSpacePreserveLineBreaks || !leftWhiteSpaceIsNormal, + }, + { + initialHTML: + `abc${caretInLeft}` + + `<div style="${rightWhiteSpace}"><div>${caretInRight}def</div>ghi<br>jkl</div>`, + expectedHTML: aAttrsInLeftBlock => { + if (rightWhiteSpaceIsNormal) { + return [ + "abcdef" + + `<div style="${rightWhiteSpace}">ghi<br>jkl</div>`, + ]; + } + return [ + `abc<span ${aAttrsInLeftBlock}>def</span>` + + `<div style="${rightWhiteSpace}">ghi<br>jkl</div>`, + ]; + }, + skip: !leftWhiteSpaceIsNormal, + }, + { + initialHTML: + `abc${caretInLeft}` + + `<div style="${rightWhiteSpace}">${caretInRight}def<div>ghi</div>\njkl</div>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `abc<span ${aAttrsInLeftBlock}>def</span>` + + `<div style="${rightWhiteSpace}"><div>ghi</div>\njkl</div>`, + ]; + }, + skip: !rightWhiteSpacePreserveLineBreaks || !leftWhiteSpaceIsNormal, + }, + { + initialHTML: + `abc${caretInLeft}` + + `<div style="${rightWhiteSpace}">${caretInRight}def<div>ghi</div><br>jkl</div>`, + expectedHTML: aAttrsInLeftBlock => { + if (rightWhiteSpaceIsNormal) { + return [ + "abcdef" + + `<div style="${rightWhiteSpace}"><div>ghi</div><br>jkl</div>`, + ]; + } + return [ + `abc<span ${aAttrsInLeftBlock}>def</span>` + + `<div style="${rightWhiteSpace}"><div>ghi</div><br>jkl</div>`, + ]; + }, + skip: !leftWhiteSpaceIsNormal, + }, + { + initialHTML: + `abc${caretInLeft}` + + `<div style="${rightWhiteSpace}"><div>${caretInRight}def\nghi</div>jkl\nmno</div>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `abc<span ${aAttrsInLeftBlock}>def</span>` + + `<div style="${rightWhiteSpace}"><div>ghi</div>jkl\nmno</div>`, + ]; + }, + skip: !rightWhiteSpacePreserveLineBreaks || !leftWhiteSpaceIsNormal, + }, + { + initialHTML: + `abc${caretInLeft}` + + `<div style="${rightWhiteSpace}"><div>${caretInRight}def<br>ghi</div>jkl<br>mno</div>`, + expectedHTML: aAttrsInLeftBlock => { + if (rightWhiteSpaceIsNormal) { + return [ + "abcdef" + + `<div style="${rightWhiteSpace}"><div>ghi</div>jkl<br>mno</div>`, + ]; + } + return [ + `abc<span ${aAttrsInLeftBlock}>def</span>` + + `<div style="${rightWhiteSpace}"><div>ghi</div>jkl<br>mno</div>`, + ]; + }, + skip: !leftWhiteSpaceIsNormal, + }, + { + initialHTML: + `abc${caretInLeft}` + + `<div style="${rightWhiteSpace}">${caretInRight}def<div>ghi</div>jkl\nmno</div>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `abc<span ${aAttrsInLeftBlock}>def</span>` + + `<div style="${rightWhiteSpace}"><div>ghi</div>jkl\nmno</div>`, + ]; + }, + skip: !rightWhiteSpacePreserveLineBreaks || !leftWhiteSpaceIsNormal, + }, + { + initialHTML: + `abc${caretInLeft}` + + `<div style="${rightWhiteSpace}">${caretInRight}def<div>ghi</div>jkl<br>mno</div>`, + expectedHTML: aAttrsInLeftBlock => { + if (rightWhiteSpaceIsNormal) { + return [ + "abcdef" + + `<div style="${rightWhiteSpace}"><div>ghi</div>jkl<br>mno</div>`, + ]; + } + return [ + `abc<span ${aAttrsInLeftBlock}>def</span>` + + `<div style="${rightWhiteSpace}"><div>ghi</div>jkl<br>mno</div>`, + ]; + }, + skip: !leftWhiteSpaceIsNormal, + }, + + // The cases that the preceding line is a child of block element and has + // different white-space with <span>. + { + initialHTML: + `<span style="${leftWhiteSpace}">abc${caretInLeft}</span>` + + `<div style="${rightWhiteSpace}">${caretInRight}def\nghi</div>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<span style="${leftWhiteSpace}">abc</span><span ${aAttrsInLeftBlock}>def</span>` + + `<div style="${rightWhiteSpace}">ghi</div>`, + ]; + }, + skip: !rightWhiteSpacePreserveLineBreaks || leftWhiteSpaceIsNormal, + }, + { + initialHTML: + `<span style="${leftWhiteSpace}">abc${caretInLeft}</span>` + + `<div style="${rightWhiteSpace}">${caretInRight}def<br>ghi</div>`, + expectedHTML: aAttrsInLeftBlock => { + if (rightWhiteSpaceIsNormal) { + return [ + `<span style="${leftWhiteSpace}">abc</span>def` + + `<div style="${rightWhiteSpace}">ghi</div>`, + ]; + } + return [ + `<span style="${leftWhiteSpace}">abc</span><span ${aAttrsInLeftBlock}>def</span>` + + `<div style="${rightWhiteSpace}">ghi</div>`, + ]; + }, + skip: leftWhiteSpaceIsNormal, + }, + { + initialHTML: + `<span style="${leftWhiteSpace}">abc${caretInLeft}</span>` + + `<div style="${rightWhiteSpace}"><b>${caretInRight}def\nghi</b></div>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<span style="${leftWhiteSpace}">abc</span><b ${aAttrsInLeftBlock}>def</b>` + + `<div style="${rightWhiteSpace}"><b>ghi</b></div>`, + `<span style="${leftWhiteSpace}">abc</span><span ${aAttrsInLeftBlock}><b>def</b></span>` + + `<div style="${rightWhiteSpace}"><b>ghi</b></div>`, + ]; + }, + skip: !rightWhiteSpacePreserveLineBreaks || leftWhiteSpaceIsNormal, + }, + { + initialHTML: + `<span style="${leftWhiteSpace}">abc${caretInLeft}</span>` + + `<div style="${rightWhiteSpace}"><b>${caretInRight}def<br>ghi</b></div>`, + expectedHTML: aAttrsInLeftBlock => { + if (rightWhiteSpaceIsNormal) { + return [ + `<span style="${leftWhiteSpace}">abc</span><b>def</b>` + + `<div style="${rightWhiteSpace}"><b>ghi</b></div>`, + ]; + } + return [ + `<span style="${leftWhiteSpace}">abc</span><b ${aAttrsInLeftBlock}>def</b>` + + `<div style="${rightWhiteSpace}"><b>ghi</b></div>`, + `<span style="${leftWhiteSpace}">abc</span><span ${aAttrsInLeftBlock}><b>def</b></span>` + + `<div style="${rightWhiteSpace}"><b>ghi</b></div>`, + ]; + }, + skip: leftWhiteSpaceIsNormal, + }, + { + initialHTML: + `<span style="${leftWhiteSpace}">abc${caretInLeft}</span>` + + `<div style="${rightWhiteSpace}"><b>${caretInRight}def</b>ghi\njkl</div>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<span style="${leftWhiteSpace}">abc</span><b ${aAttrsInLeftBlock}>def</b><span ${aAttrsInLeftBlock}>ghi</span>` + + `<div style="${rightWhiteSpace}">jkl</div>`, + `<span style="${leftWhiteSpace}">abc</span><span ${aAttrsInLeftBlock}><b>def</b>ghi</span>` + + `<div style="${rightWhiteSpace}">jkl</div>`, + ]; + }, + skip: !rightWhiteSpacePreserveLineBreaks || leftWhiteSpaceIsNormal, + }, + { + initialHTML: + `<span style="${leftWhiteSpace}">abc${caretInLeft}</span>` + + `<div style="${rightWhiteSpace}"><b>${caretInRight}def</b>ghi<br>jkl</div>`, + expectedHTML: aAttrsInLeftBlock => { + if (rightWhiteSpaceIsNormal) { + return [ + `<span style="${leftWhiteSpace}">abc</span><b>def</b>ghi` + + `<div style="${rightWhiteSpace}">jkl</div>`, + ]; + } + return [ + `<span style="${leftWhiteSpace}">abc</span><b ${aAttrsInLeftBlock}>def</b><span ${aAttrsInLeftBlock}>ghi</span>` + + `<div style="${rightWhiteSpace}">jkl</div>`, + `<span style="${leftWhiteSpace}">abc</span><span ${aAttrsInLeftBlock}><b>def</b>ghi</span>` + + `<div style="${rightWhiteSpace}">jkl</div>`, + ]; + }, + skip: leftWhiteSpaceIsNormal, + }, + { + initialHTML: + `<span style="${leftWhiteSpace}">abc${caretInLeft}</span>` + + `<div style="${rightWhiteSpace}"><b>${caretInRight}def</b>\nghi</div>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<span style="${leftWhiteSpace}">abc</span><b ${aAttrsInLeftBlock}>def</b>` + + `<div style="${rightWhiteSpace}">ghi</div>`, + `<span style="${leftWhiteSpace}">abc</span><span ${aAttrsInLeftBlock}><b>def</b></span>` + + `<div style="${rightWhiteSpace}">ghi</div>`, + ]; + }, + skip: !rightWhiteSpacePreserveLineBreaks || leftWhiteSpaceIsNormal, + }, + { + initialHTML: + `<span style="${leftWhiteSpace}">abc${caretInLeft}</span>` + + `<div style="${rightWhiteSpace}"><b>${caretInRight}def</b><br>ghi</div>`, + expectedHTML: aAttrsInLeftBlock => { + if (rightWhiteSpaceIsNormal) { + return [ + `<span style="${leftWhiteSpace}">abc</span><b>def</b>` + + `<div style="${rightWhiteSpace}">ghi</div>`, + ]; + } + return [ + `<span style="${leftWhiteSpace}">abc</span><b ${aAttrsInLeftBlock}>def</b>` + + `<div style="${rightWhiteSpace}">ghi</div>`, + `<span style="${leftWhiteSpace}">abc</span><span ${aAttrsInLeftBlock}><b>def</b></span>` + + `<div style="${rightWhiteSpace}">ghi</div>`, + ]; + }, + skip: leftWhiteSpaceIsNormal, + }, + { + initialHTML: + `<span style="${leftWhiteSpace}">abc${caretInLeft}</span>` + + `<div style="${rightWhiteSpace}"><b>${caretInRight}def\n</b>ghi</div>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<span style="${leftWhiteSpace}">abc</span><b ${aAttrsInLeftBlock}>def</b>` + + `<div style="${rightWhiteSpace}">ghi</div>`, + `<span style="${leftWhiteSpace}">abc</span><span ${aAttrsInLeftBlock}><b>def</b></span>` + + `<div style="${rightWhiteSpace}">ghi</div>`, + ]; + }, + skip: !rightWhiteSpacePreserveLineBreaks || leftWhiteSpaceIsNormal, + }, + { + initialHTML: + `<span style="${leftWhiteSpace}">abc${caretInLeft}</span>` + + `<div style="${rightWhiteSpace}"><b>${caretInRight}def<br></b>ghi</div>`, + expectedHTML: aAttrsInLeftBlock => { + if (rightWhiteSpaceIsNormal) { + return [ + `<span style="${leftWhiteSpace}">abc</span><b>def</b>` + + `<div style="${rightWhiteSpace}">ghi</div>`, + ]; + } + return [ + `<span style="${leftWhiteSpace}">abc</span><b ${aAttrsInLeftBlock}>def</b>` + + `<div style="${rightWhiteSpace}">ghi</div>`, + `<span style="${leftWhiteSpace}">abc</span><span ${aAttrsInLeftBlock}><b>def</b></span>` + + `<div style="${rightWhiteSpace}">ghi</div>`, + ]; + }, + skip: leftWhiteSpaceIsNormal, + }, + { + initialHTML: + `<span style="${leftWhiteSpace}">abc${caretInLeft}</span>` + + `<div style="${rightWhiteSpace}"><div>${caretInRight}def</div>ghi</div>`, + expectedHTML: aAttrsInLeftBlock => { + if (rightWhiteSpaceIsNormal) { + return [ + `<span style="${leftWhiteSpace}">abc</span>def` + + `<div style="${rightWhiteSpace}">ghi</div>`, + ]; + } + return [ + `<span style="${leftWhiteSpace}">abc</span><span ${aAttrsInLeftBlock}>def</span>` + + `<div style="${rightWhiteSpace}">ghi</div>`, + ]; + }, + skip: leftWhiteSpaceIsNormal, + }, + { + initialHTML: + `<span style="${leftWhiteSpace}">abc${caretInLeft}</span>` + + `<div style="${rightWhiteSpace}">${caretInRight}def<div>ghi</div></div>`, + expectedHTML: aAttrsInLeftBlock => { + if (rightWhiteSpaceIsNormal) { + return [ + `<span style="${leftWhiteSpace}">abc</span>def` + + `<div style="${rightWhiteSpace}"><div>ghi</div></div>`, + ]; + } + return [ + `<span style="${leftWhiteSpace}">abc</span><span ${aAttrsInLeftBlock}>def</span>` + + `<div style="${rightWhiteSpace}"><div>ghi</div></div>`, + ]; + }, + skip: leftWhiteSpaceIsNormal, + }, + { + initialHTML: + `<span style="${leftWhiteSpace}">abc${caretInLeft}</span>` + + `<div style="${rightWhiteSpace}"><div>${caretInRight}def</div>ghi\njkl</div>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<span style="${leftWhiteSpace}">abc</span><span ${aAttrsInLeftBlock}>def</span>` + + `<div style="${rightWhiteSpace}">ghi\njkl</div>`, + ]; + }, + skip: !rightWhiteSpacePreserveLineBreaks || leftWhiteSpaceIsNormal, + }, + { + initialHTML: `<span style="${leftWhiteSpace}">abc${caretInLeft}</span>` + + `<div style="${rightWhiteSpace}"><div>${caretInRight}def</div>ghi<br>jkl</div>`, + expectedHTML: aAttrsInLeftBlock => { + if (rightWhiteSpaceIsNormal) { + return [ + `<span style="${leftWhiteSpace}">abc</span>def` + + `<div style="${rightWhiteSpace}">ghi<br>jkl</div>`, + ]; + } + return [ + `<span style="${leftWhiteSpace}">abc</span><span ${aAttrsInLeftBlock}>def</span>` + + `<div style="${rightWhiteSpace}">ghi<br>jkl</div>`, + ]; + }, + skip: leftWhiteSpaceIsNormal, + }, + { + initialHTML: + `<span style="${leftWhiteSpace}">abc${caretInLeft}</span>` + + `<div style="${rightWhiteSpace}">${caretInRight}def<div>ghi</div>\njkl</div>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<span style="${leftWhiteSpace}">abc</span><span ${aAttrsInLeftBlock}>def</span>` + + `<div style="${rightWhiteSpace}"><div>ghi</div>\njkl</div>`, + ]; + }, + skip: !rightWhiteSpacePreserveLineBreaks || leftWhiteSpaceIsNormal, + }, + { + initialHTML: `<span style="${leftWhiteSpace}">abc${caretInLeft}</span>` + + `<div style="${rightWhiteSpace}">${caretInRight}def<div>ghi</div><br>jkl</div>`, + expectedHTML: aAttrsInLeftBlock => { + if (rightWhiteSpaceIsNormal) { + return [ + `<span style="${leftWhiteSpace}">abc</span>def` + + `<div style="${rightWhiteSpace}"><div>ghi</div><br>jkl</div>`, + ]; + } + return [ + `<span style="${leftWhiteSpace}">abc</span><span ${aAttrsInLeftBlock}>def</span>` + + `<div style="${rightWhiteSpace}"><div>ghi</div><br>jkl</div>`, + ]; + }, + skip: leftWhiteSpaceIsNormal, + }, + { + initialHTML: + `<span style="${leftWhiteSpace}">abc${caretInLeft}</span>` + + `<div style="${rightWhiteSpace}"><div>${caretInRight}def\nghi</div>jkl\nmno</div>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<span style="${leftWhiteSpace}">abc</span><span ${aAttrsInLeftBlock}>def</span>` + + `<div style="${rightWhiteSpace}"><div>ghi</div>jkl\nmno</div>`, + ]; + }, + skip: !rightWhiteSpacePreserveLineBreaks || leftWhiteSpaceIsNormal, + }, + { + initialHTML: + `<span style="${leftWhiteSpace}">abc${caretInLeft}</span>` + + `<div style="${rightWhiteSpace}"><div>${caretInRight}def<br>ghi</div>jkl<br>mno</div>`, + expectedHTML: aAttrsInLeftBlock => { + if (rightWhiteSpaceIsNormal) { + return [ + `<span style="${leftWhiteSpace}">abc</span>def` + + `<div style="${rightWhiteSpace}"><div>ghi</div>jkl<br>mno</div>`, + ]; + } + return [ + `<span style="${leftWhiteSpace}">abc</span><span ${aAttrsInLeftBlock}>def</span>` + + `<div style="${rightWhiteSpace}"><div>ghi</div>jkl<br>mno</div>`, + ]; + }, + skip: leftWhiteSpaceIsNormal, + }, + { + initialHTML: + `<span style="${leftWhiteSpace}">abc${caretInLeft}</span>` + + `<div style="${rightWhiteSpace}">${caretInRight}def<div>ghi</div>jkl\nmno</div>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<span style="${leftWhiteSpace}">abc</span><span ${aAttrsInLeftBlock}>def</span>` + + `<div style="${rightWhiteSpace}"><div>ghi</div>jkl\nmno</div>`, + ]; + }, + skip: !rightWhiteSpacePreserveLineBreaks || leftWhiteSpaceIsNormal, + }, + { + initialHTML: + `<span style="${leftWhiteSpace}">abc${caretInLeft}</span>` + + `<div style="${rightWhiteSpace}">${caretInRight}def<div>ghi</div>jkl<br>mno</div>`, + expectedHTML: aAttrsInLeftBlock => { + if (rightWhiteSpaceIsNormal) { + return [ + `<span style="${leftWhiteSpace}">abc</span>def` + + `<div style="${rightWhiteSpace}"><div>ghi</div>jkl<br>mno</div>`, + ]; + } + return [ + `<span style="${leftWhiteSpace}">abc</span><span ${aAttrsInLeftBlock}>def</span>` + + `<div style="${rightWhiteSpace}"><div>ghi</div>jkl<br>mno</div>`, + ]; + }, + skip: leftWhiteSpaceIsNormal, + }, +]; + +const rightStyleAttr = new RegExp(`style="${rightWhiteSpace}"`, "g"); +const leftStyleAttr = new RegExp(`style="${leftWhiteSpace}"`, "g"); +const styledRightDiv = new RegExp(`<div style="${rightWhiteSpace}">`, "g"); +for (const t of tests) { + if (t.skip) { + continue; + } + promise_test(async () => { + utils.setupEditingHost(t.initialHTML); + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + utils.normalizeStyleAttributeValues(); + assert_in_array( + editingHost.innerHTML, + t.expectedHTML(`style="${rightWhiteSpace}"`), + "white-space should be preserved by <span> elements" + ); + }, `${commandName} at ${t.initialHTML.replace(/\n/g, "\\n")}`); + + if (rightWhiteSpaceClass !== null) { + // Replace style attribute with class attribute. + const initialHTMLWithClass = + t.initialHTML.replace( + rightStyleAttr, + `class="${rightWhiteSpaceClass}"` + ); + if (initialHTMLWithClass != t.initialHTML) { + promise_test(async () => { + utils.setupEditingHost(initialHTMLWithClass); + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + utils.normalizeStyleAttributeValues(); + const expectedHTMLs = []; + for (const styleAndOrClassAttr of [ + `style="${rightWhiteSpace}"`, + `class="${rightWhiteSpaceClass}" style="${rightWhiteSpace}"`, + `style="${rightWhiteSpace}" class="${rightWhiteSpaceClass}"`, + ]) { + for (const origExpectedHTML of t.expectedHTML(styleAndOrClassAttr)) { + expectedHTMLs.push( + origExpectedHTML.replace( + styledRightDiv, + `<div class="${rightWhiteSpaceClass}">` + ) + ); + } + } + assert_in_array( + editingHost.innerHTML, + expectedHTMLs, + "white-space should be preserved by <span> elements with class or style attribute" + ); + }, `${commandName} at ${initialHTMLWithClass.replace(/\n/g, "\\n")}`); + } + } + + if (leftWhiteSpaceClass !== null) { + // Replace style attribute with class attribute. + const initialHTMLWithClass = + t.initialHTML.replace( + leftStyleAttr, + `class="${leftWhiteSpaceClass}"` + ); + if (initialHTMLWithClass != t.initialHTML) { + promise_test(async () => { + utils.setupEditingHost(initialHTMLWithClass); + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + utils.normalizeStyleAttributeValues(); + const expectedHTMLs = []; + for (const styleAndOrClassAttr of [ + `style="${rightWhiteSpace}"`, + `class="${rightWhiteSpaceClass}" style="${rightWhiteSpace}"`, + `style="${rightWhiteSpace}" class="${rightWhiteSpaceClass}"`, + ]) { + for (const origExpectedHTML of t.expectedHTML(styleAndOrClassAttr)) { + expectedHTMLs.push( + origExpectedHTML.replace( + leftStyleAttr, + `class="${leftWhiteSpaceClass}"` + ) + ); + } + } + assert_in_array( + editingHost.innerHTML, + expectedHTMLs, + "white-space should be preserved by <span> elements with class or style attribute" + ); + }, `${commandName} at ${initialHTMLWithClass.replace(/\n/g, "\\n")}`); + } + } +} + +</script> +</body> +</html> diff --git a/testing/web-platform/tests/editing/other/join-different-white-space-style-left-paragraph-and-right-line.html b/testing/web-platform/tests/editing/other/join-different-white-space-style-left-paragraph-and-right-line.html new file mode 100644 index 0000000000..b55cacc44b --- /dev/null +++ b/testing/web-platform/tests/editing/other/join-different-white-space-style-left-paragraph-and-right-line.html @@ -0,0 +1,493 @@ +<!doctype html> +<head> +<meta charset="utf-8"> +<meta name="timeout" content="long"> +<meta name="variant" content="?method=backspace&left-white-space=normal&right-white-space=pre"> +<meta name="variant" content="?method=backspace&left-white-space=normal&right-white-space=pre-wrap"> +<meta name="variant" content="?method=backspace&left-white-space=normal&right-white-space=pre-line"> +<meta name="variant" content="?method=backspace&left-white-space=normal&right-white-space=nowrap"> +<meta name="variant" content="?method=backspace&left-white-space=pre&right-white-space=normal"> +<meta name="variant" content="?method=backspace&left-white-space=pre&right-white-space=pre-wrap"> +<meta name="variant" content="?method=backspace&left-white-space=pre&right-white-space=pre-line"> +<meta name="variant" content="?method=backspace&left-white-space=pre&right-white-space=nowrap"> +<meta name="variant" content="?method=backspace&left-white-space=pre-wrap&right-white-space=normal"> +<meta name="variant" content="?method=backspace&left-white-space=pre-wrap&right-white-space=pre"> +<meta name="variant" content="?method=backspace&left-white-space=pre-wrap&right-white-space=pre-line"> +<meta name="variant" content="?method=backspace&left-white-space=pre-wrap&right-white-space=nowrap"> +<meta name="variant" content="?method=backspace&left-white-space=pre-line&right-white-space=normal"> +<meta name="variant" content="?method=backspace&left-white-space=pre-line&right-white-space=pre"> +<meta name="variant" content="?method=backspace&left-white-space=pre-line&right-white-space=pre-wrap"> +<meta name="variant" content="?method=backspace&left-white-space=pre-line&right-white-space=nowrap"> +<meta name="variant" content="?method=backspace&left-white-space=nowrap&right-white-space=normal"> +<meta name="variant" content="?method=backspace&left-white-space=nowrap&right-white-space=pre"> +<meta name="variant" content="?method=backspace&left-white-space=nowrap&right-white-space=pre-wrap"> +<meta name="variant" content="?method=backspace&left-white-space=nowrap&right-white-space=pre-line"> + +<meta name="variant" content="?method=forwarddelete&left-white-space=normal&right-white-space=pre"> +<meta name="variant" content="?method=forwarddelete&left-white-space=normal&right-white-space=pre-wrap"> +<meta name="variant" content="?method=forwarddelete&left-white-space=normal&right-white-space=pre-line"> +<meta name="variant" content="?method=forwarddelete&left-white-space=normal&right-white-space=nowrap"> +<meta name="variant" content="?method=forwarddelete&left-white-space=pre&right-white-space=normal"> +<meta name="variant" content="?method=forwarddelete&left-white-space=pre&right-white-space=pre-wrap"> +<meta name="variant" content="?method=forwarddelete&left-white-space=pre&right-white-space=pre-line"> +<meta name="variant" content="?method=forwarddelete&left-white-space=pre&right-white-space=nowrap"> +<meta name="variant" content="?method=forwarddelete&left-white-space=pre-wrap&right-white-space=normal"> +<meta name="variant" content="?method=forwarddelete&left-white-space=pre-wrap&right-white-space=pre"> +<meta name="variant" content="?method=forwarddelete&left-white-space=pre-wrap&right-white-space=pre-line"> +<meta name="variant" content="?method=forwarddelete&left-white-space=pre-wrap&right-white-space=nowrap"> +<meta name="variant" content="?method=forwarddelete&left-white-space=pre-line&right-white-space=normal"> +<meta name="variant" content="?method=forwarddelete&left-white-space=pre-line&right-white-space=pre"> +<meta name="variant" content="?method=forwarddelete&left-white-space=pre-line&right-white-space=pre-wrap"> +<meta name="variant" content="?method=forwarddelete&left-white-space=pre-line&right-white-space=nowrap"> +<meta name="variant" content="?method=forwarddelete&left-white-space=nowrap&right-white-space=normal"> +<meta name="variant" content="?method=forwarddelete&left-white-space=nowrap&right-white-space=pre"> +<meta name="variant" content="?method=forwarddelete&left-white-space=nowrap&right-white-space=pre-wrap"> +<meta name="variant" content="?method=forwarddelete&left-white-space=nowrap&right-white-space=pre-line"> + +<meta name="variant" content="?method=select-boundary&left-white-space=normal&right-white-space=pre"> +<meta name="variant" content="?method=select-boundary&left-white-space=normal&right-white-space=pre-wrap"> +<meta name="variant" content="?method=select-boundary&left-white-space=normal&right-white-space=pre-line"> +<meta name="variant" content="?method=select-boundary&left-white-space=normal&right-white-space=nowrap"> +<meta name="variant" content="?method=select-boundary&left-white-space=pre&right-white-space=normal"> +<meta name="variant" content="?method=select-boundary&left-white-space=pre&right-white-space=pre-wrap"> +<meta name="variant" content="?method=select-boundary&left-white-space=pre&right-white-space=pre-line"> +<meta name="variant" content="?method=select-boundary&left-white-space=pre&right-white-space=nowrap"> +<meta name="variant" content="?method=select-boundary&left-white-space=pre-wrap&right-white-space=normal"> +<meta name="variant" content="?method=select-boundary&left-white-space=pre-wrap&right-white-space=pre"> +<meta name="variant" content="?method=select-boundary&left-white-space=pre-wrap&right-white-space=pre-line"> +<meta name="variant" content="?method=select-boundary&left-white-space=pre-wrap&right-white-space=nowrap"> +<meta name="variant" content="?method=select-boundary&left-white-space=pre-line&right-white-space=normal"> +<meta name="variant" content="?method=select-boundary&left-white-space=pre-line&right-white-space=pre"> +<meta name="variant" content="?method=select-boundary&left-white-space=pre-line&right-white-space=pre-wrap"> +<meta name="variant" content="?method=select-boundary&left-white-space=pre-line&right-white-space=nowrap"> +<meta name="variant" content="?method=select-boundary&left-white-space=nowrap&right-white-space=normal"> +<meta name="variant" content="?method=select-boundary&left-white-space=nowrap&right-white-space=pre"> +<meta name="variant" content="?method=select-boundary&left-white-space=nowrap&right-white-space=pre-wrap"> +<meta name="variant" content="?method=select-boundary&left-white-space=nowrap&right-white-space=pre-line"> +<title>Tests for joining left paragraph and its following line</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script src="../include/editor-test-utils.js"></script> +<style> +.pre { + white-space: pre; +} +.preWrap { + white-space: pre-wrap; +} +.preLine { + white-space: pre-line; +} +.nowrap { + white-space: nowrap; +} +</style> +</head> +<body> +<div contenteditable></div> +<script> +"use strict"; + +const searchParams = new URLSearchParams(document.location.search); +const testingBackspace = searchParams.get("method") == "backspace"; +const testingSelectBoundary = searchParams.get("method") == "select-boundary"; +const commandName = + testingBackspace || testingSelectBoundary ? "delete" : "forwarddelete"; +const editingHost = document.querySelector("div[contenteditable]"); +const caretInLeft = (() => { + if (testingSelectBoundary) { + return "["; + } + return testingBackspace ? "" : "[]"; +})(); +const caretInRight = (() => { + if (testingSelectBoundary) { + return "]"; + } + return testingBackspace ? "[]" : ""; +})(); +const leftWhiteSpace = `white-space:${searchParams.get("left-white-space")}`; +const rightWhiteSpace = `white-space:${searchParams.get("right-white-space")}`; +const leftWhiteSpacePreserveLineBreaks = + searchParams.get("left-white-space") == "pre" || + searchParams.get("left-white-space") == "pre-wrap" || + searchParams.get("left-white-space") == "pre-line"; +const rightWhiteSpacePreserveLineBreaks = + searchParams.get("right-white-space") == "pre" || + searchParams.get("right-white-space") == "pre-wrap" || + searchParams.get("right-white-space") == "pre-line"; +const leftWhiteSpaceIsNormal = + searchParams.get("left-white-space") == "normal"; +const rightWhiteSpaceIsNormal = + searchParams.get("right-white-space") == "normal"; +const leftWhiteSpaceClass = (() => { + switch (searchParams.get("left-white-space")) { + case "pre": + return "pre"; + case "pre-wrap": + return "preWrap"; + case "pre-line": + return "preLine"; + case "nowrap": + return "nowrap"; + default: + return null; + } +})(); +const rightWhiteSpaceClass = (() => { + switch (searchParams.get("right-white-space")) { + case "pre": + return "pre"; + case "pre-wrap": + return "preWrap"; + case "pre-line": + return "preLine"; + case "nowrap": + return "nowrap"; + default: + return null; + } +})(); +const utils = new EditorTestUtils(editingHost); + +const tests = [ + // The cases that the following line is a child of parent block whose + // white-space is normal. + { + initialHTML: + `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` + + `${caretInRight}def`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}>def</span></div>`, + ]; + }, + skip: !rightWhiteSpaceIsNormal, + }, + { + initialHTML: + `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` + + `${caretInRight}def<br>ghi`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}>def</span></div>` + + "ghi", + ]; + }, + skip: !rightWhiteSpaceIsNormal, + }, + { + initialHTML: + `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` + + `${caretInRight}def<div>ghi</div>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}>def</span></div>` + + "<div>ghi</div>", + ]; + }, + skip: !rightWhiteSpaceIsNormal, + }, + { + initialHTML: + `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` + + `<b>${caretInRight}def</b>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<div style="${leftWhiteSpace}">abc<b ${aAttrsInLeftBlock}>def</b></div>`, + `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}><b>def</b></span></div>`, + ]; + }, + skip: !rightWhiteSpaceIsNormal, + }, + { + initialHTML: + `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` + + `<b>${caretInRight}def<br>ghi</b>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<div style="${leftWhiteSpace}">abc<b ${aAttrsInLeftBlock}>def</b></div>` + + "<b>ghi</b>", + `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}><b>def</b></span></div>` + + "<b>ghi</b>", + ]; + }, + skip: !rightWhiteSpaceIsNormal, + }, + { + initialHTML: + `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` + + `<b>${caretInRight}def</b><br>ghi`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<div style="${leftWhiteSpace}">abc<b ${aAttrsInLeftBlock}>def</b></div>` + + "ghi", + `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}><b>def</b></span></div>` + + "ghi", + ]; + }, + skip: !rightWhiteSpaceIsNormal, + }, + { + initialHTML: + `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` + + `<b>${caretInRight}def<br></b>ghi`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<div style="${leftWhiteSpace}">abc<b ${aAttrsInLeftBlock}>def</b></div>` + + "ghi", + `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}><b>def</b></span></div>` + + "ghi", + ]; + }, + skip: !rightWhiteSpaceIsNormal, + }, + + // The cases that the following line is a child of block element and has + // different white-space with <span>. + { + initialHTML: + `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` + + `<span style="${rightWhiteSpace}">${caretInRight}def</span>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}>def</span></div>`, + ]; + }, + skip: rightWhiteSpaceIsNormal, + }, + { + initialHTML: + `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` + + `<span style="${rightWhiteSpace}">${caretInRight}def\nghi</span>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}>def</span></div>` + + `<span style="${rightWhiteSpace}">ghi</span>`, + ]; + }, + skip: !rightWhiteSpacePreserveLineBreaks || rightWhiteSpaceIsNormal, + }, + { + initialHTML: + `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` + + `<span style="${rightWhiteSpace}">${caretInRight}def<br>ghi</span>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}>def</span></div>` + + `<span style="${rightWhiteSpace}">ghi</span>`, + ]; + }, + skip: rightWhiteSpaceIsNormal, + }, + { + initialHTML: + `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` + + `<span style="${rightWhiteSpace}"><b>${caretInRight}def\nghi</b></span>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<div style="${leftWhiteSpace}">abc<b ${aAttrsInLeftBlock}>def</b></div>` + + `<span style="${rightWhiteSpace}"><b>ghi</b></span>`, + `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}><b>def</b></span></div>` + + `<span style="${rightWhiteSpace}"><b>ghi</b></span>`, + ]; + }, + skip: !rightWhiteSpacePreserveLineBreaks || rightWhiteSpaceIsNormal, + }, + { + initialHTML: + `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` + + `<span style="${rightWhiteSpace}"><b>${caretInRight}def<br>ghi</b></span>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<div style="${leftWhiteSpace}">abc<b ${aAttrsInLeftBlock}>def</b></div>` + + `<span style="${rightWhiteSpace}"><b>ghi</b></span>`, + `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}><b>def</b></span></div>` + + `<span style="${rightWhiteSpace}"><b>ghi</b></span>`, + ]; + }, + skip: rightWhiteSpaceIsNormal, + }, + { + initialHTML: + `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` + + `<span style="${rightWhiteSpace}"><b>${caretInRight}def</b>\nghi</span>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<div style="${leftWhiteSpace}">abc<b ${aAttrsInLeftBlock}>def</b></div>` + + `<span style="${rightWhiteSpace}">ghi</span>`, + `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}><b>def</b></span></div>` + + `<span style="${rightWhiteSpace}">ghi</span>`, + ]; + }, + skip: !rightWhiteSpacePreserveLineBreaks || rightWhiteSpaceIsNormal, + }, + { + initialHTML: + `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` + + `<span style="${rightWhiteSpace}"><b>${caretInRight}def</b><br>ghi</span>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<div style="${leftWhiteSpace}">abc<b ${aAttrsInLeftBlock}>def</b></div>` + + `<span style="${rightWhiteSpace}">ghi</span>`, + `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}><b>def</b></span></div>` + + `<span style="${rightWhiteSpace}">ghi</span>`, + ]; + }, + skip: rightWhiteSpaceIsNormal, + }, + { + initialHTML: + `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` + + `<span style="${rightWhiteSpace}"><b>${caretInRight}def\n</b>ghi</span>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<div style="${leftWhiteSpace}">abc<b ${aAttrsInLeftBlock}>def</b></div>` + + `<span style="${rightWhiteSpace}">ghi</span>`, + `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}><b>def</b></span></div>` + + `<span style="${rightWhiteSpace}">ghi</span>`, + ]; + }, + skip: !rightWhiteSpacePreserveLineBreaks || rightWhiteSpaceIsNormal, + }, + { + initialHTML: + `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` + + `<span style="${rightWhiteSpace}"><b>${caretInRight}def<br></b>ghi</span>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<div style="${leftWhiteSpace}">abc<b ${aAttrsInLeftBlock}>def</b></div>` + + `<span style="${rightWhiteSpace}">ghi</span>`, + `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}><b>def</b></span></div>` + + `<span style="${rightWhiteSpace}">ghi</span>`, + ]; + }, + skip: rightWhiteSpaceIsNormal, + }, + { + initialHTML: + `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` + + `<span style="${rightWhiteSpace}"><b>${caretInRight}def\nghi</b>jkl</span>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<div style="${leftWhiteSpace}">abc<b ${aAttrsInLeftBlock}>def</b></div>` + + `<span style="${rightWhiteSpace}"><b>ghi</b>jkl</span>`, + `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}><b>def</b></span></div>` + + `<span style="${rightWhiteSpace}"><b>ghi</b>jkl</span>`, + ]; + }, + skip: !rightWhiteSpacePreserveLineBreaks || rightWhiteSpaceIsNormal, + }, + { + initialHTML: + `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` + + `<span style="${rightWhiteSpace}"><b>${caretInRight}def<br>ghi</b>jkl</span>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<div style="${leftWhiteSpace}">abc<b ${aAttrsInLeftBlock}>def</b></div>` + + `<span style="${rightWhiteSpace}"><b>ghi</b>jkl</span>`, + `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}><b>def</b></span></div>` + + `<span style="${rightWhiteSpace}"><b>ghi</b>jkl</span>`, + ]; + }, + skip: rightWhiteSpaceIsNormal, + }, +]; + +const rightStyleAttr = new RegExp(`style="${rightWhiteSpace}"`, "g"); +const leftStyleAttr = new RegExp(`style="${leftWhiteSpace}"`, "g"); +const rightStyledSpan = new RegExp(`</div><span style="${rightWhiteSpace}">`, "g"); +for (const t of tests) { + if (t.skip) { + continue; + } + promise_test(async () => { + utils.setupEditingHost(t.initialHTML); + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + utils.normalizeStyleAttributeValues(); + assert_in_array( + editingHost.innerHTML, + t.expectedHTML(`style="${rightWhiteSpace}"`), + "white-space should be preserved by <span> elements" + ); + }, `${commandName} at ${t.initialHTML.replace(/\n/g, "\\n")}`); + + if (rightWhiteSpaceClass !== null) { + // Replace style attribute with class attribute. + const initialHTMLWithClass = + t.initialHTML.replace( + rightStyleAttr, + `class="${rightWhiteSpaceClass}"` + ); + if (initialHTMLWithClass != t.initialHTML) { + promise_test(async () => { + utils.setupEditingHost(initialHTMLWithClass); + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + utils.normalizeStyleAttributeValues(); + const expectedHTMLs = []; + for (const styleAndOrClassAttr of [ + `style="${rightWhiteSpace}"`, + `class="${rightWhiteSpaceClass}" style="${rightWhiteSpace}"`, + `style="${rightWhiteSpace}" class="${rightWhiteSpaceClass}"`, + ]) { + for (const origExpectedHTML of t.expectedHTML(styleAndOrClassAttr)) { + expectedHTMLs.push( + origExpectedHTML.replace( + rightStyledSpan, + `</div><span class="${rightWhiteSpaceClass}">` + ) + ); + } + } + assert_in_array( + editingHost.innerHTML, + expectedHTMLs, + "white-space should be preserved by <span> elements with class or style attribute" + ); + }, `${commandName} at ${initialHTMLWithClass.replace(/\n/g, "\\n")}`); + } + } + + if (leftWhiteSpaceClass !== null) { + // Replace style attribute with class attribute. + const initialHTMLWithClass = + t.initialHTML.replace( + leftStyleAttr, + `class="${leftWhiteSpaceClass}"` + ); + if (initialHTMLWithClass != t.initialHTML) { + promise_test(async () => { + utils.setupEditingHost(initialHTMLWithClass); + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + utils.normalizeStyleAttributeValues(); + const expectedHTMLs = []; + for (const styleAndOrClassAttr of [ + `style="${rightWhiteSpace}"`, + `class="${rightWhiteSpaceClass}" style="${rightWhiteSpace}"`, + `style="${rightWhiteSpace}" class="${rightWhiteSpaceClass}"`, + ]) { + for (const origExpectedHTML of t.expectedHTML(styleAndOrClassAttr)) { + expectedHTMLs.push( + origExpectedHTML.replace( + leftStyleAttr, + `class="${leftWhiteSpaceClass}"` + ) + ); + } + } + assert_in_array( + editingHost.innerHTML, + expectedHTMLs, + "white-space should be preserved by <span> elements with class or style attribute" + ); + }, `${commandName} at ${initialHTMLWithClass.replace(/\n/g, "\\n")}`); + } + } +} + +</script> +</body> +</html> diff --git a/testing/web-platform/tests/editing/other/join-different-white-space-style-paragraphs.html b/testing/web-platform/tests/editing/other/join-different-white-space-style-paragraphs.html new file mode 100644 index 0000000000..605f2a4483 --- /dev/null +++ b/testing/web-platform/tests/editing/other/join-different-white-space-style-paragraphs.html @@ -0,0 +1,499 @@ +<!doctype html> +<head> +<meta charset="utf-8"> +<meta name="timeout" content="long"> +<meta name="variant" content="?method=backspace&left-white-space=normal&right-white-space=pre"> +<meta name="variant" content="?method=backspace&left-white-space=normal&right-white-space=pre-wrap"> +<meta name="variant" content="?method=backspace&left-white-space=normal&right-white-space=pre-line"> +<meta name="variant" content="?method=backspace&left-white-space=normal&right-white-space=nowrap"> +<meta name="variant" content="?method=backspace&left-white-space=pre&right-white-space=normal"> +<meta name="variant" content="?method=backspace&left-white-space=pre&right-white-space=pre-wrap"> +<meta name="variant" content="?method=backspace&left-white-space=pre&right-white-space=pre-line"> +<meta name="variant" content="?method=backspace&left-white-space=pre&right-white-space=nowrap"> +<meta name="variant" content="?method=backspace&left-white-space=pre-wrap&right-white-space=normal"> +<meta name="variant" content="?method=backspace&left-white-space=pre-wrap&right-white-space=pre"> +<meta name="variant" content="?method=backspace&left-white-space=pre-wrap&right-white-space=pre-line"> +<meta name="variant" content="?method=backspace&left-white-space=pre-wrap&right-white-space=nowrap"> +<meta name="variant" content="?method=backspace&left-white-space=pre-line&right-white-space=normal"> +<meta name="variant" content="?method=backspace&left-white-space=pre-line&right-white-space=pre"> +<meta name="variant" content="?method=backspace&left-white-space=pre-line&right-white-space=pre-wrap"> +<meta name="variant" content="?method=backspace&left-white-space=pre-line&right-white-space=nowrap"> +<meta name="variant" content="?method=backspace&left-white-space=nowrap&right-white-space=normal"> +<meta name="variant" content="?method=backspace&left-white-space=nowrap&right-white-space=pre"> +<meta name="variant" content="?method=backspace&left-white-space=nowrap&right-white-space=pre-wrap"> +<meta name="variant" content="?method=backspace&left-white-space=nowrap&right-white-space=pre-line"> + +<meta name="variant" content="?method=forwarddelete&left-white-space=normal&right-white-space=pre"> +<meta name="variant" content="?method=forwarddelete&left-white-space=normal&right-white-space=pre-wrap"> +<meta name="variant" content="?method=forwarddelete&left-white-space=normal&right-white-space=pre-line"> +<meta name="variant" content="?method=forwarddelete&left-white-space=normal&right-white-space=nowrap"> +<meta name="variant" content="?method=forwarddelete&left-white-space=pre&right-white-space=normal"> +<meta name="variant" content="?method=forwarddelete&left-white-space=pre&right-white-space=pre-wrap"> +<meta name="variant" content="?method=forwarddelete&left-white-space=pre&right-white-space=pre-line"> +<meta name="variant" content="?method=forwarddelete&left-white-space=pre&right-white-space=nowrap"> +<meta name="variant" content="?method=forwarddelete&left-white-space=pre-wrap&right-white-space=normal"> +<meta name="variant" content="?method=forwarddelete&left-white-space=pre-wrap&right-white-space=pre"> +<meta name="variant" content="?method=forwarddelete&left-white-space=pre-wrap&right-white-space=pre-line"> +<meta name="variant" content="?method=forwarddelete&left-white-space=pre-wrap&right-white-space=nowrap"> +<meta name="variant" content="?method=forwarddelete&left-white-space=pre-line&right-white-space=normal"> +<meta name="variant" content="?method=forwarddelete&left-white-space=pre-line&right-white-space=pre"> +<meta name="variant" content="?method=forwarddelete&left-white-space=pre-line&right-white-space=pre-wrap"> +<meta name="variant" content="?method=forwarddelete&left-white-space=pre-line&right-white-space=nowrap"> +<meta name="variant" content="?method=forwarddelete&left-white-space=nowrap&right-white-space=normal"> +<meta name="variant" content="?method=forwarddelete&left-white-space=nowrap&right-white-space=pre"> +<meta name="variant" content="?method=forwarddelete&left-white-space=nowrap&right-white-space=pre-wrap"> +<meta name="variant" content="?method=forwarddelete&left-white-space=nowrap&right-white-space=pre-line"> + +<meta name="variant" content="?method=select-boundary&left-white-space=normal&right-white-space=pre"> +<meta name="variant" content="?method=select-boundary&left-white-space=normal&right-white-space=pre-wrap"> +<meta name="variant" content="?method=select-boundary&left-white-space=normal&right-white-space=pre-line"> +<meta name="variant" content="?method=select-boundary&left-white-space=normal&right-white-space=nowrap"> +<meta name="variant" content="?method=select-boundary&left-white-space=pre&right-white-space=normal"> +<meta name="variant" content="?method=select-boundary&left-white-space=pre&right-white-space=pre-wrap"> +<meta name="variant" content="?method=select-boundary&left-white-space=pre&right-white-space=pre-line"> +<meta name="variant" content="?method=select-boundary&left-white-space=pre&right-white-space=nowrap"> +<meta name="variant" content="?method=select-boundary&left-white-space=pre-wrap&right-white-space=normal"> +<meta name="variant" content="?method=select-boundary&left-white-space=pre-wrap&right-white-space=pre"> +<meta name="variant" content="?method=select-boundary&left-white-space=pre-wrap&right-white-space=pre-line"> +<meta name="variant" content="?method=select-boundary&left-white-space=pre-wrap&right-white-space=nowrap"> +<meta name="variant" content="?method=select-boundary&left-white-space=pre-line&right-white-space=normal"> +<meta name="variant" content="?method=select-boundary&left-white-space=pre-line&right-white-space=pre"> +<meta name="variant" content="?method=select-boundary&left-white-space=pre-line&right-white-space=pre-wrap"> +<meta name="variant" content="?method=select-boundary&left-white-space=pre-line&right-white-space=nowrap"> +<meta name="variant" content="?method=select-boundary&left-white-space=nowrap&right-white-space=normal"> +<meta name="variant" content="?method=select-boundary&left-white-space=nowrap&right-white-space=pre"> +<meta name="variant" content="?method=select-boundary&left-white-space=nowrap&right-white-space=pre-wrap"> +<meta name="variant" content="?method=select-boundary&left-white-space=nowrap&right-white-space=pre-line"> +<title>Tests for joining paragraphs which have different white-space styles</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script src="../include/editor-test-utils.js"></script> +<style> +.pre { + white-space: pre; +} +.preWrap { + white-space: pre-wrap; +} +.preLine { + white-space: pre-line; +} +.nowrap { + white-space: nowrap; +} +</style> +</head> +<body> +<div contenteditable></div> +<script> +"use strict"; + +const searchParams = new URLSearchParams(document.location.search); +const testingBackspace = searchParams.get("method") == "backspace"; +const testingSelectBoundary = searchParams.get("method") == "select-boundary"; +const commandName = + testingBackspace || testingSelectBoundary ? "delete" : "forwarddelete"; +const editingHost = document.querySelector("div[contenteditable]"); +const caretInLeft = (() => { + if (testingSelectBoundary) { + return "["; + } + return testingBackspace ? "" : "[]"; +})(); +const caretInRight = (() => { + if (testingSelectBoundary) { + return "]"; + } + return testingBackspace ? "[]" : ""; +})(); +const leftWhiteSpace = `white-space:${searchParams.get("left-white-space")}`; +const rightWhiteSpace = `white-space:${searchParams.get("right-white-space")}`; +const leftWhiteSpacePreserveLineBreaks = + searchParams.get("left-white-space") == "pre" || + searchParams.get("left-white-space") == "pre-wrap" || + searchParams.get("left-white-space") == "pre-line"; +const rightWhiteSpacePreserveLineBreaks = + searchParams.get("right-white-space") == "pre" || + searchParams.get("right-white-space") == "pre-wrap" || + searchParams.get("right-white-space") == "pre-line"; +const leftWhiteSpaceClass = (() => { + switch (searchParams.get("left-white-space")) { + case "pre": + return "pre"; + case "pre-wrap": + return "preWrap"; + case "pre-line": + return "preLine"; + case "nowrap": + return "nowrap"; + default: + return null; + } +})(); +const rightWhiteSpaceClass = (() => { + switch (searchParams.get("right-white-space")) { + case "pre": + return "pre"; + case "pre-wrap": + return "preWrap"; + case "pre-line": + return "preLine"; + case "nowrap": + return "nowrap"; + default: + return null; + } +})(); +const utils = new EditorTestUtils(editingHost); + +const tests = [ + { + initialHTML: + `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` + + `<div style="${rightWhiteSpace}">${caretInRight}def</div>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}>def</span></div>`, + ]; + }, + }, + // Only first line of the right paragraph should be merged into the left paragraph. + { + initialHTML: + `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` + + `<div style="${rightWhiteSpace}">${caretInRight}def\nghi</div>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}>def</span></div>` + + `<div style="${rightWhiteSpace}">ghi</div>`, + ]; + }, + skip: !rightWhiteSpacePreserveLineBreaks, + }, + { + initialHTML: + `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` + + `<div style="${rightWhiteSpace}">${caretInRight}def<br>ghi</div>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}>def</span></div>` + + `<div style="${rightWhiteSpace}">ghi</div>`, + ]; + }, + }, + // `white-space` should be preserved with <b>. + { + initialHTML: + `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` + + `<div style="${rightWhiteSpace}"><b>${caretInRight}def\nghi</b></div>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<div style="${leftWhiteSpace}">abc<b ${aAttrsInLeftBlock}>def</b></div>` + + `<div style="${rightWhiteSpace}"><b>ghi</b></div>`, + `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}><b>def</b></span></div>` + + `<div style="${rightWhiteSpace}"><b>ghi</b></div>`, + ]; + }, + skip: !rightWhiteSpacePreserveLineBreaks, + }, + { + initialHTML: + `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` + + `<div style="${rightWhiteSpace}"><b>${caretInRight}def<br>ghi</b></div>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<div style="${leftWhiteSpace}">abc<b ${aAttrsInLeftBlock}>def</b></div>` + + `<div style="${rightWhiteSpace}"><b>ghi</b></div>`, + `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}><b ${aAttrsInLeftBlock}>def</b></span></div>` + + `<div style="${rightWhiteSpace}"><b>ghi</b></div>`, + ]; + }, + }, + // `white-space` should be preserved with <b> as far as possible, and create <span> for no container part. + { + initialHTML: + `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` + + `<div style="${rightWhiteSpace}"><b>${caretInRight}def</b>ghi\njkl</div>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<div style="${leftWhiteSpace}">abc<b ${aAttrsInLeftBlock}>def</b><span ${aAttrsInLeftBlock}>ghi</span></div>` + + `<div style="${rightWhiteSpace}">jkl</div>`, + `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}><b>def</b>ghi</span></div>` + + `<div style="${rightWhiteSpace}">jkl</div>`, + ]; + }, + skip: !rightWhiteSpacePreserveLineBreaks, + }, + { + initialHTML: + `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` + + `<div style="${rightWhiteSpace}"><b>${caretInRight}def</b>ghi<br>jkl</div>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<div style="${leftWhiteSpace}">abc<b ${aAttrsInLeftBlock}>def</b><span ${aAttrsInLeftBlock}>ghi</span></div>` + + `<div style="${rightWhiteSpace}">jkl</div>`, + `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}><b>def</b>ghi</span></div>` + + `<div style="${rightWhiteSpace}">jkl</div>`, + ]; + }, + }, + { + initialHTML: + `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` + + `<div style="${rightWhiteSpace}"><b>${caretInRight}def</b>\nghi</div>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<div style="${leftWhiteSpace}">abc<b ${aAttrsInLeftBlock}>def</b></div>` + + `<div style="${rightWhiteSpace}">ghi</div>`, + `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}><b>def</b></span></div>` + + `<div style="${rightWhiteSpace}">ghi</div>`, + ]; + }, + skip: !rightWhiteSpacePreserveLineBreaks, + }, + { + initialHTML: + `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` + + `<div style="${rightWhiteSpace}"><b>${caretInRight}def</b><br>ghi</div>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<div style="${leftWhiteSpace}">abc<b ${aAttrsInLeftBlock}>def</b></div>` + + `<div style="${rightWhiteSpace}">ghi</div>`, + `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}><b>def</b></span></div>` + + `<div style="${rightWhiteSpace}">ghi</div>`, + ]; + }, + }, + { + initialHTML: + `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` + + `<div style="${rightWhiteSpace}"><b>${caretInRight}def\n</b>ghi</div>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<div style="${leftWhiteSpace}">abc<b ${aAttrsInLeftBlock}>def</b></div>` + + `<div style="${rightWhiteSpace}">ghi</div>`, + `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}><b>def</b></span></div>` + + `<div style="${rightWhiteSpace}">ghi</div>`, + ]; + }, + skip: !rightWhiteSpacePreserveLineBreaks, + }, + { + initialHTML: + `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` + + `<div style="${rightWhiteSpace}"><b>${caretInRight}def<br></b>ghi</div>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<div style="${leftWhiteSpace}">abc<b ${aAttrsInLeftBlock}>def</b></div>` + + `<div style="${rightWhiteSpace}">ghi</div>`, + `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}><b>def</b></span></div>` + + `<div style="${rightWhiteSpace}">ghi</div>`, + ]; + }, + }, + // nested paragraph cases + { + initialHTML: + `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` + + `<div style="${rightWhiteSpace}"><div>${caretInRight}def</div>ghi</div>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}>def</span></div>` + + `<div style="${rightWhiteSpace}">ghi</div>`, + ]; + }, + }, + { + initialHTML: + `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` + + `<div style="${rightWhiteSpace}">${caretInRight}def<div>ghi</div></div>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}>def</span></div>` + + `<div style="${rightWhiteSpace}"><div>ghi</div></div>`, + ]; + }, + }, + { + initialHTML: + `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` + + `<div style="${rightWhiteSpace}"><div>${caretInRight}def</div>ghi\njkl</div>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}>def</span></div>` + + `<div style="${rightWhiteSpace}">ghi\njkl</div>`, + ]; + }, + skip: !rightWhiteSpacePreserveLineBreaks, + }, + { + initialHTML: + `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` + + `<div style="${rightWhiteSpace}"><div>${caretInRight}def</div>ghi<br>jkl</div>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}>def</span></div>` + + `<div style="${rightWhiteSpace}">ghi<br>jkl</div>`, + ]; + }, + }, + { + initialHTML: + `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` + + `<div style="${rightWhiteSpace}">${caretInRight}def<div>ghi</div>jkl\nmno</div>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}>def</span></div>` + + `<div style="${rightWhiteSpace}"><div>ghi</div>jkl\nmno</div>`, + ]; + }, + skip: !rightWhiteSpacePreserveLineBreaks, + }, + { + initialHTML: + `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` + + `<div style="${rightWhiteSpace}">${caretInRight}def<div>ghi</div>jkl<br>mno</div>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}>def</span></div>` + + `<div style="${rightWhiteSpace}"><div>ghi</div>jkl<br>mno</div>`, + ]; + }, + }, + { + initialHTML: + `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` + + `<div style="${rightWhiteSpace}"><div>${caretInRight}def\nghi</div>jkl</div>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}>def</span></div>` + + `<div style="${rightWhiteSpace}"><div>ghi</div>jkl</div>`, + ]; + }, + skip: !rightWhiteSpacePreserveLineBreaks, + }, + { + initialHTML: + `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` + + `<div style="${rightWhiteSpace}"><div>${caretInRight}def<br>ghi</div>jkl</div>`, + expectedHTML: aAttrsInLeftBlock => { + return [ + `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}>def</span></div>` + + `<div style="${rightWhiteSpace}"><div>ghi</div>jkl</div>`, + ]; + }, + }, +]; + +const betweenDivs = /<\/div><div /; +const rightStyleAttr = new RegExp(`style="${rightWhiteSpace}"`, "g"); +const leftStyleAttr = new RegExp(`style="${leftWhiteSpace}"`, "g"); +const styledRightDiv = new RegExp(`<div style="${rightWhiteSpace}">`, "g"); +const styledLeftDiv = new RegExp(`<div style="${leftWhiteSpace}">`, "g"); +for (const t of tests) { + if (t.skip) { + continue; + } + promise_test(async () => { + utils.setupEditingHost(t.initialHTML); + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + utils.normalizeStyleAttributeValues(); + assert_in_array( + editingHost.innerHTML, + t.expectedHTML(`style="${rightWhiteSpace}"`), + "white-space should be preserved by <span> elements" + ); + }, `${commandName} at ${t.initialHTML.replace(/\n/g, "\\n")}`); + + // Repeat same tests with inserting a line break between the paragraphs. + const initialHTMLWithLineBreak = + t.initialHTML.replace(betweenDivs, "</div>\n<div "); + promise_test(async () => { + utils.setupEditingHost(initialHTMLWithLineBreak); + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + utils.normalizeStyleAttributeValues(); + assert_in_array( + editingHost.innerHTML, + t.expectedHTML(`style="${rightWhiteSpace}"`), + "white-space should be preserved by <span> elements (testing with a line break between paragraphs)" + ); + }, `${commandName} at ${initialHTMLWithLineBreak.replace(/\n/g, "\\n")}`); + + if (rightWhiteSpaceClass !== null) { + // Replace style attribute with class attribute. + const initialHTMLWithClass = + t.initialHTML.replace( + rightStyleAttr, + `class="${rightWhiteSpaceClass}"` + ); + if (initialHTMLWithClass != t.initialHTML) { + promise_test(async () => { + utils.setupEditingHost(initialHTMLWithClass); + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + utils.normalizeStyleAttributeValues(); + const expectedHTMLs = []; + for (const styleAndOrClassAttr of [ + `style="${rightWhiteSpace}"`, + `class="${rightWhiteSpaceClass}" style="${rightWhiteSpace}"`, + `style="${rightWhiteSpace}" class="${rightWhiteSpaceClass}"`, + ]) { + for (const origExpectedHTML of t.expectedHTML(styleAndOrClassAttr)) { + expectedHTMLs.push( + origExpectedHTML.replace( + styledRightDiv, + `<div class="${rightWhiteSpaceClass}">` + ) + ); + } + } + assert_in_array( + editingHost.innerHTML, + expectedHTMLs, + "white-space should be preserved by <span> elements with class or style attribute" + ); + }, `${commandName} at ${initialHTMLWithClass.replace(/\n/g, "\\n")}`); + } + } + + if (leftWhiteSpaceClass !== null) { + // Replace style attribute with class attribute. + const initialHTMLWithClass = + t.initialHTML.replace( + leftStyleAttr, + `class="${leftWhiteSpaceClass}"` + ); + if (initialHTMLWithClass != t.initialHTML) { + promise_test(async () => { + utils.setupEditingHost(initialHTMLWithClass); + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + utils.normalizeStyleAttributeValues(); + const expectedHTMLs = []; + for (const styleAndOrClassAttr of [ + `style="${rightWhiteSpace}"`, + `class="${rightWhiteSpaceClass}" style="${rightWhiteSpace}"`, + `style="${rightWhiteSpace}" class="${rightWhiteSpaceClass}"`, + ]) { + for (const origExpectedHTML of t.expectedHTML(styleAndOrClassAttr)) { + expectedHTMLs.push( + origExpectedHTML.replace( + leftStyleAttr, + `class="${leftWhiteSpaceClass}"` + ) + ); + } + } + assert_in_array( + editingHost.innerHTML, + expectedHTMLs, + "white-space should be preserved by <span> elements with class or style attribute" + ); + }, `${commandName} at ${initialHTMLWithClass.replace(/\n/g, "\\n")}`); + } + } +} +</script> +</body> +</html> diff --git a/testing/web-platform/tests/editing/other/join-pre-and-other-block.html b/testing/web-platform/tests/editing/other/join-pre-and-other-block.html new file mode 100644 index 0000000000..39e455a848 --- /dev/null +++ b/testing/web-platform/tests/editing/other/join-pre-and-other-block.html @@ -0,0 +1,329 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<meta name="variant" content="?method=backspace&block=div"> +<meta name="variant" content="?method=backspace&block=p"> +<meta name="variant" content="?method=backspace&block=blockquote"> +<meta name="variant" content="?method=forwarddelete&block=div"> +<meta name="variant" content="?method=forwarddelete&block=p"> +<meta name="variant" content="?method=forwarddelete&block=blockquote"> +<meta name="variant" content="?method=select-boundary&block=div"> +<meta name="variant" content="?method=select-boundary&block=p"> +<meta name="variant" content="?method=select-boundary&block=blockquote"> +<title>Tests for joining pre and other block element</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script src="../include/editor-test-utils.js"></script> +</head> +<body> +<div contenteditable></div> +<script> +"use strict"; + +const searchParams = new URLSearchParams(document.location.search); +const testingBackspace = searchParams.get("method") == "backspace"; +const testingSelectBoundary = searchParams.get("method") == "select-boundary"; +const commandName = + testingBackspace || testingSelectBoundary ? "delete" : "forwarddelete"; +const editingHost = document.querySelector("div[contenteditable]"); +const caretInLeft = (() => { + if (testingSelectBoundary) { + return "["; + } + return testingBackspace ? "" : "[]"; +})(); +const caretInRight = (() => { + if (testingSelectBoundary) { + return "]"; + } + return testingBackspace ? "[]" : ""; +})(); +const tag = searchParams.get("block"); + +// These expectations are odd because they don't preserve white-space style +// coming from another element. However, this is traditional behavior so that +// browsers should not change the behavior. +const tests = [ + { + initialHTML: + `<pre>abc${caretInLeft}</pre>` + + `<${tag}>${caretInRight}def</${tag}>`, + expectedHTML: [ + "<pre>abcdef</pre>", + ], + }, + { + initialHTML: + `<${tag}>abc${caretInLeft}</${tag}>` + + `<pre>${caretInRight}def</pre>`, + expectedHTML: [ + `<${tag}>abcdef</${tag}>`, + ], + expectedHTMLWithStyledPre: [ + `<${tag}>abc<span style="white-space:pre">def</span></${tag}>`, + ], + }, + { + initialHTML: + `<pre>abc${caretInLeft}</pre>` + + `<${tag}>${caretInRight}def<br>ghi</${tag}>`, + expectedHTML: [ + `<pre>abcdef</pre>` + + `<${tag}>ghi</${tag}>`, + ], + }, + { + initialHTML: + `<pre>abc${caretInLeft}</pre>` + + `<${tag}>${caretInRight}def<div>ghi</div></${tag}>`, + expectedHTML: [ + "<pre>abcdef</pre>" + + `<${tag}><div>ghi</div></${tag}>`, + ], + skip: tag == "p", + }, + { + initialHTML: + `<${tag}>abc${caretInLeft}</${tag}>` + + `<pre>${caretInRight}def\nghi</pre>`, + expectedHTML: [ + `<${tag}>abcdef</${tag}>` + + "<pre>ghi</pre>", + ], + expectedHTMLWithStyledPre: [ + `<${tag}>abc<span style="white-space:pre">def</span></${tag}>` + + "<pre>ghi</pre>", + ], + }, + { + initialHTML: + `<${tag}>abc${caretInLeft}</${tag}>` + + `<pre>${caretInRight}def<br>ghi</pre>`, + expectedHTML: [ + `<${tag}>abcdef</${tag}>` + + "<pre>ghi</pre>", + ], + expectedHTMLWithStyledPre: [ + `<${tag}>abc<span style="white-space:pre">def</span></${tag}>` + + "<pre>ghi</pre>", + ], + }, + { + initialHTML: + `<pre>abc${caretInLeft}</pre>` + + `<${tag}><b>${caretInRight}def</b></${tag}>`, + expectedHTML: [ + "<pre>abc<b>def</b></pre>", + ], + }, + { + initialHTML: + `<pre>abc${caretInLeft}</pre>` + + `<${tag}><b>${caretInRight}def<br>ghi</b></${tag}>`, + expectedHTML: [ + "<pre>abc<b>def</b></pre>" + + `<${tag}><b>ghi</b></${tag}>`, + ], + }, + { + initialHTML: + `<${tag}>abc${caretInLeft}</${tag}>` + + `<pre><b>${caretInRight}def\nghi</b></pre>`, + expectedHTML: [ + `<${tag}>abc<b>def</b></${tag}>` + + "<pre><b>ghi</b></pre>", + ], + expectedHTMLWithStyledPre: [ + `<${tag}>abc<b style="white-space:pre">def</b></${tag}>` + + "<pre><b>ghi</b></pre>", + `<${tag}>abc<span style="white-space:pre"><b>def</b></span></${tag}>` + + "<pre><b>ghi</b></pre>", + ], + }, + { + initialHTML: + `<${tag}>abc${caretInLeft}</${tag}>` + + `<pre><b>${caretInRight}def<br>ghi</b></pre>`, + expectedHTML: [ + `<${tag}>abc<b>def</b></${tag}>` + + "<pre><b>ghi</b></pre>", + ], + expectedHTMLWithStyledPre: [ + `<${tag}>abc<b style="white-space:pre">def</b></${tag}>` + + "<pre><b>ghi</b></pre>", + `<${tag}>abc<span style="white-space:pre"><b>def</b></span></${tag}>` + + "<pre><b>ghi</b></pre>", + ], + }, + { + initialHTML: + `<${tag}>abc${caretInLeft}</${tag}>` + + `<pre><b>${caretInRight}def</b>\nghi</pre>`, + expectedHTML: [ + `<${tag}>abc<b>def</b></${tag}>` + + "<pre>ghi</pre>", + ], + expectedHTMLWithStyledPre: [ + `<${tag}>abc<b style="white-space:pre">def</b></${tag}>` + + "<pre>ghi</pre>", + `<${tag}>abc<span style="white-space:pre"><b>def</b></span></${tag}>` + + "<pre>ghi</pre>", + ], + }, + { + initialHTML: + `<${tag}>abc${caretInLeft}</${tag}>` + + `<pre><b>${caretInRight}def</b><br>ghi</pre>`, + expectedHTML: [ + `<${tag}>abc<b>def</b></${tag}>` + + "<pre>ghi</pre>", + ], + expectedHTMLWithStyledPre: [ + `<${tag}>abc<b style="white-space:pre">def</b></${tag}>` + + "<pre>ghi</pre>", + `<${tag}>abc<span style="white-space:pre"><b>def</b></span></${tag}>` + + "<pre>ghi</pre>", + ], + }, + { + initialHTML: + `<${tag}>abc${caretInLeft}</${tag}>` + + `<pre><b>${caretInRight}def\n</b>ghi</pre>`, + expectedHTML: [ + `<${tag}>abc<b>def</b></${tag}>` + + "<pre>ghi</pre>", + ], + expectedHTMLWithStyledPre: [ + `<${tag}>abc<b style="white-space:pre">def</b></${tag}>` + + `<pre>ghi</pre>`, + `<${tag}>abc<span style="white-space:pre"><b>def</b></span></${tag}>` + + "<pre>ghi</pre>", + ], + }, + { + initialHTML: + `<${tag}>abc${caretInLeft}</${tag}>` + + `<pre><b>${caretInRight}def<br></b>ghi</pre>`, + expectedHTML: [ + `<${tag}>abc<b>def</b></${tag}>` + + "<pre>ghi</pre>", + ], + expectedHTMLWithStyledPre: [ + `<${tag}>abc<b style="white-space:pre">def</b></${tag}>` + + "<pre>ghi</pre>", + `<${tag}>abc<span style="white-space:pre"><b>def</b></span></${tag}>` + + "<pre>ghi</pre>", + ], + }, + // One linefeed at start of <pre> should be ignored. + // Note that if setupEditingHost() does not touch the text node in <pre>, + // the leading line break is ignored, but if it touches the text node, + // the value is set to as-is. Therefore, the following tests can work + // with empty caretInRight value. + { + initialHTML: + `<${tag}>abc${caretInLeft}</${tag}>` + + `<pre>\ndef\nghi</pre>`, + expectedHTML: [ + `<${tag}>abcdef</${tag}>` + + `<pre>ghi</pre>`, + ], + expectedHTMLWithStyledPre: [ + `<${tag}>abc<span style="white-space:pre">def</span></${tag}>` + + "<pre>ghi</pre>", + ], + skip: caretInRight !== "", + }, + // When there are two line breaks at start of <pre>, the first one should be + // ignored by the parser but the second one should make empty first line. + // Therefore, the first empty line should be removed. + { + initialHTML: + `<${tag}>abc${caretInLeft}</${tag}>` + + `<pre>\n\ndef\nghi</pre>`, + expectedHTML: [ + `<${tag}>abc</${tag}>` + + "<pre>def\nghi</pre>", + ], + skip: caretInRight !== "", + }, +]; +const utils = new EditorTestUtils(editingHost); + +const betweenBlockAndPre = new RegExp(`</${tag}><pre>`); +const betweenPreAndBlock = new RegExp(`</pre><${tag}>`); +function putStyleElement() { + const styleElement = document.createElement("style"); + styleElement.textContent = "pre { white-space: pre; }"; + document.head.appendChild(styleElement); +} + +for (const specifyPreStyle of [false, true]) { + for (const t of tests) { + if (t.skip) { + continue; + } + if (specifyPreStyle && !t.expectedHTMLWithStyledPre) { + continue; + } + promise_test(async () => { + if (specifyPreStyle) { + putStyleElement(); + } + try { + utils.setupEditingHost(t.initialHTML); + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + utils.normalizeStyleAttributeValues(); + assert_in_array( + editingHost.innerHTML, + specifyPreStyle ? t.expectedHTMLWithStyledPre : t.expectedHTML, + `white-space should${ + !specifyPreStyle ? " not" : "" + } be preserved by <span> elements` + ); + } finally { + if (specifyPreStyle) { + document.querySelector("style")?.remove(); + } + } + }, `${commandName} at ${t.initialHTML.replace(/\n/g, "\\n")}${ + specifyPreStyle ? " (with <style>pre { white-space: pre; }</style>)" : "" + }`); + + // Repeat same tests with inserting a line break between the paragraphs. + const initialHTMLWithLineBreak = + t.initialHTML + .replace(betweenBlockAndPre, `</${tag}>\n<pre>`) + .replace(betweenPreAndBlock, `</pre>\n<${tag}>`); + promise_test(async () => { + if (specifyPreStyle) { + putStyleElement(); + } + try { + utils.setupEditingHost(initialHTMLWithLineBreak); + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + utils.normalizeStyleAttributeValues(); + assert_in_array( + editingHost.innerHTML, + specifyPreStyle ? t.expectedHTMLWithStyledPre : t.expectedHTML, + `white-space should${ + !specifyPreStyle ? " not" : "" + } be preserved by <span> elements (testing with a line break between paragraphs)` + ); + } finally { + if (specifyPreStyle) { + document.querySelector("style")?.remove(); + } + } + }, `${commandName} at ${initialHTMLWithLineBreak.replace(/\n/g, "\\n")}${ + specifyPreStyle ? " (with <style>pre { white-space: pre; }</style>)" : "" + }`); + } +} +</script> +</body> +</html> diff --git a/testing/web-platform/tests/editing/other/justify-preserving-selection.tentative.html b/testing/web-platform/tests/editing/other/justify-preserving-selection.tentative.html new file mode 100644 index 0000000000..94a63e8505 --- /dev/null +++ b/testing/web-platform/tests/editing/other/justify-preserving-selection.tentative.html @@ -0,0 +1,148 @@ +<!doctype html> +<html> +<head> +<meta chareset="utf-8"> +<meta name="timeout" content="long"> +<meta name="variant" content="?styleWithCSS=false&command=justifyCenter"> +<meta name="variant" content="?styleWithCSS=false&command=justifyFull"> +<meta name="variant" content="?styleWithCSS=false&command=justifyLeft"> +<meta name="variant" content="?styleWithCSS=false&command=justifyRight"> +<meta name="variant" content="?styleWithCSS=true&command=justifyCenter"> +<meta name="variant" content="?styleWithCSS=true&command=justifyFull"> +<meta name="variant" content="?styleWithCSS=true&command=justifyLeft"> +<meta name="variant" content="?styleWithCSS=true&command=justifyRight"> +<title>Test preserving selection after justifying selected content</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script src="../include/editor-test-utils.js"></script> +</head> +<body> +<div contenteditable></div> +<script> +"use strict"; + +const editor = document.querySelector("div[contenteditable]"); +const utils = new EditorTestUtils(editor); +const searchParams = new URLSearchParams(document.location.search); +const styleWithCSS = searchParams.get("styleWithCSS"); +const command = searchParams.get("command"); +document.execCommand("styleWithCSS", false, styleWithCSS); + +// Note that it's not scope of this test how browsers to align the selected +// content. + +// html: Initial HTML which will be set editor.innerHTML, it should contain +// selection range with a pair of "[" or "{" and "]" or "}". +// expectedSelectedString: After executing "outdent", compared with +// getSelection().toString().replace(/[ \n\r\t]+/g, "") +const tests = [ + { + html: "<div>a[b]c</div>", + expectedSelectedString: "b", + }, + { + html: "<address>a[b]c</address>", // <address> cannot have align attribute + expectedSelectedString: "b", + }, + { + html: "<div>a[bc</div>" + + "<div>de]f</div>", + expectedSelectedString: "bcde", + }, + { + html: "<div>a[bc</div>" + + "<address>de]f</address>", + expectedSelectedString: "bcde", + }, + { + html: "<address>a[bc</address>" + + "<div>de]f</div>", + expectedSelectedString: "bcde", + }, + { + html: "<address>a[bc</address>" + + "<address>de]f</address>", + expectedSelectedString: "bcde", + }, + { + html: "<ul><li>a[b]c</li></ul>", + expectedSelectedString: "b", + }, + { + html: "<ul><li>a[bc</li><li>de]f</li></ul>", + expectedSelectedString: "bcde", + }, + { + html: "<ul><li>a[bc</li><li>de]f</li><li>ghi</li></ul>", + expectedSelectedString: "bcde", + }, + { + html: "<ul><li>abc</li><li>d[ef</li><li>gh]i</li></ul>", + expectedSelectedString: "efgh", + }, + { + html: "<ul><li>abc</li><li>d[e]f</li><li>ghi</li></ul>", + expectedSelectedString: "e", + }, + { + html: "<ul><li>a[bc</li></ul>" + + "<div>de]f</div>", + expectedSelectedString: "bcde", + }, + { + html: "<ul><li>abc</li><li>d[ef</li></ul>" + + "<div>gh]i</div>", + expectedSelectedString: "efgh", + }, + { + html: "<div>a[bc</div>" + + "<ul><li>de]f</li></ul>", + expectedSelectedString: "bcde", + }, + { + html: "<div>a[bc</div>" + + "<ul><li>de]f</li><li>ghi</li></ul>", + expectedSelectedString: "bcde", + }, + { + html: "<table><tr><td>a[b]c</td></tr></table>", + expectedSelectedString: "b", + }, + { + html: "<table><tr><td>a[bc</td><td>de]f</td></tr></table>", + expectedSelectedString: "bcde", + }, + { + html: "<table><tr><td>a[bc</td></tr><tr><td>de]f</td></tr></table>", + expectedSelectedString: "bcde", + }, + { + html: "<div>a[bc</div>" + + "<table><tr><td>de]f</td></tr></table>", + expectedSelectedString: "bcde", + }, + { + html: "<table><tr><td>a[bc</td></tr></table>" + + "<div>de]f</div>", + expectedSelectedString: "bcde", + }, +]; + +for (const t of tests) { + test(() => { + utils.setupEditingHost(t.html); + document.execCommand(command); + assert_equals( + getSelection().toString().replace(/[ \n\r\t]+/g, ""), + t.expectedSelectedString, + `Result: ${editor.innerHTML}` + ); + }, `Preserve selection after ${command} at ${t.html}`); +} + +</script> +</body> +</html> diff --git a/testing/web-platform/tests/editing/other/keeping-attributes-at-joining-elements.tentative.html b/testing/web-platform/tests/editing/other/keeping-attributes-at-joining-elements.tentative.html new file mode 100644 index 0000000000..99a0dab56a --- /dev/null +++ b/testing/web-platform/tests/editing/other/keeping-attributes-at-joining-elements.tentative.html @@ -0,0 +1,1167 @@ +<!doctype html> +<meta chareset="utf-8"> +<meta name="timeout" content="long"> +<meta name="variant" content="?method=backspace"> +<meta name="variant" content="?method=forwarddelete"> +<title>Not merging attributes at joining elements in contenteditable</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script src="../include/editor-test-utils.js"></script> +</style> +<div contenteditable></div> +<script> +"use strict"; + +const testingBackspace = + new URLSearchParams(document.location.search).get("method") == "backspace"; +const caretForBackSpace = testingBackspace ? "[]" : ""; +const caretForForwardDelete = testingBackspace ? "" : "[]"; +document.execCommand("defaultParagraphSeparator", false, "div"); +const utils = + new EditorTestUtils(document.querySelector("div[contenteditable]")); + +// DO NOT USE multi-line comment in this file, then, you can comment out +// unnecessary tests when you need to attach the browser with a debugger. + +// At joining 2 elements, the attributes shouldn't be merged, and from point of +// view of JS/DOM, both element kept after the join and element deleted from the +// DOM tree should have attributes as-is. +promise_test(async t => { + utils.setupEditingHost( + `<div id="left">abc${caretForForwardDelete}</div><div id="right">${caretForBackSpace}def</div>` + ); + const leftNode = document.getElementById("left"); + const rightNode = document.getElementById("right"); + + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + + test(() => { + assert_equals( + leftNode.getAttribute("id"), + "left", + `The left node should keep having id=left (isConnected=${leftNode.isConnected}, ${t.name})` + ); + }); + test(() => { + assert_equals( + rightNode.getAttribute("id"), + "right", + `The right node should keep having id=right (isConnected=${rightNode.isConnected}, ${t.name})` + ); + }); + assert_equals( + leftNode.isConnected ^ rightNode.isConnected, + 1, + `One should stay in the document and the other should be disconnected (${utils.editingHost.innerHTML}, ${t.name})` + ); +}, "Joining <div id=\"left\"> and <div id=\"right\">"); + +promise_test(async t => { + utils.setupEditingHost( + `<div class="left">abc${caretForForwardDelete}</div><div class="right">${caretForBackSpace}def</div>` + ); + const leftNode = utils.editingHost.querySelector(".left"); + const rightNode = utils.editingHost.querySelector(".right"); + + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + + test(() => { + assert_equals( + leftNode.getAttribute("class"), + "left", + `The left node should keep having class=left (isConnected=${leftNode.isConnected}, ${t.name})` + ); + }); + test(() => { + assert_equals( + rightNode.getAttribute("class"), + "right", + `The right node should keep having class=right (isConnected=${rightNode.isConnected}, ${t.name})` + ); + }); + assert_equals( + leftNode.isConnected ^ rightNode.isConnected, + 1, + `One should stay in the document and the other should be disconnected (${utils.editingHost.innerHTML}, ${t.name})` + ); +}, "Joining <div class=\"left\"> and <div class=\"right\">"); + +promise_test(async t => { + utils.setupEditingHost( + `<div style="font-size:0.8rem">abc${caretForForwardDelete}</div><div style="font-weight:bold">${caretForBackSpace}def</div>` + ); + const leftNode = utils.editingHost.querySelector("div[style]"); + const rightNode = leftNode.nextSibling; + + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + + // style attribute values shouldn't be touched in this but case, but it's + // okay if the values are not merged. + test(() => { + assert_true( + leftNode.getAttribute("style").includes("font-size"), + `The left node should keep having style attribute containing font-size (style="${leftNode.getAttribute("style")}", ${t.name})` + ); + assert_false( + leftNode.getAttribute("style").includes("font-weight"), + `The left node should have font-weight in its style attribute (style="${leftNode.getAttribute("style")}", ${t.name})` + ); + }); + test(() => { + assert_true( + rightNode.getAttribute("style").includes("font-weight"), + `The right node should keep having style attribute containing font-size (style="${rightNode.getAttribute("style")}", ${t.name})` + ); + assert_false( + rightNode.getAttribute("style").includes("font-style"), + `The right node should have font-size in its style attribute (style="${rightNode.getAttribute("style")}", ${t.name})` + ); + }); + assert_equals( + leftNode.isConnected ^ rightNode.isConnected, + 1, + `One should stay in the document and the other should be disconnected (${utils.editingHost.innerHTML}, ${t.name})` + ); +}, "Joining <div style=\"font-size:0.8rem\"> and <div style=\"font-weight:bold\">"); + +promise_test(async t => { + utils.setupEditingHost( + `<div data-foo="left">abc${caretForForwardDelete}</div><div data-bar="right">${caretForBackSpace}def</div>` + ); + const leftNode = utils.editingHost.querySelector("[data-foo=left]"); + const rightNode = utils.editingHost.querySelector("[data-bar=right]"); + + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + + test(() => { + assert_equals( + leftNode.getAttribute("data-foo"), + "left", + `The left node should keep having class=left (isConnected=${leftNode.isConnected}, ${t.name})` + ); + }); + test(() => { + assert_false( + leftNode.hasAttribute("data-bar"), + `The left node shouldn't have data-bar attribute (isConnected=${leftNode.isConnected}, ${t.name})` + ); + }); + test(() => { + assert_equals( + rightNode.getAttribute("data-bar"), + "right", + `The right node should keep having class=right (isConnected=${rightNode.isConnected}, ${t.name})` + ); + }); + test(() => { + assert_false( + rightNode.hasAttribute("data-foo"), + `The right node shouldn't have data-foo attribute (isConnected=${leftNode.isConnected}, ${t.name})` + ); + }); + assert_equals( + leftNode.isConnected ^ rightNode.isConnected, + 1, + `One should stay in the document and the other should be disconnected (${utils.editingHost.innerHTML}, ${t.name})` + ); +}, "Joining <div data-foo=\"left\"> and <div data-bar=\"right\">"); + +// Same tests for list-item elements because they may be handled in a different +// path. +promise_test(async t => { + utils.setupEditingHost( + `<ul><li id="left">abc${caretForForwardDelete}</li><li id="right">${caretForBackSpace}def</li></ul>` + ); + const leftNode = document.getElementById("left"); + const rightNode = document.getElementById("right"); + + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + + test(() => { + assert_equals( + leftNode.getAttribute("id"), + "left", + `The left node should keep having id=left (isConnected=${leftNode.isConnected}, ${t.name})` + ); + }); + test(() => { + assert_equals( + rightNode.getAttribute("id"), + "right", + `The right node should keep having id=right (isConnected=${rightNode.isConnected}, ${t.name})` + ); + }); + assert_equals( + leftNode.isConnected ^ rightNode.isConnected, + 1, + `One should stay in the document and the other should be disconnected (${utils.editingHost.innerHTML}, ${t.name})` + ); +}, "Joining <li id=\"left\"> and <li id=\"right\">"); + +promise_test(async t => { + utils.setupEditingHost( + `<ul><li class="left">abc${caretForForwardDelete}</li><li class="right">${caretForBackSpace}def</li></ul>` + ); + const leftNode = utils.editingHost.querySelector(".left"); + const rightNode = utils.editingHost.querySelector(".right"); + + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + + test(() => { + assert_equals( + leftNode.getAttribute("class"), + "left", + `The left node should keep having class=left (isConnected=${leftNode.isConnected}, ${t.name})` + ); + }); + test(() => { + assert_equals( + rightNode.getAttribute("class"), + "right", + `The right node should keep having class=right (isConnected=${rightNode.isConnected}, ${t.name})` + ); + }); + assert_equals( + leftNode.isConnected ^ rightNode.isConnected, + 1, + `One should stay in the document and the other should be disconnected (${utils.editingHost.innerHTML}, ${t.name})` + ); +}, "Joining <li class=\"left\"> and <li class=\"right\">"); + +promise_test(async t => { + utils.setupEditingHost( + `<ul><li style="font-size:0.8rem">abc${caretForForwardDelete}</li><li style="font-weight:bold">${caretForBackSpace}def</li></ul>` + ); + const leftNode = utils.editingHost.querySelector("li[style]"); + const rightNode = leftNode.nextSibling; + + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + + // style attribute values shouldn't be touched in this but case, but it's + // okay if the values are not merged. + test(() => { + assert_true( + leftNode.getAttribute("style").includes("font-size"), + `The left node should keep having style attribute containing font-size (style="${leftNode.getAttribute("style")}", ${t.name})` + ); + assert_false( + leftNode.getAttribute("style").includes("font-weight"), + `The left node should have font-weight in its style attribute (style="${leftNode.getAttribute("style")}", ${t.name})` + ); + }); + test(() => { + assert_true( + rightNode.getAttribute("style").includes("font-weight"), + `The right node should keep having style attribute containing font-size (style="${rightNode.getAttribute("style")}", ${t.name})` + ); + assert_false( + rightNode.getAttribute("style").includes("font-style"), + `The right node should have font-size in its style attribute (style="${rightNode.getAttribute("style")}", ${t.name})` + ); + }); + assert_equals( + leftNode.isConnected ^ rightNode.isConnected, + 1, + `One should stay in the document and the other should be disconnected (${utils.editingHost.innerHTML}, ${t.name})` + ); +}, "Joining <li style=\"font-size:0.8rem\"> and <li style=\"font-weight:bold\">"); + +promise_test(async t => { + utils.setupEditingHost( + `<ul><li data-foo="left">abc${caretForForwardDelete}</li><li data-bar="right">${caretForBackSpace}def</li></ul>` + ); + const leftNode = utils.editingHost.querySelector("[data-foo=left]"); + const rightNode = utils.editingHost.querySelector("[data-bar=right]"); + + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + + test(() => { + assert_equals( + leftNode.getAttribute("data-foo"), + "left", + `The left node should keep having class=left (isConnected=${leftNode.isConnected}, ${t.name})` + ); + }); + test(() => { + assert_false( + leftNode.hasAttribute("data-bar"), + `The left node shouldn't have data-bar attribute (isConnected=${leftNode.isConnected}, ${t.name})` + ); + }); + test(() => { + assert_equals( + rightNode.getAttribute("data-bar"), + "right", + `The right node should keep having class=right (isConnected=${rightNode.isConnected}, ${t.name})` + ); + }); + test(() => { + assert_false( + rightNode.hasAttribute("data-foo"), + `The right node shouldn't have data-foo attribute (isConnected=${leftNode.isConnected}, ${t.name})` + ); + }); + assert_equals( + leftNode.isConnected ^ rightNode.isConnected, + 1, + `One should stay in the document and the other should be disconnected (${utils.editingHost.innerHTML}, ${t.name})` + ); +}, "Joining <li data-foo=\"left\"> and <li data-bar=\"right\">"); + +// Same tests for <dt> elements because they may be handled in a different +// path. +promise_test(async t => { + utils.setupEditingHost( + `<dl><dt id="left">abc${caretForForwardDelete}</dt><dt id="right">${caretForBackSpace}def</dt></dl>` + ); + const leftNode = document.getElementById("left"); + const rightNode = document.getElementById("right"); + + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + + test(() => { + assert_equals( + leftNode.getAttribute("id"), + "left", + `The left node should keep having id=left (isConnected=${leftNode.isConnected}, ${t.name})` + ); + }); + test(() => { + assert_equals( + rightNode.getAttribute("id"), + "right", + `The right node should keep having id=right (isConnected=${rightNode.isConnected}, ${t.name})` + ); + }); + assert_equals( + leftNode.isConnected ^ rightNode.isConnected, + 1, + `One should stay in the document and the other should be disconnected (${utils.editingHost.innerHTML}, ${t.name})` + ); +}, "Joining <dt id=\"left\"> and <dt id=\"right\">"); + +promise_test(async t => { + utils.setupEditingHost( + `<dl><dt class="left">abc${caretForForwardDelete}</dt><dt class="right">${caretForBackSpace}def</dt></dl>` + ); + const leftNode = utils.editingHost.querySelector(".left"); + const rightNode = utils.editingHost.querySelector(".right"); + + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + + test(() => { + assert_equals( + leftNode.getAttribute("class"), + "left", + `The left node should keep having class=left (isConnected=${leftNode.isConnected}, ${t.name})` + ); + }); + test(() => { + assert_equals( + rightNode.getAttribute("class"), + "right", + `The right node should keep having class=right (isConnected=${rightNode.isConnected}, ${t.name})` + ); + }); + assert_equals( + leftNode.isConnected ^ rightNode.isConnected, + 1, + `One should stay in the document and the other should be disconnected (${utils.editingHost.innerHTML}, ${t.name})` + ); +}, "Joining <dt class=\"left\"> and <dt class=\"right\">"); + +promise_test(async t => { + utils.setupEditingHost( + `<dl><dt style="font-size:0.8rem">abc${caretForForwardDelete}</dt><dt style="font-weight:bold">${caretForBackSpace}def</dt></dl>` + ); + const leftNode = utils.editingHost.querySelector("dt[style]"); + const rightNode = leftNode.nextSibling; + + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + + // style attribute values shouldn't be touched in this but case, but it's + // okay if the values are not merged. + test(() => { + assert_true( + leftNode.getAttribute("style").includes("font-size"), + `The left node should keep having style attribute containing font-size (style="${leftNode.getAttribute("style")}", ${t.name})` + ); + assert_false( + leftNode.getAttribute("style").includes("font-weight"), + `The left node should have font-weight in its style attribute (style="${leftNode.getAttribute("style")}", ${t.name})` + ); + }); + test(() => { + assert_true( + rightNode.getAttribute("style").includes("font-weight"), + `The right node should keep having style attribute containing font-size (style="${rightNode.getAttribute("style")}", ${t.name})` + ); + assert_false( + rightNode.getAttribute("style").includes("font-style"), + `The right node should have font-size in its style attribute (style="${rightNode.getAttribute("style")}", ${t.name})` + ); + }); + assert_equals( + leftNode.isConnected ^ rightNode.isConnected, + 1, + `One should stay in the document and the other should be disconnected (${utils.editingHost.innerHTML}, ${t.name})` + ); +}, "Joining <dt style=\"font-size:0.8rem\"> and <dt style=\"font-weight:bold\">"); + +promise_test(async t => { + utils.setupEditingHost( + `<dl><dt data-foo="left">abc${caretForForwardDelete}</dt><dt data-bar="right">${caretForBackSpace}def</dt></dl>` + ); + const leftNode = utils.editingHost.querySelector("[data-foo=left]"); + const rightNode = utils.editingHost.querySelector("[data-bar=right]"); + + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + + test(() => { + assert_equals( + leftNode.getAttribute("data-foo"), + "left", + `The left node should keep having class=left (isConnected=${leftNode.isConnected}, ${t.name})` + ); + }); + test(() => { + assert_false( + leftNode.hasAttribute("data-bar"), + `The left node shouldn't have data-bar attribute (isConnected=${leftNode.isConnected}, ${t.name})` + ); + }); + test(() => { + assert_equals( + rightNode.getAttribute("data-bar"), + "right", + `The right node should keep having class=right (isConnected=${rightNode.isConnected}, ${t.name})` + ); + }); + test(() => { + assert_false( + rightNode.hasAttribute("data-foo"), + `The right node shouldn't have data-foo attribute (isConnected=${leftNode.isConnected}, ${t.name})` + ); + }); + assert_equals( + leftNode.isConnected ^ rightNode.isConnected, + 1, + `One should stay in the document and the other should be disconnected (${utils.editingHost.innerHTML}, ${t.name})` + ); +}, "Joining <dt data-foo=\"left\"> and <dt data-bar=\"right\">"); + +// Same tests for <dd> elements because they may be handled in a different +// path. +promise_test(async t => { + utils.setupEditingHost( + `<dl><dd id="left">abc${caretForForwardDelete}</dd><dd id="right">${caretForBackSpace}def</dd></dl>` + ); + const leftNode = document.getElementById("left"); + const rightNode = document.getElementById("right"); + + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + + test(() => { + assert_equals( + leftNode.getAttribute("id"), + "left", + `The left node should keep having id=left (isConnected=${leftNode.isConnected}, ${t.name})` + ); + }); + test(() => { + assert_equals( + rightNode.getAttribute("id"), + "right", + `The right node should keep having id=right (isConnected=${rightNode.isConnected}, ${t.name})` + ); + }); + assert_equals( + leftNode.isConnected ^ rightNode.isConnected, + 1, + `One should stay in the document and the other should be disconnected (${utils.editingHost.innerHTML}, ${t.name})` + ); +}, "Joining <dd id=\"left\"> and <dd id=\"right\">"); + +promise_test(async t => { + utils.setupEditingHost( + `<dl><dd class="left">abc${caretForForwardDelete}</dd><dd class="right">${caretForBackSpace}def</dd></dl>` + ); + const leftNode = utils.editingHost.querySelector(".left"); + const rightNode = utils.editingHost.querySelector(".right"); + + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + + test(() => { + assert_equals( + leftNode.getAttribute("class"), + "left", + `The left node should keep having class=left (isConnected=${leftNode.isConnected}, ${t.name})` + ); + }); + test(() => { + assert_equals( + rightNode.getAttribute("class"), + "right", + `The right node should keep having class=right (isConnected=${rightNode.isConnected}, ${t.name})` + ); + }); + assert_equals( + leftNode.isConnected ^ rightNode.isConnected, + 1, + `One should stay in the document and the other should be disconnected (${utils.editingHost.innerHTML}, ${t.name})` + ); +}, "Joining <dd class=\"left\"> and <dd class=\"right\">"); + +promise_test(async t => { + utils.setupEditingHost( + `<dl><dd style="font-size:0.8rem">abc${caretForForwardDelete}</dd><dd style="font-weight:bold">${caretForBackSpace}def</dd></dl>` + ); + const leftNode = utils.editingHost.querySelector("dd[style]"); + const rightNode = leftNode.nextSibling; + + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + + // style attribute values shouldn't be touched in this but case, but it's + // okay if the values are not merged. + test(() => { + assert_true( + leftNode.getAttribute("style").includes("font-size"), + `The left node should keep having style attribute containing font-size (style="${leftNode.getAttribute("style")}", ${t.name})` + ); + assert_false( + leftNode.getAttribute("style").includes("font-weight"), + `The left node should have font-weight in its style attribute (style="${leftNode.getAttribute("style")}", ${t.name})` + ); + }); + test(() => { + assert_true( + rightNode.getAttribute("style").includes("font-weight"), + `The right node should keep having style attribute containing font-size (style="${rightNode.getAttribute("style")}", ${t.name})` + ); + assert_false( + rightNode.getAttribute("style").includes("font-style"), + `The right node should have font-size in its style attribute (style="${rightNode.getAttribute("style")}", ${t.name})` + ); + }); + assert_equals( + leftNode.isConnected ^ rightNode.isConnected, + 1, + `One should stay in the document and the other should be disconnected (${utils.editingHost.innerHTML}, ${t.name})` + ); +}, "Joining <dd style=\"font-size:0.8rem\"> and <dd style=\"font-weight:bold\">"); + +promise_test(async t => { + utils.setupEditingHost( + `<dl><dd data-foo="left">abc${caretForForwardDelete}</dd><dd data-bar="right">${caretForBackSpace}def</dd></dl>` + ); + const leftNode = utils.editingHost.querySelector("[data-foo=left]"); + const rightNode = utils.editingHost.querySelector("[data-bar=right]"); + + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + + test(() => { + assert_equals( + leftNode.getAttribute("data-foo"), + "left", + `The left node should keep having class=left (isConnected=${leftNode.isConnected}, ${t.name})` + ); + }); + test(() => { + assert_false( + leftNode.hasAttribute("data-bar"), + `The left node shouldn't have data-bar attribute (isConnected=${leftNode.isConnected}, ${t.name})` + ); + }); + test(() => { + assert_equals( + rightNode.getAttribute("data-bar"), + "right", + `The right node should keep having class=right (isConnected=${rightNode.isConnected}, ${t.name})` + ); + }); + test(() => { + assert_false( + rightNode.hasAttribute("data-foo"), + `The right node shouldn't have data-foo attribute (isConnected=${leftNode.isConnected}, ${t.name})` + ); + }); + assert_equals( + leftNode.isConnected ^ rightNode.isConnected, + 1, + `One should stay in the document and the other should be disconnected (${utils.editingHost.innerHTML}, ${t.name})` + ); +}, "Joining <dd data-foo=\"left\"> and <dd data-bar=\"right\">"); + +// Same tests for <dt> and <dd> because they may be handled in a different +// path. +promise_test(async t => { + utils.setupEditingHost( + `<dl><dt id="left">abc${caretForForwardDelete}</dt><dd id="right">${caretForBackSpace}def</dd></dl>` + ); + const leftNode = document.getElementById("left"); + const rightNode = document.getElementById("right"); + + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + + test(() => { + assert_equals( + leftNode.getAttribute("id"), + "left", + `The left node should keep having id=left (isConnected=${leftNode.isConnected}, ${t.name})` + ); + }); + test(() => { + assert_equals( + rightNode.getAttribute("id"), + "right", + `The right node should keep having id=right (isConnected=${rightNode.isConnected}, ${t.name})` + ); + }); + assert_equals( + leftNode.isConnected ^ rightNode.isConnected, + 1, + `One should stay in the document and the other should be disconnected (${utils.editingHost.innerHTML}, ${t.name})` + ); +}, "Joining <dt id=\"left\"> and <dd id=\"right\">"); + +promise_test(async t => { + utils.setupEditingHost( + `<dl><dt class="left">abc${caretForForwardDelete}</dt><dd class="right">${caretForBackSpace}def</dd></dl>` + ); + const leftNode = utils.editingHost.querySelector(".left"); + const rightNode = utils.editingHost.querySelector(".right"); + + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + + test(() => { + assert_equals( + leftNode.getAttribute("class"), + "left", + `The left node should keep having class=left (isConnected=${leftNode.isConnected}, ${t.name})` + ); + }); + test(() => { + assert_equals( + rightNode.getAttribute("class"), + "right", + `The right node should keep having class=right (isConnected=${rightNode.isConnected}, ${t.name})` + ); + }); + assert_equals( + leftNode.isConnected ^ rightNode.isConnected, + 1, + `One should stay in the document and the other should be disconnected (${utils.editingHost.innerHTML}, ${t.name})` + ); +}, "Joining <dt class=\"left\"> and <dd class=\"right\">"); + +promise_test(async t => { + utils.setupEditingHost( + `<dl><dt style="font-size:0.8rem">abc${caretForForwardDelete}</dt><dd style="font-weight:bold">${caretForBackSpace}def</dd></dl>` + ); + const leftNode = utils.editingHost.querySelector("dt[style]"); + const rightNode = utils.editingHost.querySelector("dd[style]"); + + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + + // style attribute values shouldn't be touched in this but case, but it's + // okay if the values are not merged. + test(() => { + assert_true( + leftNode.getAttribute("style").includes("font-size"), + `The left node should keep having style attribute containing font-size (style="${leftNode.getAttribute("style")}", ${t.name})` + ); + assert_false( + leftNode.getAttribute("style").includes("font-weight"), + `The left node should have font-weight in its style attribute (style="${leftNode.getAttribute("style")}", ${t.name})` + ); + }); + test(() => { + assert_true( + rightNode.getAttribute("style").includes("font-weight"), + `The right node should keep having style attribute containing font-size (style="${rightNode.getAttribute("style")}", ${t.name})` + ); + assert_false( + rightNode.getAttribute("style").includes("font-style"), + `The right node should have font-size in its style attribute (style="${rightNode.getAttribute("style")}", ${t.name})` + ); + }); + assert_equals( + leftNode.isConnected ^ rightNode.isConnected, + 1, + `One should stay in the document and the other should be disconnected (${utils.editingHost.innerHTML}, ${t.name})` + ); +}, "Joining <dt style=\"font-size:0.8rem\"> and <dd style=\"font-weight:bold\">"); + +promise_test(async t => { + utils.setupEditingHost( + `<dl><dt data-foo="left">abc${caretForForwardDelete}</dt><dd data-bar="right">${caretForBackSpace}def</dd></dl>` + ); + const leftNode = utils.editingHost.querySelector("[data-foo=left]"); + const rightNode = utils.editingHost.querySelector("[data-bar=right]"); + + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + + test(() => { + assert_equals( + leftNode.getAttribute("data-foo"), + "left", + `The left node should keep having class=left (isConnected=${leftNode.isConnected}, ${t.name})` + ); + }); + test(() => { + assert_false( + leftNode.hasAttribute("data-bar"), + `The left node shouldn't have data-bar attribute (isConnected=${leftNode.isConnected}, ${t.name})` + ); + }); + test(() => { + assert_equals( + rightNode.getAttribute("data-bar"), + "right", + `The right node should keep having class=right (isConnected=${rightNode.isConnected}, ${t.name})` + ); + }); + test(() => { + assert_false( + rightNode.hasAttribute("data-foo"), + `The right node shouldn't have data-foo attribute (isConnected=${leftNode.isConnected}, ${t.name})` + ); + }); + assert_equals( + leftNode.isConnected ^ rightNode.isConnected, + 1, + `One should stay in the document and the other should be disconnected (${utils.editingHost.innerHTML}, ${t.name})` + ); +}, "Joining <dt data-foo=\"left\"> and <dd data-bar=\"right\">"); + +// Same tests for <dd> and <dt> because they may be handled in a different +// path. +promise_test(async t => { + utils.setupEditingHost( + `<dl><dd id="left">abc${caretForForwardDelete}</dd><dt id="right">${caretForBackSpace}def</dt></dl>` + ); + const leftNode = document.getElementById("left"); + const rightNode = document.getElementById("right"); + + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + + test(() => { + assert_equals( + leftNode.getAttribute("id"), + "left", + `The left node should keep having id=left (isConnected=${leftNode.isConnected}, ${t.name})` + ); + }); + test(() => { + assert_equals( + rightNode.getAttribute("id"), + "right", + `The right node should keep having id=right (isConnected=${rightNode.isConnected}, ${t.name})` + ); + }); + assert_equals( + leftNode.isConnected ^ rightNode.isConnected, + 1, + `One should stay in the document and the other should be disconnected (${utils.editingHost.innerHTML}, ${t.name})` + ); +}, "Joining <dd id=\"left\"> and <dt id=\"right\">"); + +promise_test(async t => { + utils.setupEditingHost( + `<dl><dd class="left">abc${caretForForwardDelete}</dd><dt class="right">${caretForBackSpace}def</dt></dl>` + ); + const leftNode = utils.editingHost.querySelector(".left"); + const rightNode = utils.editingHost.querySelector(".right"); + + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + + test(() => { + assert_equals( + leftNode.getAttribute("class"), + "left", + `The left node should keep having class=left (isConnected=${leftNode.isConnected}, ${t.name})` + ); + }); + test(() => { + assert_equals( + rightNode.getAttribute("class"), + "right", + `The right node should keep having class=right (isConnected=${rightNode.isConnected}, ${t.name})` + ); + }); + assert_equals( + leftNode.isConnected ^ rightNode.isConnected, + 1, + `One should stay in the document and the other should be disconnected (${utils.editingHost.innerHTML}, ${t.name})` + ); +}, "Joining <dd class=\"left\"> and <dt class=\"right\">"); + +promise_test(async t => { + utils.setupEditingHost( + `<dl><dd style="font-size:0.8rem">abc${caretForForwardDelete}</dd><dt style="font-weight:bold">${caretForBackSpace}def</dt></dl>` + ); + const leftNode = utils.editingHost.querySelector("dd[style]"); + const rightNode = utils.editingHost.querySelector("dt[style]"); + + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + + // style attribute values shouldn't be touched in this but case, but it's + // okay if the values are not merged. + test(() => { + assert_true( + leftNode.getAttribute("style").includes("font-size"), + `The left node should keep having style attribute containing font-size (style="${leftNode.getAttribute("style")}", ${t.name})` + ); + assert_false( + leftNode.getAttribute("style").includes("font-weight"), + `The left node should have font-weight in its style attribute (style="${leftNode.getAttribute("style")}", ${t.name})` + ); + }); + test(() => { + assert_true( + rightNode.getAttribute("style").includes("font-weight"), + `The right node should keep having style attribute containing font-size (style="${rightNode.getAttribute("style")}", ${t.name})` + ); + assert_false( + rightNode.getAttribute("style").includes("font-style"), + `The right node should have font-size in its style attribute (style="${rightNode.getAttribute("style")}", ${t.name})` + ); + }); + assert_equals( + leftNode.isConnected ^ rightNode.isConnected, + 1, + `One should stay in the document and the other should be disconnected (${utils.editingHost.innerHTML}, ${t.name})` + ); +}, "Joining <dd style=\"font-size:0.8rem\"> and <dt style=\"font-weight:bold\">"); + +promise_test(async t => { + utils.setupEditingHost( + `<dl><dd data-foo="left">abc${caretForForwardDelete}</dd><dt data-bar="right">${caretForBackSpace}def</dt></dl>` + ); + const leftNode = utils.editingHost.querySelector("[data-foo=left]"); + const rightNode = utils.editingHost.querySelector("[data-bar=right]"); + + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + + test(() => { + assert_equals( + leftNode.getAttribute("data-foo"), + "left", + `The left node should keep having class=left (isConnected=${leftNode.isConnected}, ${t.name})` + ); + }); + test(() => { + assert_false( + leftNode.hasAttribute("data-bar"), + `The left node shouldn't have data-bar attribute (isConnected=${leftNode.isConnected}, ${t.name})` + ); + }); + test(() => { + assert_equals( + rightNode.getAttribute("data-bar"), + "right", + `The right node should keep having class=right (isConnected=${rightNode.isConnected}, ${t.name})` + ); + }); + test(() => { + assert_false( + rightNode.hasAttribute("data-foo"), + `The right node shouldn't have data-foo attribute (isConnected=${leftNode.isConnected}, ${t.name})` + ); + }); + assert_equals( + leftNode.isConnected ^ rightNode.isConnected, + 1, + `One should stay in the document and the other should be disconnected (${utils.editingHost.innerHTML}, ${t.name})` + ); +}, "Joining <dd data-foo=\"left\"> and <dt data-bar=\"right\">"); + +// Same tests for <h3> and <div> because they may be handled in a different +// path. +promise_test(async t => { + utils.setupEditingHost( + `<h3 id="left">abc${caretForForwardDelete}</h3><div id="right">${caretForBackSpace}def</div>` + ); + const leftNode = document.getElementById("left"); + const rightNode = document.getElementById("right"); + + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + + test(() => { + assert_equals( + leftNode.getAttribute("id"), + "left", + `The left node should keep having id=left (isConnected=${leftNode.isConnected}, ${t.name})` + ); + }); + test(() => { + assert_equals( + rightNode.getAttribute("id"), + "right", + `The right node should keep having id=right (isConnected=${rightNode.isConnected}, ${t.name})` + ); + }); + assert_equals( + leftNode.isConnected ^ rightNode.isConnected, + 1, + `One should stay in the document and the other should be disconnected (${utils.editingHost.innerHTML}, ${t.name})` + ); +}, "Joining <h3 id=\"left\"> and <div id=\"right\">"); + +promise_test(async t => { + utils.setupEditingHost( + `<h3 class="left">abc${caretForForwardDelete}</h3><div class="right">${caretForBackSpace}def</div>` + ); + const leftNode = utils.editingHost.querySelector(".left"); + const rightNode = utils.editingHost.querySelector(".right"); + + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + + test(() => { + assert_equals( + leftNode.getAttribute("class"), + "left", + `The left node should keep having class=left (isConnected=${leftNode.isConnected}, ${t.name})` + ); + }); + test(() => { + assert_equals( + rightNode.getAttribute("class"), + "right", + `The right node should keep having class=right (isConnected=${rightNode.isConnected}, ${t.name})` + ); + }); + assert_equals( + leftNode.isConnected ^ rightNode.isConnected, + 1, + `One should stay in the document and the other should be disconnected (${utils.editingHost.innerHTML}, ${t.name})` + ); +}, "Joining <h3 class=\"left\"> and <div class=\"right\">"); + +promise_test(async t => { + utils.setupEditingHost( + `<h3 style="font-size:0.8rem">abc${caretForForwardDelete}</h3><div style="font-weight:bold">${caretForBackSpace}def</div>` + ); + const leftNode = utils.editingHost.querySelector("h3[style]"); + const rightNode = utils.editingHost.querySelector("div[style]"); + + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + + // style attribute values shouldn't be touched in this but case, but it's + // okay if the values are not merged. + test(() => { + assert_true( + leftNode.getAttribute("style").includes("font-size"), + `The left node should keep having style attribute containing font-size (style="${leftNode.getAttribute("style")}", ${t.name})` + ); + assert_false( + leftNode.getAttribute("style").includes("font-weight"), + `The left node should have font-weight in its style attribute (style="${leftNode.getAttribute("style")}", ${t.name})` + ); + }); + test(() => { + assert_true( + rightNode.getAttribute("style").includes("font-weight"), + `The right node should keep having style attribute containing font-size (style="${rightNode.getAttribute("style")}", ${t.name})` + ); + assert_false( + rightNode.getAttribute("style").includes("font-style"), + `The right node should have font-size in its style attribute (style="${rightNode.getAttribute("style")}", ${t.name})` + ); + }); + assert_equals( + leftNode.isConnected ^ rightNode.isConnected, + 1, + `One should stay in the document and the other should be disconnected (${utils.editingHost.innerHTML}, ${t.name})` + ); +}, "Joining <h3 style=\"font-size:0.8rem\"> and <div style=\"font-weight:bold\">"); + +promise_test(async t => { + utils.setupEditingHost( + `<h3 data-foo="left">abc${caretForForwardDelete}</h3><div data-bar="right">${caretForBackSpace}def</div>` + ); + const leftNode = utils.editingHost.querySelector("[data-foo=left]"); + const rightNode = utils.editingHost.querySelector("[data-bar=right]"); + + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + + test(() => { + assert_equals( + leftNode.getAttribute("data-foo"), + "left", + `The left node should keep having class=left (isConnected=${leftNode.isConnected}, ${t.name})` + ); + }); + test(() => { + assert_false( + leftNode.hasAttribute("data-bar"), + `The left node shouldn't have data-bar attribute (isConnected=${leftNode.isConnected}, ${t.name})` + ); + }); + test(() => { + assert_equals( + rightNode.getAttribute("data-bar"), + "right", + `The right node should keep having class=right (isConnected=${rightNode.isConnected}, ${t.name})` + ); + }); + test(() => { + assert_false( + rightNode.hasAttribute("data-foo"), + `The right node shouldn't have data-foo attribute (isConnected=${leftNode.isConnected}, ${t.name})` + ); + }); + assert_equals( + leftNode.isConnected ^ rightNode.isConnected, + 1, + `One should stay in the document and the other should be disconnected (${utils.editingHost.innerHTML}, ${t.name})` + ); +}, "Joining <h3 data-foo=\"left\"> and <div data-bar=\"right\">"); + +// Same tests for <div> and <h3> because they may be handled in a different +// path. +promise_test(async t => { + utils.setupEditingHost( + `<div id="left">abc${caretForForwardDelete}</div><h3 id="right">${caretForBackSpace}def</h3>` + ); + const leftNode = document.getElementById("left"); + const rightNode = document.getElementById("right"); + + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + + test(() => { + assert_equals( + leftNode.getAttribute("id"), + "left", + `The left node should keep having id=left (isConnected=${leftNode.isConnected}, ${t.name})` + ); + }); + test(() => { + assert_equals( + rightNode.getAttribute("id"), + "right", + `The right node should keep having id=right (isConnected=${rightNode.isConnected}, ${t.name})` + ); + }); + assert_equals( + leftNode.isConnected ^ rightNode.isConnected, + 1, + `One should stay in the document and the other should be disconnected (${utils.editingHost.innerHTML}, ${t.name})` + ); +}, "Joining <div id=\"left\"> and <h3 id=\"right\">"); + +promise_test(async t => { + utils.setupEditingHost( + `<div class="left">abc${caretForForwardDelete}</div><h3 class="right">${caretForBackSpace}def</h3>` + ); + const leftNode = utils.editingHost.querySelector(".left"); + const rightNode = utils.editingHost.querySelector(".right"); + + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + + test(() => { + assert_equals( + leftNode.getAttribute("class"), + "left", + `The left node should keep having class=left (isConnected=${leftNode.isConnected}, ${t.name})` + ); + }); + test(() => { + assert_equals( + rightNode.getAttribute("class"), + "right", + `The right node should keep having class=right (isConnected=${rightNode.isConnected}, ${t.name})` + ); + }); + assert_equals( + leftNode.isConnected ^ rightNode.isConnected, + 1, + `One should stay in the document and the other should be disconnected (${utils.editingHost.innerHTML}, ${t.name})` + ); +}, "Joining <div class=\"left\"> and <h3 class=\"right\">"); + +promise_test(async t => { + utils.setupEditingHost( + `<div style="font-size:0.8rem">abc${caretForForwardDelete}</div><h3 style="font-weight:bold">${caretForBackSpace}def</h3>` + ); + const leftNode = utils.editingHost.querySelector("div[style]"); + const rightNode = utils.editingHost.querySelector("h3[style]"); + + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + + // style attribute values shouldn't be touched in this but case, but it's + // okay if the values are not merged. + test(() => { + assert_true( + leftNode.getAttribute("style").includes("font-size"), + `The left node should keep having style attribute containing font-size (style="${leftNode.getAttribute("style")}", ${t.name})` + ); + assert_false( + leftNode.getAttribute("style").includes("font-weight"), + `The left node should have font-weight in its style attribute (style="${leftNode.getAttribute("style")}", ${t.name})` + ); + }); + test(() => { + assert_true( + rightNode.getAttribute("style").includes("font-weight"), + `The right node should keep having style attribute containing font-size (style="${rightNode.getAttribute("style")}", ${t.name})` + ); + assert_false( + rightNode.getAttribute("style").includes("font-style"), + `The right node should have font-size in its style attribute (style="${rightNode.getAttribute("style")}", ${t.name})` + ); + }); + assert_equals( + leftNode.isConnected ^ rightNode.isConnected, + 1, + `One should stay in the document and the other should be disconnected (${utils.editingHost.innerHTML}, ${t.name})` + ); +}, "Joining <div style=\"font-size:0.8rem\"> and <h3 style=\"font-weight:bold\">"); + +promise_test(async t => { + utils.setupEditingHost( + `<div data-foo="left">abc${caretForForwardDelete}</div><h3 data-bar="right">${caretForBackSpace}def</h3>` + ); + const leftNode = utils.editingHost.querySelector("[data-foo=left]"); + const rightNode = utils.editingHost.querySelector("[data-bar=right]"); + + await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + + test(() => { + assert_equals( + leftNode.getAttribute("data-foo"), + "left", + `The left node should keep having class=left (isConnected=${leftNode.isConnected}, ${t.name})` + ); + }); + test(() => { + assert_false( + leftNode.hasAttribute("data-bar"), + `The left node shouldn't have data-bar attribute (isConnected=${leftNode.isConnected}, ${t.name})` + ); + }); + test(() => { + assert_equals( + rightNode.getAttribute("data-bar"), + "right", + `The right node should keep having class=right (isConnected=${rightNode.isConnected}, ${t.name})` + ); + }); + test(() => { + assert_false( + rightNode.hasAttribute("data-foo"), + `The right node shouldn't have data-foo attribute (isConnected=${leftNode.isConnected}, ${t.name})` + ); + }); + assert_equals( + leftNode.isConnected ^ rightNode.isConnected, + 1, + `One should stay in the document and the other should be disconnected (${utils.editingHost.innerHTML}, ${t.name})` + ); +}, "Joining <div data-foo=\"left\"> and <h3 data-bar=\"right\">"); + + +</script> diff --git a/testing/web-platform/tests/editing/other/legacy-edit-command.html b/testing/web-platform/tests/editing/other/legacy-edit-command.html new file mode 100644 index 0000000000..81ff89d81b --- /dev/null +++ b/testing/web-platform/tests/editing/other/legacy-edit-command.html @@ -0,0 +1,117 @@ +<!doctype html> +<html> +<meta charset=utf-8> +<meta name="variant" content="?command=increaseFontSize"> +<meta name="variant" content="?command=decreaseFontSize"> +<meta name="variant" content="?command=getHTML"> +<meta name="variant" content="?command=insertBrOrReturn¶m=true"> +<meta name="variant" content="?command=insertBrOrReturn¶m=false"> +<meta name="variant" content="?command=heading¶m=h1"> +<meta name="variant" content="?command=heading¶m=h2"> +<meta name="variant" content="?command=heading¶m=h3"> +<meta name="variant" content="?command=heading¶m=h4"> +<meta name="variant" content="?command=heading¶m=h5"> +<meta name="variant" content="?command=heading¶m=h6"> +<meta name="variant" content="?command=contentReadOnly¶m=true"> +<meta name="variant" content="?command=contentReadOnly¶m=false"> +<meta name="variant" content="?command=readonly¶m=true"> +<meta name="variant" content="?command=readonly¶m=false"> +<title>Test legacy commands won't work</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +</head> +<body contenteditable></body> +<script> +"use strict"; + +const testParams = new URLSearchParams(location.search.substring(1)); +const command = testParams.get("command"); +const param = testParams.has("param") ? testParams.get("param") : undefined; + +const editor = document.body; + +promise_test(async () => { + await new Promise(resolve => addEventListener("load", resolve, {once: true})); +}, "Wait for load..."); + +promise_test(async () => { + function reset() { + editor.innerHTML = "<p>abc</p>"; + editor.focus(); + getSelection().setBaseAndExtent( + editor.querySelector("p").firstChild, + 1, + editor.querySelector("p").firstChild, + 2 + ); + } + test(() => { + reset(); + let inputEvents = []; + function onInput(event) { + inputEvents.push(event); + } + editor.addEventListener("input", onInput); + try { + assert_equals( + document.execCommand(command, false, param), + false, + "result should be false" + ); + assert_equals( + editor.outerHTML, + "<body contenteditable=\"\"><p>abc</p></body>", + "editable content shouldn't be modified" + ); + assert_equals( + inputEvents.length, + 0, + "no input events should be fired" + ); + } finally { + editor.removeEventListener("input", onInput); + } + }, `execCommand("${command}", false, ${param === undefined ? "undefined" : `"${param}"`})`); + test(() => { + reset(); + assert_equals( + document.queryCommandState(command), + false, + "result should be false" + ); + }, `queryCommandState("${command}")`); + test(() => { + reset(); + assert_equals( + document.queryCommandEnabled(command), + false, + "result should be false" + ); + }, `queryCommandEnabled("${command}")`); + test(() => { + reset(); + assert_equals( + document.queryCommandIndeterm(command), + false, + "result should be false" + ); + }, `queryCommandIndeterm("${command}")`); + test(() => { + reset(); + assert_equals( + document.queryCommandValue(command), + "", + "result should be empty string" + ); + }, `queryCommandValue("${command}")`); + test(() => { + reset(); + assert_equals( + document.queryCommandSupported(command), + false, + "result should be false" + ); + }, `queryCommandSupported("${command}")`); +}, `command: "${command}", param: "${param}"`); +</script> +</html> diff --git a/testing/web-platform/tests/editing/other/link-boundaries-insertion.html b/testing/web-platform/tests/editing/other/link-boundaries-insertion.html new file mode 100644 index 0000000000..567cc33ad9 --- /dev/null +++ b/testing/web-platform/tests/editing/other/link-boundaries-insertion.html @@ -0,0 +1,44 @@ +<!DOCTYPE HTML> +<meta charset=utf-8> +<title>Placing selection and typing inside empty elements</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="../include/editor-test-utils.js"></script> + +<div contenteditable></div> + +<script> + const utils = new EditorTestUtils( document.querySelector( 'div[contenteditable]' ) ); + + test( () => { + utils.setupEditingHost( `<p><a href="https://example.com" id="test-end">Link</a></p>` ); + + const target = document.querySelector( '#test-end' ); + const range = document.createRange(); + const selection = getSelection(); + + range.selectNodeContents( target ); + selection.removeAllRanges(); + selection.addRange( range ); + selection.collapseToEnd(); + + document.execCommand( 'insertText', false, 'a' ); + assert_equals( target.innerHTML, 'Linka', 'The text should be inserted into the link' ); + }, 'Insert text into the selection at the end of a link' ); + + test( () => { + utils.setupEditingHost( `<p><a href="https://example.com" id="test-beginning">Link</a></p>` ); + + const target = document.querySelector( '#test-beginning' ); + const range = document.createRange(); + const selection = getSelection(); + + range.selectNodeContents( target ); + selection.removeAllRanges(); + selection.addRange( range ); + selection.collapseToStart(); + + document.execCommand( 'insertText', false, 'a' ); + assert_equals( target.innerHTML, 'aLink', 'The text should be inserted into the link' ); + }, 'Insert text into the selection at the beginning of a link' ); +</script> diff --git a/testing/web-platform/tests/editing/other/move-inserted-node-from-DOMNodeInserted-during-exec-command-insertHTML.html b/testing/web-platform/tests/editing/other/move-inserted-node-from-DOMNodeInserted-during-exec-command-insertHTML.html new file mode 100644 index 0000000000..41e012a62e --- /dev/null +++ b/testing/web-platform/tests/editing/other/move-inserted-node-from-DOMNodeInserted-during-exec-command-insertHTML.html @@ -0,0 +1,27 @@ +<!doctype html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div contenteditable> +<p id="p1"><br></p> +<p id="p2"></p> +</div> +<script> +"use strict"; +let editor = document.querySelector("[contenteditable]"); +let p1 = document.getElementById("p1"); +let p2 = document.getElementById("p2"); +p1.addEventListener("DOMNodeInserted", event => { + if (event.target.localName === "i") { + p2.appendChild(event.target); + } +}); +document.getSelection().collapse(p1, 0); +document.execCommand("insertHTML", false, + "<b>bold1</b><i>italic1</i><b>bold2</b><i>italic2</i>"); +test(function () { + assert_in_array(p1.innerHTML, ["<b>bold1</b><b>bold2</b><br>", "<b>bold1</b><b>bold2</b>"]); +}, "First <p> element should have only <b> elements"); +test(function () { + assert_equals(p2.innerHTML, "<i>italic1</i><i>italic2</i>"); +}, "Second <p> element should have only <i> elements"); +</script>
\ No newline at end of file diff --git a/testing/web-platform/tests/editing/other/non-html-document.html b/testing/web-platform/tests/editing/other/non-html-document.html new file mode 100644 index 0000000000..ffd2e6f594 --- /dev/null +++ b/testing/web-platform/tests/editing/other/non-html-document.html @@ -0,0 +1,24 @@ +<!doctype html> +<meta charset=utf-8> +<title>Non-HTML document tests</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script> + +test(function() { + let xmldoc = + document.implementation.createDocument("http://www.w3.org/1999/xlink", + "html", null); + for (let f of [ + () => xmldoc.execCommand("bold"), + () => xmldoc.queryCommandEnabled("bold"), + () => xmldoc.queryCommandIndeterm("bold"), + () => xmldoc.queryCommandState("bold"), + () => xmldoc.queryCommandSupported("bold"), + () => xmldoc.queryCommandValue("bold"), + ]) { + assert_throws_dom("InvalidStateError", f); + } +}, "editing APIs on an XML document should be disabled"); + +</script> diff --git a/testing/web-platform/tests/editing/other/outdent-preserving-selection.tentative.html b/testing/web-platform/tests/editing/other/outdent-preserving-selection.tentative.html new file mode 100644 index 0000000000..9f299bda49 --- /dev/null +++ b/testing/web-platform/tests/editing/other/outdent-preserving-selection.tentative.html @@ -0,0 +1,192 @@ +<!doctype html> +<html> +<head> +<meta chareset="utf-8"> +<meta name="timeout" content="long"> +<meta name="variant" content="?styleWithCSS=false"> +<meta name="variant" content="?styleWithCSS=true"> +<title>Test preserving selection after outdent</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script src="../include/editor-test-utils.js"></script> +</head> +<body> +<div contenteditable></div> +<script> +"use strict"; + +const editor = document.querySelector("div[contenteditable]"); +const utils = new EditorTestUtils(editor); +const styleWithCSS = + new URLSearchParams(document.location.search).get("styleWithCSS"); +document.execCommand("styleWithCSS", false, styleWithCSS); + +// Note that it's not scope of this test how browsers to outdent the selected +// content. + +// html: Initial HTML which will be set editor.innerHTML, it should contain +// selection range with a pair of "[" or "{" and "]" or "}". +// expectedSelectedString: After executing "outdent", compared with +// getSelection().toString().replace(/[ \n\r]+/g, "") +const tests = [ + { + html: "<blockquote>a[b]c</blockquote>", + expectedSelectedString: "b", + }, + { + html: "<blockquote><div>a[b]c</div></blockquote>", + expectedSelectedString: "b", + }, + { + html: "<blockquote><div>a[bc</div><div>de]f</div></blockquote>", + expectedSelectedString: "bcde", + }, + { + html: "<blockquote>a[bc</blockquote>" + + "<blockquote>de]f</blockquote>", + expectedSelectedString: "bcde", + }, + { + html: '<div style="margin-left:15px">a[b]c</div>', + expectedSelectedString: "b", + }, + { + html: '<div style="margin-left:15px">a[bc</div>' + + '<div style="margin-left:15px">de]f</div>', + expectedSelectedString: "bcde", + }, + { + html: "<ul><li>a[b]c</li></ul>", + expectedSelectedString: "b", + }, + { + html: "<ul><li>a[bc</li><li>de]f</li></ul>", + expectedSelectedString: "bcde", + }, + { + html: "<ol><ul><li>a[b]c</li></ul></ol>", + expectedSelectedString: "b", + }, + { + html: "<ol><ul><li>a[bc</li><li>de]f</li></ul></ol>", + expectedSelectedString: "bcde", + }, + { + html: "<ul><ul><li>a[b]c</li></ul></ul>", + expectedSelectedString: "b", + }, + { + html: "<ul><ul><li>a[bc</li><li>de]f</li></ul></ul>", + expectedSelectedString: "bcde", + }, + { + html: "<ol><li><ul><li>a[b]c</li></ul></li></ol>", + expectedSelectedString: "b", + }, + { + html: "<ol><li><ul><li>a[bc</li><li>de]f</li></ul></li></ol>", + expectedSelectedString: "bcde", + }, + { + html: "<ul><li><ul><li>a[b]c</li></ul></li></ul>", + expectedSelectedString: "b", + }, + { + html: "<ul><li><ul><li>a[bc</li><li>de]f</li></ul></li></ul>", + expectedSelectedString: "bcde", + }, + { + html: "<blockquote><div>a[bc</div></blockquote>" + + "<ul><ul><li>de]f</li></ul></ul>", + expectedSelectedString: "bcde", + }, + { + html: "<blockquote><div>a[bc</div></blockquote>" + + "<ol><ul><li>de]f</li></ul></ol>", + expectedSelectedString: "bcde", + }, + { + html: '<div style="margin-left:15px">a[bc</div>' + + "<ul><ul><li>de]f</li></ul></ul>", + expectedSelectedString: "bcde", + }, + { + html: "<blockquote><div>a[bc</div></blockquote>" + + "<ul><li><ul><li>de]f</li></ul></li></ul>", + expectedSelectedString: "bcde", + }, + { + html: "<blockquote><div>a[bc</div></blockquote>" + + "<ol><li><ul><li>de]f</li></ul></li></ol>", + expectedSelectedString: "bcde", + }, + { + html: "<ol><ul><li>a[bc</li></ul></ol>" + + "<blockquote><div>de]f</div></blockquote>", + expectedSelectedString: "bcde", + }, + { + html: "<ul><ul><li>a[bc</li></ul></ul>" + + '<div style="margin-left:15px">de]f</div>', + expectedSelectedString: "bcde", + }, + { + html: "<ul><li><ul><li>a[bc</li></ul></li></ul>" + + "<blockquote><div>de]f</div></blockquote>", + expectedSelectedString: "bcde", + }, + { + html: "<ol><li><ul><li>a[bc</li></ul></li></ol>" + + "<blockquote><div>de]f</div></blockquote>", + expectedSelectedString: "bcde", + }, + { + html: "<ul><li>a[bc</li></ul>" + + "<ul><li>de]f</li></ul>", + expectedSelectedString: "bcde", + }, + { + html: "<ul><li>abc</li><li>d[ef</li></ul>" + + "<ul><li>gh]i</li></ul>", + expectedSelectedString: "efgh", + }, + { + html: "<ul><li>abc</li><li>d[ef</li></ul>" + + "<ul><li>gh]i</li><li>jkl</li></ul>", + expectedSelectedString: "efgh", + }, + { + html: "<ol><li>a[bc</li></ol>" + + "<ul><li>de]f</li></ul>", + expectedSelectedString: "bcde", + }, + { + html: "<ol><li>abc</li><li>d[ef</li></ol>" + + "<ul><li>gh]i</li></ul>", + expectedSelectedString: "efgh", + }, + { + html: "<ol><li>abc</li><li>d[ef</li></ol>" + + "<ul><li>gh]i</li><li>jkl</li></ul>", + expectedSelectedString: "efgh", + }, +]; + +for (const t of tests) { + test(() => { + utils.setupEditingHost(t.html); + document.execCommand("outdent"); + assert_equals( + getSelection().toString().replace(/[ \n\r]+/g, ""), + t.expectedSelectedString, + `Result: ${editor.innerHTML}` + ); + }, `Preserve selection after outdent at ${t.html}`); +} + +</script> +</body> +</html> diff --git a/testing/web-platform/tests/editing/other/recursive-exec-command-calls.tentative.html b/testing/web-platform/tests/editing/other/recursive-exec-command-calls.tentative.html new file mode 100644 index 0000000000..60a3b03099 --- /dev/null +++ b/testing/web-platform/tests/editing/other/recursive-exec-command-calls.tentative.html @@ -0,0 +1,37 @@ +<!doctype html> +<meta charset=utf-8> +<title>Test recursive `Document.execCommand()` calls</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<div contenteditable><br></div> +<script> +"use strict"; + +setup({explicit_done: true}); + +/** + * This test checks whether the browser allows or disallows recursive + * Document.execCommand() calls. + * https://github.com/w3c/editing/issues/200#issuecomment-578097441 + */ +function runTests() { + test(function () { + let editor = document.querySelector("div[contenteditable]"); + editor.focus(); + let counter = 0; + editor.addEventListener("input", event => { + if (++counter < 10) { + let result = document.execCommand("insertText", false, `, ${counter}`); + assert_false(result, + '`execCommand("insertText") in the "input" event listener should return `false`'); + } + }); + document.execCommand("insertText", false, "0"); + assert_equals(editor.textContent, "0", + '`execCommand("insertText") in the "input" event listener should do nothing'); + }, "Recursive `Document.execCommand()` shouldn't be supported"); + done(); +} + +window.addEventListener("load", runTests, {once: true}); +</script> diff --git a/testing/web-platform/tests/editing/other/removing-inline-style-specified-by-parent-block.tentative.html b/testing/web-platform/tests/editing/other/removing-inline-style-specified-by-parent-block.tentative.html new file mode 100644 index 0000000000..c799819a38 --- /dev/null +++ b/testing/web-platform/tests/editing/other/removing-inline-style-specified-by-parent-block.tentative.html @@ -0,0 +1,125 @@ +<!doctype html> +<html> +<meta charset=utf-8> +<meta name="variant" content="?b"> +<meta name="variant" content="?i"> +<meta name="variant" content="?u"> +<title>Test removing inline style which is specified by parent block</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<body> +<div contenteditable></div> +</body> +<script> +"use strict"; + +const tag = location.search.substring(1); +const style = (() => { + switch (tag) { + case "b": + return "font-weight: bold"; + case "i": + return "font-style: italic"; + case "u": + return "text-decoration: underline"; + } +})(); +const cancelingStyle = (() => { + switch (tag) { + case "b": + return "font-weight: normal"; + case "i": + return "font-style: normal"; + case "u": + return ""; // Cannot delete parent underline + } +})(); +const command = (() => { + switch (tag) { + case "b": + return "bold"; + case "i": + return "italic"; + case "u": + return "underline"; + } +})(); +const editor = document.querySelector("div[contenteditable]"); + +promise_test(async () => { + await new Promise(resolve => { + addEventListener("load", () => { + assert_true(true, "The document is loaded"); + resolve(); + }, { once: true }); + }); +}, "Waiting for load..."); + +promise_test(async () => { + document.execCommand("styleWithCSS", false, "false"); + editor.innerHTML = `<p style="${style}">foo</p>`; + editor.focus(); + getSelection().selectAllChildren(editor.querySelector("p")); + document.execCommand(command); + assert_in_array( + editor.innerHTML, + [ + "<p>foo</p>", + "<p>foo<br></p>", + "<p style=\"\">foo</p>", + "<p style=\"\">foo<br></p>", + ]); +}, "Disabling style to text, it's applied to the parent block"); + +promise_test(async () => { + document.execCommand("styleWithCSS", false, "false"); + editor.innerHTML = `<p>foo</p>`; + editor.setAttribute("style", style); + editor.focus(); + getSelection().selectAllChildren(editor.querySelector("p")); + document.execCommand(command); + if (cancelingStyle !== "") { + assert_in_array( + editor.innerHTML, + [ + `<p><span style="${cancelingStyle};">foo</span></p>`, + `<p><span style="${cancelingStyle};">foo</span><br></p>`, + ]); + } else { + assert_in_array( + editor.innerHTML, + [ + "<p>foo</p>", + "<p>foo<br></p>", + ]); + } + assert_equals(editor.getAttribute("style"), style); + editor.removeAttribute("style"); +}, "Disabling style to text, it's applied to the editing host"); + +promise_test(async () => { + document.execCommand("styleWithCSS", false, "false"); + editor.innerHTML = `<p>foo</p>`; + document.body.setAttribute("style", style); + editor.focus(); + getSelection().selectAllChildren(editor.querySelector("p")); + document.execCommand(command); + if (cancelingStyle !== "") { + assert_in_array( + editor.innerHTML, + [ + `<p><span style="${cancelingStyle};">foo</span></p>`, + `<p><span style="${cancelingStyle};">foo</span><br></p>`, + ]); + } else { + assert_in_array( + editor.innerHTML, + [ + "<p>foo</p>", + "<p>foo<br></p>", + ]); + } + assert_equals(document.body.getAttribute("style"), style); + document.body.removeAttribute("style"); +}, "Disabling style to text, it's applied to the body"); +</script>
\ No newline at end of file diff --git a/testing/web-platform/tests/editing/other/restoration.html b/testing/web-platform/tests/editing/other/restoration.html new file mode 100644 index 0000000000..4c53008b41 --- /dev/null +++ b/testing/web-platform/tests/editing/other/restoration.html @@ -0,0 +1,90 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Restoration of style tests</title> +<!-- +No spec, based on: https://bugzilla.mozilla.org/show_bug.cgi?id=1250805 +If the user presses Ctrl+B and then hits Enter and then types text, the text +should still be bold. Hitting Enter shouldn't make it forget. And so too for +other commands. +--> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<div contenteditable></div> +<script> +var div = document.querySelector("div"); + +function doTestInner(cmd, param, startBold) { + div.innerHTML = startBold ? "<b>foo</b>bar" : "foobar"; + getSelection().collapse(startBold ? div.firstChild.firstChild + : div.firstChild, 3); + + // Set/unset bold, then run command and see if it's still there + assert_true(document.execCommand("bold", false, ""), + "execCommand needs to return true for bold"); + + assert_true(document.execCommand(cmd, false, param), + "execCommand needs to return true for " + cmd + " " + param); + + assert_equals(document.queryCommandState("bold"), !startBold, + "bold state"); + + assert_true(document.execCommand("inserttext", false, "x"), + "execCommand needs to return true for inserttext x"); + + // Find the new text node and check that it's actually bold (or not) + var node = div; + while (node) { + if (node.nodeType == Node.TEXT_NODE && node.nodeValue.indexOf("x") != -1) { + assert_in_array(getComputedStyle(node.parentNode).fontWeight, + !startBold ? ["700", "bold"] : ["400", "normal"], + "font-weight"); + return; + } + if (node.firstChild) { + node = node.firstChild; + continue; + } + while (node != div && !node.nextSibling) { + node = node.parentNode; + } + if (node == div) { + assert_unreached("x not found!"); + break; + } + node = node.nextSibling; + } +} + +function doTest(cmd, param) { + if (param === undefined) { + param = ""; + } + + test(function() { + doTestInner(cmd, param, true); + }, cmd + " " + param + " starting bold"); + + test(function() { + doTestInner(cmd, param, false); + }, cmd + " " + param + " starting not bold"); +} + +doTest("insertparagraph"); +doTest("insertlinebreak"); +doTest("delete"); +doTest("forwarddelete"); +doTest("insertorderedlist"); +doTest("insertunorderedlist"); +doTest("indent"); +// Outdent does nothing here, but should be harmless. +doTest("outdent"); +doTest("justifyleft"); +doTest("justifyright"); +doTest("justifycenter"); +doTest("justifyfull"); +doTest("formatblock", "div"); +doTest("formatblock", "blockquote"); +doTest("inserthorizontalrule"); +doTest("insertimage", "a"); +doTest("inserttext", "bar"); +</script> diff --git a/testing/web-platform/tests/editing/other/select-all-and-delete-in-html-element-having-contenteditable.html b/testing/web-platform/tests/editing/other/select-all-and-delete-in-html-element-having-contenteditable.html new file mode 100644 index 0000000000..ab324c6d03 --- /dev/null +++ b/testing/web-platform/tests/editing/other/select-all-and-delete-in-html-element-having-contenteditable.html @@ -0,0 +1,151 @@ +<!doctype html> +<html contenteditable> +<head> +<meta charset=utf-8> +<title>Test "Select all" and deletion work with <html contenteditable></title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/resources/testdriver-actions.js"></script> +</head> +<body> +<script> +"use strict"; + +const kBackspaceKey = "\uE003"; +const kDeleteKey = "\uE017"; +const kMeta = "\uE03d"; +const kControl = "\uE009"; + +async function selectAllWithKey(elementToSelectAll) { + if (elementToSelectAll.length === 0) { + throw "element to select all must not be empty"; + } + getSelection().collapse(elementToSelectAll, 0); + try { + await new test_driver.Actions() + .keyDown(kControl) + .keyDown("a") + .keyUp("a") + .keyUp(kControl) + .send(); + if (!getSelection().isCollapsed) { + return; + } + await new test_driver.Actions() + .keyDown(kMeta) + .keyDown("a") + .keyUp("a") + .keyUp(kMeta) + .send(); + if (!getSelection().isCollapsed) { + return; + } + } catch (ex) { + throw ex; + } + throw "Neither Control-A nor Meta-A does select all contents"; +} + +function deleteWithBackspaceKey() { + return new test_driver.Actions() + .keyDown(kBackspaceKey) + .keyUp(kBackspaceKey) + .send(); +} + +function deleteWithDeleteKey() { + return new test_driver.Actions() + .keyDown(kDeleteKey) + .keyUp(kDeleteKey) + .send(); +} + +promise_test(async () => { + document.body.innerHTML = "abc"; + await selectAllWithKey(document.body); + await deleteWithBackspaceKey(); + assert_in_array(document.body.innerHTML, ["", "<br>"]); +}, "Select All, then, Backspace"); + +promise_test(async () => { + document.body.innerHTML = "abc"; + await selectAllWithKey(document.body); + await deleteWithDeleteKey(); + assert_in_array(document.body.innerHTML, ["", "<br>"]); +}, "Select All, then, Delete"); + +promise_test(async () => { + document.body.innerHTML = "abc"; + document.execCommand("selectall"); + await deleteWithBackspaceKey(); + assert_in_array(document.body.innerHTML, ["", "<br>"]); +}, 'execCommand("selectall"), then, Backspace'); + +promise_test(async () => { + document.body.innerHTML = "abc"; + document.execCommand("selectall"); + await deleteWithDeleteKey(); + assert_in_array(document.body.innerHTML, ["", "<br>"]); +}, 'execCommand("selectall"), then, Delete'); + +promise_test(async () => { + document.body.innerHTML = "abc"; + await selectAllWithKey(document.body); + document.execCommand("forwarddelete", false, false); + assert_in_array(document.body.innerHTML, ["", "<br>"]); +}, 'Select All, then, execCommand("forwarddelete")'); + +promise_test(async () => { + document.body.innerHTML = "abc"; + await selectAllWithKey(document.body); + document.execCommand("delete", false, false); + assert_in_array(document.body.innerHTML, ["", "<br>"]); +}, 'Select All, then, execCommand("delete")'); + +test(() => { + document.body.innerHTML = "abc"; + document.execCommand("selectall"); + document.execCommand("forwarddelete", false, false); + assert_in_array(document.body.innerHTML, ["", "<br>"]); +}, 'execCommand("selectall"), then, execCommand("forwarddelete")'); + +test(() => { + document.body.innerHTML = "abc"; + document.execCommand("selectall"); + document.execCommand("delete", false, false); + assert_in_array(document.body.innerHTML, ["", "<br>"]); +}, 'execCommand("selectall"), then, execCommand("delete")'); + +promise_test(async () => { + document.body.innerHTML = "abc"; + getSelection().selectAllChildren(document.documentElement); + await deleteWithBackspaceKey(); + assert_in_array(document.body.innerHTML, ["", "<br>"]); +}, 'getSelection().selectAllChildren(document.documentElement), then, Backspace'); + +promise_test(async () => { + document.body.innerHTML = "abc"; + getSelection().selectAllChildren(document.documentElement); + await deleteWithDeleteKey(); + assert_in_array(document.body.innerHTML, ["", "<br>"]); +}, 'getSelection().selectAllChildren(document.documentElement), then, Delete'); + +test(() => { + document.body.innerHTML = "abc"; + getSelection().selectAllChildren(document.documentElement); + document.execCommand("forwarddelete", false, false); + assert_in_array(document.body.innerHTML, ["", "<br>"]); +}, 'getSelection().selectAllChildren(document.documentElement), then, execCommand("forwarddelete")'); + +test(() => { + document.body.innerHTML = "abc"; + getSelection().selectAllChildren(document.documentElement); + document.execCommand("delete", false, false); + assert_in_array(document.body.innerHTML, ["", "<br>"]); +}, 'getSelection().selectAllChildren(document.documentElement), then, execCommand("delete")'); + +</script> +</body> +</html>
\ No newline at end of file diff --git a/testing/web-platform/tests/editing/other/selectall-in-editinghost.html b/testing/web-platform/tests/editing/other/selectall-in-editinghost.html new file mode 100644 index 0000000000..680817a771 --- /dev/null +++ b/testing/web-platform/tests/editing/other/selectall-in-editinghost.html @@ -0,0 +1,125 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset=utf-8> +<title>Select All in focused editor</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +"use strict"; + +addEventListener("DOMContentLoaded", () => { + const editingHost = document.querySelector("div[contenteditable]"); + test(() => { + editingHost.focus(); + document.execCommand("selectAll"); + assert_false( + getSelection().isCollapsed, + 'Selection should not be collapsed after calling document.execCommand("selectAll")' + ); + const rangeText = getSelection().toString(); + assert_false( + rangeText.includes("preceding text"), + "Selection should not contain the preceding text of the editing host" + ); + assert_true( + rangeText.includes("editable text"), + "Selection should contain the editable text in the editing host" + ); + assert_false( + rangeText.includes("following text"), + "Selection should not contain the following text of the editing host" + ); + getSelection().removeAllRanges(); + }, "execCommand('selectAll') should select all content in the editing host"); + + test(() => { + editingHost.focus(); + getSelection().removeAllRanges(); + document.execCommand("selectAll"); + assert_false( + getSelection().isCollapsed, + 'Selection should not be collapsed after calling document.execCommand("selectAll")' + ); + const rangeText = getSelection().toString(); + assert_false( + rangeText.includes("preceding text"), + "Selection should not contain the preceding text of the editing host" + ); + assert_true( + rangeText.includes("editable text"), + "Selection should contain the editable text in the editing host" + ); + assert_false( + rangeText.includes("following text"), + "Selection should not contain the following text of the editing host" + ); + getSelection().removeAllRanges(); + }, "execCommand('selectAll') should select all content in the editing host when it has focus but no selection range"); + + test(() => { + editingHost.focus(); + editingHost.innerHTML = "preceding editable text<input value='input value'>following editable text"; + getSelection().collapse(editingHost.querySelector("input"), 0); + document.execCommand("selectAll"); + assert_false( + getSelection().isCollapsed, + 'Selection should not be collapsed after calling document.execCommand("selectAll")' + ); + const rangeText = getSelection().toString(); + assert_false( + rangeText.includes("preceding text"), + "Selection should not contain the preceding text of the editing host" + ); + assert_true( + rangeText.includes("preceding editable text"), + "Selection should contain the preceding editable text of <input> in the editing host" + ); + assert_true( + rangeText.includes("following editable text"), + "Selection should contain the following editable text of <input> in the editing host" + ); + assert_false( + rangeText.includes("following text"), + "Selection should not contain the following text of the editing host" + ); + getSelection().removeAllRanges(); + }, "execCommand('selectAll') should select all content in the editing host when selection collapsed in the <input>"); + + test(() => { + editingHost.focus(); + editingHost.innerHTML = "preceding editable text<textarea>textarea value</textarea>following editable text"; + getSelection().collapse(editingHost.querySelector("textarea"), 0); + document.execCommand("selectAll"); + assert_false( + getSelection().isCollapsed, + 'Selection should not be collapsed after calling document.execCommand("selectAll")' + ); + const rangeText = getSelection().toString(); + assert_false( + rangeText.includes("preceding text"), + "Selection should not contain the preceding text of the editing host" + ); + assert_true( + rangeText.includes("preceding editable text"), + "Selection should contain the preceding editable text of <textarea> in the editing host" + ); + assert_true( + rangeText.includes("following editable text"), + "Selection should contain the following editable text of <textarea> in the editing host" + ); + assert_false( + rangeText.includes("following text"), + "Selection should not contain the following text of the editing host" + ); + getSelection().removeAllRanges(); + }, "execCommand('selectAll') should select all content in the editing host when selection collapsed in the <textarea>"); +}); +</script> +</head> +<body> +<p>preceding text</p> +<div contenteditable>editable text</div> +<p>following text</p> +</body> +</html> diff --git a/testing/web-platform/tests/editing/other/selectall-without-focus.html b/testing/web-platform/tests/editing/other/selectall-without-focus.html new file mode 100644 index 0000000000..508fdc47a2 --- /dev/null +++ b/testing/web-platform/tests/editing/other/selectall-without-focus.html @@ -0,0 +1,73 @@ +<!DOCTYPE HTML> +<head> +<meta charset=utf-8> +<title>Select All without focus should select not select only in the editing host</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +"use strict"; + +addEventListener("DOMContentLoaded", () => { + test(() => { + document.head.remove(); + document.execCommand("selectAll"); + assert_false( + getSelection().isCollapsed, + 'Selection should not be collapsed after calling document.execCommand("selectAll")' + ); + const rangeText = getSelection().toString(); + assert_true( + rangeText.includes("preceding text"), + "Selection should contain the preceding text of the editing host" + ); + assert_true( + rangeText.includes("editable text"), + "Selection should contain the editable text in the editing host" + ); + getSelection().removeAllRanges(); + }, "execCommand('selectAll') should select all content in the document even if the document body ends with editable content"); + + test(() => { + document.querySelector("p").innerHTML = "preceding text <input value='input value'>"; + getSelection().collapse(document.querySelector("input"), 0); + document.execCommand("selectAll"); + assert_false( + getSelection().isCollapsed, + 'Selection should not be collapsed after calling document.execCommand("selectAll")' + ); + const rangeText = getSelection().toString(); + assert_true( + rangeText.includes("preceding text"), + "Selection should contain the preceding text of the editing host" + ); + assert_true( + rangeText.includes("editable text"), + "Selection should contain the editable text in the editing host" + ); + getSelection().removeAllRanges(); + }, "execCommand('selectAll') should select all content in the document when selection is in <input>"); + + test(() => { + document.querySelector("p").innerHTML = "preceding text <textarea>textarea value</textarea>"; + getSelection().collapse(document.querySelector("textarea"), 0); + document.execCommand("selectAll"); + assert_false( + getSelection().isCollapsed, + 'Selection should not be collapsed after calling document.execCommand("selectAll")' + ); + const rangeText = getSelection().toString(); + assert_true( + rangeText.includes("preceding text"), + "Selection should contain the preceding text of the editing host" + ); + assert_true( + rangeText.includes("editable text"), + "Selection should contain the editable text in the editing host" + ); + getSelection().removeAllRanges(); + }, "execCommand('selectAll') should select all content in the document when selection is in <textarea>"); +}); +</script> +</head> +<p>preceding text</p> +<div contenteditable>editable text diff --git a/testing/web-platform/tests/editing/other/setting-value-of-textcontrol-immediately-after-hidden.html b/testing/web-platform/tests/editing/other/setting-value-of-textcontrol-immediately-after-hidden.html new file mode 100644 index 0000000000..f8a867f078 --- /dev/null +++ b/testing/web-platform/tests/editing/other/setting-value-of-textcontrol-immediately-after-hidden.html @@ -0,0 +1,118 @@ +<!doctype html> +<meta charset=utf-8> +<meta name="variant" content="?editor=input&hide-target=editor"> +<meta name="variant" content="?editor=textarea&hide-target=editor"> +<meta name="variant" content="?editor=input&hide-target=parent"> +<meta name="variant" content="?editor=textarea&hide-target=parent"> +<title>Testing edit action in zombie editor</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<body> +<script> +"use strict"; + +const params = new URLSearchParams(location.search); + +/** + * The expected results is based on Chrome 93. + * The behavior is reasonable because JS API which does not require focus keeps + * working even if it's hidden. + */ + +function init() { + const div = document.createElement("div"); + const editor = document.createElement(params.get("editor")); + const hideTarget = params.get("hide-target") == "editor" ? editor : div; + editor.value = "default value"; + div.appendChild(editor); + document.body.appendChild(div); + return [ hideTarget, editor ]; +} + +function finalize(editor) { + editor.blur(); + editor.parentNode.remove(); + document.body.getBoundingClientRect(); +} + +promise_test(async () => { + await new Promise(resolve => addEventListener("load", resolve, {once: true})); +}, "Wait for load event"); + +promise_test(async () => { + const [hideTarget, editor] = init(); + try { + hideTarget.style.display = "none"; + editor.value = "new value"; + assert_equals(editor.value, "new value", "The value should be set properly"); + } finally { + finalize(editor); + } +}, `<${params.get("editor")}>.value = "new value" (without focus)`); + +promise_test(async () => { + const [hideTarget, editor] = init(); + try { + editor.focus(); + hideTarget.style.display = "none"; + editor.value = "new value"; + assert_equals(editor.value, "new value", "The value should be set properly"); + } finally { + finalize(editor); + } +}, `<${params.get("editor")}>.value = "new value" (with focus)`); + +promise_test(async () => { + const [hideTarget, editor] = init(); + try { + editor.focus(); + editor.blur(); + hideTarget.style.display = "none"; + editor.value = "new value"; + assert_equals(editor.value, "new value", "The value should be set properly"); + } finally { + finalize(editor); + } +}, `<${params.get("editor")}>.value = "new value" (after blur)`); + +promise_test(async () => { + const [hideTarget, editor] = init(); + try { + hideTarget.style.display = "none"; + editor.setRangeText("new", 0, "default".length); + assert_equals(editor.value, "new value", "The value should be set properly by setRangeText"); + } finally { + finalize(editor); + } +}, `<${params.get("editor")}>.setRangeText("new", 0, "default".length) (without focus)`); + +promise_test(async () => { + const [hideTarget, editor] = init(); + try { + editor.focus(); + hideTarget.style.display = "none"; + editor.setRangeText("new", 0, "default".length); + assert_equals(editor.value, "new value", "The value should be set properly by setRangeText"); + } finally { + finalize(editor); + } +}, `<${params.get("editor")}>.setRangeText("new", 0, "default".length) (with focus)`); + +promise_test(async () => { + const [hideTarget, editor] = init(); + try { + editor.focus(); + editor.blur(); + hideTarget.style.display = "none"; + editor.setRangeText("new", 0, "default".length); + assert_equals(editor.value, "new value", "The value should be set properly by setRangeText"); + } finally { + finalize(editor); + } +}, `<${params.get("editor")}>.setRangeText("new", 0, "default".length) (after blur)`); + +</script> +</body> diff --git a/testing/web-platform/tests/editing/other/typing-around-link-element-after-joining-paragraphs.html b/testing/web-platform/tests/editing/other/typing-around-link-element-after-joining-paragraphs.html new file mode 100644 index 0000000000..4934530c9b --- /dev/null +++ b/testing/web-platform/tests/editing/other/typing-around-link-element-after-joining-paragraphs.html @@ -0,0 +1,194 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<meta name="timeout" content="long"> +<meta name="variant" content="?action=Backspace"> +<meta name="variant" content="?action=Delete"> +<title>Typing after joining paragraph shouldn't be inserted into the link</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script src="../include/editor-test-utils.js"></script> +</head> +<body> +<div contenteditable></div> +<script> +"use strict"; + +const params = new URLSearchParams(location.search.substring(1)); +const backspace = params.get("action") == "Backspace"; +const bracketsForBackspace = backspace ? "[]" : ""; +const bracketsForDelete = backspace ? "" : "[]"; + +const editingHost = document.querySelector("div[contenteditable]"); +const utils = new EditorTestUtils(editingHost); + +function addPromiseTest(aTest) { + promise_test(async () => { + editingHost.focus(); + utils.setupEditingHost(aTest.innerHTML); + await (backspace ? utils.sendBackspaceKey() : utils.sendDeleteKey()); + await utils.sendKey("X", utils.kShiftKey); + await utils.sendKey("Y", utils.kShiftKey); + utils.normalizeStyleAttributeValues(); + if (Array.isArray(aTest.expectedResult)) { + assert_in_array(editingHost.innerHTML, aTest.expectedResult); + } else { + assert_equals(editingHost.innerHTML, aTest.expectedResult); + } + }, `${backspace ? "Backspace" : "Delete"} in "${aTest.innerHTML}"`); +} + +addPromiseTest({ + innerHTML: `<p><a href="about:blank" style="color:rgb(0, 0, 255)">foo${ + bracketsForDelete + }</a></p><p><span style="color:rgb(255, 0, 0)">${bracketsForBackspace}bar</span></p>`, + expectedResult: `<p><a href="about:blank" style="color:rgb(0, 0, 255)">foo</a>XY<span style="color:rgb(255, 0, 0)">bar</span></p>` +}); +addPromiseTest({ + innerHTML: `<p><a href="about:blank" style="color:rgb(0, 0, 255)">foo${ + bracketsForDelete + }</a><br></p><p><span style="color:rgb(255, 0, 0)">${bracketsForBackspace}bar</span></p>`, + expectedResult: `<p><a href="about:blank" style="color:rgb(0, 0, 255)">foo</a>XY<span style="color:rgb(255, 0, 0)">bar</span></p>` +}); +addPromiseTest({ + innerHTML: `<p><a href="about:blank" style="color:rgb(0, 0, 255)">foo${ + bracketsForDelete + }<br></a></p><p><span style="color:rgb(255, 0, 0)">${bracketsForBackspace}bar</span></p>`, + expectedResult: `<p><a href="about:blank" style="color:rgb(0, 0, 255)">foo</a>XY<span style="color:rgb(255, 0, 0)">bar</span></p>` +}); +addPromiseTest({ + innerHTML: `<p><a href="about:blank" style="color:rgb(0, 0, 255)">foo${ + bracketsForDelete + }</a></p><span style="color:rgb(255, 0, 0)">${bracketsForBackspace}bar</span>`, + expectedResult: `<p><a href="about:blank" style="color:rgb(0, 0, 255)">foo</a>XY<span style="color:rgb(255, 0, 0)">bar</span></p>` +}); +addPromiseTest({ + innerHTML: `<p><a href="about:blank" style="color:rgb(0, 0, 255)">foo${ + bracketsForDelete + }</a><br></p><span style="color:rgb(255, 0, 0)">${bracketsForBackspace}bar</span>`, + expectedResult: `<p><a href="about:blank" style="color:rgb(0, 0, 255)">foo</a>XY<span style="color:rgb(255, 0, 0)">bar</span></p>` +}); +addPromiseTest({ + innerHTML: `<p><a href="about:blank" style="color:rgb(0, 0, 255)">foo${ + bracketsForDelete + }<br></a></p><span style="color:rgb(255, 0, 0)">${bracketsForBackspace}bar</span>`, + expectedResult: `<p><a href="about:blank" style="color:rgb(0, 0, 255)">foo</a>XY<span style="color:rgb(255, 0, 0)">bar</span></p>` +}); +addPromiseTest({ + innerHTML: `<a href="about:blank" style="color:rgb(0, 0, 255)">foo${ + bracketsForDelete + }</a><br><p><span style="color:rgb(255, 0, 0)">${bracketsForBackspace}bar</span></p>`, + expectedResult: `<a href="about:blank" style="color:rgb(0, 0, 255)">foo</a>XY<span style="color:rgb(255, 0, 0)">bar</span>`, +}); +addPromiseTest({ + innerHTML: `<a href="about:blank" style="color:rgb(0, 0, 255)">foo${ + bracketsForDelete + }<br></a><p><span style="color:rgb(255, 0, 0)">${bracketsForBackspace}bar</span></p>`, + expectedResult: `<a href="about:blank" style="color:rgb(0, 0, 255)">foo</a>XY<span style="color:rgb(255, 0, 0)">bar</span>`, +}); + +// Should clear only the link style. +addPromiseTest({ + innerHTML: `<p><a href="about:blank" style="color:rgb(0, 0, 255)"><b>foo${ + bracketsForDelete + }</b></a></p><p><span style="color:rgb(255, 0, 0)">${bracketsForBackspace}bar</span></p>`, + expectedResult: `<p><a href="about:blank" style="color:rgb(0, 0, 255)"><b>foo</b></a><b>XY</b><span style="color:rgb(255, 0, 0)">bar</span></p>`, +}); +addPromiseTest({ + innerHTML: `<p><a href="about:blank" style="color:rgb(0, 0, 255)"><b>foo${ + bracketsForDelete + }</b></a><br></p><p><span style="color:rgb(255, 0, 0)">${bracketsForBackspace}bar</span></p>`, + expectedResult: `<p><a href="about:blank" style="color:rgb(0, 0, 255)"><b>foo</b></a><b>XY</b><span style="color:rgb(255, 0, 0)">bar</span></p>`, +}); +addPromiseTest({ + innerHTML: `<p><a href="about:blank" style="color:rgb(0, 0, 255)"><b>foo${ + bracketsForDelete + }</b><br></a></p><p><span style="color:rgb(255, 0, 0)">${bracketsForBackspace}bar</span></p>`, + expectedResult: `<p><a href="about:blank" style="color:rgb(0, 0, 255)"><b>foo</b></a><b>XY</b><span style="color:rgb(255, 0, 0)">bar</span></p>`, +}); +addPromiseTest({ + innerHTML: `<p><a href="about:blank" style="color:rgb(0, 0, 255)"><b>foo${ + bracketsForDelete + }</b></a></p><span style="color:rgb(255, 0, 0)">${bracketsForBackspace}bar</span>`, + expectedResult: `<p><a href="about:blank" style="color:rgb(0, 0, 255)"><b>foo</b></a><b>XY</b><span style="color:rgb(255, 0, 0)">bar</span></p>`, +}); +addPromiseTest({ + innerHTML: `<p><a href="about:blank" style="color:rgb(0, 0, 255)"><b>foo${ + bracketsForDelete + }</b></a><br></p><span style="color:rgb(255, 0, 0)">${bracketsForBackspace}bar</span>`, + expectedResult: `<p><a href="about:blank" style="color:rgb(0, 0, 255)"><b>foo</b></a><b>XY</b><span style="color:rgb(255, 0, 0)">bar</span></p>`, +}); +addPromiseTest({ + innerHTML: `<p><a href="about:blank" style="color:rgb(0, 0, 255)"><b>foo${ + bracketsForDelete + }</b><br></a></p><span style="color:rgb(255, 0, 0)">${bracketsForBackspace}bar</span>`, + expectedResult: `<p><a href="about:blank" style="color:rgb(0, 0, 255)"><b>foo</b></a><b>XY</b><span style="color:rgb(255, 0, 0)">bar</span></p>`, +}); +addPromiseTest({ + innerHTML: `<a href="about:blank" style="color:rgb(0, 0, 255)"><b>foo${ + bracketsForDelete + }</b></a><br><p><span style="color:rgb(255, 0, 0)">${bracketsForBackspace}bar</span></p>`, + expectedResult: `<a href="about:blank" style="color:rgb(0, 0, 255)"><b>foo</b></a><b>XY</b><span style="color:rgb(255, 0, 0)">bar</span>`, +}); +addPromiseTest({ + innerHTML: `<a href="about:blank" style="color:rgb(0, 0, 255)"><b>foo${ + bracketsForDelete + }</b><br></a><p><span style="color:rgb(255, 0, 0)">${bracketsForBackspace}bar</span></p>`, + expectedResult: `<a href="about:blank" style="color:rgb(0, 0, 255)"><b>foo</b></a><b>XY</b><span style="color:rgb(255, 0, 0)">bar</span>`, +}); + +addPromiseTest({ + innerHTML: `<p><b><a href="about:blank" style="color:rgb(0, 0, 255)">foo${ + bracketsForDelete + }</a></b></p><p><span style="color:rgb(255, 0, 0)">${bracketsForBackspace}bar</span></p>`, + expectedResult: `<p><b><a href="about:blank" style="color:rgb(0, 0, 255)">foo</a>XY</b><span style="color:rgb(255, 0, 0)">bar</span></p>`, +}); +addPromiseTest({ + innerHTML: `<p><b><a href="about:blank" style="color:rgb(0, 0, 255)">foo${ + bracketsForDelete + }</a></b><br></p><p><span style="color:rgb(255, 0, 0)">${bracketsForBackspace}bar</span></p>`, + expectedResult: `<p><b><a href="about:blank" style="color:rgb(0, 0, 255)">foo</a>XY</b><span style="color:rgb(255, 0, 0)">bar</span></p>`, +}); +addPromiseTest({ + innerHTML: `<p><b><a href="about:blank" style="color:rgb(0, 0, 255)">foo${ + bracketsForDelete + }<br></a></b></p><p><span style="color:rgb(255, 0, 0)">${bracketsForBackspace}bar</span></p>`, + expectedResult: `<p><b><a href="about:blank" style="color:rgb(0, 0, 255)">foo</a>XY</b><span style="color:rgb(255, 0, 0)">bar</span></p>`, +}); +addPromiseTest({ + innerHTML: `<p><b><a href="about:blank" style="color:rgb(0, 0, 255)">foo${ + bracketsForDelete + }</a></b></p><span style="color:rgb(255, 0, 0)">${bracketsForBackspace}bar</span>`, + expectedResult: `<p><b><a href="about:blank" style="color:rgb(0, 0, 255)">foo</a>XY</b><span style="color:rgb(255, 0, 0)">bar</span></p>`, +}); +addPromiseTest({ + innerHTML: `<p><b><a href="about:blank" style="color:rgb(0, 0, 255)">foo${ + bracketsForDelete + }</a></b><br></p><span style="color:rgb(255, 0, 0)">${bracketsForBackspace}bar</span>`, + expectedResult: `<p><b><a href="about:blank" style="color:rgb(0, 0, 255)">foo</a>XY</b><span style="color:rgb(255, 0, 0)">bar</span></p>`, +}); +addPromiseTest({ + innerHTML: `<p><b><a href="about:blank" style="color:rgb(0, 0, 255)">foo${ + bracketsForDelete + }<br></a></b></p><span style="color:rgb(255, 0, 0)">${bracketsForBackspace}bar</span>`, + expectedResult: `<p><b><a href="about:blank" style="color:rgb(0, 0, 255)">foo</a>XY</b><span style="color:rgb(255, 0, 0)">bar</span></p>`, +}); +addPromiseTest({ + innerHTML: `<b><a href="about:blank" style="color:rgb(0, 0, 255)">foo${ + bracketsForDelete + }</a></b><br><p><span style="color:rgb(255, 0, 0)">${bracketsForBackspace}bar</span></p>`, + expectedResult: `<b><a href="about:blank" style="color:rgb(0, 0, 255)">foo</a>XY</b><span style="color:rgb(255, 0, 0)">bar</span>`, +}); +addPromiseTest({ + innerHTML: `<b><a href="about:blank" style="color:rgb(0, 0, 255)">foo${ + bracketsForDelete + }<br></a></b><p><span style="color:rgb(255, 0, 0)">${bracketsForBackspace}bar</span></p>`, + expectedResult: `<b><a href="about:blank" style="color:rgb(0, 0, 255)">foo</a>XY</b><span style="color:rgb(255, 0, 0)">bar</span>`, +}); +</script> +</body> +</html> diff --git a/testing/web-platform/tests/editing/other/typing-around-link-element-at-collapsed-selection.tentative.html b/testing/web-platform/tests/editing/other/typing-around-link-element-at-collapsed-selection.tentative.html new file mode 100644 index 0000000000..2b2e304aba --- /dev/null +++ b/testing/web-platform/tests/editing/other/typing-around-link-element-at-collapsed-selection.tentative.html @@ -0,0 +1,635 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<meta name="timeout" content="long"> +<meta name="variant" content="?target=ContentEditable"> +<meta name="variant" content="?target=ContentEditable&parent=b"> +<meta name="variant" content="?target=ContentEditable&child=b"> +<meta name="variant" content="?target=ContentEditable&parent=b&child=i"> +<meta name="variant" content="?target=DesignMode"> +<meta name="variant" content="?target=DesignMode&parent=b"> +<meta name="variant" content="?target=DesignMode&child=b"> +<meta name="variant" content="?target=DesignMode&parent=b&child=i"> +<title>Testing inserting content around link element</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script src="../include/editor-test-utils.js"></script> +<style> +.bold { + font-weight: bold; +} +</style> +</head> +<body> +<div contenteditable></div> +<iframe srcdoc=" + <!doctype html> + <html> + <script>document.designMode='on';</script> + <script src='/resources/testdriver.js'></script> + <script src='/resources/testdriver-vendor.js'></script> + <script src='/resources/testdriver-actions.js'></script> + <body></body> + </html>"></iframe> +<script> +"use strict"; + +const params = new URLSearchParams(location.search.substring(1)); +const kTarget = params.get("target"); +const kParentTag = params.get("parent") === null + ? ["", ""] + : [`<${params.get("parent")}>`, `</${params.get("parent")}>`]; +const kChildTag = params.get("child") === null + ? ["", ""] + : [`<${params.get("child")}>`, `</${params.get("child")}>`]; +const kLinkDesc = (() => { + let result = "" + if (kParentTag[0] !== "") { + result += `in ${kParentTag[0]} `; + if (kChildTag[0] !== "") { + result += "and "; + } + } + if (kChildTag[0] !== "") { + result += `containing ${kChildTag[0]} `; + } + return result; +})(); +const kNewContainerOfLink = (() => { + if (kParentTag !== "" && kChildTag !== "") { + return [`${kParentTag[0]}${kChildTag[0]}`, `${kChildTag[1]}${kParentTag[1]}`]; + } + if (kParentTag !== "") { + return kParentTag; + } + if (kChildTag !== "") { + return kChildTag; + } + return ["", ""]; +})(); +const kSelectorForTextNodeContainer = kChildTag[0] === "" + ? "a" + : `a > ${kChildTag[0].substr(1, kChildTag[0].length - 2)}`; + +function getEditingHost() { + return kTarget === "ContentEditable" + ? document.querySelector("div[contenteditable]") + : document.querySelector("iframe").contentDocument.body; +} + +function addPromiseTest(test) { + promise_test(async () => { + let editingHost = getEditingHost(); + let utils = new EditorTestUtils(editingHost); + utils.setupEditingHost(test.innerHTML); + utils.window.focus(); + utils.document.body.focus(); + editingHost.focus(); + await test.run(utils); + if (Array.isArray(test.expectedResult)) { + assert_in_array(editingHost.innerHTML, test.expectedResult); + } else { + assert_equals(editingHost.innerHTML, test.expectedResult); + } + }, `${test.description.trim()} in ${test.innerHTML}`); +} + +promise_test(async () => { + await new Promise(resolve => { + addEventListener("load", resolve, { once: true }); + }); +}, ""); + +if (kChildTag[0] === "") { + // Immediately after creating a link with Document.execCommand. + + addPromiseTest({ + description: `Replacing text in a link ${kLinkDesc}with "XY"`, + innerHTML: `<p>${kParentTag[0]}[abc]${kParentTag[1]}</p>`, + run: async (utils) => { + utils.document.execCommand("createLink", false, "about:blank"); + await utils.sendKey("X", utils.kShiftKey); + await utils.sendKey("Y", utils.kShiftKey); + }, + expectedResult: [ + `<p>${kParentTag[0]}<a href="about:blank">XY${kParentTag[1]}</a></p>`, + `<p>${kParentTag[0]}<a href="about:blank">XY${kParentTag[1]}</a><br></p>`, + ], + }); + + addPromiseTest({ + description: `Inserting "XY" after making a link ${kLinkDesc}(following Selection.collapseToEnd)`, + innerHTML: `<p>${kParentTag[0]}[abc]${kParentTag[1]}</p>`, + run: async (utils) => { + utils.document.execCommand("createLink", false, "about:blank"); + utils.selection.collapseToEnd(); + await utils.sendKey("X", utils.kShiftKey); + await utils.sendKey("Y", utils.kShiftKey); + }, + expectedResult: [ + `<p>${kParentTag[0]}<a href="about:blank">abc</a>XY${kParentTag[1]}</p>`, + `<p>${kParentTag[0]}<a href="about:blank">abc</a>XY${kParentTag[1]}<br></p>`, + ], + }); + + addPromiseTest({ + description: `Inserting "XY" after making a link ${kLinkDesc}(following ArrowRight key press)`, + innerHTML: `<p>${kParentTag[0]}[abc]${kParentTag[1]}</p>`, + run: async (utils) => { + utils.document.execCommand("createLink", false, "about:blank"); + await utils.sendArrowRightKey(); + await utils.sendKey("X", utils.kShiftKey); + await utils.sendKey("Y", utils.kShiftKey); + }, + expectedResult: [ + `<p>${kParentTag[0]}<a href="about:blank">abc</a>XY${kParentTag[1]}</p>`, + `<p>${kParentTag[0]}<a href="about:blank">abc</a>XY${kParentTag[1]}<br></p>`, + ], + }); + + addPromiseTest({ + description: `Inserting "XY" after making a link ${kLinkDesc}(following End key press)`, + innerHTML: `<p>${kParentTag[0]}[abc]${kParentTag[1]}</p>`, + run: async (utils) => { + utils.document.execCommand("createLink", false, "about:blank"); + if (!navigator.platform.includes("Mac")) { + await utils.sendEndKey(); + } else { + await utils.sendArrowRightKey(utils.kMetaKey); + } + await utils.sendKey("X", utils.kShiftKey); + await utils.sendKey("Y", utils.kShiftKey); + }, + expectedResult: [ + `<p>${kParentTag[0]}<a href="about:blank">abc</a>XY${kParentTag[1]}</p>`, + `<p>${kParentTag[0]}<a href="about:blank">abc</a>XY${kParentTag[1]}<br></p>`, + ], + }); + + addPromiseTest({ + description: `Inserting "XY" after making a link ${kLinkDesc}(following Selection.collapseToStart)`, + innerHTML: `<p>${kParentTag[0]}[abc]${kParentTag[1]}</p>`, + run: async (utils) => { + utils.document.execCommand("createLink", false, "about:blank"); + utils.selection.collapseToStart(); + await utils.sendKey("X", utils.kShiftKey); + await utils.sendKey("Y", utils.kShiftKey); + }, + expectedResult: [ + `<p>${kParentTag[0]}XY<a href="about:blank">abc</a>${kParentTag[1]}</p>`, + `<p>${kParentTag[0]}XY<a href="about:blank">abc</a>${kParentTag[1]}<br></p>`, + ], + }); + + addPromiseTest({ + description: `Inserting "XY" after making a link ${kLinkDesc}(following ArrowLeft key press)`, + innerHTML: `<p>${kParentTag[0]}[abc]${kParentTag[1]}</p>`, + run: async (utils) => { + utils.document.execCommand("createLink", false, "about:blank"); + await utils.sendArrowLeftKey(); + await utils.sendKey("X", utils.kShiftKey); + await utils.sendKey("Y", utils.kShiftKey); + }, + expectedResult: [ + `<p>${kParentTag[0]}XY<a href="about:blank">abc</a>${kParentTag[1]}</p>`, + `<p>${kParentTag[0]}XY<a href="about:blank">abc</a>${kParentTag[1]}<br></p>`, + ], + }); + + addPromiseTest({ + description: `Inserting "XY" after making a link ${kLinkDesc}(following Home key press)`, + innerHTML: `<p>${kParentTag[0]}[abc]${kParentTag[1]}</p>`, + run: async (utils) => { + utils.document.execCommand("createLink", false, "about:blank"); + if (!navigator.platform.includes("Mac")) { + await utils.sendHomeKey(); + } else { + await utils.sendArrowLeftKey(utils.kMetaKey); + } + await utils.sendKey("X", utils.kShiftKey); + await utils.sendKey("Y", utils.kShiftKey); + }, + expectedResult: [ + `<p>${kParentTag[0]}XY<a href="about:blank">abc</a>${kParentTag[1]}</p>`, + `<p>${kParentTag[0]}XY<a href="about:blank">abc</a>${kParentTag[1]}<br></p>`, + ], + }); +} + +addPromiseTest({ + description: `Inserting "XY" after setting caret position to middle of a link ${kLinkDesc}(Selection.collapse)`, + innerHTML: `<p>${kParentTag[0]}<a href="about:blank">${kChildTag[0]}[]abc${kChildTag[1]}</a>${kParentTag[1]}</p>`, + run: async (utils) => { + utils.selection.collapse(utils.editingHost.querySelector(kSelectorForTextNodeContainer).firstChild, 2); + await utils.sendKey("X", utils.kShiftKey); + await utils.sendKey("Y", utils.kShiftKey); + }, + expectedResult: [ + `<p>${kParentTag[0]}<a href="about:blank">${kChildTag[0]}abXYc${kChildTag[1]}</a>${kParentTag[1]}</p>`, + `<p>${kParentTag[0]}<a href="about:blank">${kChildTag[0]}abXYc${kChildTag[1]}</a>${kParentTag[1]}<br></p>`, + ], +}); + +addPromiseTest({ + description: `Inserting "XY" after setting caret position to middle of a link ${kLinkDesc}(Selection.addRange)`, + innerHTML: `<p>${kParentTag[0]}<a href="about:blank">${kChildTag[0]}[]abc${kChildTag[1]}</a>${kParentTag[1]}</p>`, + run: async (utils) => { + utils.selection.removeAllRanges(); + let range = utils.document.createRange(); + range.setStart(utils.editingHost.querySelector(kSelectorForTextNodeContainer).firstChild, 2); + utils.selection.addRange(range); + await utils.sendKey("X", utils.kShiftKey); + await utils.sendKey("Y", utils.kShiftKey); + }, + expectedResult: [ + `<p>${kParentTag[0]}<a href="about:blank">${kChildTag[0]}abXYc${kChildTag[1]}</a>${kParentTag[1]}</p>`, + `<p>${kParentTag[0]}<a href="about:blank">${kChildTag[0]}abXYc${kChildTag[1]}</a>${kParentTag[1]}<br></p>`, + ], +}); + +addPromiseTest({ + description: `Inserting "XY" after setting caret position to start of a link ${kLinkDesc}(Selection.collapse)`, + innerHTML: `<p>${kParentTag[0]}<a href="about:blank">${kChildTag[0]}ab[]c${kChildTag[1]}</a>${kParentTag[1]}</p>`, + run: async (utils) => { + utils.selection.collapse(utils.editingHost.querySelector(kSelectorForTextNodeContainer).firstChild, 0); + await utils.sendKey("X", utils.kShiftKey); + await utils.sendKey("Y", utils.kShiftKey); + }, + expectedResult: [ + `<p>${kNewContainerOfLink[0]}XY<a href="about:blank">abc</a>${kNewContainerOfLink[1]}</p>`, + `<p>${kNewContainerOfLink[0]}XY<a href="about:blank">abc</a>${kNewContainerOfLink[2]}<br></p>`, + ], +}); + +addPromiseTest({ + description: `Inserting "XY" after setting caret position to start of a link ${kLinkDesc}(Selection.addRange)`, + innerHTML: `<p>${kParentTag[0]}<a href="about:blank">${kChildTag[0]}ab[]c${kChildTag[1]}</a>${kParentTag[1]}</p>`, + run: async (utils) => { + utils.selection.removeAllRanges(); + let range = utils.document.createRange(); + range.setStart(utils.editingHost.querySelector(kSelectorForTextNodeContainer).firstChild, 0); + utils.selection.addRange(range); + await utils.sendKey("X", utils.kShiftKey); + await utils.sendKey("Y", utils.kShiftKey); + }, + expectedResult: [ + `<p>${kNewContainerOfLink[0]}XY<a href="about:blank">abc</a>${kNewContainerOfLink[1]}</p>`, + `<p>${kNewContainerOfLink[0]}XY<a href="about:blank">abc</a>${kNewContainerOfLink[2]}<br></p>`, + ], +}); + +addPromiseTest({ + description: `Inserting "XY" after setting caret position to end of a link ${kLinkDesc}(Selection.collapse)`, + innerHTML: `<p>${kParentTag[0]}<a href="about:blank">${kChildTag[0]}ab[]c${kChildTag[1]}</a>${kParentTag[1]}</p>`, + run: async (utils) => { + utils.selection.collapse(utils.editingHost.querySelector(kSelectorForTextNodeContainer).firstChild, "abc".length); + await utils.sendKey("X", utils.kShiftKey); + await utils.sendKey("Y", utils.kShiftKey); + }, + expectedResult: [ + `<p>${kNewContainerOfLink[0]}<a href="about:blank">abc</a>XY${kNewContainerOfLink[1]}</p>`, + `<p>${kNewContainerOfLink[0]}<a href="about:blank">abc</a>XY${kNewContainerOfLink[2]}<br></p>`, + ], +}); + +addPromiseTest({ + description: `Inserting "XY" after setting caret position to end of a link ${kLinkDesc}(Selection.addRange)`, + innerHTML: `<p>${kParentTag[0]}<a href="about:blank">${kChildTag[0]}ab[]c${kChildTag[1]}</a>${kParentTag[1]}</p>`, + run: async (utils) => { + utils.selection.collapse(utils.editingHost.querySelector(kSelectorForTextNodeContainer).firstChild, "abc".length); + await utils.sendKey("X", utils.kShiftKey); + await utils.sendKey("Y", utils.kShiftKey); + }, + expectedResult: [ + `<p>${kNewContainerOfLink[0]}<a href="about:blank">abc</a>XY${kNewContainerOfLink[1]}</p>`, + `<p>${kNewContainerOfLink[0]}<a href="about:blank">abc</a>XY${kNewContainerOfLink[2]}<br></p>`, + ], +}); + +// Type text after moving caret with Range API. +addPromiseTest({ + description: `Inserting "XY" after modifying caret position to middle of a link ${kLinkDesc}`, + innerHTML: `<p>${kParentTag[0]}<a href="about:blank">${kChildTag[0]}[]abc${kChildTag[1]}</a>${kParentTag[1]}</p>`, + run: async (utils) => { + let range = utils.selection.getRangeAt(0); + range.setStart(utils.editingHost.querySelector(kSelectorForTextNodeContainer).firstChild, 2); + await utils.sendKey("X", utils.kShiftKey); + await utils.sendKey("Y", utils.kShiftKey); + }, + expectedResult: [ + `<p>${kParentTag[0]}<a href="about:blank">${kChildTag[0]}abXYc${kChildTag[1]}</a>${kParentTag[1]}</p>`, + `<p>${kParentTag[0]}<a href="about:blank">${kChildTag[0]}abXYc${kChildTag[1]}</a>${kParentTag[1]}<br></p>`, + ], +}); + +addPromiseTest({ + description: `Inserting "XY" after modifying caret position to start of a link ${kLinkDesc}`, + innerHTML: `<p>${kParentTag[0]}<a href="about:blank">${kChildTag[0]}ab[]c${kChildTag[1]}</a>${kParentTag[1]}</p>`, + run: async (utils) => { + let range = utils.selection.getRangeAt(0); + range.setStart(utils.editingHost.querySelector(kSelectorForTextNodeContainer).firstChild, 0); + range.setEnd(utils.editingHost.querySelector(kSelectorForTextNodeContainer).firstChild, 0); + await utils.sendKey("X", utils.kShiftKey); + await utils.sendKey("Y", utils.kShiftKey); + }, + expectedResult: [ + `<p>${kNewContainerOfLink[0]}XY<a href="about:blank">abc</a>${kNewContainerOfLink[1]}</p>`, + `<p>${kNewContainerOfLink[0]}XY<a href="about:blank">abc</a>${kNewContainerOfLink[1]}<br></p>`, + ], +}); + +addPromiseTest({ + description: `Inserting "XY" after modifying caret position to end of a link ${kLinkDesc}`, + innerHTML: `<p>${kParentTag[0]}<a href="about:blank">${kChildTag[0]}ab[]c${kChildTag[1]}</a>${kParentTag[1]}</p>`, + run: async (utils) => { + let range = utils.selection.getRangeAt(0); + range.setStart(utils.editingHost.querySelector(kSelectorForTextNodeContainer).firstChild, "abc".length); + await utils.sendKey("X", utils.kShiftKey); + await utils.sendKey("Y", utils.kShiftKey); + }, + expectedResult: [ + `<p>${kNewContainerOfLink[0]}<a href="about:blank">abc</a>XY${kNewContainerOfLink[1]}</p>`, + `<p>${kNewContainerOfLink[0]}<a href="about:blank">abc</a>XY${kNewContainerOfLink[1]}<br></p>`, + ], +}); + +// Type text after deleting character immediately before/after a link. +addPromiseTest({ + description: `Inserting "XY" after deleting following character of a link ${kLinkDesc}(Backspace)`, + innerHTML: `<p>${kParentTag[0]}<a href="about:blank">${kChildTag[0]}abc${kChildTag[1]}</a>d[]${kParentTag[1]}</p>`, + run: async (utils) => { + await utils.sendBackspaceKey(); + await utils.sendKey("X", utils.kShiftKey); + await utils.sendKey("Y", utils.kShiftKey); + }, + expectedResult: [ + `<p>${kNewContainerOfLink[0]}<a href="about:blank">abc</a>XY${kNewContainerOfLink[1]}</p>`, + `<p>${kNewContainerOfLink[0]}<a href="about:blank">abc</a>XY${kNewContainerOfLink[1]}<br></p>`, + ], +}); + +addPromiseTest({ + description: `Inserting "XY" after deleting following character of a link ${kLinkDesc}(execCommand("delete"))`, + innerHTML: `<p>${kParentTag[0]}<a href="about:blank">${kChildTag[0]}abc${kChildTag[1]}</a>d[]${kParentTag[1]}</p>`, + run: async (utils) => { + await utils.document.execCommand("delete", false); + await utils.sendKey("X", utils.kShiftKey); + await utils.sendKey("Y", utils.kShiftKey); + }, + expectedResult: [ + `<p>${kNewContainerOfLink[0]}<a href="about:blank">abc</a>XY${kNewContainerOfLink[1]}</p>`, + `<p>${kNewContainerOfLink[0]}<a href="about:blank">abc</a>XY${kNewContainerOfLink[1]}<br></p>`, + ], +}); + +addPromiseTest({ + description: `Inserting "XY" after deleting a previous character of a link ${kLinkDesc}(Delete)`, + innerHTML: `<p>${kParentTag[0]}[]z<a href="about:blank">${kChildTag[0]}abc${kChildTag[1]}</a>${kParentTag[1]}</p>`, + run: async (utils) => { + await utils.sendDeleteKey(); + await utils.sendKey("X", utils.kShiftKey); + await utils.sendKey("Y", utils.kShiftKey); + }, + expectedResult: [ + `<p>${kNewContainerOfLink[0]}XY<a href="about:blank">abc</a>${kNewContainerOfLink[1]}</p>`, + `<p>${kNewContainerOfLink[0]}XY<a href="about:blank">abc</a>${kNewContainerOfLink[1]}<br></p>`, + ], +}); + +addPromiseTest({ + description: `Inserting "XY" after deleting a previous character of a link ${kLinkDesc}(execCommand("forwarddelete"))`, + innerHTML: `<p>${kParentTag[0]}[]z<a href="about:blank">${kChildTag[0]}abc${kChildTag[1]}</a>${kParentTag[1]}</p>`, + run: async (utils) => { + await utils.document.execCommand("forwarddelete", false); + await utils.sendKey("X", utils.kShiftKey); + await utils.sendKey("Y", utils.kShiftKey); + }, + expectedResult: [ + `<p>${kNewContainerOfLink[0]}XY<a href="about:blank">abc</a>${kNewContainerOfLink[1]}</p>`, + `<p>${kNewContainerOfLink[0]}XY<a href="about:blank">abc</a>${kNewContainerOfLink[1]}<br></p>`, + ], +}); + +// Type text after deleting the last character in a link. +addPromiseTest({ + description: `Inserting "XY" after deleting last character of a link ${kLinkDesc}(Backspace)`, + innerHTML: `<p>${kParentTag[0]}<a href="about:blank">${kChildTag[0]}abcd[]${kChildTag[1]}</a>${kParentTag[1]}</p>`, + run: async (utils) => { + await utils.sendBackspaceKey(); + await utils.sendKey("X", utils.kShiftKey); + await utils.sendKey("Y", utils.kShiftKey); + }, + expectedResult: [ + `<p>${kNewContainerOfLink[0]}<a href="about:blank">abc</a>XY${kNewContainerOfLink[1]}</p>`, + `<p>${kNewContainerOfLink[1]}<a href="about:blank">abc</a>XY${kNewContainerOfLink[1]}<br></p>`, + ], +}); + +addPromiseTest({ + description: `Inserting "XY" after deleting last character of a link ${kLinkDesc}(execCommand("delete"))`, + innerHTML: `<p>${kParentTag[0]}<a href="about:blank">${kChildTag[0]}abcd[]${kChildTag[1]}</a>${kParentTag[1]}</p>`, + run: async (utils) => { + await utils.document.execCommand("delete", false); + await utils.sendKey("X", utils.kShiftKey); + await utils.sendKey("Y", utils.kShiftKey); + }, + expectedResult: [ + `<p>${kNewContainerOfLink[0]}<a href="about:blank">abc</a>XY${kNewContainerOfLink[1]}</p>`, + `<p>${kNewContainerOfLink[1]}<a href="about:blank">abc</a>XY${kNewContainerOfLink[1]}<br></p>`, + ], +}); + +addPromiseTest({ + description: `Inserting "XY" after deleting last character of a link ${kLinkDesc}(Delete)`, + innerHTML: `<p>${kParentTag[0]}<a href="about:blank">${kChildTag[0]}abc[]d${kChildTag[1]}</a>${kParentTag[1]}</p>`, + run: async (utils) => { + await utils.sendDeleteKey(); + await utils.sendKey("X", utils.kShiftKey); + await utils.sendKey("Y", utils.kShiftKey); + }, + expectedResult: [ + `<p>${kNewContainerOfLink[0]}<a href="about:blank">abc</a>XY${kNewContainerOfLink[1]}</p>`, + `<p>${kNewContainerOfLink[0]}<a href="about:blank">abc</a>XY${kNewContainerOfLink[1]}<br></p>`, + ], +}); + +addPromiseTest({ + description: `Inserting "XY" after deleting last character of a link ${kLinkDesc}(execCommand("forwarddelete"))`, + innerHTML: `<p>${kParentTag[0]}<a href="about:blank">${kChildTag[0]}abc[]d${kChildTag[1]}</a>${kParentTag[1]}</p>`, + run: async (utils) => { + await utils.document.execCommand("forwarddelete", false); + await utils.sendKey("X", utils.kShiftKey); + await utils.sendKey("Y", utils.kShiftKey); + }, + expectedResult: [ + `<p>${kNewContainerOfLink[0]}<a href="about:blank">abc</a>XY${kNewContainerOfLink[1]}</p>`, + `<p>${kNewContainerOfLink[0]}<a href="about:blank">abc</a>XY${kNewContainerOfLink[1]}<br></p>`, + ], +}); + +// Type text after deleting the first character in a link. +addPromiseTest({ + description: `Inserting "XY" after deleting first character of a link ${kLinkDesc}(Backspace)`, + innerHTML: `<p>${kParentTag[0]}<a href="about:blank">${kChildTag[0]}z[]abc${kChildTag[1]}</a>${kParentTag[1]}</p>`, + run: async (utils) => { + await utils.sendBackspaceKey(); + await utils.sendKey("X", utils.kShiftKey); + await utils.sendKey("Y", utils.kShiftKey); + }, + expectedResult: [ + `<p>${kNewContainerOfLink[0]}XY<a href="about:blank">abc</a>${kNewContainerOfLink[1]}</p>`, + `<p>${kNewContainerOfLink[0]}XY<a href="about:blank">abc</a>${kNewContainerOfLink[1]}<br></p>`, + ], +}); + +addPromiseTest({ + description: `Inserting "XY" after deleting first character of a link ${kLinkDesc}(execCommand("delete"))`, + innerHTML: `<p>${kParentTag[0]}<a href="about:blank">${kChildTag[0]}z[]abc${kChildTag[1]}</a>${kParentTag[1]}</p>`, + run: async (utils) => { + await utils.document.execCommand("delete", false); + await utils.sendKey("X", utils.kShiftKey); + await utils.sendKey("Y", utils.kShiftKey); + }, + expectedResult: [ + `<p>${kNewContainerOfLink[0]}XY<a href="about:blank">abc</a>${kNewContainerOfLink[1]}</p>`, + `<p>${kNewContainerOfLink[0]}XY<a href="about:blank">abc</a>${kNewContainerOfLink[1]}<br></p>`, + ], +}); + +addPromiseTest({ + description: `Inserting "XY" after deleting first character of a link ${kLinkDesc}(Delete)`, + innerHTML: `<p>${kParentTag[0]}<a href="about:blank">${kChildTag[0]}[]zabc${kChildTag[1]}</a>${kParentTag[1]}</p>`, + run: async (utils) => { + await utils.sendDeleteKey(); + await utils.sendKey("X", utils.kShiftKey); + await utils.sendKey("Y", utils.kShiftKey); + }, + expectedResult: [ + `<p>${kNewContainerOfLink[0]}XY<a href="about:blank">abc</a>${kNewContainerOfLink[1]}</p>`, + `<p>${kNewContainerOfLink[0]}XY<a href="about:blank">abc</a>${kNewContainerOfLink[1]}<br></p>`, + ], +}); + +addPromiseTest({ + description: `Inserting "XY" after deleting first character of a link ${kLinkDesc}(execCommand("forwarddelete"))`, + innerHTML: `<p>${kParentTag[0]}<a href="about:blank">${kChildTag[0]}[]zabc${kChildTag[1]}</a>${kParentTag[1]}</p>`, + run: async (utils) => { + await utils.document.execCommand("forwarddelete", false); + await utils.sendKey("X", utils.kShiftKey); + await utils.sendKey("Y", utils.kShiftKey); + }, + expectedResult: [ + `<p>${kNewContainerOfLink[0]}XY<a href="about:blank">abc</a>${kNewContainerOfLink[1]}</p>`, + `<p>${kNewContainerOfLink[0]}XY<a href="about:blank">abc</a>${kNewContainerOfLink[1]}<br></p>`, + ], +}); + +// Don't create `<span>` element for preserving specified style of the link and +// don't clone `class` nor `style` attribute of the link. +addPromiseTest({ + description: `Inserting "XY" at start of a link which has a class for bold text`, + innerHTML: `<p>${kParentTag[0]}<a href="about:blank" class="bold">${kChildTag[0]}[]abc${kChildTag[1]}</a>${kParentTag[1]}</p>`, + run: async (utils) => { + await utils.sendKey("X", utils.kShiftKey); + await utils.sendKey("Y", utils.kShiftKey); + }, + expectedResult: [ + `<p>${kNewContainerOfLink[0]}XY<a href="about:blank" class="bold">abc</a>${kNewContainerOfLink[1]}</p>`, + `<p>${kNewContainerOfLink[0]}XY<a href="about:blank" class="bold">abc</a>${kNewContainerOfLink[1]}<br></p>`, + ], +}); +addPromiseTest({ + description: `Inserting "XY" at end of a link which has a class for bold text`, + innerHTML: `<p>${kParentTag[0]}<a href="about:blank" class="bold">${kChildTag[0]}abc[]${kChildTag[1]}</a>${kParentTag[1]}</p>`, + run: async (utils) => { + await utils.sendKey("X", utils.kShiftKey); + await utils.sendKey("Y", utils.kShiftKey); + }, + expectedResult: [ + `<p>${kNewContainerOfLink[0]}<a href="about:blank" class="bold">abc</a>XY${kNewContainerOfLink[1]}</p>`, + `<p>${kNewContainerOfLink[0]}<a href="about:blank" class="bold">abc</a>XY${kNewContainerOfLink[1]}<br></p>`, + ], +}); +addPromiseTest({ + description: `Inserting "XY" at start of a link which has inline style for bold text`, + innerHTML: `<p>${kParentTag[0]}<a href="about:blank" style="font-weight: bold">${kChildTag[0]}[]abc${kChildTag[1]}</a>${kParentTag[1]}</p>`, + run: async (utils) => { + await utils.sendKey("X", utils.kShiftKey); + await utils.sendKey("Y", utils.kShiftKey); + }, + expectedResult: [ + `<p>${kNewContainerOfLink[0]}XY<a href="about:blank" style="font-weight: bold">abc</a>${kNewContainerOfLink[1]}</p>`, + `<p>${kNewContainerOfLink[0]}XY<a href="about:blank" style="font-weight: bold">abc</a>${kNewContainerOfLink[1]}<br></p>`, + ], +}); +addPromiseTest({ + description: `Inserting "XY" at end of a link which has inline style for bold text`, + innerHTML: `<p>${kParentTag[0]}<a href="about:blank" style="font-weight: bold">${kChildTag[0]}abc[]${kChildTag[1]}</a>${kParentTag[1]}</p>`, + run: async (utils) => { + await utils.sendKey("X", utils.kShiftKey); + await utils.sendKey("Y", utils.kShiftKey); + }, + expectedResult: [ + `<p>${kNewContainerOfLink[0]}<a href="about:blank" style="font-weight: bold">abc</a>XY${kNewContainerOfLink[1]}</p>`, + `<p>${kNewContainerOfLink[0]}<a href="about:blank" style="font-weight: bold">abc</a>XY${kNewContainerOfLink[1]}<br></p>`, + ], +}); +document.execCommand("styleWithCSS", false, "true"); +addPromiseTest({ + description: `Inserting "XY" at start of a link which has a class for bold text (in CSS mode)`, + innerHTML: `<p>${kParentTag[0]}<a href="about:blank" class="bold">${kChildTag[0]}[]abc${kChildTag[1]}</a>${kParentTag[1]}</p>`, + run: async (utils) => { + await utils.sendKey("X", utils.kShiftKey); + await utils.sendKey("Y", utils.kShiftKey); + }, + expectedResult: [ + `<p>${kNewContainerOfLink[0]}XY<a href="about:blank" class="bold">abc</a>${kNewContainerOfLink[1]}</p>`, + `<p>${kNewContainerOfLink[0]}XY<a href="about:blank" class="bold">abc</a>${kNewContainerOfLink[1]}<br></p>`, + ], +}); +addPromiseTest({ + description: `Inserting "XY" at end of a link which has a class for bold text (in CSS mode)`, + innerHTML: `<p>${kParentTag[0]}<a href="about:blank" class="bold">${kChildTag[0]}abc[]${kChildTag[1]}</a>${kParentTag[1]}</p>`, + run: async (utils) => { + await utils.sendKey("X", utils.kShiftKey); + await utils.sendKey("Y", utils.kShiftKey); + }, + expectedResult: [ + `<p>${kNewContainerOfLink[0]}<a href="about:blank" class="bold">abc</a>XY${kNewContainerOfLink[1]}</p>`, + `<p>${kNewContainerOfLink[0]}<a href="about:blank" class="bold">abc</a>XY${kNewContainerOfLink[1]}<br></p>`, + ], +}); +addPromiseTest({ + description: `Inserting "XY" at start of a link which has inline style for bold text (in CSS mode)`, + innerHTML: `<p>${kParentTag[0]}<a href="about:blank" style="font-weight: bold">${kChildTag[0]}[]abc${kChildTag[1]}</a>${kParentTag[1]}</p>`, + run: async (utils) => { + await utils.sendKey("X", utils.kShiftKey); + await utils.sendKey("Y", utils.kShiftKey); + }, + expectedResult: [ + `<p>${kNewContainerOfLink[0]}XY<a href="about:blank" style="font-weight: bold">abc</a>${kNewContainerOfLink[1]}</p>`, + `<p>${kNewContainerOfLink[0]}XY<a href="about:blank" style="font-weight: bold">abc</a>${kNewContainerOfLink[1]}<br></p>`, + ], +}); +document.execCommand("styleWithCSS", false, "false"); +addPromiseTest({ + description: `Inserting "XY" at end of a link which has inline style for bold text (in CSS mode)`, + innerHTML: `<p>${kParentTag[0]}<a href="about:blank" style="font-weight: bold">${kChildTag[0]}abc[]${kChildTag[1]}</a>${kParentTag[1]}</p>`, + run: async (utils) => { + await utils.sendKey("X", utils.kShiftKey); + await utils.sendKey("Y", utils.kShiftKey); + }, + expectedResult: [ + `<p>${kNewContainerOfLink[0]}<a href="about:blank" style="font-weight: bold">abc</a>XY${kNewContainerOfLink[1]}</p>`, + `<p>${kNewContainerOfLink[0]}<a href="about:blank" style="font-weight: bold">abc</a>XY${kNewContainerOfLink[1]}<br></p>`, + ], +}); +document.execCommand("styleWithCSS", false, "false"); + +</script> +</body> +</html> diff --git a/testing/web-platform/tests/editing/other/typing-around-link-element-at-non-collapsed-selection.tentative.html b/testing/web-platform/tests/editing/other/typing-around-link-element-at-non-collapsed-selection.tentative.html new file mode 100644 index 0000000000..a9e5790c35 --- /dev/null +++ b/testing/web-platform/tests/editing/other/typing-around-link-element-at-non-collapsed-selection.tentative.html @@ -0,0 +1,214 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<meta name="timeout" content="long"> +<meta name="variant" content="?target=ContentEditable"> +<meta name="variant" content="?target=ContentEditable&parent=b"> +<meta name="variant" content="?target=ContentEditable&child=b"> +<meta name="variant" content="?target=ContentEditable&parent=b&child=i"> +<meta name="variant" content="?target=DesignMode"> +<meta name="variant" content="?target=DesignMode&parent=b"> +<meta name="variant" content="?target=DesignMode&child=b"> +<meta name="variant" content="?target=DesignMode&parent=b&child=i"> +<title>Testing inserting content at non-collapsed selection around link element</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script src="../include/editor-test-utils.js"></script> +</head> +<body> +<div contenteditable></div> +<iframe srcdoc=" + <!doctype html> + <html> + <script>document.designMode='on';</script> + <script src='/resources/testdriver.js'></script> + <script src='/resources/testdriver-vendor.js'></script> + <script src='/resources/testdriver-actions.js'></script> + <body></body> + </html>"></iframe> +<script> +"use strict"; + +const params = new URLSearchParams(location.search.substring(1)); +const kTarget = params.get("target"); +const kParentTag = params.get("parent") === null + ? ["", ""] + : [`<${params.get("parent")}>`, `</${params.get("parent")}>`]; +const kChildTag = params.get("child") === null + ? ["", ""] + : [`<${params.get("child")}>`, `</${params.get("child")}>`]; +const kLinkDesc = (() => { + let result = "" + if (kParentTag[0] !== "") { + result += `in ${kParentTag[0]} `; + if (kChildTag[0] !== "") { + result += "and "; + } + } + if (kChildTag[0] !== "") { + result += `containing ${kChildTag[0]} `; + } + return result; +})(); +const kNewContainerOfLink = (() => { + if (kParentTag !== "" && kChildTag !== "") { + return [`${kParentTag[0]}${kChildTag[0]}`, `${kChildTag[1]}${kParentTag[1]}`]; + } + if (kParentTag !== "") { + return kParentTag; + } + if (kChildTag !== "") { + return kChildTag; + } + return ["", ""]; +})(); + +function getEditingHost() { + return kTarget === "ContentEditable" + ? document.querySelector("div[contenteditable]") + : document.querySelector("iframe").contentDocument.body; +} + +function addPromiseTest(test) { + promise_test(async () => { + let editingHost = getEditingHost(); + let utils = new EditorTestUtils(editingHost); + utils.setupEditingHost(test.innerHTML); + utils.window.focus(); + utils.document.body.focus(); + editingHost.focus(); + await test.run(utils); + if (Array.isArray(test.expectedResult)) { + assert_in_array(editingHost.innerHTML, test.expectedResult); + } else { + assert_equals(editingHost.innerHTML, test.expectedResult); + } + }, `${test.description} in ${test.innerHTML}`); +} + +promise_test(async () => { + await new Promise(resolve => { + addEventListener("load", resolve, { once: true }); + }); +}, ""); + +for (const test of [ + ["Direct typing", utils => {}], + ["Backspace", utils => { return utils.sendBackspaceKey(); }], + ["Delete", utils => { return utils.sendDeleteKey(); }], + ["execCommand(\"delete\")", utils => { utils.document.execCommand("delete", false); }], + ["execCommand(\"forwarddelete\")", utils => { utils.document.execCommand("forwarddelete", false); }], + ]) { + + addPromiseTest({ + description: `Inserting "XY" after deleting first character of a link ${kLinkDesc}(${test[0]})`, + innerHTML: `<p>${kParentTag[0]}<a href="about:blank">${kChildTag[0]}[z]abc${kChildTag[1]}</a>${kParentTag[1]}</p>`, + run: async (utils) => { + await test[1](utils); + await utils.sendKey("X", utils.kShiftKey); + await utils.sendKey("Y", utils.kShiftKey); + }, + expectedResult: (() => { + if (test[0] === "Direct typing") { + return [ + `<p>${kParentTag[0]}<a href="about:blank">${kChildTag[0]}XYabc${kChildTag[1]}</a>${kParentTag[1]}</p>`, + `<p>${kParentTag[0]}<a href="about:blank">${kChildTag[0]}XYabc${kChildTag[1]}</a>${kParentTag[1]}<br></p>`, + ]; + } + return [ + `<p>${kNewContainerOfLink[0]}XY<a href="about:blank">abc</a>${kNewContainerOfLink[1]}</p>`, + `<p>${kNewContainerOfLink[0]}XY<a href="about:blank">abc</a>${kNewContainerOfLink[1]}<br></p>`, + ]; + })(), + }); + + addPromiseTest({ + description: `Inserting "XY" after deleting last character in a non-collapsed range of a link ${kLinkDesc}(${test[0]})`, + innerHTML: `<p>${kParentTag[0]}<a href="about:blank">${kChildTag[0]}abc[d]${kChildTag[1]}</a>${kParentTag[1]}</p>`, + run: async (utils) => { + await test[1](utils); + await utils.sendKey("X", utils.kShiftKey); + await utils.sendKey("Y", utils.kShiftKey); + }, + expectedResult: (() => { + if (test[0] === "Direct typing") { + return [ + `<p>${kParentTag[0]}<a href="about:blank">${kChildTag[0]}abcXY${kChildTag[1]}</a>${kParentTag[1]}</p>`, + `<p>${kParentTag[0]}<a href="about:blank">${kChildTag[0]}abcXY${kChildTag[1]}</a>${kParentTag[1]}<br></p>`, + ]; + } + return [ + `<p>${kNewContainerOfLink[0]}<a href="about:blank">abc</a>XY${kNewContainerOfLink[1]}</p>`, + `<p>${kNewContainerOfLink[0]}<a href="about:blank">abc</a>XY${kNewContainerOfLink[1]}<br></p>`, + ]; + })(), + }); + + addPromiseTest({ + description: `Inserting "XY" after deleting text after middle of a link ${kLinkDesc}(${test[0]})`, + innerHTML: `<p>${kParentTag[0]}<a href="about:blank">${kChildTag[0]}ab[cd${kChildTag[1]}</a>de]f${kParentTag[1]}</p>`, + run: async (utils) => { + await test[1](utils); + await utils.sendKey("X", utils.kShiftKey); + await utils.sendKey("Y", utils.kShiftKey); + }, + expectedResult: [ + `<p>${kNewContainerOfLink[0]}<a href="about:blank">ab</a>XY${kChildTag[1]}f${kParentTag[1]}</p>`, + `<p>${kNewContainerOfLink[0]}<a href="about:blank">ab</a>XY${kChildTag[1]}f${kParentTag[1]}<br></p>`, + ], + }); + + addPromiseTest({ + description: `Inserting "XY" after deleting text before middle of a link ${kLinkDesc}(${test[0]})`, + innerHTML: `<p>${kParentTag[0]}a[bc<a href="about:blank">${kChildTag[0]}de]f${kChildTag[1]}</a>${kParentTag[1]}</p>`, + run: async (utils) => { + await test[1](utils); + await utils.sendKey("X", utils.kShiftKey); + await utils.sendKey("Y", utils.kShiftKey); + }, + expectedResult: [ + `<p>${kParentTag[0]}aXY<a href="about:blank">${kChildTag[0]}f${kChildTag[1]}</a>${kParentTag[1]}</p>`, + `<p>${kParentTag[0]}aXY<a href="about:blank">${kChildTag[0]}f${kChildTag[1]}</a>${kParentTag[1]}<br></p>`, + ], + }); + + if (kParentTag[0] !== "" || kChildTag[0] !== "") { + continue; + } + + addPromiseTest({ + description: `Inserting "XY" after deleting text between 2 same links (${test[0]})`, + innerHTML: '<p><a href="about:blank">a[bc</a><a href="about:blank">de]f</a></p>', + run: async (utils) => { + await test[1](utils); + await utils.sendKey("X", utils.kShiftKey); + await utils.sendKey("Y", utils.kShiftKey); + }, + expectedResult: [ + '<p><a href="about:blank">a</a>XY<a href="about:blank">f</a></p>', + '<p><a href="about:blank">a</a>XY<a href="about:blank">f</a><br></p>', + ], + }); + + addPromiseTest({ + description: `Inserting "XY" after deleting text between 2 different links (${test[0]})`, + innerHTML: '<p><a href="about:blank">a[bc</a><a href="http://example.com/">de]f</a></p>', + run: async (utils) => { + await test[1](utils); + await utils.sendKey("X", utils.kShiftKey); + await utils.sendKey("Y", utils.kShiftKey); + }, + expectedResult: [ + '<p><a href="about:blank">a</a>XY<a href="http://example.com/">f</a></p>', + '<p><a href="about:blank">a</a>XY<a href="http://example.com/">f</a><br></p>', + ], + }); +} + +</script> +</body> +</html> diff --git a/testing/web-platform/tests/editing/other/typing-space-in-editable-button.tentative.html b/testing/web-platform/tests/editing/other/typing-space-in-editable-button.tentative.html new file mode 100644 index 0000000000..0f399378ab --- /dev/null +++ b/testing/web-platform/tests/editing/other/typing-space-in-editable-button.tentative.html @@ -0,0 +1,77 @@ +<!doctype html> +<head> +<meta charset="utf-8"> +<title>Tests for pressing space in editable button element</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/resources/testdriver-actions.js"></script> +</head> +<body> +<button contenteditable>HelloWorld</button> +<div contenteditable><button>HelloWorld</button></div> +<button><div contenteditable>HelloWorld</div></button> +<script> +"use strict"; + +promise_test(async () => { + await new Promise(resolve => { + addEventListener("load", resolve, {once: true}); + }); + const button = document.querySelector("button[contenteditable]"); + getSelection().collapse(button.firstChild, "Hello".length); + let clickEvent = null; + button.addEventListener("click", event => clickEvent = event, {once: true}); + await new this.window.test_driver.Actions() + .keyDown("\uE00D") + .keyUp("\uE00D") + .send(); + assert_equals(button.textContent, "HelloWorld", "The button label shouldn't be changed"); + assert_not_equals(clickEvent, null, "Click event should be fired on the <button>"); +}, "Type space key in <button contenteditable> should be handled by the <button>"); + +promise_test(async () => { + document.querySelector("div[contenteditable]").focus(); + const button = document.querySelector("div[contenteditable] > button"); + getSelection().collapse(button.firstChild, "Hello".length); + let clickEvent = null; + button.addEventListener("click", event => clickEvent = event, {once: true}); + await new this.window.test_driver.Actions() + .keyDown("\uE00D") + .keyUp("\uE00D") + .send(); + assert_equals(button.textContent, "Hello World", "A space should be inserted into the button label"); + assert_equals(clickEvent, null, "Click event should not be fired on the <button>"); +}, "Type space key in editable <button> shouldn't be handled by the <button> when it's not focused"); + +promise_test(async () => { + const button = document.querySelector("div[contenteditable] > button"); + button.textContent = "HelloWorld"; + button.focus(); + let clickEvent = null; + button.addEventListener("click", event => clickEvent = event, {once: true}); + await new this.window.test_driver.Actions() + .keyDown("\uE00D") + .keyUp("\uE00D") + .send(); + assert_equals(button.textContent, "HelloWorld", "The button label shouldn't be changed"); + assert_not_equals(clickEvent, null, "Click event should be fired on the <button>"); +}, "Type space key in editable <button> should be handled by the <button> when it's focused"); + +promise_test(async () => { + const div = document.querySelector("button > div[contenteditable]"); + div.focus(); + getSelection().collapse(div.firstChild, "Hello".length); + let clickEvent = null; + div.parentElement.addEventListener("click", event => clickEvent = event, {once: true}); + await new this.window.test_driver.Actions() + .keyDown("\uE00D") + .keyUp("\uE00D") + .send(); + assert_equals(div.textContent, "Hello World", "A space should be inserted into the button label"); + assert_equals(clickEvent, null, "Click event should not be fired on the <button>"); +}, "Type space key in editable element in <button> shouldn't be handled by the <button>"); +</script> +</body> +</html> diff --git a/testing/web-platform/tests/editing/other/typing-space-in-editable-summary.tentative.html b/testing/web-platform/tests/editing/other/typing-space-in-editable-summary.tentative.html new file mode 100644 index 0000000000..30a751d523 --- /dev/null +++ b/testing/web-platform/tests/editing/other/typing-space-in-editable-summary.tentative.html @@ -0,0 +1,90 @@ +<!doctype html> +<head> +<meta charset="utf-8"> +<title>Tests for pressing space in editable summary element</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/resources/testdriver-actions.js"></script> +</head> +<body> +<details contenteditable><summary>HelloWorld</summary>Details</details> +<details><summary contenteditable>HelloWorld</summary>Details</details> +<details><summary><div contenteditable>HelloWorld</div></summary>Details</details> +<script> +"use strict"; + +promise_test(async () => { + const details = document.querySelector("details[contenteditable]"); + const summary = details.querySelector("summary"); + getSelection().collapse(summary.firstChild, "Hello".length); + summary.focus(); + await new this.window.test_driver.Actions() + .keyDown("\uE00D") + .keyUp("\uE00D") + .send(); + assert_equals( + details.innerHTML, + "<summary>HelloWorld</summary>Details", + "A space shouldn't be inserted into the focused <summary>" + ); + assert_true(details.open, "<details> shouldn't keep collapsed"); +}, "Type space key in editable <summary> should be handled by the <summary> when it's focused"); + +promise_test(async () => { + const details = document.querySelector("details[contenteditable]"); + details.innerHTML = "<summary>HelloWorld</summary>Details"; + details.open = false; + const summary = details.querySelector("summary"); + getSelection().collapse(summary.firstChild, "Hello".length); + details.focus(); + await new this.window.test_driver.Actions() + .keyDown("\uE00D") + .keyUp("\uE00D") + .send(); + assert_equals( + details.innerHTML, + "<summary>Hello World</summary>Details", + "A space should be inserted into the <summary>" + ); + assert_false(details.open, "<details> should keep collapsed"); +}, "Type space key in editable <summary> shouldn't be handled by the <summary> when it's not focused"); + +promise_test(async () => { + const details = document.querySelector("details > summary[contenteditable]").parentNode; + const summary = details.querySelector("summary"); + getSelection().collapse(summary.firstChild, "Hello".length); + summary.focus(); + await new this.window.test_driver.Actions() + .keyDown("\uE00D") + .keyUp("\uE00D") + .send(); + assert_equals( + details.innerHTML, + '<summary contenteditable="">HelloWorld</summary>Details', + "The content of <details> shouldn't be changed" + ); + assert_true(details.open, "<details> shouldn't keep collapsed"); +}, "Type space key in <summary contenteditable> should be handled by the <summary>"); + +promise_test(async () => { + const details = document.querySelector("summary > div[contenteditable]").parentNode.parentNode; + const summary = details.querySelector("summary"); + const editable = summary.querySelector("div[contenteditable]"); + editable.focus(); + getSelection().collapse(editable.firstChild, "Hello".length); + await new this.window.test_driver.Actions() + .keyDown("\uE00D") + .keyUp("\uE00D") + .send(); + assert_equals( + details.innerHTML, + '<summary><div contenteditable="">Hello World</div></summary>Details', + "A space should be inserted" + ); + assert_false(details.open, "<details> should keep collapsed"); +}, "Type space key in editable element in <summary> shouldn't be handled by the <summary>"); +</script> +</body> +</html> diff --git a/testing/web-platform/tests/editing/other/undo-insertparagraph-after-moving-split-nodes.html b/testing/web-platform/tests/editing/other/undo-insertparagraph-after-moving-split-nodes.html new file mode 100644 index 0000000000..c61bcff9e9 --- /dev/null +++ b/testing/web-platform/tests/editing/other/undo-insertparagraph-after-moving-split-nodes.html @@ -0,0 +1,109 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<meta name="timeout" content="long"> +<title>Undo after splitting nodes are moved</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script src="../include/editor-test-utils.js"></script> +</head> +<body> +<div contenteditable></div> +<script> +"use strict"; + +document.execCommand("defaultParagraphSeparator", false, "div"); +const utils = + new EditorTestUtils(document.querySelector("div[contenteditable]")); + +promise_test(async t => { + utils.setupEditingHost( + `<div>abc[]def</div><p>ghi</p>` + ); + await utils.sendEnterKey(); + const right = utils.editingHost.querySelector("div + div"); + utils.editingHost.appendChild(right); + // Now, the right <div> is after the <p>, it should be merged into the left + // <div> before the <p>. + document.execCommand("undo"); + assert_in_array( + utils.editingHost.innerHTML, + [ + "<div>abcdef</div><p>ghi</p>", + "<div>abcdef<br></div><p>ghi</p>", + ] + ); +}, "Undo insertParagraph after moving right node to different paragraph"); + +promise_test(async () => { + utils.setupEditingHost( + `<p>abc</p><div>def[]ghi</div>` + ); + await utils.sendEnterKey(); + const left = utils.editingHost.querySelector("div"); + utils.editingHost.insertBefore(left, document.querySelector("p")); + // Now, the left <div> is before the <p>, the right <div> after the <p> should + // be merged into it. + document.execCommand("undo"); + assert_in_array( + utils.editingHost.innerHTML, + [ + "<div>defghi</div><p>abc</p>", + "<div>defghi<br></div><p>abc</p>", + ] + ); +}, "Undo insertParagraph after moving left node to different paragraph"); + +promise_test(async () => { + utils.setupEditingHost( + `<div>abc[]def</div>` + ); + await utils.sendEnterKey(); + const left = utils.editingHost.querySelector("div"); + const right = utils.editingHost.querySelector("div + div"); + left.insertBefore(right, left.firstChild); + // Now, the right <div> is a child node of the left <div>. Its children + // should be merged to the parent. + document.execCommand("undo"); + assert_in_array( + utils.editingHost.innerHTML, + [ + "<div>abcdef</div>", + "<div>abcdef<br></div>", + ] + ); +}, "Undo insertParagraph after moving right node into the left node"); + +promise_test(async () => { + utils.setupEditingHost( + `<div>abc[]def</div>` + ); + await utils.sendEnterKey(); + const left = utils.editingHost.querySelector("div"); + const right = utils.editingHost.querySelector("div + div"); + right.appendChild(left); + // Now, the right <div> is parent of the left <div>. The children of the + // right <div> should be moved to the child left <div>, but the right <div> + // should be removed. + document.execCommand("undo"); + assert_equals( + utils.editingHost.innerHTML, + "", + "The right <div> containing the left <div> should be removed" + ); + assert_in_array( + left.innerHTML, + [ + "abcdef", + "abcdef<br>", + ], + "The left <div> which was disconnected should have the original content" + ); +}, "Undo insertParagraph after moving left node into the right node"); +</script> +</body> +</html> diff --git a/testing/web-platform/tests/editing/other/white-spaces-after-execCommand-delete.tentative.html b/testing/web-platform/tests/editing/other/white-spaces-after-execCommand-delete.tentative.html new file mode 100644 index 0000000000..1490bf06f5 --- /dev/null +++ b/testing/web-platform/tests/editing/other/white-spaces-after-execCommand-delete.tentative.html @@ -0,0 +1,342 @@ +<!doctype html> +<html> +<head> +<meta charset=utf-8> +<meta name="timeout" content="long"> +<title>Testing normalizing white-space sequence after execCommand("delete", false, "")</title> +<script src=../include/implementation.js></script> +<script>var testsJsLibraryOnly = true</script> +<script src="../include/tests.js"></script> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +</head> +<body> +<script> +"use strict"; + +setup({explicit_done: true}); + +function runTests() { + // README: + // These tests based on the behavior of Chrome 83. This test does NOT define + // nor suggest any standard behavior (actually, some expected results might + // look odd), but this test must help you to understand how other browsers + // use different logic to normalize white-space sequence. + + document.body.innerHTML = "<div contenteditable></div>"; + let editor = document.querySelector("div[contenteditable]"); + editor.focus(); + let selection = document.getSelection(); + + function toPlaintext(str) { + return str.replace(/ /g, "\u00A0"); + } + function escape(str) { + return str.replace(/\u00A0/ig, " "); + } + + // Test simple removing in a text node. + // - initialText: Set to data of text node (only entity is handled) + // - expectedText: Set to data of the text node after `execCommand("delete")` + // - white-spaceRange: Set first item to start offset of white-space sequence, + // set second item to number of white-spaces. + for (const currentTest of [ + { initialText: "a ", expectedText: "a", whiteSpaceRange: [1, 1] }, + { initialText: "a ", expectedText: "a ", whiteSpaceRange: [1, 2] }, + { initialText: "a ", expectedText: "a ", whiteSpaceRange: [1, 2] }, + { initialText: "a ", expectedText: "a ", whiteSpaceRange: [1, 3] }, + { initialText: "a ", expectedText: "a ", whiteSpaceRange: [1, 3] }, + { initialText: "a ", expectedText: "a ", whiteSpaceRange: [1, 3] }, + { initialText: "a ", expectedText: "a ", whiteSpaceRange: [1, 4] }, + { initialText: "a ", expectedText: "a ", whiteSpaceRange: [1, 4] }, + { initialText: "a ", expectedText: "a ", whiteSpaceRange: [1, 4] }, + { initialText: "a ", expectedText: "a ", whiteSpaceRange: [1, 4] }, + { initialText: "a ", expectedText: "a ", whiteSpaceRange: [1, 5] }, + { initialText: "a ", expectedText: "a ", whiteSpaceRange: [1, 5] }, + { initialText: "a ", expectedText: "a ", whiteSpaceRange: [1, 5] }, + { initialText: "a ", expectedText: "a ", whiteSpaceRange: [1, 5] }, + { initialText: "a ", expectedText: "a ", whiteSpaceRange: [1, 5] }, + { initialText: "a ", expectedText: "a ", whiteSpaceRange: [1, 10] }, + { initialText: "a ", expectedText: "a ", whiteSpaceRange: [1, 10] }, + { initialText: "a ", expectedText: "a ", whiteSpaceRange: [1, 10] }, + { initialText: "a ", expectedText: "a ", whiteSpaceRange: [1, 11] }, + { initialText: "a ", expectedText: "a ", whiteSpaceRange: [1, 11] }, + { initialText: "a b", expectedText: "ab", whiteSpaceRange: [1, 1] }, + { initialText: "a b", expectedText: "ab", whiteSpaceRange: [1, 1] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 2] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 2] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 2] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 3] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 3] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 3] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 3] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 4] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 4] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 4] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 4] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 4] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 5] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 5] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 5] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 5] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 5] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 5] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 5] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 5] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 10] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 10] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 10] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 11] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 11] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 11] }, + { initialText: " b", expectedText: "b", whiteSpaceRange: [0, 1] }, + { initialText: " b", expectedText: " b", whiteSpaceRange: [0, 2] }, + { initialText: " b", expectedText: " b", whiteSpaceRange: [0, 2] }, + { initialText: " b", expectedText: " b", whiteSpaceRange: [0, 3] }, + { initialText: " b", expectedText: " b", whiteSpaceRange: [0, 3] }, + { initialText: " b", expectedText: " b", whiteSpaceRange: [0, 3] }, + { initialText: " b", expectedText: " b", whiteSpaceRange: [0, 4] }, + { initialText: " b", expectedText: " b", whiteSpaceRange: [0, 4] }, + { initialText: " b", expectedText: " b", whiteSpaceRange: [0, 4] }, + { initialText: " b", expectedText: " b", whiteSpaceRange: [0, 4] }, + { initialText: " b", expectedText: " b", whiteSpaceRange: [0, 4] }, + { initialText: " b", expectedText: " b", whiteSpaceRange: [0, 5] }, + { initialText: " b", expectedText: " b", whiteSpaceRange: [0, 5] }, + { initialText: " b", expectedText: " b", whiteSpaceRange: [0, 5] }, + { initialText: " b", expectedText: " b", whiteSpaceRange: [0, 5] }, + { initialText: " b", expectedText: " b", whiteSpaceRange: [0, 5] }, + { initialText: " b", expectedText: " b", whiteSpaceRange: [0, 10] }, + { initialText: " b", expectedText: " b", whiteSpaceRange: [0, 10] }, + { initialText: " b", expectedText: " b", whiteSpaceRange: [0, 10] }, + { initialText: " b", expectedText: " b", whiteSpaceRange: [0, 11] }, + { initialText: " b", expectedText: " b", whiteSpaceRange: [0, 11] }, + { initialText: " b", expectedText: " b", whiteSpaceRange: [0, 11] }, + { initialText: " ", expectedText: "", whiteSpaceRange: [0, 1] }, + { initialText: " ", expectedText: " ", whiteSpaceRange: [0, 2] }, + { initialText: " ", expectedText: " ", whiteSpaceRange: [0, 3] }, + { initialText: " ", expectedText: " ", whiteSpaceRange: [0, 3] }, + { initialText: " ", expectedText: " ", whiteSpaceRange: [0, 4] }, + { initialText: " ", expectedText: " ", whiteSpaceRange: [0, 4] }, + { initialText: " ", expectedText: " ", whiteSpaceRange: [0, 4] }, + { initialText: " ", expectedText: " ", whiteSpaceRange: [0, 5] }, + { initialText: " ", expectedText: " ", whiteSpaceRange: [0, 5] }, + { initialText: " ", expectedText: " ", whiteSpaceRange: [0, 5] }, + { initialText: " ", expectedText: " ", whiteSpaceRange: [0, 5] }, + { initialText: " ", expectedText: " ", whiteSpaceRange: [0, 5] }, + { initialText: " ", expectedText: " ", whiteSpaceRange: [0, 10] }, + { initialText: " ", expectedText: " ", whiteSpaceRange: [0, 10] }, + { initialText: " ", expectedText: " ", whiteSpaceRange: [0, 10] }, + { initialText: " ", expectedText: " ", whiteSpaceRange: [0, 11] }, + { initialText: " ", expectedText: " ", whiteSpaceRange: [0, 11] }, + { initialText: " ", expectedText: " ", whiteSpaceRange: [0, 11] }, + ]) { + for (let i = currentTest.whiteSpaceRange[0]; i < currentTest.whiteSpaceRange[0] + currentTest.whiteSpaceRange[1]; i++) { + currentTest.getInitialText = function (aCaretPos) { + return escape(`${toPlaintext(this.initialText).slice(0, aCaretPos)}[]${toPlaintext(this.initialText).slice(aCaretPos)}`); + } + test(function () { + editor.innerHTML = ""; + editor.appendChild(document.createTextNode(toPlaintext(currentTest.initialText))); + selection.collapse(editor.firstChild, i + 1); + document.execCommand("delete", false, ""); + if (currentTest.expectedText.length) { + assert_equals(escape(editor.childNodes.item(0).data), currentTest.expectedText, "Modified text is wrong"); + assert_equals(selection.focusNode, editor.childNodes.item(0), "Selection focus node is wrong"); + assert_equals(selection.focusOffset, i, "Selection focus offset is wrong"); + assert_equals(selection.anchorNode, editor.childNodes.item(0), "Selection anchor node is wrong"); + assert_equals(selection.anchorOffset, i, "Selection anchor offset is wrong"); + } else { + assert_equals(escape(editor.textContent), "", "Modified text is wrong"); + assert_equals(selection.focusNode, editor, "Selection focus node is wrong"); + assert_equals(selection.focusOffset, 0, "Selection focus offset is wrong"); + assert_equals(selection.anchorNode, editor, "Selection anchor node is wrong"); + assert_equals(selection.anchorOffset, 0, "Selection anchor offset is wrong"); + } + }, `execCommand("delete", false, ""): "${currentTest.getInitialText(i + 1)}" (length of whiteSpace sequence: ${currentTest.whiteSpaceRange[1]})`); + } + } + + // Test white space sequence split to multiple text node. + // - initialText: Set to data of text nodes. This must have "|" at least one. + // Then, the text will be split at every "|". + // Same as above test, only is handled at setting. + // "[]" means that caret position. + // - expectedText: Set to data of all text nodes as an array. + // Same as above test, only is handled before comparing. + for (const currentTest of [ + { initialText: "a |[] b", expectedText: ["a []", " b"] }, + { initialText: "a []| b", expectedText: ["a []", " b"] }, + { initialText: "a |[] b", expectedText: ["a []", " b"] }, + { initialText: "a []| b", expectedText: ["a []", " b"] }, + { initialText: "a |[] b", expectedText: ["a []", " b"] }, + { initialText: "a []| b", expectedText: ["a []", " b"] }, + { initialText: "a | [] b", expectedText: ["a []", " b"] }, + { initialText: "a | [] b", expectedText: ["a []", " b"] }, + { initialText: "a | [] b", expectedText: ["a []", " b"] }, + { initialText: "a | [] b", expectedText: ["a []", " b"] }, + + { initialText: "a | [] b", expectedText: ["a ", " [] b"] }, + { initialText: "a | [] b", expectedText: ["a []", " b"] }, + { initialText: "a |[] b", expectedText: ["a []", " b"] }, + { initialText: "a b[] | c", expectedText: ["a [] ", " c"] }, + { initialText: "a b[] | c", expectedText: ["a [] ", " c"] }, + { initialText: "a b[]| c", expectedText: ["a []", " c"] }, + { initialText: "a b|[] c", expectedText: ["a []", " c"] }, + { initialText: "a b[]| c", expectedText: ["a []", " c"] }, + { initialText: "a b|[] c", expectedText: ["a []", " c"] }, + { initialText: "a |b[] c", expectedText: ["a []", " c"] }, + { initialText: "a []|b c", expectedText: ["a []", "b c"] }, + { initialText: "a | b[] c", expectedText: ["a ", " [] c"] }, + + { initialText: "a | |[] c", expectedText: ["a []", " c"] }, + { initialText: "a | |[] c", expectedText: ["a []", " c"] }, + { initialText: "a | []| c", expectedText: ["a []", " c"] }, + { initialText: "a []| | c", expectedText: ["a []", " ", " c"] }, + { initialText: "a [] | | c", expectedText: ["a [] ", " ", " c"] }, + { initialText: "a [] | | c", expectedText: ["a [] ", " ", " c"] }, + { initialText: "a [] | | c", expectedText: ["a [] ", " ", " c"] }, + { initialText: "a || [] c", expectedText: ["a []", " c"] }, + { initialText: "a ||[] c", expectedText: ["a []", " c"] }, + { initialText: "a |[]| c", expectedText: ["a []", " c"] }, + { initialText: "a []|| c", expectedText: ["a []", " c"] }, + { initialText: "a [] || c", expectedText: ["a [] ", "", " c"] }, + ]) { + test(function () { + editor.innerHTML = ""; + let caret = { container: null, offset: -1 }; + for (let text of toPlaintext(currentTest.initialText).split("|")) { + let caretOffset = text.indexOf("[]"); + if (caretOffset >= 0) { + text = text.slice(0, caretOffset) + text.slice(caretOffset + 2); + } + let textNode = document.createTextNode(text); + editor.appendChild(textNode); + if (caretOffset >= 0) { + caret = { container: textNode, offset: caretOffset }; + } + } + selection.collapse(caret.container, caret.offset); + document.execCommand("delete", false, ""); + let child = editor.firstChild; + for (let expectedText of currentTest.expectedText) { + expectedText = toPlaintext(expectedText); + let caretOffset = expectedText.indexOf("[]"); + if (caretOffset >= 0) { + expectedText = expectedText.slice(0, caretOffset) + expectedText.slice(caretOffset + 2); + } + if (!child || child.nodeName !== "#text") { + assert_equals("", escape(expectedText), "Expected text node is not there"); + if (caretOffset >= 0) { + assert_equals(-1, caretOffset, "Selection should be contained in this node"); + } + } else { + assert_equals(escape(child.data), escape(expectedText), "Modified text is wrong"); + if (caretOffset >= 0) { + assert_equals(selection.focusNode, child, "Selection focus node is wrong"); + assert_equals(selection.focusOffset, caretOffset, "Selection focus offset is wrong"); + assert_equals(selection.anchorNode, child, "Selection anchor node is wrong"); + assert_equals(selection.anchorOffset, caretOffset, "Selection anchor offset is wrong"); + } + } + child = child.nextSibling; + } + if (child && child.nodeName === "#text") { + assert_equals(escape(child.data), "", "Unexpected text node is there"); + } + }, `execCommand("delete", false, ""): "${currentTest.initialText}"`); + } + + // Test white spaces around inline element boundary + // - initialHTML: Set to innerHTML of the <div> ("[{" and "]}" set selection to the range) + // - expectedText: Set to innerHTML of the <div> after `execCommand("delete")` + for (const currentTest of [ + { initialHTML: "<span>abc <span> []def</span></span>", expectedHTML: "<span>abc <span>def</span></span>" }, + { initialHTML: "<span>abc <span>[] def</span></span>", expectedHTML: "<span>abc<span> def</span></span>" }, + { initialHTML: "<span>abc []<span> def</span></span>", expectedHTML: "<span>abc<span> def</span></span>" }, + { initialHTML: "<span>abc <span> []def</span></span>", expectedHTML: "<span>abc <span>def</span></span>" }, + { initialHTML: "<span>abc <span>[] def</span></span>", expectedHTML: "<span>abc<span> def</span></span>" }, + { initialHTML: "<span>abc []<span> def</span></span>", expectedHTML: "<span>abc<span> def</span></span>" }, + { initialHTML: "<span>abc <span> []def</span></span>", expectedHTML: "<span>abc <span>def</span></span>" }, + { initialHTML: "<span>abc <span>[] def</span></span>", expectedHTML: "<span>abc <span> def</span></span>" }, + { initialHTML: "<span>abc []<span> def</span></span>", expectedHTML: "<span>abc <span> def</span></span>" }, + { initialHTML: "<span>abc <span> []def</span></span>", expectedHTML: "<span>abc <span>def</span></span>" }, + { initialHTML: "<span>abc <span>[] def</span></span>", expectedHTML: "<span>abc <span> def</span></span>" }, + { initialHTML: "<span>abc []<span> def</span></span>", expectedHTML: "<span>abc <span> def</span></span>" }, + + { initialHTML: "<span>abc </span><span> []def</span>", expectedHTML: "<span>abc </span><span>def</span>" }, + { initialHTML: "<span>abc </span><span>[] def</span>", expectedHTML: "<span>abc</span><span> def</span>" }, + { initialHTML: "<span>abc []</span><span> def</span>", expectedHTML: "<span>abc</span><span> def</span>" }, + { initialHTML: "<span>abc </span><span> []def</span>", expectedHTML: "<span>abc </span><span>def</span>" }, + { initialHTML: "<span>abc </span><span>[] def</span>", expectedHTML: "<span>abc</span><span> def</span>" }, + { initialHTML: "<span>abc []</span><span> def</span>", expectedHTML: "<span>abc</span><span> def</span>" }, + { initialHTML: "<span>abc </span><span> []def</span>", expectedHTML: "<span>abc </span><span>def</span>" }, + { initialHTML: "<span>abc </span><span>[] def</span>", expectedHTML: "<span>abc </span><span> def</span>" }, + { initialHTML: "<span>abc []</span><span> def</span>", expectedHTML: "<span>abc </span><span> def</span>" }, + { initialHTML: "<span>abc </span><span> []def</span>", expectedHTML: "<span>abc </span><span>def</span>" }, + { initialHTML: "<span>abc </span><span>[] def</span>", expectedHTML: "<span>abc </span><span> def</span>" }, + { initialHTML: "<span>abc []</span><span> def</span>", expectedHTML: "<span>abc </span><span> def</span>" }, + { initialHTML: "<span>abc </span><span> []def</span>", expectedHTML: "<span>abc </span><span> def</span>" }, + { initialHTML: "<span>abc </span><span> []def</span>", expectedHTML: "<span>abc </span><span> def</span>" }, + { initialHTML: "<span>abc </span><span> [] def</span>", expectedHTML: "<span>abc </span><span> def</span>" }, + { initialHTML: "<span>abc </span><span> [] def</span>", expectedHTML: "<span>abc </span><span> def</span>" }, + { initialHTML: "<span>abc </span><span> []def</span>", expectedHTML: "<span>abc </span><span> def</span>" }, + { initialHTML: "<span>abc </span><span> [] def</span>", expectedHTML: "<span>abc </span><span> def</span>" }, + { initialHTML: "<span>abc </span><span> [] def</span>", expectedHTML: "<span>abc </span><span> def</span>" }, + { initialHTML: "<span>abc </span><span>[] def</span>", expectedHTML: "<span>abc</span><span> def</span>" }, + { initialHTML: "<span>abc []</span><span> def</span>", expectedHTML: "<span>abc</span><span> def</span>" }, + { initialHTML: "<span>abc []</span><span> def</span>", expectedHTML: "<span>abc </span><span> def</span>" }, + { initialHTML: "<span>abc []</span><span> def</span>", expectedHTML: "<span>abc </span><span> def</span>" }, + { initialHTML: "<span>abc []</span><span> def</span>", expectedHTML: "<span>abc </span><span> def</span>" }, + + { initialHTML: "<span><span>abc </span> []def</span>", expectedHTML: "<span><span>abc </span>def</span>" }, + { initialHTML: "<span><span>abc </span>[] def</span>", expectedHTML: "<span><span>abc</span> def</span>" }, + { initialHTML: "<span><span>abc []</span> def</span>", expectedHTML: "<span><span>abc</span> def</span>" }, + { initialHTML: "<span><span>abc </span> []def</span>", expectedHTML: "<span><span>abc </span>def</span>" }, + { initialHTML: "<span><span>abc </span>[] def</span>", expectedHTML: "<span><span>abc</span> def</span>" }, + { initialHTML: "<span><span>abc []</span> def</span>", expectedHTML: "<span><span>abc</span> def</span>" }, + { initialHTML: "<span><span>abc </span> []def</span>", expectedHTML: "<span><span>abc </span>def</span>" }, + { initialHTML: "<span><span>abc </span>[] def</span>", expectedHTML: "<span><span>abc </span> def</span>" }, + { initialHTML: "<span><span>abc []</span> def</span>", expectedHTML: "<span><span>abc </span> def</span>" }, + { initialHTML: "<span><span>abc </span> []def</span>", expectedHTML: "<span><span>abc </span>def</span>" }, + { initialHTML: "<span><span>abc </span>[] def</span>", expectedHTML: "<span><span>abc </span> def</span>" }, + { initialHTML: "<span><span>abc []</span> def</span>", expectedHTML: "<span><span>abc </span> def</span>" }, + + { initialHTML: "<span><span>abc </span></span><span> []def</span>", expectedHTML: "<span><span>abc </span></span><span>def</span>" }, + { initialHTML: "<span><span>abc </span></span><span>[] def</span>", expectedHTML: "<span><span>abc </span></span><span> def</span>" }, + { initialHTML: "<span><span>abc []</span></span><span> def</span>", expectedHTML: "<span><span>abc </span></span><span> def</span>" }, + + + { initialHTML: "a<span style=white-space:pre;>b[] </span>c", expectedHTML: "a<span style=\"white-space:pre;\"> </span>c" }, + { initialHTML: "a<span style=white-space:pre;>b [] </span>c", expectedHTML: "a<span style=\"white-space:pre;\">b </span>c" }, + { initialHTML: "a<span style=white-space:pre;>b [] </span>c", expectedHTML: "a<span style=\"white-space:pre;\">b </span>c" }, + { initialHTML: "a<span style=white-space:pre;>b []</span>c", expectedHTML: "a<span style=\"white-space:pre;\">b </span>c" }, + { initialHTML: "a<span style=white-space:pre;>b [] </span>", expectedHTML: "a<span style=\"white-space:pre;\">b </span>" }, + { initialHTML: "a<span style=white-space:pre;> </span>[]b", expectedHTML: "ab" }, + { initialHTML: "a <span style=white-space:pre;>[] </span>", expectedHTML: "a <span style=\"white-space:pre;\"> </span>" }, + { initialHTML: "a []<span style=white-space:pre;> </span>", expectedHTML: "a <span style=\"white-space:pre;\"> </span>" }, + { initialHTML: "a [] <span style=white-space:pre;> </span>", expectedHTML: "a <span style=\"white-space:pre;\"> </span>" }, + { initialHTML: "a [] <span style=white-space:pre;>b </span>", expectedHTML: "a <span style=\"white-space:pre;\">b </span>" }, + { initialHTML: "a <span style=white-space:pre;>[] </span>", expectedHTML: "a <span style=\"white-space:pre;\"> </span>" }, + { initialHTML: "a []<span style=white-space:pre;> </span>", expectedHTML: "a <span style=\"white-space:pre;\"> </span>" }, + { initialHTML: "a [] <span style=white-space:pre;> </span>", expectedHTML: "a <span style=\"white-space:pre;\"> </span>" }, + { initialHTML: "a [] <span style=white-space:pre;>b </span>", expectedHTML: "a <span style=\"white-space:pre;\">b </span>" }, + { initialHTML: "<span style=white-space:pre;> [] </span> a", expectedHTML: "<span style=\"white-space:pre;\"> </span> a" }, + { initialHTML: "<span style=white-space:pre;> []</span> a", expectedHTML: "<span style=\"white-space:pre;\"> </span> a" }, + { initialHTML: "<span style=white-space:pre;> </span>[] a", expectedHTML: "<span style=\"white-space:pre;\"> </span> a" }, + { initialHTML: "<span style=white-space:pre;> </span> [] a", expectedHTML: "<span style=\"white-space:pre;\"> </span> a" }, + ]) { + test(function () { + let points = setupDiv(editor, currentTest.initialHTML); + selection.setBaseAndExtent(points[0], points[1], points[2], points[3]); + document.execCommand("delete", false, ""); + assert_equals(editor.innerHTML, currentTest.expectedHTML); + }, `execCommand("delete", false, ""): "${currentTest.initialHTML}"`); + } + + done(); +} + +window.addEventListener("load", runTests, {once: true}); +</script> +</body> +</html> diff --git a/testing/web-platform/tests/editing/other/white-spaces-after-execCommand-forwarddelete.tentative.html b/testing/web-platform/tests/editing/other/white-spaces-after-execCommand-forwarddelete.tentative.html new file mode 100644 index 0000000000..af5c052c56 --- /dev/null +++ b/testing/web-platform/tests/editing/other/white-spaces-after-execCommand-forwarddelete.tentative.html @@ -0,0 +1,357 @@ +<!doctype html> +<html> +<head> +<meta charset=utf-8> +<title>Testing normalizing white space sequence after execCommand("forward", false, "")</title> +<script src=../include/implementation.js></script> +<script>var testsJsLibraryOnly = true</script> +<script src="../include/tests.js"></script> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +</head> +<body> +<script> +"use strict"; + +setup({explicit_done: true}); + +function runTests() { + // README: + // These tests based on the behavior of Chrome 83. This test does NOT define + // nor suggest any standard behavior (actually, some expected results might + // look odd), but this test must help you to understand how other browsers + // use different logic to normalize white-space sequence. + + document.body.innerHTML = "<div contenteditable></div>"; + let editor = document.querySelector("div[contenteditable]"); + editor.focus(); + let selection = document.getSelection(); + + function toPlaintext(str) { + return str.replace(/ /g, "\u00A0"); + } + function escape(str) { + return str.replace(/\u00A0/ig, " "); + } + + // Test simple removing in a text node. + // - initialText: Set to data of text node (only entity is handled) + // - expectedText: Set to data of the text node after `execCommand("forward")` + // - whiteSpaceRange: Set first item to start offset of whitespace sequence, + // set second item to number of white spaces. + for (const currentTest of [ + { initialText: "a ", expectedText: "a", whiteSpaceRange: [1, 1] }, + { initialText: "a ", expectedText: "a ", whiteSpaceRange: [1, 2] }, + { initialText: "a ", expectedText: "a ", whiteSpaceRange: [1, 2] }, + { initialText: "a ", expectedText: "a ", whiteSpaceRange: [1, 3] }, + { initialText: "a ", expectedText: "a ", whiteSpaceRange: [1, 3] }, + { initialText: "a ", expectedText: "a ", whiteSpaceRange: [1, 3] }, + { initialText: "a ", expectedText: "a ", whiteSpaceRange: [1, 4] }, + { initialText: "a ", expectedText: "a ", whiteSpaceRange: [1, 4] }, + { initialText: "a ", expectedText: "a ", whiteSpaceRange: [1, 4] }, + { initialText: "a ", expectedText: "a ", whiteSpaceRange: [1, 4] }, + { initialText: "a ", expectedText: "a ", whiteSpaceRange: [1, 5] }, + { initialText: "a ", expectedText: "a ", whiteSpaceRange: [1, 5] }, + { initialText: "a ", expectedText: "a ", whiteSpaceRange: [1, 5] }, + { initialText: "a ", expectedText: "a ", whiteSpaceRange: [1, 5] }, + { initialText: "a ", expectedText: "a ", whiteSpaceRange: [1, 5] }, + { initialText: "a ", expectedText: "a ", whiteSpaceRange: [1, 10] }, + { initialText: "a ", expectedText: "a ", whiteSpaceRange: [1, 10] }, + { initialText: "a ", expectedText: "a ", whiteSpaceRange: [1, 10] }, + { initialText: "a ", expectedText: "a ", whiteSpaceRange: [1, 11] }, + { initialText: "a ", expectedText: "a ", whiteSpaceRange: [1, 11] }, + { initialText: "a b", expectedText: "ab", whiteSpaceRange: [1, 1] }, + { initialText: "a b", expectedText: "ab", whiteSpaceRange: [1, 1] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 2] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 2] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 2] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 3] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 3] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 3] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 3] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 4] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 4] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 4] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 4] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 4] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 5] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 5] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 5] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 5] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 5] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 5] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 5] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 5] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 10] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 10] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 10] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 11] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 11] }, + { initialText: "a b", expectedText: "a b", whiteSpaceRange: [1, 11] }, + { initialText: " b", expectedText: "b", whiteSpaceRange: [0, 1] }, + { initialText: " b", expectedText: " b", whiteSpaceRange: [0, 2] }, + { initialText: " b", expectedText: " b", whiteSpaceRange: [0, 2] }, + { initialText: " b", expectedText: " b", whiteSpaceRange: [0, 3] }, + { initialText: " b", expectedText: " b", whiteSpaceRange: [0, 3] }, + { initialText: " b", expectedText: " b", whiteSpaceRange: [0, 3] }, + { initialText: " b", expectedText: " b", whiteSpaceRange: [0, 4] }, + { initialText: " b", expectedText: " b", whiteSpaceRange: [0, 4] }, + { initialText: " b", expectedText: " b", whiteSpaceRange: [0, 4] }, + { initialText: " b", expectedText: " b", whiteSpaceRange: [0, 4] }, + { initialText: " b", expectedText: " b", whiteSpaceRange: [0, 4] }, + { initialText: " b", expectedText: " b", whiteSpaceRange: [0, 5] }, + { initialText: " b", expectedText: " b", whiteSpaceRange: [0, 5] }, + { initialText: " b", expectedText: " b", whiteSpaceRange: [0, 5] }, + { initialText: " b", expectedText: " b", whiteSpaceRange: [0, 5] }, + { initialText: " b", expectedText: " b", whiteSpaceRange: [0, 5] }, + { initialText: " b", expectedText: " b", whiteSpaceRange: [0, 10] }, + { initialText: " b", expectedText: " b", whiteSpaceRange: [0, 10] }, + { initialText: " b", expectedText: " b", whiteSpaceRange: [0, 10] }, + { initialText: " b", expectedText: " b", whiteSpaceRange: [0, 11] }, + { initialText: " b", expectedText: " b", whiteSpaceRange: [0, 11] }, + { initialText: " b", expectedText: " b", whiteSpaceRange: [0, 11] }, + { initialText: " ", expectedText: "", whiteSpaceRange: [0, 1] }, + { initialText: " ", expectedText: " ", whiteSpaceRange: [0, 2] }, + { initialText: " ", expectedText: " ", whiteSpaceRange: [0, 3] }, + { initialText: " ", expectedText: " ", whiteSpaceRange: [0, 3] }, + { initialText: " ", expectedText: " ", whiteSpaceRange: [0, 4] }, + { initialText: " ", expectedText: " ", whiteSpaceRange: [0, 4] }, + { initialText: " ", expectedText: " ", whiteSpaceRange: [0, 4] }, + { initialText: " ", expectedText: " ", whiteSpaceRange: [0, 5] }, + { initialText: " ", expectedText: " ", whiteSpaceRange: [0, 5] }, + { initialText: " ", expectedText: " ", whiteSpaceRange: [0, 5] }, + { initialText: " ", expectedText: " ", whiteSpaceRange: [0, 5] }, + { initialText: " ", expectedText: " ", whiteSpaceRange: [0, 5] }, + { initialText: " ", expectedText: " ", whiteSpaceRange: [0, 10] }, + { initialText: " ", expectedText: " ", whiteSpaceRange: [0, 10] }, + { initialText: " ", expectedText: " ", whiteSpaceRange: [0, 10] }, + { initialText: " ", expectedText: " ", whiteSpaceRange: [0, 11] }, + { initialText: " ", expectedText: " ", whiteSpaceRange: [0, 11] }, + { initialText: " ", expectedText: " ", whiteSpaceRange: [0, 11] }, + ]) { + for (let i = currentTest.whiteSpaceRange[0]; i < currentTest.whiteSpaceRange[0] + currentTest.whiteSpaceRange[1]; i++) { + currentTest.getInitialText = function (aCaretPos) { + return escape(`${toPlaintext(this.initialText).slice(0, aCaretPos)}[]${toPlaintext(this.initialText).slice(aCaretPos)}`); + } + test(function () { + editor.innerHTML = ""; + editor.appendChild(document.createTextNode(toPlaintext(currentTest.initialText))); + selection.collapse(editor.firstChild, i); + document.execCommand("forwarddelete", false, ""); + if (currentTest.expectedText.length) { + assert_equals(escape(editor.childNodes.item(0).data), currentTest.expectedText, "Modified text is wrong"); + assert_equals(selection.focusNode, editor.childNodes.item(0), "Selection focus node is wrong"); + assert_equals(selection.focusOffset, i, "Selection focus offset is wrong"); + assert_equals(selection.anchorNode, editor.childNodes.item(0), "Selection anchor node is wrong"); + assert_equals(selection.anchorOffset, i, "Selection anchor offset is wrong"); + } else { + assert_equals(escape(editor.textContent), "", "Modified text is wrong"); + assert_equals(selection.focusNode, editor, "Selection focus node is wrong"); + assert_equals(selection.focusOffset, 0, "Selection focus offset is wrong"); + assert_equals(selection.anchorNode, editor, "Selection anchor node is wrong"); + assert_equals(selection.anchorOffset, 0, "Selection anchor offset is wrong"); + } + }, `execCommand("forwarddelete", false, ""): "${currentTest.getInitialText(i)}" (length of whitespace sequence: ${currentTest.whiteSpaceRange[1]})`); + } + } + + // Test white space sequence split to multiple text node. + // - initialText: Set to data of text nodes. This must have "|" at least one. + // Then, the text will be split at every "|". + // Same as above test, only is handled at setting. + // "[]" means that caret position. + // - expectedText: Set to data of all text nodes as an array. + // Same as above test, only is handled before comparing. + for (const currentTest of [ + { initialText: "a [] | b", expectedText: ["a []", " b"] }, + { initialText: "a [] | b", expectedText: ["a []", " b"] }, + { initialText: "a []| b", expectedText: ["a []", " b"] }, + { initialText: "a []| b", expectedText: ["a []", " b"] }, + { initialText: "a |[] b", expectedText: ["a []", " b"] }, + { initialText: "a |[] b", expectedText: ["a []", " b"] }, + { initialText: "a | [] b", expectedText: ["a ", " [] b"] }, + { initialText: "a |[] b", expectedText: ["a []", " b"] }, + { initialText: "a []| b", expectedText: ["a []", " b"] }, + { initialText: "a [] | b", expectedText: ["a []", " b"] }, + + { initialText: "a [] | b", expectedText: ["a [] ", " b"] }, + { initialText: "a [] | b", expectedText: ["a []", " b"] }, + { initialText: "a []| b", expectedText: ["a []", " b"] }, + { initialText: "a []b | c", expectedText: ["a [] ", " c"] }, + { initialText: "a []b | c", expectedText: ["a [] ", " c"] }, + { initialText: "a []b| c", expectedText: ["a []", " c"] }, + { initialText: "a []|b c", expectedText: ["a []", " c"] }, + { initialText: "a |[]b c", expectedText: ["a []", " c"] }, + { initialText: "a [] |b c", expectedText: ["a []", "b c"] }, + { initialText: "a | []b c", expectedText: ["a ", " [] c"] }, + + { initialText: "a | |[] c", expectedText: ["a ", " []", " c"] }, + { initialText: "a | |[] c", expectedText: ["a ", " []", " c"] }, + { initialText: "a | []| c", expectedText: ["a ", " []", " c"] }, + { initialText: "a |[] | c", expectedText: ["a []", " c"] }, + { initialText: "a []| | c", expectedText: ["a []", " c"] }, + { initialText: "a [] | | c", expectedText: ["a []", " ", " c"] }, + { initialText: "a [] | | c", expectedText: ["a [] ", " ", " c"] }, + { initialText: "a [] | | c", expectedText: ["a [] ", " ", " c"] }, + { initialText: "a || [] c", expectedText: ["a ", "", " [] c"] }, + { initialText: "a ||[] c", expectedText: ["a []", " c"] }, + { initialText: "a |[]| c", expectedText: ["a []", " c"] }, + { initialText: "a []|| c", expectedText: ["a []", " c"] }, + { initialText: "a [] || c", expectedText: ["a []", " c"] }, + { initialText: "a [] || c", expectedText: ["a [] ", "", " c"] }, + ]) { + test(function () { + editor.innerHTML = ""; + let caret = { container: null, offset: -1 }; + for (let text of toPlaintext(currentTest.initialText).split("|")) { + let caretOffset = text.indexOf("[]"); + if (caretOffset >= 0) { + text = text.slice(0, caretOffset) + text.slice(caretOffset + 2); + } + let textNode = document.createTextNode(text); + editor.appendChild(textNode); + if (caretOffset >= 0) { + caret = { container: textNode, offset: caretOffset }; + } + } + selection.collapse(caret.container, caret.offset); + document.execCommand("forwarddelete", false, ""); + let child = editor.firstChild; + for (let expectedText of currentTest.expectedText) { + expectedText = toPlaintext(expectedText); + let caretOffset = expectedText.indexOf("[]"); + if (caretOffset >= 0) { + expectedText = expectedText.slice(0, caretOffset) + expectedText.slice(caretOffset + 2); + } + if (!child || child.nodeName !== "#text") { + assert_equals("", escape(expectedText), "Expected text node is not there"); + if (caretOffset >= 0) { + assert_equals(-1, caretOffset, "Selection should be contained in this node"); + } + } else { + assert_equals(escape(child.data), escape(expectedText), "Modified text is wrong"); + if (caretOffset >= 0) { + assert_equals(selection.focusNode, child, "Selection focus node is wrong"); + assert_equals(selection.focusOffset, caretOffset, "Selection focus offset is wrong"); + assert_equals(selection.anchorNode, child, "Selection anchor node is wrong"); + assert_equals(selection.anchorOffset, caretOffset, "Selection anchor offset is wrong"); + } + } + child = child.nextSibling; + } + if (child && child.nodeName === "#text") { + assert_equals(escape(child.data), "", "Unexpected text node is there"); + } + }, `execCommand("forwarddelete", false, ""): "${currentTest.initialText}"`); + } + + // Test white spaces around inline element boundary + // - initialHTML: Set to innerHTML of the <div> ("[{" and "]}" set selection to the range) + // - expectedText: Set to innerHTML of the <div> after `execCommand("delete")` + for (const currentTest of [ + { initialHTML: "<span>abc[] <span> def</span></span>", expectedHTML: "<span>abc<span> def</span></span>" }, + { initialHTML: "<span>abc[] <span> def</span></span>", expectedHTML: "<span>abc<span> def</span></span>" }, + { initialHTML: "<span>abc[] <span> def</span></span>", expectedHTML: "<span>abc<span> def</span></span>" }, + { initialHTML: "<span>abc []<span> def</span></span>", expectedHTML: "<span>abc <span>def</span></span>" }, + { initialHTML: "<span>abc []<span> def</span></span>", expectedHTML: "<span>abc <span>def</span></span>" }, + { initialHTML: "<span>abc []<span> def</span></span>", expectedHTML: "<span>abc <span>def</span></span>" }, + { initialHTML: "<span>abc[] <span> def</span></span>", expectedHTML: "<span>abc<span> def</span></span>" }, + { initialHTML: "<span>abc[] <span> def</span></span>", expectedHTML: "<span>abc<span> def</span></span>" }, + { initialHTML: "<span>abc[] <span> def</span></span>", expectedHTML: "<span>abc <span> def</span></span>" }, + { initialHTML: "<span>abc[] <span> def</span></span>", expectedHTML: "<span>abc <span> def</span></span>" }, + { initialHTML: "<span>abc[] <span> def</span></span>", expectedHTML: "<span>abc <span> def</span></span>" }, + { initialHTML: "<span>abc[] <span> def</span></span>", expectedHTML: "<span>abc <span> def</span></span>" }, + { initialHTML: "<span>abc[] <span> def</span></span>", expectedHTML: "<span>abc <span> def</span></span>" }, + { initialHTML: "<span>abc[] <span> def</span></span>", expectedHTML: "<span>abc <span> def</span></span>" }, + { initialHTML: "<span>abc []<span> def</span></span>", expectedHTML: "<span>abc <span> def</span></span>" }, + { initialHTML: "<span>abc <span>[] def</span></span>", expectedHTML: "<span>abc <span> def</span></span>" }, + { initialHTML: "<span>abc []<span> def</span></span>", expectedHTML: "<span>abc <span> def</span></span>" }, + { initialHTML: "<span>abc <span>[] def</span></span>", expectedHTML: "<span>abc <span> def</span></span>" }, + { initialHTML: "<span>abc []<span> def</span></span>", expectedHTML: "<span>abc <span> def</span></span>" }, + { initialHTML: "<span>abc <span>[] def</span></span>", expectedHTML: "<span>abc <span> def</span></span>" }, + { initialHTML: "<span>abc <span> [] def</span></span>", expectedHTML: "<span>abc <span> def</span></span>" }, + { initialHTML: "<span>abc <span> [] def</span></span>", expectedHTML: "<span>abc <span> def</span></span>" }, + { initialHTML: "<span>abc <span> [] def</span></span>", expectedHTML: "<span>abc <span> def</span></span>" }, + + { initialHTML: "<span><span>abc[] </span> def</span>", expectedHTML: "<span><span>abc</span> def</span>" }, + { initialHTML: "<span><span>abc[] </span> def</span>", expectedHTML: "<span><span>abc</span> def</span>" }, + { initialHTML: "<span><span>abc[] </span> def</span>", expectedHTML: "<span><span>abc</span> def</span>" }, + { initialHTML: "<span><span>abc []</span> def</span>", expectedHTML: "<span><span>abc </span>def</span>" }, + { initialHTML: "<span><span>abc []</span> def</span>", expectedHTML: "<span><span>abc </span>def</span>" }, + { initialHTML: "<span><span>abc []</span> def</span>", expectedHTML: "<span><span>abc </span>def</span>" }, + { initialHTML: "<span><span>abc[] </span> def</span>", expectedHTML: "<span><span>abc</span> def</span>" }, + { initialHTML: "<span><span>abc[] </span> def</span>", expectedHTML: "<span><span>abc</span> def</span>" }, + { initialHTML: "<span><span>abc[] </span> def</span>", expectedHTML: "<span><span>abc </span> def</span>" }, + { initialHTML: "<span><span>abc[] </span> def</span>", expectedHTML: "<span><span>abc </span> def</span>" }, + { initialHTML: "<span><span>abc[] </span> def</span>", expectedHTML: "<span><span>abc </span> def</span>" }, + { initialHTML: "<span><span>abc[] </span> def</span>", expectedHTML: "<span><span>abc </span> def</span>" }, + { initialHTML: "<span><span>abc[] </span> def</span>", expectedHTML: "<span><span>abc </span> def</span>" }, + { initialHTML: "<span><span>abc[] </span> def</span>", expectedHTML: "<span><span>abc </span> def</span>" }, + { initialHTML: "<span><span>abc []</span> def</span>", expectedHTML: "<span><span>abc </span> def</span>" }, + { initialHTML: "<span><span>abc </span>[] def</span>", expectedHTML: "<span><span>abc </span> def</span>" }, + { initialHTML: "<span><span>abc []</span> def</span>", expectedHTML: "<span><span>abc </span> def</span>" }, + { initialHTML: "<span><span>abc </span>[] def</span>", expectedHTML: "<span><span>abc </span> def</span>" }, + { initialHTML: "<span><span>abc []</span> def</span>", expectedHTML: "<span><span>abc </span> def</span>" }, + { initialHTML: "<span><span>abc </span>[] def</span>", expectedHTML: "<span><span>abc </span> def</span>" }, + { initialHTML: "<span><span>abc </span> [] def</span>", expectedHTML: "<span><span>abc </span> def</span>" }, + { initialHTML: "<span><span>abc </span> [] def</span>", expectedHTML: "<span><span>abc </span> def</span>" }, + { initialHTML: "<span><span>abc </span> [] def</span>", expectedHTML: "<span><span>abc </span> def</span>" }, + + { initialHTML: "<span>abc[] </span><span> def</span>", expectedHTML: "<span>abc</span><span> def</span>" }, + { initialHTML: "<span>abc[] </span><span> def</span>", expectedHTML: "<span>abc</span><span> def</span>" }, + { initialHTML: "<span>abc[] </span><span> def</span>", expectedHTML: "<span>abc</span><span> def</span>" }, + { initialHTML: "<span>abc []</span><span> def</span>", expectedHTML: "<span>abc </span><span>def</span>" }, + { initialHTML: "<span>abc []</span><span> def</span>", expectedHTML: "<span>abc </span><span>def</span>" }, + { initialHTML: "<span>abc []</span><span> def</span>", expectedHTML: "<span>abc </span><span>def</span>" }, + { initialHTML: "<span>abc[] </span><span> def</span>", expectedHTML: "<span>abc</span><span> def</span>" }, + { initialHTML: "<span>abc[] </span><span> def</span>", expectedHTML: "<span>abc</span><span> def</span>" }, + { initialHTML: "<span>abc[] </span><span> def</span>", expectedHTML: "<span>abc </span><span> def</span>" }, + { initialHTML: "<span>abc[] </span><span> def</span>", expectedHTML: "<span>abc </span><span> def</span>" }, + { initialHTML: "<span>abc[] </span><span> def</span>", expectedHTML: "<span>abc </span><span> def</span>" }, + { initialHTML: "<span>abc[] </span><span> def</span>", expectedHTML: "<span>abc </span><span> def</span>" }, + { initialHTML: "<span>abc[] </span><span> def</span>", expectedHTML: "<span>abc </span><span> def</span>" }, + { initialHTML: "<span>abc[] </span><span> def</span>", expectedHTML: "<span>abc </span><span> def</span>" }, + { initialHTML: "<span>abc []</span><span> def</span>", expectedHTML: "<span>abc </span><span> def</span>" }, + { initialHTML: "<span>abc </span><span>[] def</span>", expectedHTML: "<span>abc </span><span> def</span>" }, + { initialHTML: "<span>abc []</span><span> def</span>", expectedHTML: "<span>abc </span><span> def</span>" }, + { initialHTML: "<span>abc </span><span>[] def</span>", expectedHTML: "<span>abc </span><span> def</span>" }, + { initialHTML: "<span>abc []</span><span> def</span>", expectedHTML: "<span>abc </span><span> def</span>" }, + { initialHTML: "<span>abc </span><span>[] def</span>", expectedHTML: "<span>abc </span><span> def</span>" }, + { initialHTML: "<span>abc </span><span> [] def</span>", expectedHTML: "<span>abc </span><span> def</span>" }, + { initialHTML: "<span>abc </span><span> [] def</span>", expectedHTML: "<span>abc </span><span> def</span>" }, + { initialHTML: "<span>abc </span><span> [] def</span>", expectedHTML: "<span>abc </span><span> def</span>" }, + + { initialHTML: "a[]<span style=white-space:pre;>b </span>c", expectedHTML: "a<span style=\"white-space:pre;\"> </span>c" }, + { initialHTML: "a<span style=white-space:pre;>b[] </span>c", expectedHTML: "a<span style=\"white-space:pre;\">b </span>c" }, + { initialHTML: "a<span style=white-space:pre;>b [] </span>c", expectedHTML: "a<span style=\"white-space:pre;\">b </span>c" }, + { initialHTML: "a<span style=white-space:pre;>b [] </span>c", expectedHTML: "a<span style=\"white-space:pre;\">b </span>c" }, + { initialHTML: "a<span style=white-space:pre;>b []</span>c", expectedHTML: "a<span style=\"white-space:pre;\">b </span>" }, + { initialHTML: "a<span style=white-space:pre;>b [] </span>", expectedHTML: "a<span style=\"white-space:pre;\">b </span>" }, + { initialHTML: "a[]<span style=white-space:pre;> </span>b", expectedHTML: "ab" }, + { initialHTML: "a []<span style=white-space:pre;> </span>", expectedHTML: "a <span style=\"white-space:pre;\"> </span>" }, + { initialHTML: "a [] <span style=white-space:pre;> </span>", expectedHTML: "a <span style=\"white-space:pre;\"> </span>" }, + { initialHTML: "a [] <span style=white-space:pre;> </span>", expectedHTML: "a <span style=\"white-space:pre;\"> </span>" }, + { initialHTML: "a [] <span style=white-space:pre;>b </span>", expectedHTML: "a <span style=\"white-space:pre;\">b </span>" }, + { initialHTML: "a [] <span style=white-space:pre;> </span>", expectedHTML: "a <span style=\"white-space:pre;\"> </span>" }, + { initialHTML: "a [] <span style=white-space:pre;> </span>", expectedHTML: "a <span style=\"white-space:pre;\"> </span>" }, + { initialHTML: "a [] <span style=white-space:pre;>b </span>", expectedHTML: "a <span style=\"white-space:pre;\">b </span>" }, + { initialHTML: "<span style=white-space:pre;> [] </span> a", expectedHTML: "<span style=\"white-space:pre;\"> </span> a" }, + { initialHTML: "<span style=white-space:pre;> [] </span> a", expectedHTML: "<span style=\"white-space:pre;\"> </span> a" }, + { initialHTML: "<span style=white-space:pre;> []</span> a", expectedHTML: "<span style=\"white-space:pre;\"> </span> a" }, + { initialHTML: "<span style=white-space:pre;> </span>[] a", expectedHTML: "<span style=\"white-space:pre;\"> </span> a" }, + ]) { + test(function () { + let points = setupDiv(editor, currentTest.initialHTML); + selection.setBaseAndExtent(points[0], points[1], points[2], points[3]); + document.execCommand("forwarddelete", false, ""); + assert_equals(editor.innerHTML, currentTest.expectedHTML); + }, `execCommand("forwarddelete", false, ""): "${currentTest.initialHTML}"`); + } + + done(); +} + +window.addEventListener("load", runTests, {once: true}); +</script> +</body> +</html> diff --git a/testing/web-platform/tests/editing/other/white-spaces-after-execCommand-insertlinebreak.tentative.html b/testing/web-platform/tests/editing/other/white-spaces-after-execCommand-insertlinebreak.tentative.html new file mode 100644 index 0000000000..a961ee77bc --- /dev/null +++ b/testing/web-platform/tests/editing/other/white-spaces-after-execCommand-insertlinebreak.tentative.html @@ -0,0 +1,150 @@ +<!doctype html> +<html> +<head> +<meta charset=utf-8> +<title>Testing normalizing white-space sequence after execCommand("insertlinebreak", false, "foo")</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +</head> +<body> +<script> +"use strict"; + +setup({explicit_done: true}); + +function runTests() { + // README: + // These tests based on the behavior of Chrome 83. This test does NOT define + // nor suggest any standard behavior (actually, some expected results might + // look odd), but this test must help you to understand how other browsers + // use different logic to normalize white-space sequence. + + document.body.innerHTML = "<div contenteditable></div>"; + let editor = document.querySelector("div[contenteditable]"); + editor.focus(); + let selection = document.getSelection(); + + function escape(str) { + return typeof(str) === "string" ? str.replace(/\u00A0/ig, " ") : ""; + } + + function generateWhiteSpaces(num, lastIsAlwaysNBSP) { + let str = ""; + for (let i = 0; i < num - 1; i++) { + str += i % 2 ? " " : "\u00A0"; + } + str += lastIsAlwaysNBSP || num % 2 ? "\u00A0" : " "; + return escape(str); + } + function getDescriptionForTextNode(textNode) { + return selection.focusNode === textNode ? + `${escape(textNode.data.slice(0, selection.focusOffset))}[]${escape(textNode.data.slice(selection.focusOffset))}` : + escape(textNode); + } + + editor.innerHTML = "a b"; + selection.collapse(editor.firstChild, 0); + test(function () { + document.execCommand("insertlinebreak", false, ""); + assert_equals(editor.innerHTML, + `<br>a b`, + "Modified text is wrong"); + }, `execCommand("insertlinebreak", false, "") at "${getDescriptionForTextNode(editor.firstChild)}"`); + + editor.innerHTML = "a b"; + selection.collapse(editor.firstChild, 1); + test(function () { + document.execCommand("insertlinebreak", false, ""); + assert_equals(editor.innerHTML, + `a<br>${escape(generateWhiteSpaces(9, false))}b`, + "Modified text is wrong"); + }, `execCommand("insertlinebreak", false, "") at "${getDescriptionForTextNode(editor.firstChild)}"`); + + editor.innerHTML = "a b"; + selection.collapse(editor.firstChild, 2); + test(function () { + document.execCommand("insertlinebreak", false, ""); + assert_equals(editor.innerHTML, + `a <br>${escape(generateWhiteSpaces(8, false))}b`, + "Modified text is wrong"); + }, `execCommand("insertlinebreak", false, "") at "${getDescriptionForTextNode(editor.firstChild)}"`); + + editor.innerHTML = "a b"; + selection.collapse(editor.firstChild, 3); + test(function () { + document.execCommand("insertlinebreak", false, ""); + assert_equals(editor.innerHTML, + `a <br>${escape(generateWhiteSpaces(7, false))}b`, + "Modified text is wrong"); + }, `execCommand("insertlinebreak", false, "") at "${getDescriptionForTextNode(editor.firstChild)}"`); + + editor.innerHTML = "a b"; + selection.collapse(editor.firstChild, 4); + test(function () { + document.execCommand("insertlinebreak", false, ""); + assert_equals(editor.innerHTML, + `a <br>${escape(generateWhiteSpaces(6, false))}b`, + "Modified text is wrong"); + }, `execCommand("insertlinebreak", false, "") at "${getDescriptionForTextNode(editor.firstChild)}"`); + + editor.innerHTML = "a b"; + selection.collapse(editor.firstChild, 5); + test(function () { + document.execCommand("insertlinebreak", false, ""); + assert_equals(editor.innerHTML, + `a <br>${escape(generateWhiteSpaces(5, false))}b`, + "Modified text is wrong"); + }, `execCommand("insertlinebreak", false, "") at "${getDescriptionForTextNode(editor.firstChild)}"`); + + editor.innerHTML = "a b"; + selection.collapse(editor.firstChild, 6); + test(function () { + document.execCommand("insertlinebreak", false, ""); + assert_equals(editor.innerHTML, + `a <br>${escape(generateWhiteSpaces(4, false))}b`, + "Modified text is wrong"); + }, `execCommand("insertlinebreak", false, "") at "${getDescriptionForTextNode(editor.firstChild)}"`); + + editor.innerHTML = "a b"; + selection.collapse(editor.firstChild, 7); + test(function () { + document.execCommand("insertlinebreak", false, ""); + assert_equals(editor.innerHTML, + `a <br>${escape(generateWhiteSpaces(3, false))}b`, + "Modified text is wrong"); + }, `execCommand("insertlinebreak", false, "") at "${getDescriptionForTextNode(editor.firstChild)}"`); + + editor.innerHTML = "a b"; + selection.collapse(editor.firstChild, 8); + test(function () { + document.execCommand("insertlinebreak", false, ""); + assert_equals(editor.innerHTML, + `a <br>${escape(generateWhiteSpaces(2, false))}b`, + "Modified text is wrong"); + }, `execCommand("insertlinebreak", false, "") at "${getDescriptionForTextNode(editor.firstChild)}"`); + + editor.innerHTML = "a b"; + selection.collapse(editor.firstChild, 9); + test(function () { + document.execCommand("insertlinebreak", false, ""); + assert_equals(editor.innerHTML, + `a <br>${escape(generateWhiteSpaces(1, false))}b`, + "Modified text is wrong"); + }, `execCommand("insertlinebreak", false, "") at "${getDescriptionForTextNode(editor.firstChild)}"`); + + editor.innerHTML = "a b"; + selection.collapse(editor.firstChild, 10); + test(function () { + document.execCommand("insertlinebreak", false, ""); + assert_equals(editor.innerHTML, + `a <br>b`, + "Modified text is wrong"); + }, `execCommand("insertlinebreak", false, "") at "${getDescriptionForTextNode(editor.firstChild)}"`); + + done(); +} + +window.addEventListener("load", runTests, {once: true}); +</script> +</body> +</html> diff --git a/testing/web-platform/tests/editing/other/white-spaces-after-execCommand-insertparagraph.tentative.html b/testing/web-platform/tests/editing/other/white-spaces-after-execCommand-insertparagraph.tentative.html new file mode 100644 index 0000000000..854e6b3dae --- /dev/null +++ b/testing/web-platform/tests/editing/other/white-spaces-after-execCommand-insertparagraph.tentative.html @@ -0,0 +1,72 @@ +<!doctype html> +<html> +<head> +<meta charset=utf-8> +<title>Testing normalizing white-space sequence after execCommand("insertparagraph", false, "foo")</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +</head> +<body> +<script> +"use strict"; + +setup({explicit_done: true}); + +function runTests() { + // README: + // These tests based on the behavior of Chrome 83. This test does NOT define + // nor suggest any standard behavior (actually, some expected results might + // look odd), but this test must help you to understand how other browsers + // use different logic to normalize white-space sequence. + + document.body.innerHTML = "<div contenteditable></div>"; + let editor = document.querySelector("div[contenteditable]"); + editor.focus(); + let selection = document.getSelection(); + + function escape(str) { + return typeof(str) === "string" ? str.replace(/\u00A0/ig, " ") : ""; + } + + function generateWhiteSpaces(num, lastIsAlwaysNBSP) { + let str = ""; + for (let i = 0; i < num - 1; i++) { + str += i % 2 ? " " : "\u00A0"; + } + str += lastIsAlwaysNBSP || num % 2 ? "\u00A0" : " "; + return escape(str); + } + function getDescriptionForTextNode(textNode) { + return selection.focusNode === textNode ? + `${escape(textNode.data.slice(0, selection.focusOffset))}[]${escape(textNode.data.slice(selection.focusOffset))}` : + escape(textNode); + } + + editor.innerHTML = "<div>a b</div>"; + selection.collapse(editor.firstChild.firstChild, 0); + test(function () { + document.execCommand("insertparagraph", false, ""); + assert_equals(editor.innerHTML, + `<div><br></div><div>a b</div>`, + "Modified text is wrong"); + }, `execCommand("insertparagraph", false, "") at "<div>${getDescriptionForTextNode(editor.firstChild.firstChild)}</div>"`); + + for (let i = 1; i <= 10; i++) { + editor.innerHTML = "<div>a b</div>"; + selection.collapse(editor.firstChild.firstChild, i); + test(function () { + let text = editor.firstChild.firstChild.data; + document.execCommand("insertparagraph", false, ""); + assert_equals(editor.innerHTML, + `<div>${escape(text.slice(0, i))}</div><div>${escape(text.slice(i))}</div>`, + "Modified text is wrong"); + }, `execCommand("insertparagraph", false, "") at "<div>${getDescriptionForTextNode(editor.firstChild.firstChild)}</div>"`); + } + + done(); +} + +window.addEventListener("load", runTests, {once: true}); +</script> +</body> +</html> diff --git a/testing/web-platform/tests/editing/other/white-spaces-after-execCommand-inserttext.tentative.html b/testing/web-platform/tests/editing/other/white-spaces-after-execCommand-inserttext.tentative.html new file mode 100644 index 0000000000..4b4146b509 --- /dev/null +++ b/testing/web-platform/tests/editing/other/white-spaces-after-execCommand-inserttext.tentative.html @@ -0,0 +1,526 @@ +<!doctype html> +<html> +<head> +<meta charset=utf-8> +<title>Testing normalizing white-space sequence after execCommand("inserttext", false, "foo")</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +</head> +<body> +<script> +"use strict"; + +setup({explicit_done: true}); + +function runTests() { + // README: + // These tests based on the behavior of Chrome 83. This test does NOT define + // nor suggest any standard behavior (actually, some expected results might + // look odd), but this test must help you to understand how other browsers + // use different logic to normalize white-space sequence. + + document.body.innerHTML = "<div contenteditable></div>"; + let editor = document.querySelector("div[contenteditable]"); + editor.focus(); + let selection = document.getSelection(); + + function toPlaintext(str) { + return str.replace(/ /g, "\u00A0"); + } + function escape(str) { + return typeof(str) === "string" ? str.replace(/\u00A0/ig, " ") : ""; + } + + function generateWhiteSpaces(num, lastIsAlwaysNBSP) { + if (!num) { + return ""; + } + let str = ""; + for (let i = 0; i < num - 1; i++) { + str += i % 2 ? " " : "\u00A0"; + } + str += lastIsAlwaysNBSP || num % 2 ? "\u00A0" : " "; + return escape(str); + } + function getDescriptionForTextNode(textNode) { + return selection.focusNode === textNode ? + `${escape(textNode.data.slice(0, selection.focusOffset))}[]${escape(textNode.data.slice(selection.focusOffset))}` : + escape(textNode); + } + + for (let i = 0; i < 12; i++) { + editor.innerHTML = `a${i === 1 ? " " : generateWhiteSpaces(i, false)}b`; + selection.collapse(editor.firstChild, i + 1); + test(function () { + document.execCommand("inserttext", false, " "); + assert_equals(escape(editor.firstChild.data), + `a${i === 0 ? " " : escape(generateWhiteSpaces(i + 1, false))}b`, + "Modified text is wrong"); + }, `execCommand("inserttext", false, " ") at "${getDescriptionForTextNode(editor.firstChild)}"`); + } + + for (let i = 0; i < 12; i++) { + editor.innerHTML = `a${generateWhiteSpaces(i, true)}`; + selection.collapse(editor.firstChild, i + 1); + test(function () { + document.execCommand("inserttext", false, " "); + assert_equals(escape(editor.firstChild.data), + `a${escape(generateWhiteSpaces(i + 1, true))}`, + "Modified text is wrong"); + }, `execCommand("inserttext", false, " ") at "${getDescriptionForTextNode(editor.firstChild)}"`); + } + + for (let i = 0; i < 12; i++) { + editor.innerHTML = `${generateWhiteSpaces(i, false)}b`; + selection.collapse(editor.firstChild, i); + test(function () { + document.execCommand("inserttext", false, " "); + assert_equals(escape(editor.firstChild.data), + `${i === 0 ? " " : escape(generateWhiteSpaces(i + 1, false))}b`, + "Modified text is wrong"); + }, `execCommand("inserttext", false, " ") at "${getDescriptionForTextNode(editor.firstChild)}"`); + } + + for (let i = 0; i < 12; i++) { + editor.innerHTML = `a${i === 0 ? " " : generateWhiteSpaces(i + 1, false)}b`; + selection.collapse(editor.firstChild, i + 1); + test(function () { + document.execCommand("inserttext", false, " "); + assert_equals(escape(editor.firstChild.data), + `a${i === 0 ? " " : escape(generateWhiteSpaces(i + 2, false))}b`, + "Modified text is wrong"); + }, `execCommand("inserttext", false, " ") at "${getDescriptionForTextNode(editor.firstChild)}"`); + } + + editor.innerHTML = "a b"; + selection.collapse(editor.firstChild, 1); + test(function () { + document.execCommand("inserttext", false, " "); + assert_equals(escape(editor.firstChild.data), "a b", "Modified text is wrong"); + }, `execCommand("inserttext", false, " ") at "${getDescriptionForTextNode(editor.firstChild)}"`); + + for (let i = 1; i <= 3; i++) { + editor.innerHTML = "a b"; + selection.collapse(editor.firstChild, i); + test(function () { + document.execCommand("inserttext", false, " "); + assert_equals(escape(editor.firstChild.data), + `a${escape(generateWhiteSpaces(3, false))}b`, + "Modified text is wrong"); + }, `execCommand("inserttext", false, " ") at "${getDescriptionForTextNode(editor.firstChild)}"`); + } + + for (let i = 1; i <= 6; i++) { + editor.innerHTML = "a b"; + selection.collapse(editor.firstChild, i); + test(function () { + document.execCommand("inserttext", false, " "); + assert_equals(escape(editor.firstChild.data), + `a${escape(generateWhiteSpaces(6, false))}b`, + "Modified text is wrong"); + }, `execCommand("inserttext", false, " ") at "${getDescriptionForTextNode(editor.firstChild)}"`); + } + + for (let i = 1; i <= 7; i++) { + editor.innerHTML = "a b"; + selection.collapse(editor.firstChild, i); + test(function () { + document.execCommand("inserttext", false, " "); + assert_equals(escape(editor.firstChild.data), + `a${escape(generateWhiteSpaces(7, false))}b`, + "Modified text is wrong"); + }, `execCommand("inserttext", false, " ") at "${getDescriptionForTextNode(editor.firstChild)}"`); + } + + for (let i = 0; i < 12; i++) { + editor.innerHTML = `a${generateWhiteSpaces(i)}b`; + selection.collapse(editor.firstChild, i + 1); + test(function () { + document.execCommand("inserttext", false, "\u00A0"); + assert_equals(escape(editor.firstChild.data), + `a${i === 0 ? " " : escape(generateWhiteSpaces(i + 1, false))}b`, + "Modified text is wrong"); + }, `execCommand("inserttext", false, "\\u00A0") at "${getDescriptionForTextNode(editor.firstChild)}"`); + } + + for (let i = 0; i < 5; i++) { + editor.innerHTML = `a<span>${i === 0 ? " " : generateWhiteSpaces(i + 1)}</span>b`; + selection.collapse(editor.querySelector("span").firstChild, i + 1); + test(function () { + document.execCommand("inserttext", false, " "); + assert_equals(editor.innerHTML, + `a<span>${escape(generateWhiteSpaces(i + 2, true))}</span>b`, + "Modified text is wrong"); + }, `execCommand("inserttext", false, " ") at "a<span>${getDescriptionForTextNode(editor.querySelector("span").firstChild)}</span>b"`); + } + + for (let i = 0; i < 5; i++) { + editor.innerHTML = `a<span>b${generateWhiteSpaces(i, true)}</span>c`; + selection.collapse(editor.querySelector("span").firstChild, i + 1); + test(function () { + document.execCommand("inserttext", false, " "); + assert_equals(editor.innerHTML, + `a<span>b${escape(generateWhiteSpaces(i + 1, true))}</span>c`, + "Modified text is wrong"); + }, `execCommand("inserttext", false, " ") at "a<span>${getDescriptionForTextNode(editor.querySelector("span").firstChild)}</span>c"`); + } + + for (let i = 0; i < 5; i++) { + editor.innerHTML = `a<span>b${generateWhiteSpaces(i, true)}</span> c`; + selection.collapse(editor.querySelector("span").firstChild, i + 1); + test(function () { + document.execCommand("inserttext", false, " "); + assert_equals(editor.innerHTML, + `a<span>b${escape(generateWhiteSpaces(i + 1, true))}</span> c`, + "Modified text is wrong"); + }, `execCommand("inserttext", false, " ") at "a<span>${getDescriptionForTextNode(editor.querySelector("span").firstChild)}</span> c"`); + } + + for (let i = 0; i < 5; i++) { + editor.innerHTML = `a<span>b${generateWhiteSpaces(i, true)}</span> c`; + selection.collapse(editor.querySelector("span").firstChild, i + 1); + test(function () { + document.execCommand("inserttext", false, " "); + assert_equals(editor.innerHTML, + `a<span>b${escape(generateWhiteSpaces(i + 1, true))}</span> c`, + "Modified text is wrong"); + }, `execCommand("inserttext", false, " ") at "a<span>${getDescriptionForTextNode(editor.querySelector("span").firstChild)}</span> c"`); + } + + for (let i = 0; i < 5; i++) { + editor.innerHTML = `a<span>b${generateWhiteSpaces(i, true)}</span><span>c</span>`; + selection.collapse(editor.querySelector("span").firstChild, i + 1); + test(function () { + document.execCommand("inserttext", false, " "); + assert_equals(editor.innerHTML, + `a<span>b${escape(generateWhiteSpaces(i + 1, true))}</span><span>c</span>`, + "Modified text is wrong"); + }, `execCommand("inserttext", false, " ") at "a<span>${getDescriptionForTextNode(editor.querySelector("span").firstChild)}</span><span>c</span>"`); + } + + for (let i = 0; i < 5; i++) { + editor.innerHTML = `a<span>b${generateWhiteSpaces(i, true)}</span><span> c</span>`; + selection.collapse(editor.querySelector("span").firstChild, i + 1); + test(function () { + document.execCommand("inserttext", false, " "); + assert_equals(editor.innerHTML, + `a<span>b${escape(generateWhiteSpaces(i + 1, true))}</span><span> c</span>`, + "Modified text is wrong"); + }, `execCommand("inserttext", false, " ") at "a<span>${getDescriptionForTextNode(editor.querySelector("span").firstChild)}</span><span> c</span>"`); + } + + for (let i = 0; i < 5; i++) { + editor.innerHTML = `a<span>b${generateWhiteSpaces(i, true)}</span><span> c</span>`; + selection.collapse(editor.querySelector("span").firstChild, i + 1); + test(function () { + document.execCommand("inserttext", false, " "); + assert_equals(editor.innerHTML, + `a<span>b${escape(generateWhiteSpaces(i + 1, true))}</span><span> c</span>`, + "Modified text is wrong"); + }, `execCommand("inserttext", false, " ") at "a<span>${getDescriptionForTextNode(editor.querySelector("span").firstChild)}</span><span> c</span>"`); + } + + for (let i = 0; i < 5; i++) { + editor.innerHTML = `a<span>b${generateWhiteSpaces(i, true)}</span><span><span>c</span></span>`; + selection.collapse(editor.querySelector("span").firstChild, i + 1); + test(function () { + document.execCommand("inserttext", false, " "); + assert_equals(editor.innerHTML, + `a<span>b${escape(generateWhiteSpaces(i + 1, true))}</span><span><span>c</span></span>`, + "Modified text is wrong"); + }, `execCommand("inserttext", false, " ") at "a<span>${getDescriptionForTextNode(editor.querySelector("span").firstChild)}</span><span><span>c</span></span>"`); + } + + for (let i = 0; i < 5; i++) { + editor.innerHTML = `a<span>b${generateWhiteSpaces(i, true)}</span><span><span> c</span></span>`; + selection.collapse(editor.querySelector("span").firstChild, i + 1); + test(function () { + document.execCommand("inserttext", false, " "); + assert_equals(editor.innerHTML, + `a<span>b${escape(generateWhiteSpaces(i + 1, true))}</span><span><span> c</span></span>`, + "Modified text is wrong"); + }, `execCommand("inserttext", false, " ") at "a<span>${getDescriptionForTextNode(editor.querySelector("span").firstChild)}</span><span><span> c</span></span>"`); + } + + for (let i = 0; i < 5; i++) { + editor.innerHTML = `a<span>b${generateWhiteSpaces(i, true)}</span><span><span> c</span></span>`; + selection.collapse(editor.querySelector("span").firstChild, i + 1); + test(function () { + document.execCommand("inserttext", false, " "); + assert_equals(editor.innerHTML, + `a<span>b${escape(generateWhiteSpaces(i + 1, true))}</span><span><span> c</span></span>`, + "Modified text is wrong"); + }, `execCommand("inserttext", false, " ") at "a<span>${getDescriptionForTextNode(editor.querySelector("span").firstChild)}</span><span><span> c</span></span>"`); + } + + for (let i = 0; i < 5; i++) { + editor.innerHTML = `a<span><span>b${generateWhiteSpaces(i, true)}</span></span><span>c</span>`; + selection.collapse(editor.querySelector("span span").firstChild, i + 1); + test(function () { + document.execCommand("inserttext", false, " "); + assert_equals(editor.innerHTML, + `a<span><span>b${escape(generateWhiteSpaces(i + 1, true))}</span></span><span>c</span>`, + "Modified text is wrong"); + }, `execCommand("inserttext", false, " ") at "a<span><span>${getDescriptionForTextNode(editor.querySelector("span span").firstChild)}</span></span><span>c</span>"`); + } + + for (let i = 0; i < 5; i++) { + editor.innerHTML = `a<span><span>b${generateWhiteSpaces(i, true)}</span></span><span> c</span>`; + selection.collapse(editor.querySelector("span span").firstChild, i + 1); + test(function () { + document.execCommand("inserttext", false, " "); + assert_equals(editor.innerHTML, + `a<span><span>b${escape(generateWhiteSpaces(i + 1, true))}</span></span><span> c</span>`, + "Modified text is wrong"); + }, `execCommand("inserttext", false, " ") at "a<span><span>${getDescriptionForTextNode(editor.querySelector("span span").firstChild)}</span></span><span> c</span>"`); + } + + for (let i = 0; i < 5; i++) { + editor.innerHTML = `a<span><span>b${generateWhiteSpaces(i, true)}</span></span><span> c</span>`; + selection.collapse(editor.querySelector("span span").firstChild, i + 1); + test(function () { + document.execCommand("inserttext", false, " "); + assert_equals(editor.innerHTML, + `a<span><span>b${escape(generateWhiteSpaces(i + 1, true))}</span></span><span> c</span>`, + "Modified text is wrong"); + }, `execCommand("inserttext", false, " ") at "a<span><span>${getDescriptionForTextNode(editor.querySelector("span span").firstChild)}</span></span><span> c</span>"`); + } + + for (let i = 2; i < 8; i++) { + editor.innerHTML = "ab"; + selection.collapse(editor.firstChild, 1); + test(function () { + document.execCommand("inserttext", false, " ".repeat(i)); + assert_equals(escape(editor.firstChild.data), + `a${i > 0 ? escape(generateWhiteSpaces(i, false)) : " "}b`, + "Modified text is wrong"); + }, `execCommand("inserttext", false, "${" ".repeat(i)}") at "${getDescriptionForTextNode(editor.firstChild)}"`); + } + + for (let i = 2; i < 8; i++) { + editor.innerHTML = "a"; + selection.collapse(editor.firstChild, 1); + test(function () { + document.execCommand("inserttext", false, " ".repeat(i)); + assert_equals(escape(editor.firstChild.data), + `a${i > 0 ? escape(generateWhiteSpaces(i, true)) : " "}`, + "Modified text is wrong"); + }, `execCommand("inserttext", false, "${" ".repeat(i)}") at "${getDescriptionForTextNode(editor.firstChild)}"`); + } + + for (let i = 2; i < 8; i++) { + editor.innerHTML = "ab"; + selection.collapse(editor.firstChild, 1); + test(function () { + document.execCommand("inserttext", false, "\u00A0".repeat(i)); + assert_equals(escape(editor.firstChild.data), + `a${i > 0 ? escape(generateWhiteSpaces(i, false)) : " "}b`, + "Modified text is wrong"); + }, `execCommand("inserttext", false, "${"\\u00A0".repeat(i)}") at "${getDescriptionForTextNode(editor.firstChild)}"`); + } + + for (let i = 2; i < 8; i++) { + editor.innerHTML = "a"; + selection.collapse(editor.firstChild, 1); + test(function () { + document.execCommand("inserttext", false, "\u00A0".repeat(i)); + assert_equals(escape(editor.firstChild.data), + `a${i > 0 ? escape(generateWhiteSpaces(i, true)) : " "}`, + "Modified text is wrong"); + }, `execCommand("inserttext", false, "${"\\u00A0".repeat(i)}") at "${getDescriptionForTextNode(editor.firstChild)}"`); + } + + for (let i = 0; i < 5; i++) { + editor.innerHTML = `a${generateWhiteSpaces(i, true)}<span style=white-space:pre>b</span>`; + selection.collapse(editor.firstChild, i + 1); + test(function () { + document.execCommand("inserttext", false, " "); + assert_equals(editor.innerHTML, + `a${escape(generateWhiteSpaces(i + 1, true))}<span style=\"white-space:pre\">b</span>`, + "Modified text is wrong"); + }, `execCommand("inserttext", false, " ") at "${getDescriptionForTextNode(editor.firstChild)}<span style=white-space:pre>b</span>"`); + } + + for (let i = 0; i < 5; i++) { + editor.innerHTML = `a${generateWhiteSpaces(i, true)}<span style=white-space:pre> </span>`; + selection.collapse(editor.firstChild, i + 1); + test(function () { + document.execCommand("inserttext", false, " "); + assert_equals(editor.innerHTML, + `a${escape(generateWhiteSpaces(i + 1, true))}<span style=\"white-space:pre\"> </span>`, + "Modified text is wrong"); + }, `execCommand("inserttext", false, " ") at "${getDescriptionForTextNode(editor.firstChild)}<span style=white-space:pre> </span>"`); + } + + for (let i = 0; i < 5; i++) { + editor.innerHTML = `a${generateWhiteSpaces(i, true)}<span style=white-space:pre> </span>`; + selection.collapse(editor.firstChild, i + 1); + test(function () { + document.execCommand("inserttext", false, " "); + assert_equals(editor.innerHTML, + `a${escape(generateWhiteSpaces(i + 1, true))}<span style=\"white-space:pre\"> </span>`, + "Modified text is wrong"); + }, `execCommand("inserttext", false, " ") at "${getDescriptionForTextNode(editor.firstChild)}<span style=white-space:pre> </span>"`); + } + + for (let i = 0; i < 5; i++) { + editor.innerHTML = `a${generateWhiteSpaces(i, true)}<span style=white-space:pre>b</span>`; + selection.collapse(editor.firstChild, i + 1); + test(function () { + document.execCommand("inserttext", false, "\u00A0"); + assert_equals(editor.innerHTML, + `a${escape(generateWhiteSpaces(i + 1, true))}<span style=\"white-space:pre\">b</span>`, + "Modified text is wrong"); + }, `execCommand("inserttext", false, "\\u00A0") at "${getDescriptionForTextNode(editor.firstChild)}<span style=white-space:pre>b</span>"`); + } + + for (let i = 0; i < 5; i++) { + editor.innerHTML = `a${generateWhiteSpaces(i, true)}<span style=white-space:pre> </span>`; + selection.collapse(editor.firstChild, i + 1); + test(function () { + document.execCommand("inserttext", false, "\u00A0"); + assert_equals(editor.innerHTML, + `a${escape(generateWhiteSpaces(i + 1, true))}<span style=\"white-space:pre\"> </span>`, + "Modified text is wrong"); + }, `execCommand("inserttext", false, "\\u00A0") at "${getDescriptionForTextNode(editor.firstChild)}<span style=white-space:pre> </span>"`); + } + + for (let i = 0; i < 5; i++) { + editor.innerHTML = `a${generateWhiteSpaces(i, true)}<span style=white-space:pre> </span>`; + selection.collapse(editor.firstChild, i + 1); + test(function () { + document.execCommand("inserttext", false, "\u00A0"); + assert_equals(editor.innerHTML, + `a${escape(generateWhiteSpaces(i + 1, true))}<span style=\"white-space:pre\"> </span>`, + "Modified text is wrong"); + }, `execCommand("inserttext", false, "\\u00A0") at "${getDescriptionForTextNode(editor.firstChild)}<span style=white-space:pre> </span>"`); + } + + editor.innerHTML = "a c"; + selection.collapse(editor.firstChild, 2); + test(function () { + document.execCommand("inserttext", false, "b"); + assert_equals(escape(editor.firstChild.data), "a b c", "Modified text is wrong"); + }, `execCommand("inserttext", false, "b") at "${getDescriptionForTextNode(editor.firstChild)}"`); + + editor.innerHTML = "a c"; + selection.collapse(editor.firstChild, 1); + test(function () { + document.execCommand("inserttext", false, "b"); + assert_equals(escape(editor.firstChild.data), `ab${escape(generateWhiteSpaces(4))}c`, "Modified text is wrong"); + }, `execCommand("inserttext", false, "b") at "${getDescriptionForTextNode(editor.firstChild)}"`); + + editor.innerHTML = "a c"; + selection.collapse(editor.firstChild, 2); + test(function () { + document.execCommand("inserttext", false, "b"); + assert_equals(escape(editor.firstChild.data), `a b${escape(generateWhiteSpaces(3))}c`, "Modified text is wrong"); + }, `execCommand("inserttext", false, "b") at "${getDescriptionForTextNode(editor.firstChild)}"`); + + editor.innerHTML = "a c"; + selection.collapse(editor.firstChild, 3); + test(function () { + document.execCommand("inserttext", false, "b"); + assert_equals(escape(editor.firstChild.data), + `a${escape(generateWhiteSpaces(2))}b${escape(generateWhiteSpaces(2))}c`, + "Modified text is wrong"); + }, `execCommand("inserttext", false, "b") at "${getDescriptionForTextNode(editor.firstChild)}"`); + + editor.innerHTML = "a c"; + selection.collapse(editor.firstChild, 4); + test(function () { + document.execCommand("inserttext", false, "b"); + assert_equals(escape(editor.firstChild.data), + `a${escape(generateWhiteSpaces(3))}b c`, + "Modified text is wrong"); + }, `execCommand("inserttext", false, "b") at "${getDescriptionForTextNode(editor.firstChild)}"`); + + editor.innerHTML = "a c"; + selection.collapse(editor.firstChild, 5); + test(function () { + document.execCommand("inserttext", false, "b"); + assert_equals(escape(editor.firstChild.data), `a${escape(generateWhiteSpaces(4))}bc`, "Modified text is wrong"); + }, `execCommand("inserttext", false, "b") at "${getDescriptionForTextNode(editor.firstChild)}"`); + + // Test white space sequence split to multiple text node. + // - initialText: Set to data of text nodes. This must have "|" at least one. + // Then, the text will be split at every "|". + // Same as above test, only is handled at setting. + // "[]" means that caret position. + // - expectedText: Set to data of all text nodes as an array. + // Same as above test, only is handled before comparing. + for (const currentTest of [ + { initialText: "a[]|b", expectedText: ["a", "b"] }, + { initialText: "a []|b", expectedText: ["a ", "b"] }, + { initialText: "a |[]b", expectedText: ["a ", "b"] }, + { initialText: "a[] |b", expectedText: ["a ", "b"] }, + { initialText: "a []|b", expectedText: ["a ", "b"] }, + { initialText: "a |[]b", expectedText: ["a ", "b"] }, + { initialText: "a[]| b", expectedText: ["a", " b"] }, + { initialText: "a|[] b", expectedText: ["a", " b"] }, + { initialText: "a| []b", expectedText: ["a", " b"] }, + { initialText: "a[] | b", expectedText: ["a ", " b"] }, + { initialText: "a []| b", expectedText: ["a ", " b"] }, + { initialText: "a |[] b", expectedText: ["a ", " b"] }, + { initialText: "a | []b", expectedText: ["a ", " b"] }, + { initialText: "a[] | b", expectedText: ["a ", " b"] }, + { initialText: "a []| b", expectedText: ["a ", " b"] }, + { initialText: "a |[] b", expectedText: ["a ", " b"] }, + { initialText: "a | []b", expectedText: ["a ", " b"] }, + { initialText: "a[] | b", expectedText: ["a ", " b"] }, + { initialText: "a []| b", expectedText: ["a ", " b"] }, + { initialText: "a |[] b", expectedText: ["a ", " b"] }, + { initialText: "a | []b", expectedText: ["a ", " b"] }, + ]) { + test(function () { + editor.innerHTML = ""; + let caret = { container: null, offset: -1 }; + for (let text of toPlaintext(currentTest.initialText).split("|")) { + let caretOffset = text.indexOf("[]"); + if (caretOffset >= 0) { + text = text.slice(0, caretOffset) + text.slice(caretOffset + 2); + } + let textNode = document.createTextNode(text); + editor.appendChild(textNode); + if (caretOffset >= 0) { + caret = { container: textNode, offset: caretOffset }; + } + } + selection.collapse(caret.container, caret.offset); + document.execCommand("inserttext", false, ""); + let child = editor.firstChild; + for (let expectedText of currentTest.expectedText) { + expectedText = toPlaintext(expectedText); + let caretOffset = expectedText.indexOf("[]"); + if (caretOffset >= 0) { + expectedText = expectedText.slice(0, caretOffset) + expectedText.slice(caretOffset + 2); + } + if (!child || child.nodeName !== "#text") { + assert_equals("", escape(expectedText), "Expected text node is not there"); + if (caretOffset >= 0) { + assert_equals(-1, caretOffset, "Selection should be contained in this node"); + } + } else { + assert_equals(escape(child.data), escape(expectedText), "Modified text is wrong"); + if (caretOffset >= 0) { + assert_equals(selection.focusNode, child, "Selection focus node is wrong"); + assert_equals(selection.focusOffset, caretOffset, "Selection focus offset is wrong"); + assert_equals(selection.anchorNode, child, "Selection anchor node is wrong"); + assert_equals(selection.anchorOffset, caretOffset, "Selection anchor offset is wrong"); + } + } + child = child.nextSibling; + } + if (child && child.nodeName === "#text") { + assert_equals(escape(child.data), "", "Unexpected text node is there"); + } + }, `execCommand("inserttext", false, ""): "${currentTest.initialText}"`); + } + + done(); +} + +window.addEventListener("load", runTests, {once: true}); +</script> +</body> +</html> diff --git a/testing/web-platform/tests/editing/run/backcolor.html b/testing/web-platform/tests/editing/run/backcolor.html new file mode 100644 index 0000000000..5a4c35c34e --- /dev/null +++ b/testing/web-platform/tests/editing/run/backcolor.html @@ -0,0 +1,43 @@ +<!doctype html> +<meta charset=utf-8> +<meta name="timeout" content="long"> +<link rel=stylesheet href=../include/reset.css> +<title>backcolor - HTML editing conformance tests</title> + +<div id=log></div> + +<div id=test-container></div> + +<script src=../include/implementation.js></script> +<script>var testsJsLibraryOnly = true</script> +<script src=../include/tests.js></script> +<script src=../data/backcolor.js></script> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/common/subset-tests.js"></script> +<script> +"use strict"; + +(function() { + // Make document.body.innerHTML more tidy by removing unnecessary things. + [].forEach.call(document.querySelectorAll("script"), function(node) { + node.parentNode.removeChild(node); + }); + + if (false) { + // Silly hack: the CSS styling flag should be true, not false, to match + // expected results. This is because every group of tests except the + // last (multitest) sets styleWithCSS automatically, and it sets it + // first to false and then to true. Thus it's left at true at the end + // of each group of tests, so in gentest.html it will be true when + // starting each group of tests other than the first. But browsers are + // supposed to default it to false when the page loads, so flip it. + try { document.execCommand("styleWithCSS", false, "true") } catch(e) {} + } + + browserTests.forEach(runConformanceTest); + + document.getElementById("test-container").parentNode + .removeChild(document.getElementById("test-container")); +})(); +</script> diff --git a/testing/web-platform/tests/editing/run/bold.html b/testing/web-platform/tests/editing/run/bold.html new file mode 100644 index 0000000000..30981f6658 --- /dev/null +++ b/testing/web-platform/tests/editing/run/bold.html @@ -0,0 +1,48 @@ +<!doctype html> +<meta charset=utf-8> +<meta name="timeout" content="long"> +<meta name="variant" content="?1-1000"> +<meta name="variant" content="?1001-2000"> +<meta name="variant" content="?2001-3000"> +<meta name="variant" content="?3001-last"> +<link rel=stylesheet href=../include/reset.css> +<title>bold - HTML editing conformance tests</title> + +<div id=log></div> + +<div id=test-container></div> + +<script src=../include/implementation.js></script> +<script>var testsJsLibraryOnly = true</script> +<script src=../include/tests.js></script> +<script src=../data/bold.js></script> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/common/subset-tests.js"></script> +<script> +"use strict"; + +(function() { + // Make document.body.innerHTML more tidy by removing unnecessary things. + [].forEach.call(document.querySelectorAll("script"), function(node) { + node.parentNode.removeChild(node); + }); + + if (true) { + // Silly hack: the CSS styling flag should be true, not false, to match + // expected results. This is because every group of tests except the + // last (multitest) sets styleWithCSS automatically, and it sets it + // first to false and then to true. Thus it's left at true at the end + // of each group of tests, so in gentest.html it will be true when + // starting each group of tests other than the first. But browsers are + // supposed to default it to false when the page loads, so flip it. + try { document.execCommand("styleWithCSS", false, "true") } catch(e) {} + } + + browserTests.forEach(runConformanceTest); + + document.getElementById("test-container").parentNode + .removeChild(document.getElementById("test-container")); + +})(); +</script> diff --git a/testing/web-platform/tests/editing/run/caret-navigation-after-removing-line-break.html b/testing/web-platform/tests/editing/run/caret-navigation-after-removing-line-break.html new file mode 100644 index 0000000000..9855c3b9dc --- /dev/null +++ b/testing/web-platform/tests/editing/run/caret-navigation-after-removing-line-break.html @@ -0,0 +1,78 @@ +<!DOCTYPE HTML> +<style> + .wrap span { + white-space: pre-wrap; + } +</style> +<div class="wrap"> + <span id="initial" contenteditable="true"> abcd </span>111<span id="before" contenteditable="true"> efgh </span>222<br><span id="after" contenteditable="true"> ijkl </span>333<span id="next" contenteditable="true"> mnop </span>444<span id="last" contenteditable="true"> qrst </span> +</div> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script> +const KEY_CODE_MAP = { + 'ArrowLeft': '\uE012', + 'ArrowUp': '\uE013', + 'ArrowRight': '\uE014', + 'ArrowDown': '\uE015', + 'Tab': '\uE004', + 'S': '\u0053', +}; + +function keyPress(target, key) { + const code = KEY_CODE_MAP[key]; + return test_driver.send_keys(target, code); +} + +function deletebr() { + let el; + el = document.querySelector('br'); + if (el) { + el.remove(); + } +} + +// Delete the <br> element so that we get a single line +deletebr(); + +const s = getSelection(); +promise_test(async t => { + initial.focus(); + let node = initial.firstChild; + assert_equals(s.anchorNode, node, "Focus must be at the span with 'abcd'"); + assert_equals(s.anchorOffset, 0, "Caret must be at the start of the 'abcd' text"); + + await keyPress(initial, "Tab"); + node = before.firstChild + assert_equals(s.anchorNode, node, "Caret moved to span with 'efgh'"); + assert_equals(s.anchorOffset, 0, "Caret must be at the start of the 'efgh' text"); + + await keyPress(before, "Tab"); + node = after.firstChild + assert_equals(s.anchorNode, node, "Focus must be at the span with 'ijkl'"); + assert_equals(s.anchorOffset, 0, "Caret must be at the start of the 'efgh' text"); + + await keyPress(after, "Tab"); + node = next.firstChild + assert_equals(s.anchorNode, node, "Focus must be at the span with 'mnop'"); + assert_equals(s.anchorOffset, 0, "Caret must be at the start of the 'efgh' text"); + +}, "Navigate after deleting <br>"); + +promise_test(async t => { + initial.focus(); + await keyPress(initial, "Tab"); + await keyPress(before, "Tab"); + await keyPress(after, "Tab"); + await keyPress(next, "ArrowRight"); + await keyPress(next, "ArrowRight"); + await keyPress(next, "ArrowRight"); + + await keyPress(next, "S"); + assert_equals(next.firstChild.textContent, " mnSop ", "Inserting a 'S' char betwen 'n' and 'o'"); +}, "Insert text after deleting <br>") + +</script> diff --git a/testing/web-platform/tests/editing/run/caret-navigation-around-line-break.html b/testing/web-platform/tests/editing/run/caret-navigation-around-line-break.html new file mode 100644 index 0000000000..eb1499936e --- /dev/null +++ b/testing/web-platform/tests/editing/run/caret-navigation-around-line-break.html @@ -0,0 +1,137 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Caret navigation around line break</title> +<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com"> +<meta name="assert" content="This test checks that caret navigation works well around various kinds of line breaks." /> +<meta name="timeout" content="long"> +<style> +.test { + font-size: 16px; + line-height: 20px; + padding: 4px; + width: 5.5ch; + padding: 5px; + font-family: monospace; + word-wrap: break-word; +} +</style> + +<div class="test" contenteditable data-title="no separator" + >line1line2</div> +<div class="test" contenteditable data-title="<br> separator" + >line1<br>line2</div> +<div class="test" contenteditable data-title="<wbr> separator" + >line1<wbr>line2</div> +<div class="test" contenteditable data-title="<span> separator" + >line1<span></span>line2</div> +<div class="test" contenteditable data-title="two <span> separators" + >line1<span></span><span></span>line2</div> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script> +const KEY_CODE_MAP = { + 'ArrowLeft': '\uE012', + 'ArrowUp': '\uE013', + 'ArrowRight': '\uE014', + 'ArrowDown': '\uE015', +}; + +function click(target, x, y) { + return new test_driver.Actions() + .pointerMove(x, y, {origin: target}) + .pointerDown() + .pointerUp() + .send(); +} + +const s = getSelection(); +for (const test of document.querySelectorAll(".test")) { + const padding = 4; + const halfLineWidth = Math.floor((test.offsetWidth - padding) / 2); + const halfLineHeight = Math.floor(20 / 2); + const hasSeparator = test.firstChild !== test.lastChild; + const line1 = { + node: test.firstChild, + start: 0, + end: "line1".length, + }; + const line2 = { + node: test.lastChild, + start: hasSeparator ? 0 : "line1".length, + end: hasSeparator ? "line2".length : "line1line2".length, + }; + + promise_test(async t => { + // Click at the start of line 1 + await click(test, -halfLineWidth, -halfLineHeight); + assert_equals(s.anchorNode, line1.node, "Caret is in line 1"); + assert_equals(s.anchorOffset, line1.start, "Caret is at the start of line 1"); + + // Move down, expect start of line 2 + await test_driver.send_keys(test, KEY_CODE_MAP.ArrowDown); + assert_equals(s.anchorNode, line2.node, "Caret moved to line 2"); + assert_equals(s.anchorOffset, line2.start, "Caret moved to the start of line 2"); + + // Click at the end of line 1 + await click(test, +halfLineWidth, -halfLineHeight); + range = getSelection().getRangeAt(0); + assert_equals(s.anchorNode, line1.node, "Caret is in line 1"); + assert_equals(s.anchorOffset, line1.end, "Caret is at the end of line 1"); + + // Move down, expect end of line 2 + await test_driver.send_keys(test, KEY_CODE_MAP.ArrowDown); + assert_equals(s.anchorNode, line2.node, "Caret moved to line 2"); + assert_equals(s.anchorOffset, line2.end, "Caret moved to the end of line 2"); + }, test.dataset.title + " - move down"); + + promise_test(async t => { + // Click at the start of line 2 + await click(test, -halfLineWidth, +halfLineHeight); + assert_equals(s.anchorNode, line2.node, "Caret is in line 2"); + assert_equals(s.anchorOffset, line2.start, "Caret is at the start of line 2"); + + // Move up, expect start of line 1 + await test_driver.send_keys(test, KEY_CODE_MAP.ArrowUp); + assert_equals(s.anchorNode, line1.node, "Caret moved to line 1"); + assert_equals(s.anchorOffset, line1.start, "Caret moved to the start of line 1"); + + // Click at the end of line 2 + await click(test, +halfLineWidth, +halfLineHeight); + assert_equals(s.anchorNode, line2.node, "Caret is in line 2"); + assert_equals(s.anchorOffset, line2.end, "Caret is at the end of line 2"); + + // Move up, expect end of line 1 + await test_driver.send_keys(test, KEY_CODE_MAP.ArrowUp); + assert_equals(s.anchorNode, line1.node, "Caret moved to line 1"); + assert_equals(s.anchorOffset, line1.end, "Caret moved to the end of line 1"); + }, test.dataset.title + " - move up"); + + promise_test(async t => { + // Click at the end of line 1 + await click(test, +halfLineWidth, -halfLineHeight); + assert_equals(s.anchorNode, line1.node, "Caret is in line 1"); + assert_equals(s.anchorOffset, line1.end, "Caret is at the end of line 1"); + + // Move right, expect start or start+1 of line 2 + await test_driver.send_keys(test, KEY_CODE_MAP.ArrowRight); + assert_equals(s.anchorNode, line2.node, "Caret moved to line 2"); + assert_in_array(s.anchorOffset, [line2.start, line2.start + 1], "Caret moved to the start or start+1 of line 2"); + }, test.dataset.title + " - move right"); + + promise_test(async t => { + // Click at the start of line 2 + await click(test, -halfLineWidth, +halfLineHeight); + assert_equals(s.anchorNode, line2.node, "Caret is in line 2"); + assert_equals(s.anchorOffset, line2.start, "Caret is at the start of line 2"); + + // Move left, expect end or end-1 of line 1 + await test_driver.send_keys(test, KEY_CODE_MAP.ArrowLeft); + assert_equals(s.anchorNode, line1.node, "Caret moved to line 1"); + assert_in_array(s.anchorOffset, [line1.end, line1.end - 1], "Caret moved to the end or end-1 of line 1"); + }, test.dataset.title + " - move left"); +} +</script> diff --git a/testing/web-platform/tests/editing/run/caretnavigation.html b/testing/web-platform/tests/editing/run/caretnavigation.html new file mode 100644 index 0000000000..c0a8eca4ac --- /dev/null +++ b/testing/web-platform/tests/editing/run/caretnavigation.html @@ -0,0 +1,64 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Caret navigation</title> + +<link rel="stylesheet" href="../support/reset.css"> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/resources/testdriver-actions.js"></script> + +<script> +const KEY_CODE_MAP = { + 'ArrowLeft': '\uE012', + 'ArrowUp': '\uE013', + 'ArrowRight': '\uE014', + 'ArrowDown': '\uE015', +}; + +/** + * Send key event to the target element using test driver. Supports human + * friendly key names for common keyboard scroll operations e.g., arrow keys, + * page keys, etc. + * @param {Node} target + * @param {string} key + * @returns {Promise} + */ +function keyPress(target, key) { + const code = KEY_CODE_MAP[key]; + return test_driver.send_keys(target, code); +} +</script> + +<div id="container"> + <div contenteditable data-title="Move with ArrowLeft to BR following a div"> + <div>line 1</div> + <br> + <div class="caret">line 2</div> + </div> + <div contenteditable data-title="Move with ArrowLeft to BR following an img"> + <img style="display:block;width:100px;height:100px"> + <br> + <div class="caret">line 2</div> + </div> +</div> + +<script> +const container = document.getElementById("container"); + +for (const test of container.children) { + promise_test(async t => { + test.focus(); + getSelection().collapse(test.querySelector(".caret")); + await keyPress(test, "ArrowLeft"); + + const range = getSelection().getRangeAt(0); + + assert_equals(range.commonAncestorContainer.localName, "div"); + assert_equals(range.startOffset, 3); + assert_equals(range.commonAncestorContainer.childNodes[range.startOffset].localName, "br"); + }, test.dataset.title); +} +</script> diff --git a/testing/web-platform/tests/editing/run/createlink.html b/testing/web-platform/tests/editing/run/createlink.html new file mode 100644 index 0000000000..21c190703a --- /dev/null +++ b/testing/web-platform/tests/editing/run/createlink.html @@ -0,0 +1,44 @@ +<!doctype html> +<meta charset=utf-8> +<meta name="timeout" content="long"> +<link rel=stylesheet href=../include/reset.css> +<title>createlink - HTML editing conformance tests</title> + +<div id=log></div> + +<div id=test-container></div> + +<script src=../include/implementation.js></script> +<script>var testsJsLibraryOnly = true</script> +<script src=../include/tests.js></script> +<script src=../data/createlink.js></script> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/common/subset-tests.js"></script> +<script> +"use strict"; + +(function() { + // Make document.body.innerHTML more tidy by removing unnecessary things. + [].forEach.call(document.querySelectorAll("script"), function(node) { + node.parentNode.removeChild(node); + }); + + if (true) { + // Silly hack: the CSS styling flag should be true, not false, to match + // expected results. This is because every group of tests except the + // last (multitest) sets styleWithCSS automatically, and it sets it + // first to false and then to true. Thus it's left at true at the end + // of each group of tests, so in gentest.html it will be true when + // starting each group of tests other than the first. But browsers are + // supposed to default it to false when the page loads, so flip it. + try { document.execCommand("styleWithCSS", false, "true") } catch(e) {} + } + + browserTests.forEach(runConformanceTest); + + document.getElementById("test-container").parentNode + .removeChild(document.getElementById("test-container")); + +})(); +</script> diff --git a/testing/web-platform/tests/editing/run/delete-list-items-in-table-cell.html b/testing/web-platform/tests/editing/run/delete-list-items-in-table-cell.html new file mode 100644 index 0000000000..88f4458987 --- /dev/null +++ b/testing/web-platform/tests/editing/run/delete-list-items-in-table-cell.html @@ -0,0 +1,44 @@ +<!doctype html> +<meta charset=utf-8> +<meta name="timeout" content="long"> +<link rel=stylesheet href=../include/reset.css> +<title>delete list items in table cells - HTML editing conformance tests</title> + +<div id=log></div> + +<div id=test-container></div> + +<script src=../include/implementation.js></script> +<script>var testsJsLibraryOnly = true</script> +<script src=../include/tests.js></script> +<script src=../data/delete-list-items-in-table-cells.js></script> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/common/subset-tests.js"></script> +<script> +"use strict"; + +(function() { + // Make document.body.innerHTML more tidy by removing unnecessary things. + [].forEach.call(document.querySelectorAll("script"), function(node) { + node.parentNode.removeChild(node); + }); + + if (true) { + // Silly hack: the CSS styling flag should be true, not false, to match + // expected results. This is because every group of tests except the + // last (multitest) sets styleWithCSS automatically, and it sets it + // first to false and then to true. Thus it's left at true at the end + // of each group of tests, so in gentest.html it will be true when + // starting each group of tests other than the first. But browsers are + // supposed to default it to false when the page loads, so flip it. + try { document.execCommand("styleWithCSS", false, "true") } catch(e) {} + } + + browserTests.forEach(runConformanceTest); + + document.getElementById("test-container").parentNode + .removeChild(document.getElementById("test-container")); + +})(); +</script> diff --git a/testing/web-platform/tests/editing/run/delete.html b/testing/web-platform/tests/editing/run/delete.html new file mode 100644 index 0000000000..6a01ffd044 --- /dev/null +++ b/testing/web-platform/tests/editing/run/delete.html @@ -0,0 +1,51 @@ +<!doctype html> +<meta charset=utf-8> +<meta name="timeout" content="long"> +<meta name="variant" content="?1-1000"> +<meta name="variant" content="?1001-2000"> +<meta name="variant" content="?2001-3000"> +<meta name="variant" content="?3001-4000"> +<meta name="variant" content="?4001-5000"> +<meta name="variant" content="?5001-6000"> +<meta name="variant" content="?6001-7000"> +<meta name="variant" content="?7001-last"> +<link rel=stylesheet href=../include/reset.css> +<title>delete - HTML editing conformance tests</title> + +<div id=log></div> + +<div id=test-container></div> + +<script src=../include/implementation.js></script> +<script>var testsJsLibraryOnly = true</script> +<script src=../include/tests.js></script> +<script src=../data/delete.js></script> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/common/subset-tests.js"></script> +<script> +"use strict"; + +(function() { + // Make document.body.innerHTML more tidy by removing unnecessary things. + [].forEach.call(document.querySelectorAll("script"), function(node) { + node.parentNode.removeChild(node); + }); + + if (true) { + // Silly hack: the CSS styling flag should be true, not false, to match + // expected results. This is because every group of tests except the + // last (multitest) sets styleWithCSS automatically, and it sets it + // first to false and then to true. Thus it's left at true at the end + // of each group of tests, so in gentest.html it will be true when + // starting each group of tests other than the first. But browsers are + // supposed to default it to false when the page loads, so flip it. + try { document.execCommand("styleWithCSS", false, "true") } catch(e) {} + } + + browserTests.forEach(runConformanceTest); + + document.getElementById("test-container").parentNode + .removeChild(document.getElementById("test-container")); +})(); +</script> diff --git a/testing/web-platform/tests/editing/run/empty-editable-crash.html b/testing/web-platform/tests/editing/run/empty-editable-crash.html new file mode 100644 index 0000000000..eda75a13cd --- /dev/null +++ b/testing/web-platform/tests/editing/run/empty-editable-crash.html @@ -0,0 +1,11 @@ +<!DOCTYPE html> +<link rel="help" href="https://crbug.com/1171845"> +<span id="target"></span> +<div contenteditable="true"> + <span></span> +</div> +<script> +document.body.offsetTop; +document.getElementById('target').style.paddingRight = '1em'; +document.getElementById('target').style.fontVariantNumeric = 'ordinal'; +</script> diff --git a/testing/web-platform/tests/editing/run/first-letter-crossing-engine-boundary-crash.html b/testing/web-platform/tests/editing/run/first-letter-crossing-engine-boundary-crash.html new file mode 100644 index 0000000000..be6325fce4 --- /dev/null +++ b/testing/web-platform/tests/editing/run/first-letter-crossing-engine-boundary-crash.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="http://crbug.com/962090"> +<style> + #container::first-letter { background:blue; } +</style> +<div id="container"> + <div id="edit" style="overflow:hidden;" contenteditable>xx</div> + <div id="elm" style="display:none;">PASS</div> +</div> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> + document.body.offsetTop; + elm.style.display = "initial"; + test(()=>{}, "No crash or DCHECK failure"); +</script> diff --git a/testing/web-platform/tests/editing/run/fontname.html b/testing/web-platform/tests/editing/run/fontname.html new file mode 100644 index 0000000000..b9bb3b19f8 --- /dev/null +++ b/testing/web-platform/tests/editing/run/fontname.html @@ -0,0 +1,46 @@ +<!doctype html> +<meta charset=utf-8> +<meta name="timeout" content="long"> +<meta name="variant" content="?1-1000"> +<meta name="variant" content="?1001-2000"> +<meta name="variant" content="?2001-last"> +<link rel=stylesheet href=../include/reset.css> +<title>fontname - HTML editing conformance tests</title> + +<div id=log></div> + +<div id=test-container></div> + +<script src=../include/implementation.js></script> +<script>var testsJsLibraryOnly = true</script> +<script src=../include/tests.js></script> +<script src=../data/fontname.js></script> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/common/subset-tests.js"></script> +<script> +"use strict"; + +(function() { + // Make document.body.innerHTML more tidy by removing unnecessary things. + [].forEach.call(document.querySelectorAll("script"), function(node) { + node.parentNode.removeChild(node); + }); + + if (true) { + // Silly hack: the CSS styling flag should be true, not false, to match + // expected results. This is because every group of tests except the + // last (multitest) sets styleWithCSS automatically, and it sets it + // first to false and then to true. Thus it's left at true at the end + // of each group of tests, so in gentest.html it will be true when + // starting each group of tests other than the first. But browsers are + // supposed to default it to false when the page loads, so flip it. + try { document.execCommand("styleWithCSS", false, "true") } catch(e) {} + } + + browserTests.forEach(runConformanceTest); + + document.getElementById("test-container").parentNode + .removeChild(document.getElementById("test-container")); +})(); +</script> diff --git a/testing/web-platform/tests/editing/run/fontsize.html b/testing/web-platform/tests/editing/run/fontsize.html new file mode 100644 index 0000000000..830a347346 --- /dev/null +++ b/testing/web-platform/tests/editing/run/fontsize.html @@ -0,0 +1,46 @@ +<!doctype html> +<meta charset=utf-8> +<meta name="timeout" content="long"> +<meta name="variant" content="?1-1000"> +<meta name="variant" content="?1001-2000"> +<meta name="variant" content="?2001-last"> +<link rel=stylesheet href=../include/reset.css> +<title>fontsize - HTML editing conformance tests</title> + +<div id=log></div> + +<div id=test-container></div> + +<script src=../include/implementation.js></script> +<script>var testsJsLibraryOnly = true</script> +<script src=../include/tests.js></script> +<script src=../data/fontsize.js></script> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/common/subset-tests.js"></script> +<script> +"use strict"; + +(function() { + // Make document.body.innerHTML more tidy by removing unnecessary things. + [].forEach.call(document.querySelectorAll("script"), function(node) { + node.parentNode.removeChild(node); + }); + + if (true) { + // Silly hack: the CSS styling flag should be true, not false, to match + // expected results. This is because every group of tests except the + // last (multitest) sets styleWithCSS automatically, and it sets it + // first to false and then to true. Thus it's left at true at the end + // of each group of tests, so in gentest.html it will be true when + // starting each group of tests other than the first. But browsers are + // supposed to default it to false when the page loads, so flip it. + try { document.execCommand("styleWithCSS", false, "true") } catch(e) {} + } + + browserTests.forEach(runConformanceTest); + + document.getElementById("test-container").parentNode + .removeChild(document.getElementById("test-container")); +})(); +</script> diff --git a/testing/web-platform/tests/editing/run/forecolor.html b/testing/web-platform/tests/editing/run/forecolor.html new file mode 100644 index 0000000000..2ab5736b42 --- /dev/null +++ b/testing/web-platform/tests/editing/run/forecolor.html @@ -0,0 +1,46 @@ +<!doctype html> +<meta charset=utf-8> +<meta name="timeout" content="long"> +<meta name="variant" content="?1-1000"> +<meta name="variant" content="?1001-2000"> +<meta name="variant" content="?2001-last"> +<link rel=stylesheet href=../include/reset.css> +<title>forecolor - HTML editing conformance tests</title> + +<div id=log></div> + +<div id=test-container></div> + +<script src=../include/implementation.js></script> +<script>var testsJsLibraryOnly = true</script> +<script src=../include/tests.js></script> +<script src=../data/forecolor.js></script> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/common/subset-tests.js"></script> +<script> +"use strict"; + +(function() { + // Make document.body.innerHTML more tidy by removing unnecessary things. + [].forEach.call(document.querySelectorAll("script"), function(node) { + node.parentNode.removeChild(node); + }); + + if (true) { + // Silly hack: the CSS styling flag should be true, not false, to match + // expected results. This is because every group of tests except the + // last (multitest) sets styleWithCSS automatically, and it sets it + // first to false and then to true. Thus it's left at true at the end + // of each group of tests, so in gentest.html it will be true when + // starting each group of tests other than the first. But browsers are + // supposed to default it to false when the page loads, so flip it. + try { document.execCommand("styleWithCSS", false, "true") } catch(e) {} + } + + browserTests.forEach(runConformanceTest); + + document.getElementById("test-container").parentNode + .removeChild(document.getElementById("test-container")); +})(); +</script> diff --git a/testing/web-platform/tests/editing/run/formatblock.html b/testing/web-platform/tests/editing/run/formatblock.html new file mode 100644 index 0000000000..03b5a65127 --- /dev/null +++ b/testing/web-platform/tests/editing/run/formatblock.html @@ -0,0 +1,49 @@ +<!doctype html> +<meta charset=utf-8> +<meta name="timeout" content="long"> +<meta name="variant" content="?1-1000"> +<meta name="variant" content="?1001-2000"> +<meta name="variant" content="?2001-3000"> +<meta name="variant" content="?3001-4000"> +<meta name="variant" content="?4001-5000"> +<meta name="variant" content="?5001-last"> +<link rel=stylesheet href=../include/reset.css> +<title>formatblock - HTML editing conformance tests</title> + +<div id=log></div> + +<div id=test-container></div> + +<script src=../include/implementation.js></script> +<script>var testsJsLibraryOnly = true</script> +<script src=../include/tests.js></script> +<script src=../data/formatblock.js></script> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/common/subset-tests.js"></script> +<script> +"use strict"; + +(function() { + // Make document.body.innerHTML more tidy by removing unnecessary things. + [].forEach.call(document.querySelectorAll("script"), function(node) { + node.parentNode.removeChild(node); + }); + + if (true) { + // Silly hack: the CSS styling flag should be true, not false, to match + // expected results. This is because every group of tests except the + // last (multitest) sets styleWithCSS automatically, and it sets it + // first to false and then to true. Thus it's left at true at the end + // of each group of tests, so in gentest.html it will be true when + // starting each group of tests other than the first. But browsers are + // supposed to default it to false when the page loads, so flip it. + try { document.execCommand("styleWithCSS", false, "true") } catch(e) {} + } + + browserTests.forEach(runConformanceTest); + + document.getElementById("test-container").parentNode + .removeChild(document.getElementById("test-container")); +})(); +</script> diff --git a/testing/web-platform/tests/editing/run/forwarddelete.html b/testing/web-platform/tests/editing/run/forwarddelete.html new file mode 100644 index 0000000000..177cee7c1f --- /dev/null +++ b/testing/web-platform/tests/editing/run/forwarddelete.html @@ -0,0 +1,51 @@ +<!doctype html> +<meta charset=utf-8> +<meta name="timeout" content="long"> +<meta name="variant" content="?1-1000"> +<meta name="variant" content="?1001-2000"> +<meta name="variant" content="?2001-3000"> +<meta name="variant" content="?3001-4000"> +<meta name="variant" content="?4001-5000"> +<meta name="variant" content="?5001-6000"> +<meta name="variant" content="?6001-7000"> +<meta name="variant" content="?7001-last"> +<link rel=stylesheet href=../include/reset.css> +<title>forwarddelete - HTML editing conformance tests</title> + +<div id=log></div> + +<div id=test-container></div> + +<script src=../include/implementation.js></script> +<script>var testsJsLibraryOnly = true</script> +<script src=../include/tests.js></script> +<script src=../data/forwarddelete.js></script> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/common/subset-tests.js"></script> +<script> +"use strict"; + +(function() { + // Make document.body.innerHTML more tidy by removing unnecessary things. + [].forEach.call(document.querySelectorAll("script"), function(node) { + node.parentNode.removeChild(node); + }); + + if (true) { + // Silly hack: the CSS styling flag should be true, not false, to match + // expected results. This is because every group of tests except the + // last (multitest) sets styleWithCSS automatically, and it sets it + // first to false and then to true. Thus it's left at true at the end + // of each group of tests, so in gentest.html it will be true when + // starting each group of tests other than the first. But browsers are + // supposed to default it to false when the page loads, so flip it. + try { document.execCommand("styleWithCSS", false, "true") } catch(e) {} + } + + browserTests.forEach(runConformanceTest); + + document.getElementById("test-container").parentNode + .removeChild(document.getElementById("test-container")); +})(); +</script> diff --git a/testing/web-platform/tests/editing/run/hilitecolor.html b/testing/web-platform/tests/editing/run/hilitecolor.html new file mode 100644 index 0000000000..1d123b1c10 --- /dev/null +++ b/testing/web-platform/tests/editing/run/hilitecolor.html @@ -0,0 +1,44 @@ +<!doctype html> +<meta charset=utf-8> +<meta name="timeout" content="long"> +<link rel=stylesheet href=../include/reset.css> +<title>hilitecolor - HTML editing conformance tests</title> + +<div id=log></div> + +<div id=test-container></div> + +<script src=../include/implementation.js></script> +<script>var testsJsLibraryOnly = true</script> +<script src=../include/tests.js></script> +<script src=../data/hilitecolor.js></script> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/common/subset-tests.js"></script> +<script> +"use strict"; + +(function() { + // Make document.body.innerHTML more tidy by removing unnecessary things. + [].forEach.call(document.querySelectorAll("script"), function(node) { + node.parentNode.removeChild(node); + }); + + if (true) { + // Silly hack: the CSS styling flag should be true, not false, to match + // expected results. This is because every group of tests except the + // last (multitest) sets styleWithCSS automatically, and it sets it + // first to false and then to true. Thus it's left at true at the end + // of each group of tests, so in gentest.html it will be true when + // starting each group of tests other than the first. But browsers are + // supposed to default it to false when the page loads, so flip it. + try { document.execCommand("styleWithCSS", false, "true") } catch(e) {} + } + + browserTests.forEach(runConformanceTest); + + document.getElementById("test-container").parentNode + .removeChild(document.getElementById("test-container")); + +})(); +</script> diff --git a/testing/web-platform/tests/editing/run/indent.html b/testing/web-platform/tests/editing/run/indent.html new file mode 100644 index 0000000000..a4f2de86c1 --- /dev/null +++ b/testing/web-platform/tests/editing/run/indent.html @@ -0,0 +1,43 @@ +<!doctype html> +<meta charset=utf-8> +<meta name="timeout" content="long"> +<link rel=stylesheet href=../include/reset.css> +<title>indent - HTML editing conformance tests</title> + +<div id=log></div> + +<div id=test-container></div> + +<script src=../include/implementation.js></script> +<script>var testsJsLibraryOnly = true</script> +<script src=../include/tests.js></script> +<script src=../data/indent.js></script> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/common/subset-tests.js"></script> +<script> +"use strict"; + +(function() { + // Make document.body.innerHTML more tidy by removing unnecessary things. + [].forEach.call(document.querySelectorAll("script"), function(node) { + node.parentNode.removeChild(node); + }); + + if (true) { + // Silly hack: the CSS styling flag should be true, not false, to match + // expected results. This is because every group of tests except the + // last (multitest) sets styleWithCSS automatically, and it sets it + // first to false and then to true. Thus it's left at true at the end + // of each group of tests, so in gentest.html it will be true when + // starting each group of tests other than the first. But browsers are + // supposed to default it to false when the page loads, so flip it. + try { document.execCommand("styleWithCSS", false, "true") } catch(e) {} + } + + browserTests.forEach(runConformanceTest); + + document.getElementById("test-container").parentNode + .removeChild(document.getElementById("test-container")); +})(); +</script> diff --git a/testing/web-platform/tests/editing/run/insert-list-items-in-table-cell.html b/testing/web-platform/tests/editing/run/insert-list-items-in-table-cell.html new file mode 100644 index 0000000000..2d176b567b --- /dev/null +++ b/testing/web-platform/tests/editing/run/insert-list-items-in-table-cell.html @@ -0,0 +1,43 @@ +<!doctype html> +<meta charset=utf-8> +<meta name="timeout" content="long"> +<link rel=stylesheet href=../include/reset.css> +<title>Insert list items in table cells - HTML editing conformance tests</title> + +<div id=log></div> + +<div id=test-container></div> + +<script src=../include/implementation.js></script> +<script>var testsJsLibraryOnly = true</script> +<script src=../include/tests.js></script> +<script src=../data/insert-list-items-in-table-cells.js></script> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/common/subset-tests.js"></script> +<script> +"use strict"; + +(function() { + // Make document.body.innerHTML more tidy by removing unnecessary things. + [].forEach.call(document.querySelectorAll("script"), function(node) { + node.parentNode.removeChild(node); + }); + + if (true) { + // Silly hack: the CSS styling flag should be true, not false, to match + // expected results. This is because every group of tests except the + // last (multitest) sets styleWithCSS automatically, and it sets it + // first to false and then to true. Thus it's left at true at the end + // of each group of tests, so in gentest.html it will be true when + // starting each group of tests other than the first. But browsers are + // supposed to default it to false when the page loads, so flip it. + try { document.execCommand("styleWithCSS", false, "true") } catch(e) {} + } + + browserTests.forEach(runConformanceTest); + + document.getElementById("test-container").parentNode + .removeChild(document.getElementById("test-container")); +})(); +</script> diff --git a/testing/web-platform/tests/editing/run/inserthorizontalrule.html b/testing/web-platform/tests/editing/run/inserthorizontalrule.html new file mode 100644 index 0000000000..7c570fbcfd --- /dev/null +++ b/testing/web-platform/tests/editing/run/inserthorizontalrule.html @@ -0,0 +1,43 @@ +<!doctype html> +<meta charset=utf-8> +<meta name="timeout" content="long"> +<link rel=stylesheet href=../include/reset.css> +<title>inserthorizontalrule - HTML editing conformance tests</title> + +<div id=log></div> + +<div id=test-container></div> + +<script src=../include/implementation.js></script> +<script>var testsJsLibraryOnly = true</script> +<script src=../include/tests.js></script> +<script src=../data/inserthorizontalrule.js></script> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/common/subset-tests.js"></script> +<script> +"use strict"; + +(function() { + // Make document.body.innerHTML more tidy by removing unnecessary things. + [].forEach.call(document.querySelectorAll("script"), function(node) { + node.parentNode.removeChild(node); + }); + + if (true) { + // Silly hack: the CSS styling flag should be true, not false, to match + // expected results. This is because every group of tests except the + // last (multitest) sets styleWithCSS automatically, and it sets it + // first to false and then to true. Thus it's left at true at the end + // of each group of tests, so in gentest.html it will be true when + // starting each group of tests other than the first. But browsers are + // supposed to default it to false when the page loads, so flip it. + try { document.execCommand("styleWithCSS", false, "true") } catch(e) {} + } + + browserTests.forEach(runConformanceTest); + + document.getElementById("test-container").parentNode + .removeChild(document.getElementById("test-container")); +})(); +</script> diff --git a/testing/web-platform/tests/editing/run/inserthtml.html b/testing/web-platform/tests/editing/run/inserthtml.html new file mode 100644 index 0000000000..f27df67b72 --- /dev/null +++ b/testing/web-platform/tests/editing/run/inserthtml.html @@ -0,0 +1,43 @@ +<!doctype html> +<meta charset=utf-8> +<meta name="timeout" content="long"> +<link rel=stylesheet href=../include/reset.css> +<title>inserthtml - HTML editing conformance tests</title> + +<div id=log></div> + +<div id=test-container></div> + +<script src=../include/implementation.js></script> +<script>var testsJsLibraryOnly = true</script> +<script src=../include/tests.js></script> +<script src=../data/inserthtml.js></script> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/common/subset-tests.js"></script> +<script> +"use strict"; + +(function() { + // Make document.body.innerHTML more tidy by removing unnecessary things. + [].forEach.call(document.querySelectorAll("script"), function(node) { + node.parentNode.removeChild(node); + }); + + if (true) { + // Silly hack: the CSS styling flag should be true, not false, to match + // expected results. This is because every group of tests except the + // last (multitest) sets styleWithCSS automatically, and it sets it + // first to false and then to true. Thus it's left at true at the end + // of each group of tests, so in gentest.html it will be true when + // starting each group of tests other than the first. But browsers are + // supposed to default it to false when the page loads, so flip it. + try { document.execCommand("styleWithCSS", false, "true") } catch(e) {} + } + + browserTests.forEach(runConformanceTest); + + document.getElementById("test-container").parentNode + .removeChild(document.getElementById("test-container")); +})(); +</script> diff --git a/testing/web-platform/tests/editing/run/insertimage.html b/testing/web-platform/tests/editing/run/insertimage.html new file mode 100644 index 0000000000..9987b98b7d --- /dev/null +++ b/testing/web-platform/tests/editing/run/insertimage.html @@ -0,0 +1,43 @@ +<!doctype html> +<meta charset=utf-8> +<meta name="timeout" content="long"> +<link rel=stylesheet href=../include/reset.css> +<title>insertimage - HTML editing conformance tests</title> + +<div id=log></div> + +<div id=test-container></div> + +<script src=../include/implementation.js></script> +<script>var testsJsLibraryOnly = true</script> +<script src=../include/tests.js></script> +<script src=../data/insertimage.js></script> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/common/subset-tests.js"></script> +<script> +"use strict"; + +(function() { + // Make document.body.innerHTML more tidy by removing unnecessary things. + [].forEach.call(document.querySelectorAll("script"), function(node) { + node.parentNode.removeChild(node); + }); + + if (true) { + // Silly hack: the CSS styling flag should be true, not false, to match + // expected results. This is because every group of tests except the + // last (multitest) sets styleWithCSS automatically, and it sets it + // first to false and then to true. Thus it's left at true at the end + // of each group of tests, so in gentest.html it will be true when + // starting each group of tests other than the first. But browsers are + // supposed to default it to false when the page loads, so flip it. + try { document.execCommand("styleWithCSS", false, "true") } catch(e) {} + } + + browserTests.forEach(runConformanceTest); + + document.getElementById("test-container").parentNode + .removeChild(document.getElementById("test-container")); +})(); +</script> diff --git a/testing/web-platform/tests/editing/run/insertlinebreak.html b/testing/web-platform/tests/editing/run/insertlinebreak.html new file mode 100644 index 0000000000..4ca86b8b5f --- /dev/null +++ b/testing/web-platform/tests/editing/run/insertlinebreak.html @@ -0,0 +1,43 @@ +<!doctype html> +<meta charset=utf-8> +<meta name="timeout" content="long"> +<link rel=stylesheet href=../include/reset.css> +<title>insertlinebreak - HTML editing conformance tests</title> + +<div id=log></div> + +<div id=test-container></div> + +<script src=../include/implementation.js></script> +<script>var testsJsLibraryOnly = true</script> +<script src=../include/tests.js></script> +<script src=../data/insertlinebreak.js></script> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/common/subset-tests.js"></script> +<script> +"use strict"; + +(function() { + // Make document.body.innerHTML more tidy by removing unnecessary things. + [].forEach.call(document.querySelectorAll("script"), function(node) { + node.parentNode.removeChild(node); + }); + + if (true) { + // Silly hack: the CSS styling flag should be true, not false, to match + // expected results. This is because every group of tests except the + // last (multitest) sets styleWithCSS automatically, and it sets it + // first to false and then to true. Thus it's left at true at the end + // of each group of tests, so in gentest.html it will be true when + // starting each group of tests other than the first. But browsers are + // supposed to default it to false when the page loads, so flip it. + try { document.execCommand("styleWithCSS", false, "true") } catch(e) {} + } + + browserTests.forEach(runConformanceTest); + + document.getElementById("test-container").parentNode + .removeChild(document.getElementById("test-container")); +})(); +</script> diff --git a/testing/web-platform/tests/editing/run/insertorderedlist.html b/testing/web-platform/tests/editing/run/insertorderedlist.html new file mode 100644 index 0000000000..5c477f642f --- /dev/null +++ b/testing/web-platform/tests/editing/run/insertorderedlist.html @@ -0,0 +1,45 @@ +<!doctype html> +<meta charset=utf-8> +<meta name="timeout" content="long"> +<meta name="variant" content="?1-1000"> +<meta name="variant" content="?1001-last"> +<link rel=stylesheet href=../include/reset.css> +<title>insertorderedlist - HTML editing conformance tests</title> + +<div id=log></div> + +<div id=test-container></div> + +<script src=../include/implementation.js></script> +<script>var testsJsLibraryOnly = true</script> +<script src=../include/tests.js></script> +<script src=../data/insertorderedlist.js></script> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/common/subset-tests.js"></script> +<script> +"use strict"; + +(function() { + // Make document.body.innerHTML more tidy by removing unnecessary things. + [].forEach.call(document.querySelectorAll("script"), function(node) { + node.parentNode.removeChild(node); + }); + + if (true) { + // Silly hack: the CSS styling flag should be true, not false, to match + // expected results. This is because every group of tests except the + // last (multitest) sets styleWithCSS automatically, and it sets it + // first to false and then to true. Thus it's left at true at the end + // of each group of tests, so in gentest.html it will be true when + // starting each group of tests other than the first. But browsers are + // supposed to default it to false when the page loads, so flip it. + try { document.execCommand("styleWithCSS", false, "true") } catch(e) {} + } + + browserTests.forEach(runConformanceTest); + + document.getElementById("test-container").parentNode + .removeChild(document.getElementById("test-container")); +})(); +</script> diff --git a/testing/web-platform/tests/editing/run/insertparagraph.html b/testing/web-platform/tests/editing/run/insertparagraph.html new file mode 100644 index 0000000000..ef67bcfe8b --- /dev/null +++ b/testing/web-platform/tests/editing/run/insertparagraph.html @@ -0,0 +1,51 @@ +<!doctype html> +<meta charset=utf-8> +<meta name="timeout" content="long"> +<meta name="variant" content="?1-1000"> +<meta name="variant" content="?1001-2000"> +<meta name="variant" content="?2001-3000"> +<meta name="variant" content="?3001-4000"> +<meta name="variant" content="?4001-5000"> +<meta name="variant" content="?5001-6000"> +<meta name="variant" content="?6001-7000"> +<meta name="variant" content="?7001-last"> +<link rel=stylesheet href=../include/reset.css> +<title>insertparagraph - HTML editing conformance tests</title> + +<div id=log></div> + +<div id=test-container></div> + +<script src=../include/implementation.js></script> +<script>var testsJsLibraryOnly = true</script> +<script src=../include/tests.js></script> +<script src=../data/insertparagraph.js></script> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/common/subset-tests.js"></script> +<script> +"use strict"; + +(function() { + // Make document.body.innerHTML more tidy by removing unnecessary things. + [].forEach.call(document.querySelectorAll("script"), function(node) { + node.parentNode.removeChild(node); + }); + + if (true) { + // Silly hack: the CSS styling flag should be true, not false, to match + // expected results. This is because every group of tests except the + // last (multitest) sets styleWithCSS automatically, and it sets it + // first to false and then to true. Thus it's left at true at the end + // of each group of tests, so in gentest.html it will be true when + // starting each group of tests other than the first. But browsers are + // supposed to default it to false when the page loads, so flip it. + try { document.execCommand("styleWithCSS", false, "true") } catch(e) {} + } + + browserTests.forEach(runConformanceTest); + + document.getElementById("test-container").parentNode + .removeChild(document.getElementById("test-container")); +})(); +</script> diff --git a/testing/web-platform/tests/editing/run/inserttext.html b/testing/web-platform/tests/editing/run/inserttext.html new file mode 100644 index 0000000000..d0e9d7d625 --- /dev/null +++ b/testing/web-platform/tests/editing/run/inserttext.html @@ -0,0 +1,46 @@ +<!doctype html> +<meta charset=utf-8> +<meta name="timeout" content="long"> +<meta name="variant" content="?1-1000"> +<meta name="variant" content="?1001-2000"> +<meta name="variant" content="?2001-last"> +<link rel=stylesheet href=../include/reset.css> +<title>inserttext - HTML editing conformance tests</title> + +<div id=log></div> + +<div id=test-container></div> + +<script src=../include/implementation.js></script> +<script>var testsJsLibraryOnly = true</script> +<script src=../include/tests.js></script> +<script src=../data/inserttext.js></script> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/common/subset-tests.js"></script> +<script> +"use strict"; + +(function() { + // Make document.body.innerHTML more tidy by removing unnecessary things. + [].forEach.call(document.querySelectorAll("script"), function(node) { + node.parentNode.removeChild(node); + }); + + if (true) { + // Silly hack: the CSS styling flag should be true, not false, to match + // expected results. This is because every group of tests except the + // last (multitest) sets styleWithCSS automatically, and it sets it + // first to false and then to true. Thus it's left at true at the end + // of each group of tests, so in gentest.html it will be true when + // starting each group of tests other than the first. But browsers are + // supposed to default it to false when the page loads, so flip it. + try { document.execCommand("styleWithCSS", false, "true") } catch(e) {} + } + + browserTests.forEach(runConformanceTest); + + document.getElementById("test-container").parentNode + .removeChild(document.getElementById("test-container")); +})(); +</script> diff --git a/testing/web-platform/tests/editing/run/insertunorderedlist.html b/testing/web-platform/tests/editing/run/insertunorderedlist.html new file mode 100644 index 0000000000..1d6e774e0d --- /dev/null +++ b/testing/web-platform/tests/editing/run/insertunorderedlist.html @@ -0,0 +1,46 @@ +<!doctype html> +<meta charset=utf-8> +<meta name="timeout" content="long"> +<meta name="variant" content="?1-1000"> +<meta name="variant" content="?1001-2000"> +<meta name="variant" content="?2001-last"> +<link rel=stylesheet href=../include/reset.css> +<title>insertunorderedlist - HTML editing conformance tests</title> + +<div id=log></div> + +<div id=test-container></div> + +<script src=../include/implementation.js></script> +<script>var testsJsLibraryOnly = true</script> +<script src=../include/tests.js></script> +<script src=../data/insertunorderedlist.js></script> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/common/subset-tests.js"></script> +<script> +"use strict"; + +(function() { + // Make document.body.innerHTML more tidy by removing unnecessary things. + [].forEach.call(document.querySelectorAll("script"), function(node) { + node.parentNode.removeChild(node); + }); + + if (true) { + // Silly hack: the CSS styling flag should be true, not false, to match + // expected results. This is because every group of tests except the + // last (multitest) sets styleWithCSS automatically, and it sets it + // first to false and then to true. Thus it's left at true at the end + // of each group of tests, so in gentest.html it will be true when + // starting each group of tests other than the first. But browsers are + // supposed to default it to false when the page loads, so flip it. + try { document.execCommand("styleWithCSS", false, "true") } catch(e) {} + } + + browserTests.forEach(runConformanceTest); + + document.getElementById("test-container").parentNode + .removeChild(document.getElementById("test-container")); +})(); +</script> diff --git a/testing/web-platform/tests/editing/run/italic.html b/testing/web-platform/tests/editing/run/italic.html new file mode 100644 index 0000000000..d31ecf1c16 --- /dev/null +++ b/testing/web-platform/tests/editing/run/italic.html @@ -0,0 +1,46 @@ +<!doctype html> +<meta charset=utf-8> +<meta name="timeout" content="long"> +<meta name="variant" content="?1-1000"> +<meta name="variant" content="?1001-2000"> +<meta name="variant" content="?2001-last"> +<link rel=stylesheet href=../include/reset.css> +<title>italic - HTML editing conformance tests</title> + +<div id=log></div> + +<div id=test-container></div> + +<script src=../include/implementation.js></script> +<script>var testsJsLibraryOnly = true</script> +<script src=../include/tests.js></script> +<script src=../data/italic.js></script> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/common/subset-tests.js"></script> +<script> +"use strict"; + +(function() { + // Make document.body.innerHTML more tidy by removing unnecessary things. + [].forEach.call(document.querySelectorAll("script"), function(node) { + node.parentNode.removeChild(node); + }); + + if (true) { + // Silly hack: the CSS styling flag should be true, not false, to match + // expected results. This is because every group of tests except the + // last (multitest) sets styleWithCSS automatically, and it sets it + // first to false and then to true. Thus it's left at true at the end + // of each group of tests, so in gentest.html it will be true when + // starting each group of tests other than the first. But browsers are + // supposed to default it to false when the page loads, so flip it. + try { document.execCommand("styleWithCSS", false, "true") } catch(e) {} + } + + browserTests.forEach(runConformanceTest); + + document.getElementById("test-container").parentNode + .removeChild(document.getElementById("test-container")); +})(); +</script> diff --git a/testing/web-platform/tests/editing/run/justifycenter.html b/testing/web-platform/tests/editing/run/justifycenter.html new file mode 100644 index 0000000000..63f2d56255 --- /dev/null +++ b/testing/web-platform/tests/editing/run/justifycenter.html @@ -0,0 +1,50 @@ +<!doctype html> +<meta charset=utf-8> +<meta name="timeout" content="long"> +<meta name="variant" content="?1-1000"> +<meta name="variant" content="?1001-2000"> +<meta name="variant" content="?2001-3000"> +<meta name="variant" content="?3001-4000"> +<meta name="variant" content="?4001-5000"> +<meta name="variant" content="?5001-6000"> +<meta name="variant" content="?6001-last"> +<link rel=stylesheet href=../include/reset.css> +<title>justifycenter - HTML editing conformance tests</title> + +<div id=log></div> + +<div id=test-container></div> + +<script src=../include/implementation.js></script> +<script>var testsJsLibraryOnly = true</script> +<script src=../include/tests.js></script> +<script src=../data/justifycenter.js></script> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/common/subset-tests.js"></script> +<script> +"use strict"; + +(function() { + // Make document.body.innerHTML more tidy by removing unnecessary things. + [].forEach.call(document.querySelectorAll("script"), function(node) { + node.parentNode.removeChild(node); + }); + + if (true) { + // Silly hack: the CSS styling flag should be true, not false, to match + // expected results. This is because every group of tests except the + // last (multitest) sets styleWithCSS automatically, and it sets it + // first to false and then to true. Thus it's left at true at the end + // of each group of tests, so in gentest.html it will be true when + // starting each group of tests other than the first. But browsers are + // supposed to default it to false when the page loads, so flip it. + try { document.execCommand("styleWithCSS", false, "true") } catch(e) {} + } + + browserTests.forEach(runConformanceTest); + + document.getElementById("test-container").parentNode + .removeChild(document.getElementById("test-container")); +})(); +</script> diff --git a/testing/web-platform/tests/editing/run/justifyfull.html b/testing/web-platform/tests/editing/run/justifyfull.html new file mode 100644 index 0000000000..202beea885 --- /dev/null +++ b/testing/web-platform/tests/editing/run/justifyfull.html @@ -0,0 +1,48 @@ +<!doctype html> +<meta charset=utf-8> +<meta name="timeout" content="long"> +<meta name="variant" content="?1-1000"> +<meta name="variant" content="?1001-2000"> +<meta name="variant" content="?2001-3000"> +<meta name="variant" content="?3001-4000"> +<meta name="variant" content="?4001-last"> +<link rel=stylesheet href=../include/reset.css> +<title>justifyfull - HTML editing conformance tests</title> + +<div id=log></div> + +<div id=test-container></div> + +<script src=../include/implementation.js></script> +<script>var testsJsLibraryOnly = true</script> +<script src=../include/tests.js></script> +<script src=../data/justifyfull.js></script> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/common/subset-tests.js"></script> +<script> +"use strict"; + +(function() { + // Make document.body.innerHTML more tidy by removing unnecessary things. + [].forEach.call(document.querySelectorAll("script"), function(node) { + node.parentNode.removeChild(node); + }); + + if (true) { + // Silly hack: the CSS styling flag should be true, not false, to match + // expected results. This is because every group of tests except the + // last (multitest) sets styleWithCSS automatically, and it sets it + // first to false and then to true. Thus it's left at true at the end + // of each group of tests, so in gentest.html it will be true when + // starting each group of tests other than the first. But browsers are + // supposed to default it to false when the page loads, so flip it. + try { document.execCommand("styleWithCSS", false, "true") } catch(e) {} + } + + browserTests.forEach(runConformanceTest); + + document.getElementById("test-container").parentNode + .removeChild(document.getElementById("test-container")); +})(); +</script> diff --git a/testing/web-platform/tests/editing/run/justifyleft.html b/testing/web-platform/tests/editing/run/justifyleft.html new file mode 100644 index 0000000000..31772248ca --- /dev/null +++ b/testing/web-platform/tests/editing/run/justifyleft.html @@ -0,0 +1,46 @@ +<!doctype html> +<meta charset=utf-8> +<meta name="timeout" content="long"> +<meta name="variant" content="?1-1000"> +<meta name="variant" content="?1001-2000"> +<meta name="variant" content="?2001-last"> +<link rel=stylesheet href=../include/reset.css> +<title>justifyleft - HTML editing conformance tests</title> + +<div id=log></div> + +<div id=test-container></div> + +<script src=../include/implementation.js></script> +<script>var testsJsLibraryOnly = true</script> +<script src=../include/tests.js></script> +<script src=../data/justifyleft.js></script> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/common/subset-tests.js"></script> +<script> +"use strict"; + +(function() { + // Make document.body.innerHTML more tidy by removing unnecessary things. + [].forEach.call(document.querySelectorAll("script"), function(node) { + node.parentNode.removeChild(node); + }); + + if (true) { + // Silly hack: the CSS styling flag should be true, not false, to match + // expected results. This is because every group of tests except the + // last (multitest) sets styleWithCSS automatically, and it sets it + // first to false and then to true. Thus it's left at true at the end + // of each group of tests, so in gentest.html it will be true when + // starting each group of tests other than the first. But browsers are + // supposed to default it to false when the page loads, so flip it. + try { document.execCommand("styleWithCSS", false, "true") } catch(e) {} + } + + browserTests.forEach(runConformanceTest); + + document.getElementById("test-container").parentNode + .removeChild(document.getElementById("test-container")); +})(); +</script> diff --git a/testing/web-platform/tests/editing/run/justifyright.html b/testing/web-platform/tests/editing/run/justifyright.html new file mode 100644 index 0000000000..a8b5bcf5ea --- /dev/null +++ b/testing/web-platform/tests/editing/run/justifyright.html @@ -0,0 +1,48 @@ +<!doctype html> +<meta charset=utf-8> +<meta name="timeout" content="long"> +<meta name="variant" content="?1-1000"> +<meta name="variant" content="?1001-2000"> +<meta name="variant" content="?2001-3000"> +<meta name="variant" content="?3001-4000"> +<meta name="variant" content="?4001-last"> +<link rel=stylesheet href=../include/reset.css> +<title>justifyright - HTML editing conformance tests</title> + +<div id=log></div> + +<div id=test-container></div> + +<script src=../include/implementation.js></script> +<script>var testsJsLibraryOnly = true</script> +<script src=../include/tests.js></script> +<script src=../data/justifyright.js></script> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/common/subset-tests.js"></script> +<script> +"use strict"; + +(function() { + // Make document.body.innerHTML more tidy by removing unnecessary things. + [].forEach.call(document.querySelectorAll("script"), function(node) { + node.parentNode.removeChild(node); + }); + + if (true) { + // Silly hack: the CSS styling flag should be true, not false, to match + // expected results. This is because every group of tests except the + // last (multitest) sets styleWithCSS automatically, and it sets it + // first to false and then to true. Thus it's left at true at the end + // of each group of tests, so in gentest.html it will be true when + // starting each group of tests other than the first. But browsers are + // supposed to default it to false when the page loads, so flip it. + try { document.execCommand("styleWithCSS", false, "true") } catch(e) {} + } + + browserTests.forEach(runConformanceTest); + + document.getElementById("test-container").parentNode + .removeChild(document.getElementById("test-container")); +})(); +</script> diff --git a/testing/web-platform/tests/editing/run/misc.html b/testing/web-platform/tests/editing/run/misc.html new file mode 100644 index 0000000000..2bb754277a --- /dev/null +++ b/testing/web-platform/tests/editing/run/misc.html @@ -0,0 +1,43 @@ +<!doctype html> +<meta charset=utf-8> +<meta name="timeout" content="long"> +<link rel=stylesheet href=../include/reset.css> +<title>misc - HTML editing conformance tests</title> + +<div id=log></div> + +<div id=test-container></div> + +<script src=../include/implementation.js></script> +<script>var testsJsLibraryOnly = true</script> +<script src=../include/tests.js></script> +<script src=../data/misc.js></script> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/common/subset-tests.js"></script> +<script> +"use strict"; + +(function() { + // Make document.body.innerHTML more tidy by removing unnecessary things. + [].forEach.call(document.querySelectorAll("script"), function(node) { + node.parentNode.removeChild(node); + }); + + if (true) { + // Silly hack: the CSS styling flag should be true, not false, to match + // expected results. This is because every group of tests except the + // last (multitest) sets styleWithCSS automatically, and it sets it + // first to false and then to true. Thus it's left at true at the end + // of each group of tests, so in gentest.html it will be true when + // starting each group of tests other than the first. But browsers are + // supposed to default it to false when the page loads, so flip it. + try { document.execCommand("styleWithCSS", false, "true") } catch(e) {} + } + + browserTests.forEach(runConformanceTest); + + document.getElementById("test-container").parentNode + .removeChild(document.getElementById("test-container")); +})(); +</script> diff --git a/testing/web-platform/tests/editing/run/multitest.html b/testing/web-platform/tests/editing/run/multitest.html new file mode 100644 index 0000000000..4213488d77 --- /dev/null +++ b/testing/web-platform/tests/editing/run/multitest.html @@ -0,0 +1,53 @@ +<!doctype html> +<meta charset=utf-8> +<meta name="variant" content="?1-1000"> +<meta name="variant" content="?1001-2000"> +<meta name="variant" content="?2001-3000"> +<meta name="variant" content="?3001-4000"> +<meta name="variant" content="?4001-5000"> +<meta name="variant" content="?5001-6000"> +<meta name="variant" content="?6001-7000"> +<meta name="variant" content="?7001-8000"> +<meta name="variant" content="?8001-9000"> +<meta name="variant" content="?9001-last"> +<link rel=stylesheet href=../include/reset.css> +<meta name="timeout" content="long"> +<title>multitest - HTML editing conformance tests</title> + +<div id=log></div> + +<div id=test-container></div> + +<script src=../include/implementation.js></script> +<script>var testsJsLibraryOnly = true</script> +<script src=../include/tests.js></script> +<script src=../data/multitest.js></script> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/common/subset-tests.js"></script> +<script> +"use strict"; + +(function() { + // Make document.body.innerHTML more tidy by removing unnecessary things. + [].forEach.call(document.querySelectorAll("script"), function(node) { + node.parentNode.removeChild(node); + }); + + if (true) { + // Silly hack: the CSS styling flag should be true, not false, to match + // expected results. This is because every group of tests except the + // last (multitest) sets styleWithCSS automatically, and it sets it + // first to false and then to true. Thus it's left at true at the end + // of each group of tests, so in gentest.html it will be true when + // starting each group of tests other than the first. But browsers are + // supposed to default it to false when the page loads, so flip it. + try { document.execCommand("styleWithCSS", false, "true") } catch(e) {} + } + + browserTests.forEach(runConformanceTest); + + document.getElementById("test-container").parentNode + .removeChild(document.getElementById("test-container")); +})(); +</script> diff --git a/testing/web-platform/tests/editing/run/outdent.html b/testing/web-platform/tests/editing/run/outdent.html new file mode 100644 index 0000000000..04240d9f0f --- /dev/null +++ b/testing/web-platform/tests/editing/run/outdent.html @@ -0,0 +1,46 @@ +<!doctype html> +<meta charset=utf-8> +<meta name="timeout" content="long"> +<meta name="variant" content="?1-1000"> +<meta name="variant" content="?1001-2000"> +<meta name="variant" content="?2001-last"> +<link rel=stylesheet href=../include/reset.css> +<title>outdent - HTML editing conformance tests</title> + +<div id=log></div> + +<div id=test-container></div> + +<script src=../include/implementation.js></script> +<script>var testsJsLibraryOnly = true</script> +<script src=../include/tests.js></script> +<script src=../data/outdent.js></script> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/common/subset-tests.js"></script> +<script> +"use strict"; + +(function() { + // Make document.body.innerHTML more tidy by removing unnecessary things. + [].forEach.call(document.querySelectorAll("script"), function(node) { + node.parentNode.removeChild(node); + }); + + if (true) { + // Silly hack: the CSS styling flag should be true, not false, to match + // expected results. This is because every group of tests except the + // last (multitest) sets styleWithCSS automatically, and it sets it + // first to false and then to true. Thus it's left at true at the end + // of each group of tests, so in gentest.html it will be true when + // starting each group of tests other than the first. But browsers are + // supposed to default it to false when the page loads, so flip it. + try { document.execCommand("styleWithCSS", false, "true") } catch(e) {} + } + + browserTests.forEach(runConformanceTest); + + document.getElementById("test-container").parentNode + .removeChild(document.getElementById("test-container")); +})(); +</script> diff --git a/testing/web-platform/tests/editing/run/removeformat.html b/testing/web-platform/tests/editing/run/removeformat.html new file mode 100644 index 0000000000..3cc695278e --- /dev/null +++ b/testing/web-platform/tests/editing/run/removeformat.html @@ -0,0 +1,43 @@ +<!doctype html> +<meta charset=utf-8> +<meta name="timeout" content="long"> +<link rel=stylesheet href=../include/reset.css> +<title>removeformat - HTML editing conformance tests</title> + +<div id=log></div> + +<div id=test-container></div> + +<script src=../include/implementation.js></script> +<script>var testsJsLibraryOnly = true</script> +<script src=../include/tests.js></script> +<script src=../data/removeformat.js></script> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/common/subset-tests.js"></script> +<script> +"use strict"; + +(function() { + // Make document.body.innerHTML more tidy by removing unnecessary things. + [].forEach.call(document.querySelectorAll("script"), function(node) { + node.parentNode.removeChild(node); + }); + + if (true) { + // Silly hack: the CSS styling flag should be true, not false, to match + // expected results. This is because every group of tests except the + // last (multitest) sets styleWithCSS automatically, and it sets it + // first to false and then to true. Thus it's left at true at the end + // of each group of tests, so in gentest.html it will be true when + // starting each group of tests other than the first. But browsers are + // supposed to default it to false when the page loads, so flip it. + try { document.execCommand("styleWithCSS", false, "true") } catch(e) {} + } + + browserTests.forEach(runConformanceTest); + + document.getElementById("test-container").parentNode + .removeChild(document.getElementById("test-container")); +})(); +</script> diff --git a/testing/web-platform/tests/editing/run/strikethrough.html b/testing/web-platform/tests/editing/run/strikethrough.html new file mode 100644 index 0000000000..d731d3eb89 --- /dev/null +++ b/testing/web-platform/tests/editing/run/strikethrough.html @@ -0,0 +1,46 @@ +<!doctype html> +<meta charset=utf-8> +<meta name="timeout" content="long"> +<meta name="variant" content="?1-1000"> +<meta name="variant" content="?1001-2000"> +<meta name="variant" content="?2001-last"> +<link rel=stylesheet href=../include/reset.css> +<title>strikethrough - HTML editing conformance tests</title> + +<div id=log></div> + +<div id=test-container></div> + +<script src=../include/implementation.js></script> +<script>var testsJsLibraryOnly = true</script> +<script src=../include/tests.js></script> +<script src=../data/strikethrough.js></script> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/common/subset-tests.js"></script> +<script> +"use strict"; + +(function() { + // Make document.body.innerHTML more tidy by removing unnecessary things. + [].forEach.call(document.querySelectorAll("script"), function(node) { + node.parentNode.removeChild(node); + }); + + if (true) { + // Silly hack: the CSS styling flag should be true, not false, to match + // expected results. This is because every group of tests except the + // last (multitest) sets styleWithCSS automatically, and it sets it + // first to false and then to true. Thus it's left at true at the end + // of each group of tests, so in gentest.html it will be true when + // starting each group of tests other than the first. But browsers are + // supposed to default it to false when the page loads, so flip it. + try { document.execCommand("styleWithCSS", false, "true") } catch(e) {} + } + + browserTests.forEach(runConformanceTest); + + document.getElementById("test-container").parentNode + .removeChild(document.getElementById("test-container")); +})(); +</script> diff --git a/testing/web-platform/tests/editing/run/subscript.html b/testing/web-platform/tests/editing/run/subscript.html new file mode 100644 index 0000000000..24fb79932f --- /dev/null +++ b/testing/web-platform/tests/editing/run/subscript.html @@ -0,0 +1,43 @@ +<!doctype html> +<meta charset=utf-8> +<meta name="timeout" content="long"> +<link rel=stylesheet href=../include/reset.css> +<title>subscript - HTML editing conformance tests</title> + +<div id=log></div> + +<div id=test-container></div> + +<script src=../include/implementation.js></script> +<script>var testsJsLibraryOnly = true</script> +<script src=../include/tests.js></script> +<script src=../data/subscript.js></script> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/common/subset-tests.js"></script> +<script> +"use strict"; + +(function() { + // Make document.body.innerHTML more tidy by removing unnecessary things. + [].forEach.call(document.querySelectorAll("script"), function(node) { + node.parentNode.removeChild(node); + }); + + if (true) { + // Silly hack: the CSS styling flag should be true, not false, to match + // expected results. This is because every group of tests except the + // last (multitest) sets styleWithCSS automatically, and it sets it + // first to false and then to true. Thus it's left at true at the end + // of each group of tests, so in gentest.html it will be true when + // starting each group of tests other than the first. But browsers are + // supposed to default it to false when the page loads, so flip it. + try { document.execCommand("styleWithCSS", false, "true") } catch(e) {} + } + + browserTests.forEach(runConformanceTest); + + document.getElementById("test-container").parentNode + .removeChild(document.getElementById("test-container")); +})(); +</script> diff --git a/testing/web-platform/tests/editing/run/superscript.html b/testing/web-platform/tests/editing/run/superscript.html new file mode 100644 index 0000000000..de28a9c536 --- /dev/null +++ b/testing/web-platform/tests/editing/run/superscript.html @@ -0,0 +1,43 @@ +<!doctype html> +<meta charset=utf-8> +<meta name="timeout" content="long"> +<link rel=stylesheet href=../include/reset.css> +<title>superscript - HTML editing conformance tests</title> + +<div id=log></div> + +<div id=test-container></div> + +<script src=../include/implementation.js></script> +<script>var testsJsLibraryOnly = true</script> +<script src=../include/tests.js></script> +<script src=../data/superscript.js></script> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/common/subset-tests.js"></script> +<script> +"use strict"; + +(function() { + // Make document.body.innerHTML more tidy by removing unnecessary things. + [].forEach.call(document.querySelectorAll("script"), function(node) { + node.parentNode.removeChild(node); + }); + + if (true) { + // Silly hack: the CSS styling flag should be true, not false, to match + // expected results. This is because every group of tests except the + // last (multitest) sets styleWithCSS automatically, and it sets it + // first to false and then to true. Thus it's left at true at the end + // of each group of tests, so in gentest.html it will be true when + // starting each group of tests other than the first. But browsers are + // supposed to default it to false when the page loads, so flip it. + try { document.execCommand("styleWithCSS", false, "true") } catch(e) {} + } + + browserTests.forEach(runConformanceTest); + + document.getElementById("test-container").parentNode + .removeChild(document.getElementById("test-container")); +})(); +</script> diff --git a/testing/web-platform/tests/editing/run/underline.html b/testing/web-platform/tests/editing/run/underline.html new file mode 100644 index 0000000000..880b3e2032 --- /dev/null +++ b/testing/web-platform/tests/editing/run/underline.html @@ -0,0 +1,46 @@ +<!doctype html> +<meta charset=utf-8> +<meta name="timeout" content="long"> +<meta name="variant" content="?1-1000"> +<meta name="variant" content="?1001-2000"> +<meta name="variant" content="?2001-last"> +<link rel=stylesheet href=../include/reset.css> +<title>underline - HTML editing conformance tests</title> + +<div id=log></div> + +<div id=test-container></div> + +<script src=../include/implementation.js></script> +<script>var testsJsLibraryOnly = true</script> +<script src=../include/tests.js></script> +<script src=../data/underline.js></script> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/common/subset-tests.js"></script> +<script> +"use strict"; + +(function() { + // Make document.body.innerHTML more tidy by removing unnecessary things. + [].forEach.call(document.querySelectorAll("script"), function(node) { + node.parentNode.removeChild(node); + }); + + if (true) { + // Silly hack: the CSS styling flag should be true, not false, to match + // expected results. This is because every group of tests except the + // last (multitest) sets styleWithCSS automatically, and it sets it + // first to false and then to true. Thus it's left at true at the end + // of each group of tests, so in gentest.html it will be true when + // starting each group of tests other than the first. But browsers are + // supposed to default it to false when the page loads, so flip it. + try { document.execCommand("styleWithCSS", false, "true") } catch(e) {} + } + + browserTests.forEach(runConformanceTest); + + document.getElementById("test-container").parentNode + .removeChild(document.getElementById("test-container")); +})(); +</script> diff --git a/testing/web-platform/tests/editing/run/undo-redo-after-mutation.html b/testing/web-platform/tests/editing/run/undo-redo-after-mutation.html new file mode 100644 index 0000000000..8d583a161f --- /dev/null +++ b/testing/web-platform/tests/editing/run/undo-redo-after-mutation.html @@ -0,0 +1,119 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div contenteditable></div> +<script> +"use strict"; +let editor = document.querySelector("div[contenteditable]"); +let selection = document.getSelection(); + +test(function () { + editor.innerHTML = "<i>will be removed</i> abc"; + selection.collapse(editor.lastChild, editor.lastChild.length); + document.execCommand("insertLineBreak", false, ""); + assert_equals(editor.innerHTML, "<i>will be removed</i> abc<br><br>", + "<br> element should be inserted by execCommand(\"insertLineBreak\")"); + document.execCommand("undo", false, ""); + assert_equals(editor.innerHTML, "<i>will be removed</i> abc", + "<br> element should be removed by execCommand(\"undo\")"); + editor.firstChild.remove(); + document.execCommand("redo", false, ""); + assert_equals(editor.innerHTML, " abc<br><br>", + "<br> element should be inserted by execCommand(\"redo\")"); +}, "Redo for execCommand(\"insertLineBreak\") after removing prior sibling with DOM API after undoing"); + +test(function () { + editor.innerHTML = "abc"; + selection.collapse(editor.firstChild, editor.firstChild.length); + document.execCommand("insertLineBreak", false, ""); + assert_equals(editor.innerHTML, "abc<br><br>", + "<br> element should be inserted by execCommand(\"insertLineBreak\")"); + document.execCommand("undo", false, ""); + assert_equals(editor.innerHTML, "abc", + "<br> element should be removed by execCommand(\"undo\")"); + let i = document.createElement("i"); + i.textContent = " appended text"; + editor.appendChild(i); + document.execCommand("redo", false, ""); + assert_equals(editor.innerHTML, "abc<i> appended text</i><br><br>", + "<br> element should be appended by execCommand(\"redo\") after the appended text"); +}, "Redo for execCommand(\"insertLineBreak\") after appending new child with DOM API after undoing"); + +test(function () { + editor.innerHTML = "abc"; + selection.collapse(editor.firstChild, editor.firstChild.length); + document.execCommand("insertLineBreak", false, ""); + assert_equals(editor.innerHTML, "abc<br><br>", + "<br> element should be inserted by execCommand(\"insertLineBreak\")"); + document.execCommand("undo", false, ""); + assert_equals(editor.innerHTML, "abc", + "<br> element should be removed by execCommand(\"undo\")"); + let i = document.createElement("i"); + i.textContent = "inserted text "; + editor.insertBefore(i, editor.firstChild); + document.execCommand("redo", false, ""); + assert_equals(editor.innerHTML, "<i>inserted text </i>abc<br><br>", + "<br> element should be appended by execCommand(\"redo\") after the appended text"); +}, "Redo for execCommand(\"insertLineBreak\") after inserting new child with DOM API after undoing"); + +test(function () { + editor.innerHTML = "<b>will be removed</b><i>abc</i>"; + selection.collapse(editor.querySelector("b").firstChild, editor.querySelector("b").firstChild.length); + document.execCommand("insertLineBreak", false, ""); + assert_equals(editor.innerHTML, "<b>will be removed<br></b><i>abc</i>", + "<br> element should be inserted into the <b> element by execCommand(\"insertLineBreak\")"); + document.execCommand("undo", false, ""); + assert_equals(editor.innerHTML, "<b>will be removed</b><i>abc</i>", + "<br> element should be removed by execCommand(\"undo\")"); + editor.querySelector("b").remove(); + document.execCommand("redo", false, ""); + assert_equals(editor.innerHTML, "<i>abc</i>", + "<br> element shouldn't be restored by execCommand(\"redo\") after removing the <b> element"); +}, "Redo for execCommand(\"insertLineBreak\") after removing its container with DOM API after undoing"); + +test(function () { + editor.innerHTML = "<b>abc</b><i>will be removed</i>"; + selection.collapse(editor.querySelector("b").firstChild, editor.querySelector("b").firstChild.length); + document.execCommand("insertLineBreak", false, ""); + assert_equals(editor.innerHTML, "<b>abc<br></b><i>will be removed</i>", + "<br> element should be inserted into the <b> element by execCommand(\"insertLineBreak\")"); + document.execCommand("undo", false, ""); + assert_equals(editor.innerHTML, "<b>abc</b><i>will be removed</i>", + "<br> element should be removed by execCommand(\"undo\")"); + editor.querySelector("i").remove(); + document.execCommand("redo", false, ""); + assert_equals(editor.innerHTML, "<b>abc<br></b>", + "<br> element should be restored by execCommand(\"redo\") after removing the following <i> element"); +}, "Redo for execCommand(\"insertLineBreak\") after removing <i> element following the container with DOM API after undoing"); + +// Not sure whether redoing in both of the following 2 cases should work as so. +test(function () { + editor.innerHTML = "<b>will be removed</b><i>abc</i>"; + selection.collapse(editor, 1); + document.execCommand("insertLineBreak", false, ""); + assert_equals(editor.innerHTML, "<b>will be removed</b><br><i>abc</i>", + "<br> element should be inserted between the <b> and <i> elements by execCommand(\"insertLineBreak\")"); + document.execCommand("undo", false, ""); + assert_equals(editor.innerHTML, "<b>will be removed</b><i>abc</i>", + "<br> element should be removed by execCommand(\"undo\")"); + editor.querySelector("b").remove(); + document.execCommand("redo", false, ""); + assert_equals(editor.innerHTML, "<br><i>abc</i>", + "<br> element should be restored by execCommand(\"redo\") after removing the preceding <b> element"); +}, "Redo for execCommand(\"insertLineBreak\") between <b> and <i> after removing preceding <b> element with DOM API after undoing"); + +test(function () { + editor.innerHTML = "<b>abc</b><i>will be removed</i>"; + selection.collapse(editor, 1); + document.execCommand("insertLineBreak", false, ""); + assert_equals(editor.innerHTML, "<b>abc</b><br><i>will be removed</i>", + "<br> element should be inserted between the <b> and <i> elements by execCommand(\"insertLineBreak\")"); + document.execCommand("undo", false, ""); + assert_equals(editor.innerHTML, "<b>abc</b><i>will be removed</i>", + "<br> element should be removed by execCommand(\"undo\")"); + editor.querySelector("i").remove(); + document.execCommand("redo", false, ""); + assert_equals(editor.innerHTML, "<b>abc</b><br>", + "<br> element should be restored by execCommand(\"redo\") after removing the following <i> element"); +}, "Redo for execCommand(\"insertLineBreak\") between <b> and <i> after after removing following <i> element with DOM API after undoing"); +</script> diff --git a/testing/web-platform/tests/editing/run/undo-redo.html b/testing/web-platform/tests/editing/run/undo-redo.html new file mode 100644 index 0000000000..391349eeef --- /dev/null +++ b/testing/web-platform/tests/editing/run/undo-redo.html @@ -0,0 +1,229 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script src="../include/editor-test-utils.js"></script> +<iframe srcdoc=""></iframe> +<script> +"use strict"; +const iframe = document.querySelector("iframe"); + +promise_test(async () => { + await new Promise(resolve => { + addEventListener("load", resolve, {once: true}); + }); +}, "Waiting for load..."); + +/** + * This test does NOT test whether the edit result is valid or invalid. + * This test just tests whether "undo" and "redo" restores previous state + * and additional "undo" and "redo" does not run unexpectedly. + * + * description: Set string to explain what's testing. + * editorInnerHTML: Set initial innerHTML value of editor. + * init: Set a function object if you need to test complicated cases, e.g., + * testing with empty text node. + * run: Set a function object which run something modifying the editor (or + * does nothing). + * expectedUndoResult: Set an expected innerHTML result as string or array + * of the string. If this is not specified, it's compared + * with editorInnerHTML value. + * cleanUp: Set a function object if you need to clean something up after the + * test. + */ + +const tests = [ + { + description: "insertParagraph at start of a paragraph", + editorInnerHTML: "<p>[]abcdef</p>", + run: (win, doc, editingHost) => { + doc.execCommand("insertParagraph"); + }, + }, + { + description: "insertParagraph at middle of a paragraph", + editorInnerHTML: "<p>abc[]def</p>", + run: (win, doc, editingHost) => { + doc.execCommand("insertParagraph"); + }, + }, + { + description: "insertParagraph at end of a paragraph", + editorInnerHTML: "<p>abcdef[]</p>", + run: (win, doc, editingHost) => { + doc.execCommand("insertParagraph"); + }, + }, + { + description: "insertParagraph at start of a listitem", + editorInnerHTML: "<ul><li>[]abcdef</li></ul>", + run: (win, doc, editingHost) => { + doc.execCommand("insertParagraph"); + }, + }, + { + description: "insertParagraph at middle of a listitem", + editorInnerHTML: "<ul><li>abc[]def</li></ul>", + run: (win, doc, editingHost) => { + doc.execCommand("insertParagraph"); + }, + }, + { + description: "insertParagraph at end of a listitem", + editorInnerHTML: "<ul><li>abcdef[]</li></ul>", + run: (win, doc, editingHost) => { + doc.execCommand("insertParagraph"); + }, + }, + { + description: "insertLineBreak at start of a paragraph", + editorInnerHTML: "<p>[]abcdef</p>", + run: (win, doc, editingHost) => { + doc.execCommand("insertLineBreak"); + }, + }, + { + description: "insertLineBreak at middle of a paragraph", + editorInnerHTML: "<p>abc[]def</p>", + run: (win, doc, editingHost) => { + doc.execCommand("insertLineBreak"); + }, + }, + { + description: "insertLineBreak at end of a paragraph", + editorInnerHTML: "<p>abcdef[]</p>", + run: (win, doc, editingHost) => { + doc.execCommand("insertLineBreak"); + }, + }, + { + description: "insertLineBreak at start of a listitem", + editorInnerHTML: "<ul><li>[]abcdef</li></ul>", + run: (win, doc, editingHost) => { + doc.execCommand("insertLineBreak"); + }, + }, + { + description: "insertLineBreak at middle of a listitem", + editorInnerHTML: "<ul><li>abc[]def</li></ul>", + run: (win, doc, editingHost) => { + doc.execCommand("insertLineBreak"); + }, + }, + { + description: "insertLineBreak at end of a listitem", + editorInnerHTML: "<ul><li>abcdef[]</li></ul>", + run: (win, doc, editingHost) => { + doc.execCommand("insertLineBreak"); + }, + }, + { + description: "delete at start of second paragraph", + editorInnerHTML: "<p>abc</p><p>[]def</p>", + run: (win, doc, editingHost) => { + doc.execCommand("delete"); + } + }, + { + description: "forwarddelete at end of first paragraph", + editorInnerHTML: "<p>abc[]</p><p>def</p>", + run: (win, doc, editingHost) => { + doc.execCommand("forwarddelete"); + } + }, + { + description: "delete at start of second paragraph starting with an emoji", + editorInnerHTML: "<p>abc\uD83D\uDC49</p><p>[]\uD83D\uDC48def</p>", + run: (win, doc, editingHost) => { + doc.execCommand("delete"); + } + }, + { + description: "forwarddelete at end of first paragraph ending with an emoji", + editorInnerHTML: "<p>abc\uD83D\uDC49[]</p><p>\uD83D\uDC48def</p>", + run: (win, doc, editingHost) => { + doc.execCommand("forwarddelete"); + } + }, +]; + +for (const curTest of tests) { + promise_test(async t => { + await new Promise(resolve => { + iframe.addEventListener("load", resolve, {once: true}); + iframe.srcdoc = "<html><body><div contenteditable></div></body></html>"; + }); + const contentDocument = iframe.contentDocument; + const contentWindow = iframe.contentWindow; + contentWindow.focus(); + const editingHost = contentDocument.querySelector("div[contenteditable]"); + const utils = new EditorTestUtils(editingHost, window); + utils.setupEditingHost(curTest.editorInnerHTML); + contentDocument.documentElement.scrollHeight; // flush pending things + if (typeof curTest.init == "function") { + await curTest.init(contentWindow, contentDocument, editingHost); + } + const initialValue = editingHost.innerHTML; + await curTest.run(contentWindow, contentDocument, editingHost); + const newValue = editingHost.innerHTML; + test(t2 => { + const ret = contentDocument.execCommand("undo"); + if (curTest.expectedUndoResult !== undefined) { + if (typeof curTest.expectedUndoResult == "string") { + assert_equals( + editingHost.innerHTML, + curTest.expectedUndoResult, + `${t2.name}: should restore the innerHTML value` + ); + } else { + assert_in_array( + editingHost.innerHTML, + curTest.expectedUndoResult, + `${t2.name}: should restore one of the innerHTML values` + ); + } + } else { + assert_equals( + editingHost.innerHTML, + initialValue, + `${t2.name}: should restore the initial innerHTML value` + ); + } + assert_true(ret, `${t2.name}: execCommand("undo") should return true`); + }, `${t.name} - first undo`); + test(t3 => { + const ret = contentDocument.execCommand("redo"); + assert_equals( + editingHost.innerHTML, + newValue, + `${t3.name}: should restore the modified innerHTML value` + ); + assert_true(ret, `${t3.name}: execCommand("redo") should return true`); + }, `${curTest.description} - first redo`); + test(t4 => { + const ret = contentDocument.execCommand("redo"); + assert_equals( + editingHost.innerHTML, + newValue, + `${t4.name}: should not modify the modified innerHTML value` + ); + assert_false(ret, `${t4.name}: execCommand("redo") should return false`); + }, `${curTest.description} - second redo`); + if (typeof curTest.cleanUp == "function") { + await curTest.cleanUp(contentWindow, contentDocument, editingHost); + } + await new Promise(resolve => { + iframe.addEventListener("load", resolve, {once: true}); + iframe.srcdoc = ""; + }); + contentDocument.documentElement.scrollHeight; // flush pending things + await new Promise(resolve => + requestAnimationFrame( + () => requestAnimationFrame(resolve) + ) + ); + }, curTest.description); +} +</script> diff --git a/testing/web-platform/tests/editing/run/unlink.html b/testing/web-platform/tests/editing/run/unlink.html new file mode 100644 index 0000000000..331792f924 --- /dev/null +++ b/testing/web-platform/tests/editing/run/unlink.html @@ -0,0 +1,48 @@ +<!doctype html> +<meta charset=utf-8> +<meta name="timeout" content="long"> +<link rel=stylesheet href=../include/reset.css> +<title>unlink - HTML editing conformance tests</title> +<style> +.bold { + font-weight: bold; +} +</style> + +<div id=log></div> + +<div id=test-container></div> + +<script src=../include/implementation.js></script> +<script>var testsJsLibraryOnly = true</script> +<script src=../include/tests.js></script> +<script src=../data/unlink.js></script> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/common/subset-tests.js"></script> +<script> +"use strict"; + +(function() { + // Make document.body.innerHTML more tidy by removing unnecessary things. + [].forEach.call(document.querySelectorAll("script"), function(node) { + node.parentNode.removeChild(node); + }); + + if (true) { + // Silly hack: the CSS styling flag should be true, not false, to match + // expected results. This is because every group of tests except the + // last (multitest) sets styleWithCSS automatically, and it sets it + // first to false and then to true. Thus it's left at true at the end + // of each group of tests, so in gentest.html it will be true when + // starting each group of tests other than the first. But browsers are + // supposed to default it to false when the page loads, so flip it. + try { document.execCommand("styleWithCSS", false, "true") } catch(e) {} + } + + browserTests.forEach(runConformanceTest); + + document.getElementById("test-container").parentNode + .removeChild(document.getElementById("test-container")); +})(); +</script> |