| Index: third_party/WebKit/LayoutTests/editing/spelling/spellcheck-async-mutation.html
|
| diff --git a/third_party/WebKit/LayoutTests/editing/spelling/spellcheck-async-mutation.html b/third_party/WebKit/LayoutTests/editing/spelling/spellcheck-async-mutation.html
|
| index 14617808e612e3cefa645cb2a396e06d51df5534..8dddf6631947b56cfa9e20c1817a43f91784832c 100644
|
| --- a/third_party/WebKit/LayoutTests/editing/spelling/spellcheck-async-mutation.html
|
| +++ b/third_party/WebKit/LayoutTests/editing/spelling/spellcheck-async-mutation.html
|
| @@ -1,212 +1,116 @@
|
| <!DOCTYPE html>
|
| -<html>
|
| -<head>
|
| -<script src="../../resources/js-test.js"></script>
|
| -<script src="../editing.js"></script>
|
| -<script src="resources/util.js"></script>
|
| -<style>
|
| -.editing {
|
| - border: 2px solid red;
|
| - padding: 6px;
|
| - font-size: 18px;
|
| -}
|
| -</style>
|
| -</head>
|
| -<body>
|
| -<pre id="description"></pre>
|
| -<pre id="console"></pre>
|
| -
|
| -<div id="source">zz zz zz</textarea>
|
| -
|
| -<div id="container"></div>
|
| -
|
| -<div id="move-target"></div>
|
| -
|
| +<script src="../../resources/testharness.js"></script>
|
| +<script src="../../resources/testharnessreport.js"></script>
|
| +<script src="../assert_selection.js"></script>
|
| +<script src="spellcheck_test.js"></script>
|
| <script>
|
| -description(
|
| - "Test for asynchronous spellchecking in case DOM mutation happens. " +
|
| - "This test checks crash won't happen if DOM mutations happened."
|
| -);
|
| -
|
| -var jsTestIsAsync = true;
|
| -if (window.testRunner)
|
| - testRunner.setMockSpellCheckerEnabled(true);
|
| -
|
| -var sourceIds = ['source'];
|
| -var destElems = ['textarea', 'input', 'contenteditable'];
|
| -var tweaks = ['delete', 'move', 'mutate'];
|
| -
|
| -var testData = [];
|
| -for (var i = 0; i < sourceIds.length; ++i) {
|
| - for (var j = 0; j < destElems.length; ++j) {
|
| - for (var k = 0; k < tweaks.length; ++k) {
|
| - testData.push({
|
| - sourceId: sourceIds[i],
|
| - destElem: destElems[j],
|
| - tweak: tweaks[k]
|
| - });
|
| - }
|
| - }
|
| -}
|
| -
|
| -var sel = window.getSelection();
|
| -
|
| -function removeAllChildren(elem) {
|
| - while (elem.firstChild)
|
| - elem.removeChild(elem.firstChild);
|
| -}
|
| -
|
| -var testNo = 0;
|
| -function doTestIfAny() {
|
| - // Clean up first.
|
| - removeAllChildren(document.getElementById('container'));
|
| - removeAllChildren(document.getElementById('move-target'));
|
| -
|
| - var next = testData.shift();
|
| - if (next)
|
| - return window.setTimeout(function(){ doTest(++testNo, next); }, 0);
|
| -
|
| - // No more tests. Tear down.
|
| - removeAllChildren(document.getElementById('container'));
|
| - removeAllChildren(document.getElementById('move-target'));
|
| -
|
| - if (window.testRunner)
|
| - finishJSTest();
|
| -}
|
| -
|
| -var requestId;
|
| -var lastRequestId;
|
| -function doTest(testNo, testData) {
|
| - function createElement(kind) {
|
| - if (kind == 'textarea' || kind == 'input')
|
| - return document.createElement(kind);
|
| -
|
| - var div = document.createElement('div');
|
| - div.setAttribute('contenteditable', true);
|
| - return div;
|
| - }
|
| -
|
| - debug("");
|
| - debug("Test Start: " + testNo);
|
| -
|
| - var source = document.getElementById(testData.sourceId);
|
| - var destination = createElement(testData.destElem);
|
| - document.getElementById('container').appendChild(destination);
|
| -
|
| - if (window.internals)
|
| - lastRequestId = internals.lastSpellCheckRequestSequence(document);
|
| -
|
| - // A spellcheck request will be invoked.
|
| - doCopyAndPaste(source, destination);
|
| -
|
| - setTimeout(function() {
|
| - if (window.internals)
|
| - requestId = internals.lastSpellCheckRequestSequence(document);
|
| - shouldBeGreaterThanOrEqual('requestId', 'lastRequestId + 1');
|
| -
|
| - // Then, tweak
|
| - tweak(destination, testData.tweak);
|
| -
|
| - waitForSpellCheckRequestDone(requestId, destination, testData.tweak, 10, 1);
|
| - }, 0);
|
| -}
|
| -
|
| -function doCopyAndPaste(source, dest) {
|
| - function focusOn(elem) {
|
| - if (elem instanceof HTMLInputElement || elem instanceof HTMLTextAreaElement)
|
| - elem.focus();
|
| - else
|
| - sel.selectAllChildren(elem);
|
| - }
|
| -
|
| - sel.selectAllChildren(source);
|
| - document.execCommand("Copy");
|
| -
|
| - focusOn(dest);
|
| - document.execCommand("Paste");
|
| -}
|
| -
|
| -function tweak(elem, kind) {
|
| - switch (kind) {
|
| - case 'delete':
|
| - elem.parentNode.removeChild(elem);
|
| - return;
|
| - case 'move':
|
| - var target = document.getElementById('move-target');
|
| - target.appendChild(elem);
|
| - return;
|
| - case 'mutate':
|
| - if (elem instanceof HTMLInputElement || elem instanceof HTMLTextAreaElement)
|
| - elem.value = 'zzz';
|
| - else
|
| - elem.innerHTML = 'zzz';
|
| - return;
|
| - default:
|
| - testFailed('Unknown kind of tweak');
|
| - return;
|
| - }
|
| -}
|
| -
|
| -function waitForSpellCheckRequestDone(requestId, destination, tweakKind, restTry, nsleep) {
|
| - // No more try.
|
| - if (restTry <= 0) {
|
| - testFailed('Failed verification');
|
| - setTimeout(doTestIfAny, 0);
|
| - return;
|
| - }
|
| -
|
| - if (window.internals)
|
| - var lastProcessedId = internals.lastSpellCheckProcessedSequence(document);
|
| -
|
| - if (requestId != lastProcessedId) {
|
| - setTimeout(function() {
|
| - waitForSpellCheckRequestDone(requestId, destination, tweakKind, restTry - 1, nsleep * 2);
|
| - }, nsleep);
|
| - return;
|
| - }
|
| -
|
| - if (verifyExistenceOfMarkers(destination, tweakKind)) {
|
| - testPassed('Request has been processed.');
|
| - } else {
|
| - testFailed('Request has been processed but we detected unexpected marker location.');
|
| - }
|
| -
|
| - setTimeout(doTestIfAny, 0);
|
| -}
|
| -
|
| -function verifyExistenceOfMarkers(elem, tweakKind) {
|
| - if (!window.internals)
|
| - return true;
|
| -
|
| - switch (tweakKind) {
|
| - case 'delete':
|
| - return true;
|
| - case 'move':
|
| - // In move, marker should be there. However since markers are removed when unfocusing
|
| - // an input if it's the input what's moved and it's not focused return true right away.
|
| - if (elem instanceof HTMLInputElement && elem != document.activeElement)
|
| - return true;
|
| - var markerNum = internals.markerCountForNode(findFirstTextNode(elem), "spelling");
|
| - if (markerNum != 3)
|
| - return false;
|
| - for (var i = 0; i < 3; ++i) {
|
| - var range = internals.markerRangeForNode(findFirstTextNode(elem), "spelling", i);
|
| - if (range.toString() != "zz")
|
| - return false;
|
| - }
|
| - return true;
|
| - case 'mutate':
|
| - // In mutation, there aren't markers.
|
| - return internals.markerCountForNode(findFirstTextNode(elem), "spelling") == 0;
|
| - default:
|
| - testFailed('Unknown kind of tweak');
|
| - return true;
|
| - }
|
| -}
|
| -
|
| -doTestIfAny();
|
| -
|
| -var successfullyParsed = true;
|
| +spellcheck_test(
|
| + '<div><textarea id="destination"></textarea></div><div id="move-target"></div>',
|
| + document => {
|
| + document.getSelection().setClipboardData('zz zz zz');
|
| + const destination = document.getElementById('destination');
|
| + destination.focus();
|
| + document.execCommand('paste');
|
| + destination.remove();
|
| + },
|
| + '<div></div><div id="move-target"></div>',
|
| + 'Delete <textarea> with pending spell check request.');
|
| +
|
| +spellcheck_test(
|
| + '<div><textarea id="destination"></textarea></div><div id="move-target"></div>',
|
| + document => {
|
| + document.getSelection().setClipboardData('zz zz zz');
|
| + const destination = document.getElementById('destination');
|
| + destination.focus();
|
| + document.execCommand('paste');
|
| + document.getElementById('move-target').appendChild(destination);
|
| + },
|
| + '<div></div><div id="move-target"><textarea id="destination">#zz# #zz# #zz#</textarea></div>',
|
| + 'Move <textarea> with pending spell check request.');
|
| +
|
| +spellcheck_test(
|
| + '<div><textarea id="destination"></textarea></div><div id="move-target"></div>',
|
| + document => {
|
| + document.getSelection().setClipboardData('zz zz zz');
|
| + const destination = document.getElementById('destination');
|
| + destination.focus();
|
| + document.execCommand('paste');
|
| + destination.value = 'zzz';
|
| + },
|
| + '<div><textarea id="destination">zzz</textarea></div><div id="move-target"></div>',
|
| + 'Mutate content of <textarea> with pending spell check request.');
|
| +
|
| +spellcheck_test(
|
| + '<div><input id="destination"></div><div id="move-target"></div>',
|
| + document => {
|
| + document.getSelection().setClipboardData('zz zz zz');
|
| + const destination = document.getElementById('destination');
|
| + destination.focus();
|
| + document.execCommand('paste');
|
| + destination.remove();
|
| + },
|
| + '<div></div><div id="move-target"></div>',
|
| + 'Delete <input> with pending spell check request.');
|
| +
|
| +spellcheck_test(
|
| + '<div><input id="destination"></div><div id="move-target"></div>',
|
| + document => {
|
| + document.getSelection().setClipboardData('zz zz zz');
|
| + const destination = document.getElementById('destination');
|
| + destination.focus();
|
| + document.execCommand('paste');
|
| + document.getElementById('move-target').appendChild(destination);
|
| + },
|
| + // No marker because focus is lost after moving.
|
| + '<div></div><div id="move-target"><input id="destination" value="zz zz zz"></div>',
|
| + 'Move <input> with pending spell check request.');
|
| +
|
| +spellcheck_test(
|
| + '<div><input id="destination"></div><div id="move-target"></div>',
|
| + document => {
|
| + document.getSelection().setClipboardData('zz zz zz');
|
| + const destination = document.getElementById('destination');
|
| + destination.focus();
|
| + document.execCommand('paste');
|
| + destination.value = 'zzz';
|
| + },
|
| + '<div><input id="destination" value="zzz"></div><div id="move-target"></div>',
|
| + 'Mutate content of <input> with pending spell check request.');
|
| +
|
| +spellcheck_test(
|
| + '<div><div contenteditable id="destination"></div></div><div id="move-target"></div>',
|
| + document => {
|
| + document.getSelection().setClipboardData('zz zz zz');
|
| + const destination = document.getElementById('destination');
|
| + destination.focus();
|
| + document.execCommand('paste');
|
| + destination.remove();
|
| + },
|
| + '<div></div><div id="move-target"></div>',
|
| + 'Delete <div> with pending spell check request.');
|
| +
|
| +spellcheck_test(
|
| + '<div><div contenteditable id="destination"></div></div><div id="move-target"></div>',
|
| + document => {
|
| + document.getSelection().setClipboardData('zz zz zz');
|
| + const destination = document.getElementById('destination');
|
| + destination.focus();
|
| + document.execCommand('paste');
|
| + document.getElementById('move-target').appendChild(destination);
|
| + },
|
| + // No marker because checking range stays in the original <div> after moving.
|
| + '<div></div><div id="move-target"><div contenteditable id="destination">zz zz zz</div></div>',
|
| + 'Move <div> with pending spell check request.');
|
| +
|
| +spellcheck_test(
|
| + '<div><div contenteditable id="destination"></div></div><div id="move-target"></div>',
|
| + document => {
|
| + document.getSelection().setClipboardData('zz zz zz');
|
| + const destination = document.getElementById('destination');
|
| + destination.focus();
|
| + document.execCommand('paste');
|
| + destination.innerHTML = 'zzz';
|
| + },
|
| + '<div><div contenteditable id="destination">zzz</div></div><div id="move-target"></div>',
|
| + 'Mutate content of <div> with pending spell check request.');
|
| </script>
|
| -</body>
|
| -</html>
|
|
|