| 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 Classes related to cursors that point to and select parts of | 6 * @fileoverview Classes related to cursors that point to and select parts of |
| 7 * the automation tree. | 7 * the automation tree. |
| 8 */ | 8 */ |
| 9 | 9 |
| 10 goog.provide('cursors.Cursor'); | 10 goog.provide('cursors.Cursor'); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 cursors.Unit = { | 30 cursors.Unit = { |
| 31 /** A single character within accessible name or value. */ | 31 /** A single character within accessible name or value. */ |
| 32 CHARACTER: 'character', | 32 CHARACTER: 'character', |
| 33 | 33 |
| 34 /** A range of characters (given by attributes on automation nodes). */ | 34 /** A range of characters (given by attributes on automation nodes). */ |
| 35 WORD: 'word', | 35 WORD: 'word', |
| 36 | 36 |
| 37 /** A leaf node. */ | 37 /** A leaf node. */ |
| 38 NODE: 'node', | 38 NODE: 'node', |
| 39 | 39 |
| 40 /** A leaf DOM-node. */ | 40 /** |
| 41 DOM_NODE: 'dom_node', | 41 * A node or in line textbox that immediately precedes or follows a visual |
| 42 | 42 * line break. |
| 43 /** Formed by a set of leaf nodes that are inline. */ | 43 */ |
| 44 LINE: 'line' | 44 LINE: 'line' |
| 45 }; | 45 }; |
| 46 | 46 |
| 47 /** | 47 /** |
| 48 * Represents the ways in which cursors can move given a cursor unit. | 48 * Represents the ways in which cursors can move given a cursor unit. |
| 49 * @enum {string} | 49 * @enum {string} |
| 50 */ | 50 */ |
| 51 cursors.Movement = { | 51 cursors.Movement = { |
| 52 /** Move to the beginning or end of the current unit. */ | 52 /** Move to the beginning or end of the current unit. */ |
| 53 BOUND: 'bound', | 53 BOUND: 'bound', |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 211 * @return {!cursors.Cursor} The moved cursor. | 211 * @return {!cursors.Cursor} The moved cursor. |
| 212 */ | 212 */ |
| 213 move: function(unit, movement, dir) { | 213 move: function(unit, movement, dir) { |
| 214 var originalNode = this.node; | 214 var originalNode = this.node; |
| 215 if (!originalNode) | 215 if (!originalNode) |
| 216 return this; | 216 return this; |
| 217 | 217 |
| 218 var newNode = originalNode; | 218 var newNode = originalNode; |
| 219 var newIndex = this.index_; | 219 var newIndex = this.index_; |
| 220 | 220 |
| 221 if ((unit != Unit.NODE || unit != Unit.DOM_NODE) && | 221 if (unit != Unit.NODE && newIndex === cursors.NODE_INDEX) |
| 222 newIndex === cursors.NODE_INDEX) | |
| 223 newIndex = 0; | 222 newIndex = 0; |
| 224 | 223 |
| 225 switch (unit) { | 224 switch (unit) { |
| 226 case Unit.CHARACTER: | 225 case Unit.CHARACTER: |
| 227 // BOUND and DIRECTIONAL are the same for characters. | 226 // BOUND and DIRECTIONAL are the same for characters. |
| 228 var text = this.getText(); | 227 var text = this.getText(); |
| 229 newIndex = dir == Dir.FORWARD ? | 228 newIndex = dir == Dir.FORWARD ? |
| 230 StringUtil.nextCodePointOffset(text, newIndex) : | 229 StringUtil.nextCodePointOffset(text, newIndex) : |
| 231 StringUtil.previousCodePointOffset(text, newIndex); | 230 StringUtil.previousCodePointOffset(text, newIndex); |
| 232 if (newIndex < 0 || newIndex >= text.length) { | 231 if (newIndex < 0 || newIndex >= text.length) { |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 300 } | 299 } |
| 301 } | 300 } |
| 302 } | 301 } |
| 303 } | 302 } |
| 304 } else { | 303 } else { |
| 305 // TODO(dtseng): Figure out what to do in this case. | 304 // TODO(dtseng): Figure out what to do in this case. |
| 306 } | 305 } |
| 307 } | 306 } |
| 308 break; | 307 break; |
| 309 case Unit.NODE: | 308 case Unit.NODE: |
| 310 case Unit.DOM_NODE: | |
| 311 switch (movement) { | 309 switch (movement) { |
| 312 case Movement.BOUND: | 310 case Movement.BOUND: |
| 313 newIndex = dir == Dir.FORWARD ? this.getText().length - 1 : 0; | 311 newIndex = dir == Dir.FORWARD ? this.getText().length - 1 : 0; |
| 314 break; | 312 break; |
| 315 case Movement.DIRECTIONAL: | 313 case Movement.DIRECTIONAL: |
| 316 var pred = unit == Unit.NODE ? | |
| 317 AutomationPredicate.leaf : AutomationPredicate.object; | |
| 318 newNode = AutomationUtil.findNextNode( | 314 newNode = AutomationUtil.findNextNode( |
| 319 newNode, dir, pred) || originalNode; | 315 newNode, dir, AutomationPredicate.object) || originalNode; |
| 320 newIndex = cursors.NODE_INDEX; | 316 newIndex = cursors.NODE_INDEX; |
| 321 break; | 317 break; |
| 322 } | 318 } |
| 323 break; | 319 break; |
| 324 case Unit.LINE: | 320 case Unit.LINE: |
| 325 newIndex = 0; | 321 newIndex = 0; |
| 326 switch (movement) { | 322 switch (movement) { |
| 327 case Movement.BOUND: | 323 case Movement.BOUND: |
| 328 newNode = AutomationUtil.findNodeUntil(newNode, dir, | 324 newNode = AutomationUtil.findNodeUntil(newNode, dir, |
| 329 AutomationPredicate.linebreak, true); | 325 AutomationPredicate.linebreak, true); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 380 cursors.WrappingCursor.prototype = { | 376 cursors.WrappingCursor.prototype = { |
| 381 __proto__: cursors.Cursor.prototype, | 377 __proto__: cursors.Cursor.prototype, |
| 382 | 378 |
| 383 /** @override */ | 379 /** @override */ |
| 384 move: function(unit, movement, dir) { | 380 move: function(unit, movement, dir) { |
| 385 var result = this; | 381 var result = this; |
| 386 if (!result.node) | 382 if (!result.node) |
| 387 return this; | 383 return this; |
| 388 | 384 |
| 389 // Regular movement. | 385 // Regular movement. |
| 390 if (!AutomationPredicate.root(this.node) || dir == Dir.FORWARD) | 386 if (!AutomationPredicate.root(this.node) || |
| 387 dir == Dir.FORWARD || |
| 388 movement == Movement.BOUND) |
| 391 result = cursors.Cursor.prototype.move.call(this, unit, movement, dir); | 389 result = cursors.Cursor.prototype.move.call(this, unit, movement, dir); |
| 392 | 390 |
| 391 // Moving to the bounds of a unit never wraps. |
| 392 if (movement == Movement.BOUND) |
| 393 return new cursors.WrappingCursor(result.node, result.index); |
| 394 |
| 393 // There are two cases for wrapping: | 395 // There are two cases for wrapping: |
| 394 // 1. moving forwards from the last element. | 396 // 1. moving forwards from the last element. |
| 395 // 2. moving backwards from the first element. | 397 // 2. moving backwards from the first element. |
| 396 // Both result in |move| returning the same cursor. | 398 // Both result in |move| returning the same cursor. |
| 397 // For 1, simply place the new cursor on the document node. | 399 // For 1, simply place the new cursor on the document node. |
| 398 // For 2, place range on the root (if not already there). If at root, | 400 // For 2, place range on the root (if not already there). If at root, |
| 399 // try to descend to the first leaf-like object. | 401 // try to descend to the first leaf-like object. |
| 400 if (movement == Movement.DIRECTIONAL && result.equals(this)) { | 402 if (movement == Movement.DIRECTIONAL && result.equals(this)) { |
| 401 var pred = unit == Unit.DOM_NODE ? | 403 var pred = unit == Unit.NODE ? |
| 402 AutomationPredicate.object : AutomationPredicate.leaf; | 404 AutomationPredicate.object : AutomationPredicate.leaf; |
| 403 var endpoint = this.node; | 405 var endpoint = this.node; |
| 404 if (!endpoint) | 406 if (!endpoint) |
| 405 return this; | 407 return this; |
| 406 | 408 |
| 407 // Case 1: forwards (find the root-like node). | 409 // Case 1: forwards (find the root-like node). |
| 408 while (!AutomationPredicate.root(endpoint) && endpoint.parent) | 410 while (!AutomationPredicate.root(endpoint) && endpoint.parent) |
| 409 endpoint = endpoint.parent; | 411 endpoint = endpoint.parent; |
| 410 | 412 |
| 411 // Always play a wrap earcon when moving forward. | 413 // Always play a wrap earcon when moving forward. |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 561 if (newStart.node !== newEnd.node) | 563 if (newStart.node !== newEnd.node) |
| 562 newEnd = new cursors.Cursor(newStart.node, newStart.index + 1); | 564 newEnd = new cursors.Cursor(newStart.node, newStart.index + 1); |
| 563 break; | 565 break; |
| 564 case Unit.WORD: | 566 case Unit.WORD: |
| 565 case Unit.LINE: | 567 case Unit.LINE: |
| 566 newStart = newStart.move(unit, Movement.DIRECTIONAL, dir); | 568 newStart = newStart.move(unit, Movement.DIRECTIONAL, dir); |
| 567 newStart = newStart.move(unit, Movement.BOUND, Dir.BACKWARD); | 569 newStart = newStart.move(unit, Movement.BOUND, Dir.BACKWARD); |
| 568 newEnd = newStart.move(unit, Movement.BOUND, Dir.FORWARD); | 570 newEnd = newStart.move(unit, Movement.BOUND, Dir.FORWARD); |
| 569 break; | 571 break; |
| 570 case Unit.NODE: | 572 case Unit.NODE: |
| 571 case Unit.DOM_NODE: | |
| 572 newStart = newStart.move(unit, Movement.DIRECTIONAL, dir); | 573 newStart = newStart.move(unit, Movement.DIRECTIONAL, dir); |
| 573 newEnd = newStart; | 574 newEnd = newStart; |
| 574 break; | 575 break; |
| 575 default: | 576 default: |
| 576 throw Error('Invalid unit: ' + unit); | 577 throw Error('Invalid unit: ' + unit); |
| 577 } | 578 } |
| 578 return new cursors.Range(newStart, newEnd); | 579 return new cursors.Range(newStart, newEnd); |
| 579 }, | 580 }, |
| 580 | 581 |
| 581 /** | 582 /** |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 630 /** | 631 /** |
| 631 * Returns whether this range has valid start and end cursors. | 632 * Returns whether this range has valid start and end cursors. |
| 632 * @return {boolean} | 633 * @return {boolean} |
| 633 */ | 634 */ |
| 634 isValid: function() { | 635 isValid: function() { |
| 635 return this.start.isValid() && this.end.isValid(); | 636 return this.start.isValid() && this.end.isValid(); |
| 636 } | 637 } |
| 637 }; | 638 }; |
| 638 | 639 |
| 639 }); // goog.scope | 640 }); // goog.scope |
| OLD | NEW |