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 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
77 cursors.Cursor = function(node, index) { | 77 cursors.Cursor = function(node, index) { |
78 // Compensate for specific issues in Blink. | 78 // Compensate for specific issues in Blink. |
79 // TODO(dtseng): Pass through affinity; if upstream, skip below. | 79 // TODO(dtseng): Pass through affinity; if upstream, skip below. |
80 if (node.role == RoleType.STATIC_TEXT && node.name.length == index) { | 80 if (node.role == RoleType.STATIC_TEXT && node.name.length == index) { |
81 // Re-interpret this case as the beginning of the next node. | 81 // Re-interpret this case as the beginning of the next node. |
82 var nextNode = AutomationUtil.findNextNode( | 82 var nextNode = AutomationUtil.findNextNode( |
83 node, Dir.FORWARD, AutomationPredicate.leafOrStaticText); | 83 node, Dir.FORWARD, AutomationPredicate.leafOrStaticText); |
84 | 84 |
85 // The exception is when a user types at the end of a line. In that case, | 85 // The exception is when a user types at the end of a line. In that case, |
86 // staying on the current node is appropriate. | 86 // staying on the current node is appropriate. |
87 if (node && node.nextOnLine && nextNode) { | 87 if (node && node.nextOnLine && node.nextOnLine.role && nextNode) { |
88 node = nextNode; | 88 node = nextNode; |
89 index = 0; | 89 index = 0; |
90 } | 90 } |
91 } else if ( | 91 } else if ( |
92 node.role == RoleType.GENERIC_CONTAINER && node.state.richlyEditable && | 92 node.role == RoleType.GENERIC_CONTAINER && node.state.richlyEditable && |
93 (node.firstChild && | 93 (node.firstChild && |
94 (node.firstChild.role == RoleType.LINE_BREAK || | 94 (node.firstChild.role == RoleType.LINE_BREAK || |
95 node.firstChild.role == RoleType.STATIC_TEXT))) { | 95 node.firstChild.role == RoleType.STATIC_TEXT))) { |
96 // Re-interpret this case as pointing to the text under the div. | 96 // Re-interpret this case as pointing to the text under the div. |
97 node = node.find({role: RoleType.INLINE_TEXT_BOX}) || node; | 97 node = node.find({role: RoleType.INLINE_TEXT_BOX}) || node; |
98 } | 98 } |
99 | 99 |
100 /** @type {number} @private */ | 100 /** @type {number} @private */ |
101 this.index_ = index; | 101 this.index_ = index; |
102 /** @type {Array<AutomationNode>} @private */ | 102 /** @type {Array<AutomationNode>} @private */ |
103 this.ancestry_ = []; | 103 this.ancestry_ = []; |
104 /** @type {!Array<number>} @private */ | |
105 this.recoveryChildIndex_ = []; | |
106 | |
104 var nodeWalker = node; | 107 var nodeWalker = node; |
105 while (nodeWalker) { | 108 while (nodeWalker) { |
106 this.ancestry_.push(nodeWalker); | 109 this.ancestry_.push(nodeWalker); |
110 this.recoveryChildIndex_.push(nodeWalker.indexInParent); | |
dmazzoni
2017/07/06 21:17:06
I like this idea in general but how about a tiny b
David Tseng
2017/07/06 22:15:44
I'm actually something slightly different here tha
| |
107 nodeWalker = nodeWalker.parent; | 111 nodeWalker = nodeWalker.parent; |
108 if (nodeWalker && nodeWalker.role == RoleType.WINDOW) | 112 if (nodeWalker && nodeWalker.role == RoleType.WINDOW) |
109 break; | 113 break; |
110 } | 114 } |
111 }; | 115 }; |
112 | 116 |
113 /** | 117 /** |
114 * Convenience method to construct a Cursor from a node. | 118 * Convenience method to construct a Cursor from a node. |
115 * @param {!AutomationNode} node | 119 * @param {!AutomationNode} node |
116 * @return {!cursors.Cursor} | 120 * @return {!cursors.Cursor} |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
183 firstValidNode.root != undefined) { | 187 firstValidNode.root != undefined) { |
184 return firstValidNode; | 188 return firstValidNode; |
185 } | 189 } |
186 // If we have to walk up to an ancestor, reset the index to NODE_INDEX. | 190 // If we have to walk up to an ancestor, reset the index to NODE_INDEX. |
187 this.index_ = cursors.NODE_INDEX; | 191 this.index_ = cursors.NODE_INDEX; |
188 } | 192 } |
189 return null; | 193 return null; |
190 }, | 194 }, |
191 | 195 |
192 /** | 196 /** |
197 * Returns the node. If the node is invalid since the last time it | |
198 * was accessed, attempts to recover it based on a child index. | |
199 * @return {AutomationNode} | |
200 */ | |
201 get recoveryNode() { | |
202 for (var i = 0; i < this.ancestry_.length; i++) { | |
203 var firstValidNode = this.ancestry_[i]; | |
204 if (firstValidNode != null && firstValidNode.role !== undefined && | |
205 firstValidNode.root != undefined) { | |
206 if (i == 0) | |
207 return firstValidNode; | |
208 | |
209 // Otherwise, attempt to recover. | |
210 var node = firstValidNode; | |
211 for (var j = i - 1; j >= 0; j--) { | |
212 var index = this.recoveryChildIndex_[j]; | |
213 var children = node.children; | |
214 if (!children[index]) | |
215 return node; | |
216 node = children[index]; | |
217 } | |
218 return node; | |
219 } | |
220 } | |
221 return null; | |
222 }, | |
223 | |
224 /** | |
193 * @return {number} | 225 * @return {number} |
194 */ | 226 */ |
195 get index() { | 227 get index() { |
196 return this.index_; | 228 return this.index_; |
197 }, | 229 }, |
198 | 230 |
199 | 231 |
200 /** | 232 /** |
201 * A node appropriate for making selections. | 233 * A node appropriate for making selections. |
202 * @return {AutomationNode} | 234 * @return {AutomationNode} |
(...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
767 /** | 799 /** |
768 * Returns whether this range has valid start and end cursors. | 800 * Returns whether this range has valid start and end cursors. |
769 * @return {boolean} | 801 * @return {boolean} |
770 */ | 802 */ |
771 isValid: function() { | 803 isValid: function() { |
772 return this.start.isValid() && this.end.isValid(); | 804 return this.start.isValid() && this.end.isValid(); |
773 } | 805 } |
774 }; | 806 }; |
775 | 807 |
776 }); // goog.scope | 808 }); // goog.scope |
OLD | NEW |