OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 /** | 5 /** |
6 * @fileoverview Low-level DOM traversal utility functions to find the | 6 * @fileoverview Low-level DOM traversal utility functions to find the |
7 * next (or previous) character, word, sentence, line, or paragraph, | 7 * next (or previous) character, word, sentence, line, or paragraph, |
8 * in a completely stateless manner without actually manipulating the | 8 * in a completely stateless manner without actually manipulating the |
9 * selection. | 9 * selection. |
10 */ | 10 */ |
(...skipping 29 matching lines...) Expand all Loading... |
40 * its children are properties of the object that shouldn't be traversed. | 40 * its children are properties of the object that shouldn't be traversed. |
41 * | 41 * |
42 * TODO(dmazzoni): replace this with a predicate that detects nodes with | 42 * TODO(dmazzoni): replace this with a predicate that detects nodes with |
43 * ARIA roles and other objects that have their own description. | 43 * ARIA roles and other objects that have their own description. |
44 * For now we just detect a couple of common cases. | 44 * For now we just detect a couple of common cases. |
45 * | 45 * |
46 * @param {Node} node A DOM node. | 46 * @param {Node} node A DOM node. |
47 * @return {boolean} True if the node should be treated as a leaf node. | 47 * @return {boolean} True if the node should be treated as a leaf node. |
48 */ | 48 */ |
49 cvox.TraverseUtil.treatAsLeafNode = function(node) { | 49 cvox.TraverseUtil.treatAsLeafNode = function(node) { |
50 return node.childNodes.length == 0 || | 50 return node.childNodes.length == 0 || node.nodeName == 'SELECT' || |
51 node.nodeName == 'SELECT' || | 51 node.getAttribute('role') == 'listbox' || node.nodeName == 'OBJECT'; |
52 node.getAttribute('role') == 'listbox' || | |
53 node.nodeName == 'OBJECT'; | |
54 }; | 52 }; |
55 | 53 |
56 /** | 54 /** |
57 * Return true only if a single character is whitespace. | 55 * Return true only if a single character is whitespace. |
58 * From https://developer.mozilla.org/en/Whitespace_in_the_DOM, | 56 * From https://developer.mozilla.org/en/Whitespace_in_the_DOM, |
59 * whitespace is defined as one of the characters | 57 * whitespace is defined as one of the characters |
60 * "\t" TAB \u0009 | 58 * "\t" TAB \u0009 |
61 * "\n" LF \u000A | 59 * "\n" LF \u000A |
62 * "\r" CR \u000D | 60 * "\r" CR \u000D |
63 * " " SPC \u0020. | 61 * " " SPC \u0020. |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 } | 145 } |
148 | 146 |
149 // Return the next character from this leaf node. | 147 // Return the next character from this leaf node. |
150 if (cursor.index < cursor.text.length) | 148 if (cursor.index < cursor.text.length) |
151 return cursor.text[cursor.index++]; | 149 return cursor.text[cursor.index++]; |
152 | 150 |
153 // Move to the next sibling, going up the tree as necessary. | 151 // Move to the next sibling, going up the tree as necessary. |
154 while (cursor.node != null) { | 152 while (cursor.node != null) { |
155 // Try to move to the next sibling. | 153 // Try to move to the next sibling. |
156 var siblingNode = null; | 154 var siblingNode = null; |
157 for (var node = cursor.node.nextSibling; | 155 for (var node = cursor.node.nextSibling; node != null; |
158 node != null; | |
159 node = node.nextSibling) { | 156 node = node.nextSibling) { |
160 if (cvox.TraverseUtil.isHidden(node)) { | 157 if (cvox.TraverseUtil.isHidden(node)) { |
161 if (node instanceof HTMLElement) { | 158 if (node instanceof HTMLElement) { |
162 elementsEntered.push(node); | 159 elementsEntered.push(node); |
163 } | 160 } |
164 continue; | 161 continue; |
165 } | 162 } |
166 if (cvox.DomUtil.isVisible(node, {checkAncestors: false})) { | 163 if (cvox.DomUtil.isVisible(node, {checkAncestors: false})) { |
167 siblingNode = node; | 164 siblingNode = node; |
168 break; | 165 break; |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
245 | 242 |
246 // Return the previous character from this leaf node. | 243 // Return the previous character from this leaf node. |
247 if (cursor.text.length > 0 && cursor.index > 0) { | 244 if (cursor.text.length > 0 && cursor.index > 0) { |
248 return cursor.text[--cursor.index]; | 245 return cursor.text[--cursor.index]; |
249 } | 246 } |
250 | 247 |
251 // Move to the previous sibling, going up the tree as necessary. | 248 // Move to the previous sibling, going up the tree as necessary. |
252 while (true) { | 249 while (true) { |
253 // Try to move to the previous sibling. | 250 // Try to move to the previous sibling. |
254 var siblingNode = null; | 251 var siblingNode = null; |
255 for (var node = cursor.node.previousSibling; | 252 for (var node = cursor.node.previousSibling; node != null; |
256 node != null; | |
257 node = node.previousSibling) { | 253 node = node.previousSibling) { |
258 if (cvox.TraverseUtil.isHidden(node)) { | 254 if (cvox.TraverseUtil.isHidden(node)) { |
259 if (node instanceof HTMLElement) { | 255 if (node instanceof HTMLElement) { |
260 elementsEntered.push(node); | 256 elementsEntered.push(node); |
261 } | 257 } |
262 continue; | 258 continue; |
263 } | 259 } |
264 if (cvox.DomUtil.isVisible(node, {checkAncestors: false})) { | 260 if (cvox.DomUtil.isVisible(node, {checkAncestors: false})) { |
265 siblingNode = node; | 261 siblingNode = node; |
266 break; | 262 break; |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 * @param {boolean} skipWhitespace If true, will keep scanning until a | 312 * @param {boolean} skipWhitespace If true, will keep scanning until a |
317 * non-whitespace character is found. | 313 * non-whitespace character is found. |
318 * @return {?string} The next char, or null if the bottom of the | 314 * @return {?string} The next char, or null if the bottom of the |
319 * document has been reached. | 315 * document has been reached. |
320 */ | 316 */ |
321 cvox.TraverseUtil.getNextChar = function( | 317 cvox.TraverseUtil.getNextChar = function( |
322 startCursor, endCursor, elementsEntered, elementsLeft, skipWhitespace) { | 318 startCursor, endCursor, elementsEntered, elementsLeft, skipWhitespace) { |
323 | 319 |
324 // Save the starting position and get the first character. | 320 // Save the starting position and get the first character. |
325 startCursor.copyFrom(endCursor); | 321 startCursor.copyFrom(endCursor); |
326 var c = cvox.TraverseUtil.forwardsChar( | 322 var c = |
327 endCursor, elementsEntered, elementsLeft); | 323 cvox.TraverseUtil.forwardsChar(endCursor, elementsEntered, elementsLeft); |
328 if (c == null) | 324 if (c == null) |
329 return null; | 325 return null; |
330 | 326 |
331 // Keep track of whether the first character was whitespace. | 327 // Keep track of whether the first character was whitespace. |
332 var initialWhitespace = cvox.TraverseUtil.isWhitespace(c); | 328 var initialWhitespace = cvox.TraverseUtil.isWhitespace(c); |
333 | 329 |
334 // Keep scanning until we find a non-whitespace or non-skipped character. | 330 // Keep scanning until we find a non-whitespace or non-skipped character. |
335 while ((cvox.TraverseUtil.isWhitespace(c)) || | 331 while ((cvox.TraverseUtil.isWhitespace(c)) || |
336 (cvox.TraverseUtil.isHidden(endCursor.node))) { | 332 (cvox.TraverseUtil.isHidden(endCursor.node))) { |
337 c = cvox.TraverseUtil.forwardsChar( | 333 c = cvox.TraverseUtil.forwardsChar( |
338 endCursor, elementsEntered, elementsLeft); | 334 endCursor, elementsEntered, elementsLeft); |
339 if (c == null) | 335 if (c == null) |
340 return null; | 336 return null; |
341 } | 337 } |
342 if (skipWhitespace || !initialWhitespace) { | 338 if (skipWhitespace || !initialWhitespace) { |
343 // If skipWhitepace is true, or if the first character we encountered | 339 // If skipWhitepace is true, or if the first character we encountered |
344 // was not whitespace, return that non-whitespace character. | 340 // was not whitespace, return that non-whitespace character. |
345 startCursor.copyFrom(endCursor); | 341 startCursor.copyFrom(endCursor); |
346 startCursor.index--; | 342 startCursor.index--; |
347 return c; | 343 return c; |
348 } | 344 } else { |
349 else { | |
350 for (var i = 0; i < elementsEntered.length; i++) { | 345 for (var i = 0; i < elementsEntered.length; i++) { |
351 if (cvox.TraverseUtil.isHidden(elementsEntered[i])) { | 346 if (cvox.TraverseUtil.isHidden(elementsEntered[i])) { |
352 // We need to make sure that startCursor and endCursor aren't | 347 // We need to make sure that startCursor and endCursor aren't |
353 // surrounding a skippable node. | 348 // surrounding a skippable node. |
354 endCursor.index--; | 349 endCursor.index--; |
355 startCursor.copyFrom(endCursor); | 350 startCursor.copyFrom(endCursor); |
356 startCursor.index--; | 351 startCursor.index--; |
357 return ' '; | 352 return ' '; |
358 } | 353 } |
359 } | 354 } |
(...skipping 29 matching lines...) Expand all Loading... |
389 var c = cvox.TraverseUtil.backwardsChar( | 384 var c = cvox.TraverseUtil.backwardsChar( |
390 startCursor, elementsEntered, elementsLeft); | 385 startCursor, elementsEntered, elementsLeft); |
391 if (c == null) | 386 if (c == null) |
392 return null; | 387 return null; |
393 | 388 |
394 // Keep track of whether the first character was whitespace. | 389 // Keep track of whether the first character was whitespace. |
395 var initialWhitespace = cvox.TraverseUtil.isWhitespace(c); | 390 var initialWhitespace = cvox.TraverseUtil.isWhitespace(c); |
396 | 391 |
397 // Keep scanning until we find a non-whitespace or non-skipped character. | 392 // Keep scanning until we find a non-whitespace or non-skipped character. |
398 while ((cvox.TraverseUtil.isWhitespace(c)) || | 393 while ((cvox.TraverseUtil.isWhitespace(c)) || |
399 (cvox.TraverseUtil.isHidden(startCursor.node))) { | 394 (cvox.TraverseUtil.isHidden(startCursor.node))) { |
400 c = cvox.TraverseUtil.backwardsChar( | 395 c = cvox.TraverseUtil.backwardsChar( |
401 startCursor, elementsEntered, elementsLeft); | 396 startCursor, elementsEntered, elementsLeft); |
402 if (c == null) | 397 if (c == null) |
403 return null; | 398 return null; |
404 } | 399 } |
405 if (skipWhitespace || !initialWhitespace) { | 400 if (skipWhitespace || !initialWhitespace) { |
406 // If skipWhitepace is true, or if the first character we encountered | 401 // If skipWhitepace is true, or if the first character we encountered |
407 // was not whitespace, return that non-whitespace character. | 402 // was not whitespace, return that non-whitespace character. |
408 endCursor.copyFrom(startCursor); | 403 endCursor.copyFrom(startCursor); |
409 endCursor.index++; | 404 endCursor.index++; |
(...skipping 19 matching lines...) Expand all Loading... |
429 * a string of 1 or more non-whitespace characters in the same DOM node. | 424 * a string of 1 or more non-whitespace characters in the same DOM node. |
430 * @param {cvox.Cursor} startCursor On exit, will point to the beginning of the | 425 * @param {cvox.Cursor} startCursor On exit, will point to the beginning of the |
431 * word returned. | 426 * word returned. |
432 * @param {cvox.Cursor} endCursor The position to start searching for the next | 427 * @param {cvox.Cursor} endCursor The position to start searching for the next |
433 * word. On exit, will point to the end of the word returned. | 428 * word. On exit, will point to the end of the word returned. |
434 * @param {Array<Element>} elementsEntered Any HTML elements entered. | 429 * @param {Array<Element>} elementsEntered Any HTML elements entered. |
435 * @param {Array<Element>} elementsLeft Any HTML elements left. | 430 * @param {Array<Element>} elementsLeft Any HTML elements left. |
436 * @return {?string} The next word, or null if the bottom of the | 431 * @return {?string} The next word, or null if the bottom of the |
437 * document has been reached. | 432 * document has been reached. |
438 */ | 433 */ |
439 cvox.TraverseUtil.getNextWord = function(startCursor, endCursor, | 434 cvox.TraverseUtil.getNextWord = function( |
440 elementsEntered, elementsLeft) { | 435 startCursor, endCursor, elementsEntered, elementsLeft) { |
441 | 436 |
442 // Find the first non-whitespace or non-skipped character. | 437 // Find the first non-whitespace or non-skipped character. |
443 var cursor = endCursor.clone(); | 438 var cursor = endCursor.clone(); |
444 var c = cvox.TraverseUtil.forwardsChar(cursor, elementsEntered, elementsLeft); | 439 var c = cvox.TraverseUtil.forwardsChar(cursor, elementsEntered, elementsLeft); |
445 if (c == null) | 440 if (c == null) |
446 return null; | 441 return null; |
447 while ((cvox.TraverseUtil.isWhitespace(c)) || | 442 while ((cvox.TraverseUtil.isWhitespace(c)) || |
448 (cvox.TraverseUtil.isHidden(cursor.node))) { | 443 (cvox.TraverseUtil.isHidden(cursor.node))) { |
449 c = cvox.TraverseUtil.forwardsChar(cursor, elementsEntered, elementsLeft); | 444 c = cvox.TraverseUtil.forwardsChar(cursor, elementsEntered, elementsLeft); |
450 if (c == null) | 445 if (c == null) |
451 return null; | 446 return null; |
452 } | 447 } |
453 | 448 |
454 // Set startCursor to the position immediately before the first | 449 // Set startCursor to the position immediately before the first |
455 // character in our word. It's safe to decrement |index| because | 450 // character in our word. It's safe to decrement |index| because |
456 // forwardsChar guarantees that the cursor will be immediately to the | 451 // forwardsChar guarantees that the cursor will be immediately to the |
457 // right of the returned character on exit. | 452 // right of the returned character on exit. |
458 startCursor.copyFrom(cursor); | 453 startCursor.copyFrom(cursor); |
459 startCursor.index--; | 454 startCursor.index--; |
460 | 455 |
461 // Keep building up our word until we reach a whitespace character or | 456 // Keep building up our word until we reach a whitespace character or |
462 // would cross a tag. Don't actually return any tags crossed, because this | 457 // would cross a tag. Don't actually return any tags crossed, because this |
463 // word goes up until the tag boundary but not past it. | 458 // word goes up until the tag boundary but not past it. |
464 endCursor.copyFrom(cursor); | 459 endCursor.copyFrom(cursor); |
465 var word = c; | 460 var word = c; |
466 var newEntered = []; | 461 var newEntered = []; |
467 var newLeft = []; | 462 var newLeft = []; |
468 c = cvox.TraverseUtil.forwardsChar(cursor, newEntered, newLeft); | 463 c = cvox.TraverseUtil.forwardsChar(cursor, newEntered, newLeft); |
469 if (c == null) { | 464 if (c == null) { |
470 return word; | 465 return word; |
471 } | 466 } |
472 while (!cvox.TraverseUtil.isWhitespace(c) && | 467 while (!cvox.TraverseUtil.isWhitespace(c) && newEntered.length == 0 && |
473 newEntered.length == 0 && | |
474 newLeft == 0) { | 468 newLeft == 0) { |
475 word += c; | 469 word += c; |
476 endCursor.copyFrom(cursor); | 470 endCursor.copyFrom(cursor); |
477 c = cvox.TraverseUtil.forwardsChar(cursor, newEntered, newLeft); | 471 c = cvox.TraverseUtil.forwardsChar(cursor, newEntered, newLeft); |
478 if (c == null) { | 472 if (c == null) { |
479 return word; | 473 return word; |
480 } | 474 } |
481 } | 475 } |
482 | 476 |
483 return word; | 477 return word; |
484 }; | 478 }; |
485 | 479 |
486 /** | 480 /** |
487 * Finds the previous word, starting from startCursor. Upon exit, startCursor | 481 * Finds the previous word, starting from startCursor. Upon exit, startCursor |
488 * and endCursor will surround the previous word. A word is defined to be | 482 * and endCursor will surround the previous word. A word is defined to be |
489 * a string of 1 or more non-whitespace characters in the same DOM node. | 483 * a string of 1 or more non-whitespace characters in the same DOM node. |
490 * @param {cvox.Cursor} startCursor The position to start searching for the | 484 * @param {cvox.Cursor} startCursor The position to start searching for the |
491 * previous word. On exit, will point to the beginning of the | 485 * previous word. On exit, will point to the beginning of the |
492 * word returned. | 486 * word returned. |
493 * @param {cvox.Cursor} endCursor On exit, will point to the end of the | 487 * @param {cvox.Cursor} endCursor On exit, will point to the end of the |
494 * word returned. | 488 * word returned. |
495 * @param {Array<Element>} elementsEntered Any HTML elements entered. | 489 * @param {Array<Element>} elementsEntered Any HTML elements entered. |
496 * @param {Array<Element>} elementsLeft Any HTML elements left. | 490 * @param {Array<Element>} elementsLeft Any HTML elements left. |
497 * @return {?string} The previous word, or null if the bottom of the | 491 * @return {?string} The previous word, or null if the bottom of the |
498 * document has been reached. | 492 * document has been reached. |
499 */ | 493 */ |
500 cvox.TraverseUtil.getPreviousWord = function(startCursor, endCursor, | 494 cvox.TraverseUtil.getPreviousWord = function( |
501 elementsEntered, elementsLeft) { | 495 startCursor, endCursor, elementsEntered, elementsLeft) { |
502 // Find the first non-whitespace or non-skipped character. | 496 // Find the first non-whitespace or non-skipped character. |
503 var cursor = startCursor.clone(); | 497 var cursor = startCursor.clone(); |
504 var c = cvox.TraverseUtil.backwardsChar( | 498 var c = |
505 cursor, elementsEntered, elementsLeft); | 499 cvox.TraverseUtil.backwardsChar(cursor, elementsEntered, elementsLeft); |
506 if (c == null) | 500 if (c == null) |
507 return null; | 501 return null; |
508 while ((cvox.TraverseUtil.isWhitespace(c) || | 502 while ( |
509 (cvox.TraverseUtil.isHidden(cursor.node)))) { | 503 (cvox.TraverseUtil.isWhitespace(c) || |
| 504 (cvox.TraverseUtil.isHidden(cursor.node)))) { |
510 c = cvox.TraverseUtil.backwardsChar(cursor, elementsEntered, elementsLeft); | 505 c = cvox.TraverseUtil.backwardsChar(cursor, elementsEntered, elementsLeft); |
511 if (c == null) | 506 if (c == null) |
512 return null; | 507 return null; |
513 } | 508 } |
514 | 509 |
515 // Set endCursor to the position immediately after the first | 510 // Set endCursor to the position immediately after the first |
516 // character we've found (the last character of the word, since we're | 511 // character we've found (the last character of the word, since we're |
517 // searching backwards). | 512 // searching backwards). |
518 endCursor.copyFrom(cursor); | 513 endCursor.copyFrom(cursor); |
519 endCursor.index++; | 514 endCursor.index++; |
520 | 515 |
521 // Keep building up our word until we reach a whitespace character or | 516 // Keep building up our word until we reach a whitespace character or |
522 // would cross a tag. Don't actually return any tags crossed, because this | 517 // would cross a tag. Don't actually return any tags crossed, because this |
523 // word goes up until the tag boundary but not past it. | 518 // word goes up until the tag boundary but not past it. |
524 startCursor.copyFrom(cursor); | 519 startCursor.copyFrom(cursor); |
525 var word = c; | 520 var word = c; |
526 var newEntered = []; | 521 var newEntered = []; |
527 var newLeft = []; | 522 var newLeft = []; |
528 c = cvox.TraverseUtil.backwardsChar(cursor, newEntered, newLeft); | 523 c = cvox.TraverseUtil.backwardsChar(cursor, newEntered, newLeft); |
529 if (c == null) | 524 if (c == null) |
530 return word; | 525 return word; |
531 while (!cvox.TraverseUtil.isWhitespace(c) && | 526 while (!cvox.TraverseUtil.isWhitespace(c) && newEntered.length == 0 && |
532 newEntered.length == 0 && | |
533 newLeft.length == 0) { | 527 newLeft.length == 0) { |
534 word = c + word; | 528 word = c + word; |
535 startCursor.copyFrom(cursor); | 529 startCursor.copyFrom(cursor); |
536 | 530 |
537 c = cvox.TraverseUtil.backwardsChar(cursor, newEntered, newLeft); | 531 c = cvox.TraverseUtil.backwardsChar(cursor, newEntered, newLeft); |
538 if (c == null) | 532 if (c == null) |
539 return word; | 533 return word; |
540 } | 534 } |
541 | 535 |
542 return word; | 536 return word; |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
642 * break the line. | 636 * break the line. |
643 * @return {?string} The next line, or null if the bottom of the | 637 * @return {?string} The next line, or null if the bottom of the |
644 * document has been reached. | 638 * document has been reached. |
645 */ | 639 */ |
646 cvox.TraverseUtil.getNextLine = function( | 640 cvox.TraverseUtil.getNextLine = function( |
647 startCursor, endCursor, elementsEntered, elementsLeft, breakTags) { | 641 startCursor, endCursor, elementsEntered, elementsLeft, breakTags) { |
648 var range = document.createRange(); | 642 var range = document.createRange(); |
649 var currentRect = null; | 643 var currentRect = null; |
650 var rightMostRect = null; | 644 var rightMostRect = null; |
651 var prevCursor = endCursor.clone(); | 645 var prevCursor = endCursor.clone(); |
652 return cvox.TraverseUtil.getNextString( | 646 return cvox.TraverseUtil.getNextString( |
653 startCursor, endCursor, elementsEntered, elementsLeft, | 647 startCursor, endCursor, elementsEntered, elementsLeft, |
654 function(str, word, elementsEntered, elementsLeft) { | 648 function(str, word, elementsEntered, elementsLeft) { |
655 range.setStart(startCursor.node, startCursor.index); | 649 range.setStart(startCursor.node, startCursor.index); |
656 range.setEnd(endCursor.node, endCursor.index); | 650 range.setEnd(endCursor.node, endCursor.index); |
657 var currentRect = range.getBoundingClientRect(); | 651 var currentRect = range.getBoundingClientRect(); |
658 if (!rightMostRect) { | 652 if (!rightMostRect) { |
659 rightMostRect = currentRect; | 653 rightMostRect = currentRect; |
660 } | 654 } |
661 | 655 |
662 // Break at new lines except when within a link. | 656 // Break at new lines except when within a link. |
663 if (currentRect.bottom != rightMostRect.bottom && | 657 if (currentRect.bottom != rightMostRect.bottom && |
664 !cvox.DomPredicates.linkPredicate(cvox.DomUtil.getAncestors( | 658 !cvox.DomPredicates.linkPredicate( |
665 endCursor.node))) { | 659 cvox.DomUtil.getAncestors(endCursor.node))) { |
666 endCursor.copyFrom(prevCursor); | 660 endCursor.copyFrom(prevCursor); |
667 return true; | 661 return true; |
668 } | 662 } |
669 | 663 |
670 rightMostRect = currentRect; | 664 rightMostRect = currentRect; |
671 prevCursor.copyFrom(endCursor); | 665 prevCursor.copyFrom(endCursor); |
672 | 666 |
673 return cvox.TraverseUtil.includesBreakTagOrSkippedNode( | 667 return cvox.TraverseUtil.includesBreakTagOrSkippedNode( |
674 elementsEntered, elementsLeft, breakTags); | 668 elementsEntered, elementsLeft, breakTags); |
675 }); | 669 }); |
(...skipping 24 matching lines...) Expand all Loading... |
700 function(str, word, elementsEntered, elementsLeft) { | 694 function(str, word, elementsEntered, elementsLeft) { |
701 range.setStart(startCursor.node, startCursor.index); | 695 range.setStart(startCursor.node, startCursor.index); |
702 range.setEnd(endCursor.node, endCursor.index); | 696 range.setEnd(endCursor.node, endCursor.index); |
703 var currentRect = range.getBoundingClientRect(); | 697 var currentRect = range.getBoundingClientRect(); |
704 if (!leftMostRect) { | 698 if (!leftMostRect) { |
705 leftMostRect = currentRect; | 699 leftMostRect = currentRect; |
706 } | 700 } |
707 | 701 |
708 // Break at new lines except when within a link. | 702 // Break at new lines except when within a link. |
709 if (currentRect.top != leftMostRect.top && | 703 if (currentRect.top != leftMostRect.top && |
710 !cvox.DomPredicates.linkPredicate(cvox.DomUtil.getAncestors( | 704 !cvox.DomPredicates.linkPredicate( |
711 startCursor.node))) { | 705 cvox.DomUtil.getAncestors(startCursor.node))) { |
712 startCursor.copyFrom(prevCursor); | 706 startCursor.copyFrom(prevCursor); |
713 return true; | 707 return true; |
714 } | 708 } |
715 | 709 |
716 leftMostRect = currentRect; | 710 leftMostRect = currentRect; |
717 prevCursor.copyFrom(startCursor); | 711 prevCursor.copyFrom(startCursor); |
718 | 712 |
719 return cvox.TraverseUtil.includesBreakTagOrSkippedNode( | 713 return cvox.TraverseUtil.includesBreakTagOrSkippedNode( |
720 elementsEntered, elementsLeft, breakTags); | 714 elementsEntered, elementsLeft, breakTags); |
721 }); | 715 }); |
722 }; | 716 }; |
723 | 717 |
724 /** | 718 /** |
725 * Finds the next paragraph, starting from endCursor. Upon exit, | 719 * Finds the next paragraph, starting from endCursor. Upon exit, |
726 * startCursor and endCursor will surround the next paragraph. | 720 * startCursor and endCursor will surround the next paragraph. |
727 * | 721 * |
728 * @param {cvox.Cursor} startCursor On exit, marks the beginning of the | 722 * @param {cvox.Cursor} startCursor On exit, marks the beginning of the |
729 * paragraph. | 723 * paragraph. |
730 * @param {cvox.Cursor} endCursor The position to start searching for the next | 724 * @param {cvox.Cursor} endCursor The position to start searching for the next |
731 * paragraph. On exit, will point to the end of the returned string. | 725 * paragraph. On exit, will point to the end of the returned string. |
732 * @param {Array<Element>} elementsEntered Any HTML elements entered. | 726 * @param {Array<Element>} elementsEntered Any HTML elements entered. |
733 * @param {Array<Element>} elementsLeft Any HTML elements left. | 727 * @param {Array<Element>} elementsLeft Any HTML elements left. |
734 * @return {?string} The next paragraph, or null if the bottom of the | 728 * @return {?string} The next paragraph, or null if the bottom of the |
735 * document has been reached. | 729 * document has been reached. |
736 */ | 730 */ |
737 cvox.TraverseUtil.getNextParagraph = function(startCursor, endCursor, | 731 cvox.TraverseUtil.getNextParagraph = function( |
738 elementsEntered, elementsLeft) { | 732 startCursor, endCursor, elementsEntered, elementsLeft) { |
739 return cvox.TraverseUtil.getNextString( | 733 return cvox.TraverseUtil.getNextString( |
740 startCursor, endCursor, elementsEntered, elementsLeft, | 734 startCursor, endCursor, elementsEntered, elementsLeft, |
741 function(str, word, elementsEntered, elementsLeft) { | 735 function(str, word, elementsEntered, elementsLeft) { |
742 for (var i = 0; i < elementsEntered.length; i++) { | 736 for (var i = 0; i < elementsEntered.length; i++) { |
743 if (cvox.TraverseUtil.isHidden(elementsEntered[i])) { | 737 if (cvox.TraverseUtil.isHidden(elementsEntered[i])) { |
744 return true; | 738 return true; |
745 } | 739 } |
746 var style = window.getComputedStyle(elementsEntered[i], null); | 740 var style = window.getComputedStyle(elementsEntered[i], null); |
747 if (style && style.display != 'inline') { | 741 if (style && style.display != 'inline') { |
748 return true; | 742 return true; |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
918 newEntered = []; | 912 newEntered = []; |
919 newLeft = []; | 913 newLeft = []; |
920 word = cvox.TraverseUtil.getPreviousWord( | 914 word = cvox.TraverseUtil.getPreviousWord( |
921 wordStartCursor, wordEndCursor, newEntered, newLeft); | 915 wordStartCursor, wordEndCursor, newEntered, newLeft); |
922 if (word == null) | 916 if (word == null) |
923 return str; | 917 return str; |
924 } | 918 } |
925 | 919 |
926 return str; | 920 return str; |
927 }; | 921 }; |
OLD | NEW |