| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 'use strict'; | 5 'use strict'; |
| 6 | 6 |
| 7 // This file provides | 7 // This file provides |
| 8 // |spellcheck_test(sample, tester, expectedText, opt_title)| asynchronous test | 8 // |spellcheck_test(sample, tester, expectedText, opt_title)| asynchronous test |
| 9 // to W3C test harness for easier writing of spellchecker test cases. | 9 // to W3C test harness for easier writing of spellchecker test cases. |
| 10 // | 10 // |
| (...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 // something in JavaScript (e.g., a |Promise|), so that we can actively | 315 // something in JavaScript (e.g., a |Promise|), so that we can actively |
| 316 // know the completion of spellchecking instead of passively waiting for | 316 // know the completion of spellchecking instead of passively waiting for |
| 317 // markers to appear or disappear. | 317 // markers to appear or disappear. |
| 318 testObject.step_timeout( | 318 testObject.step_timeout( |
| 319 () => verifyMarkers(testObject, sample, expectedText, | 319 () => verifyMarkers(testObject, sample, expectedText, |
| 320 remainingRetry - 1, retryInterval), | 320 remainingRetry - 1, retryInterval), |
| 321 retryInterval); | 321 retryInterval); |
| 322 } | 322 } |
| 323 } | 323 } |
| 324 | 324 |
| 325 function focusNearestAncestorOfAnchor(selection) { |
| 326 for (var anchor = selection.anchorNode; anchor; anchor = anchor.parentNode) { |
| 327 if (anchor.nodeType != Node.ELEMENT_NODE) |
| 328 continue; |
| 329 anchor.focus(); |
| 330 if (anchor.ownerDocument.activeElement == anchor) |
| 331 return; |
| 332 } |
| 333 } |
| 334 |
| 325 // Spellchecker gets triggered not only by text and selection change, but also | 335 // Spellchecker gets triggered not only by text and selection change, but also |
| 326 // by focus change. For example, misspelling markers in <INPUT> disappear when | 336 // by focus change. For example, misspelling markers in <INPUT> disappear when |
| 327 // the window loses focus, even though the selection does not change. | 337 // the window loses focus, even though the selection does not change. |
| 328 // Therefore, we disallow spellcheck tests from running simultaneously to | 338 // Therefore, we disallow spellcheck tests from running simultaneously to |
| 329 // prevent interference among them. If we call spellcheck_test while another | 339 // prevent interference among them. If we call spellcheck_test while another |
| 330 // test is running, the new test will be added into testQueue waiting for the | 340 // test is running, the new test will be added into testQueue waiting for the |
| 331 // completion of the previous test. | 341 // completion of the previous test. |
| 332 | 342 |
| 333 /** @type {boolean} */ | 343 /** @type {boolean} */ |
| 334 var spellcheckTestRunning = false; | 344 var spellcheckTestRunning = false; |
| 335 /** @type {!Array<!Object>} */ | 345 /** @type {!Array<!Object>} */ |
| 336 const testQueue = []; | 346 const testQueue = []; |
| 337 | 347 |
| 338 /** | 348 /** |
| 339 * @param {!Test} testObject | 349 * @param {!Test} testObject |
| 340 * @param {!Sample|string} input | 350 * @param {!Sample|string} input |
| 341 * @param {function(!Document)|string} tester | 351 * @param {function(!Document)|string} tester |
| 342 * @param {string} expectedText | 352 * @param {string} expectedText |
| 343 */ | 353 */ |
| 344 function invokeSpellcheckTest(testObject, input, tester, expectedText) { | 354 function invokeSpellcheckTest(testObject, input, tester, expectedText) { |
| 345 spellcheckTestRunning = true; | 355 spellcheckTestRunning = true; |
| 346 | 356 |
| 347 testObject.step(() => { | 357 testObject.step(() => { |
| 348 // TODO(xiaochengh): Merge the following part with |assert_selection|. | 358 // TODO(xiaochengh): Merge the following part with |assert_selection|. |
| 349 /** @type {!Sample} */ | 359 /** @type {!Sample} */ |
| 350 const sample = typeof(input) === 'string' ? new Sample(input) : input; | 360 const sample = typeof(input) === 'string' ? new Sample(input) : input; |
| 351 testObject.sample = sample; | 361 testObject.sample = sample; |
| 362 focusNearestAncestorOfAnchor(sample.selection); |
| 352 | 363 |
| 353 if (typeof(tester) === 'function') { | 364 if (typeof(tester) === 'function') { |
| 354 tester.call(window, sample.document); | 365 tester.call(window, sample.document); |
| 355 } else if (typeof(tester) === 'string') { | 366 } else if (typeof(tester) === 'string') { |
| 356 const strings = tester.split(/ (.+)/); | 367 const strings = tester.split(/ (.+)/); |
| 357 sample.document.execCommand(strings[0], false, strings[1]); | 368 sample.document.execCommand(strings[0], false, strings[1]); |
| 358 } else { | 369 } else { |
| 359 assert_unreached(`Invalid tester: ${tester}`); | 370 assert_unreached(`Invalid tester: ${tester}`); |
| 360 } | 371 } |
| 361 | 372 |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 446 tester: tester, expectedText: expectedText}); | 457 tester: tester, expectedText: expectedText}); |
| 447 return; | 458 return; |
| 448 } | 459 } |
| 449 | 460 |
| 450 invokeSpellcheckTest(testObject, input, tester, expectedText); | 461 invokeSpellcheckTest(testObject, input, tester, expectedText); |
| 451 } | 462 } |
| 452 | 463 |
| 453 // Export symbols | 464 // Export symbols |
| 454 window.spellcheck_test = spellcheckTest; | 465 window.spellcheck_test = spellcheckTest; |
| 455 })(); | 466 })(); |
| OLD | NEW |