| 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 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 155 return this.index_; | 155 return this.index_; |
| 156 }, | 156 }, |
| 157 | 157 |
| 158 | 158 |
| 159 /** | 159 /** |
| 160 * A node appropriate for making selections. | 160 * A node appropriate for making selections. |
| 161 * @return {AutomationNode} | 161 * @return {AutomationNode} |
| 162 * @private | 162 * @private |
| 163 */ | 163 */ |
| 164 get selectionNode_() { | 164 get selectionNode_() { |
| 165 if (!this.node) | 165 var adjustedNode = this.node; |
| 166 if (!adjustedNode) |
| 166 return null; | 167 return null; |
| 167 | 168 |
| 168 if (this.node.role == RoleType.inlineTextBox) | 169 // Selections over line break nodes are broken. |
| 169 return this.node.parent; | 170 var parent = adjustedNode.parent; |
| 171 var grandparent = parent && parent.parent; |
| 172 if (parent.role == RoleType.lineBreak) { |
| 173 adjustedNode = grandparent; |
| 174 } else if (grandparent.role == RoleType.lineBreak) { |
| 175 adjustedNode = grandparent.parent; |
| 176 } else if (this.index_ == cursors.NODE_INDEX || |
| 177 adjustedNode.role == RoleType.inlineTextBox || |
| 178 chrome.automation.NameFromType[adjustedNode.nameFrom] != 'contents') { |
| 179 // A node offset or unselectable character offset. |
| 180 adjustedNode = parent; |
| 181 } else { |
| 182 // A character offset into content. |
| 183 adjustedNode = |
| 184 adjustedNode.find({role: RoleType.staticText}) || adjustedNode; |
| 185 } |
| 170 | 186 |
| 171 return this.node; | 187 return adjustedNode; |
| 172 }, | 188 }, |
| 173 | 189 |
| 174 /** | 190 /** |
| 175 * An index appropriate for making selections. If this cursor has a | 191 * An index appropriate for making selections. If this cursor has a |
| 176 * cursors.NODE_INDEX index, the selection index is a node offset e.g. the | 192 * cursors.NODE_INDEX index, the selection index is a node offset e.g. the |
| 177 * index in parent. If not, the index is a character offset. | 193 * index in parent. If not, the index is a character offset. |
| 178 * @return {number} | 194 * @return {number} |
| 179 * @private | 195 * @private |
| 180 */ | 196 */ |
| 181 get selectionIndex_() { | 197 get selectionIndex_() { |
| 182 var adjustedIndex = this.index_; | 198 var adjustedIndex = this.index_; |
| 183 if (this.node.role == RoleType.inlineTextBox) { | 199 |
| 200 // Selecting things under a line break is currently broken. |
| 201 if (this.node.role == RoleType.inlineTextBox && |
| 202 this.node.parent && this.node.parent.role != RoleType.lineBreak) { |
| 184 if (adjustedIndex == cursors.NODE_INDEX) | 203 if (adjustedIndex == cursors.NODE_INDEX) |
| 185 adjustedIndex = 0; | 204 adjustedIndex = 0; |
| 186 | 205 |
| 187 var sibling = this.node.previousSibling; | 206 var sibling = this.node.previousSibling; |
| 188 while (sibling) { | 207 while (sibling) { |
| 189 adjustedIndex += sibling.name.length; | 208 adjustedIndex += sibling.name.length; |
| 190 sibling = sibling.previousSibling; | 209 sibling = sibling.previousSibling; |
| 191 } | 210 } |
| 192 } else if (this.index_ == cursors.NODE_INDEX) { | 211 } else if (this.index_ == cursors.NODE_INDEX || |
| 193 // Indicies of this kind are buggy. Set it to 0 (different than the DOM | 212 chrome.automation.NameFromType[this.node.nameFrom] != 'contents') { |
| 194 // index in parent convention). | 213 // A node offset or unselectable character offset. |
| 195 adjustedIndex = 0; | 214 |
| 215 // The selected node could have been adjusted upwards in the tree. |
| 216 var childOfSelection = this.node; |
| 217 do { |
| 218 adjustedIndex = childOfSelection.indexInParent; |
| 219 childOfSelection = childOfSelection.parent; |
| 220 } while (childOfSelection && childOfSelection != this.selectionNode_); |
| 196 } | 221 } |
| 222 // A character offset into content is the remaining case. It requires no |
| 223 // adjustment. |
| 224 |
| 197 return adjustedIndex; | 225 return adjustedIndex; |
| 198 }, | 226 }, |
| 199 | 227 |
| 200 /** | 228 /** |
| 201 * Gets the accessible text of the node associated with this cursor. | 229 * Gets the accessible text of the node associated with this cursor. |
| 202 * | 230 * |
| 203 * @param {!AutomationNode=} opt_node Use this node rather than this cursor's | 231 * @param {!AutomationNode=} opt_node Use this node rather than this cursor's |
| 204 * node. | 232 * node. |
| 205 * @return {string} | 233 * @return {string} |
| 206 */ | 234 */ |
| (...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 610 if (!startNode || !endNode) | 638 if (!startNode || !endNode) |
| 611 return; | 639 return; |
| 612 | 640 |
| 613 // Only allow selections within the same web tree. | 641 // Only allow selections within the same web tree. |
| 614 if (startNode.root && | 642 if (startNode.root && |
| 615 startNode.root.role == RoleType.rootWebArea && | 643 startNode.root.role == RoleType.rootWebArea && |
| 616 startNode.root == endNode.root) { | 644 startNode.root == endNode.root) { |
| 617 // We want to adjust to select the entire node for node offsets; | 645 // We want to adjust to select the entire node for node offsets; |
| 618 // otherwise, use the plain character offset. | 646 // otherwise, use the plain character offset. |
| 619 var startIndex = this.start.selectionIndex_; | 647 var startIndex = this.start.selectionIndex_; |
| 620 var endIndex = this.end.index == cursors.NODE_INDEX ? | 648 var endIndex = this.end.index_ == cursors.NODE_INDEX ? |
| 621 this.end.selectionIndex_ + 1 : this.end.selectionIndex_; | 649 this.end.selectionIndex_ + 1 : this.end.selectionIndex_; |
| 622 | 650 |
| 623 chrome.automation.setDocumentSelection( | 651 chrome.automation.setDocumentSelection( |
| 624 { anchorObject: startNode, | 652 { anchorObject: startNode, |
| 625 anchorOffset: startIndex, | 653 anchorOffset: startIndex, |
| 626 focusObject: endNode, | 654 focusObject: endNode, |
| 627 focusOffset: endIndex } | 655 focusOffset: endIndex } |
| 628 ); | 656 ); |
| 629 } | 657 } |
| 630 }, | 658 }, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 642 /** | 670 /** |
| 643 * Returns whether this range has valid start and end cursors. | 671 * Returns whether this range has valid start and end cursors. |
| 644 * @return {boolean} | 672 * @return {boolean} |
| 645 */ | 673 */ |
| 646 isValid: function() { | 674 isValid: function() { |
| 647 return this.start.isValid() && this.end.isValid(); | 675 return this.start.isValid() && this.end.isValid(); |
| 648 } | 676 } |
| 649 }; | 677 }; |
| 650 | 678 |
| 651 }); // goog.scope | 679 }); // goog.scope |
| OLD | NEW |