| 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 |