Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(332)

Side by Side Diff: chrome/browser/resources/chromeos/chromevox/cvox2/background/cursors.js

Issue 2601333002: Update json_schema_compiler to handle the Automation extension API (Closed)
Patch Set: Rebase Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 * Use this for loose equality between cursors where specific character-based 114 * Use this for loose equality between cursors where specific character-based
115 * indicies do not matter such as when processing node-targeted events. 115 * indicies do not matter such as when processing node-targeted events.
116 * @param {!cursors.Cursor} rhs 116 * @param {!cursors.Cursor} rhs
117 * @return {boolean} 117 * @return {boolean}
118 */ 118 */
119 contentEquals: function(rhs) { 119 contentEquals: function(rhs) {
120 // First, normalize the two nodes so they both point to the first non-text 120 // First, normalize the two nodes so they both point to the first non-text
121 // node. 121 // node.
122 var lNode = this.node; 122 var lNode = this.node;
123 var rNode = rhs.node; 123 var rNode = rhs.node;
124 while (lNode && (lNode.role == RoleType.inlineTextBox || 124 while (lNode && (lNode.role == RoleType.INLINE_TEXT_BOX ||
125 lNode.role == RoleType.staticText)) 125 lNode.role == RoleType.STATIC_TEXT))
126 lNode = lNode.parent; 126 lNode = lNode.parent;
127 while (rNode && (rNode.role == RoleType.inlineTextBox || 127 while (rNode && (rNode.role == RoleType.INLINE_TEXT_BOX ||
128 rNode.role == RoleType.staticText)) 128 rNode.role == RoleType.STATIC_TEXT))
129 rNode = rNode.parent; 129 rNode = rNode.parent;
130 130
131 // Ignore indicies for now. 131 // Ignore indicies for now.
132 132
133 return lNode === rNode && lNode != undefined; 133 return lNode === rNode && lNode != undefined;
134 }, 134 },
135 135
136 /** 136 /**
137 * Returns the node. If the node is invalid since the last time it 137 * Returns the node. If the node is invalid since the last time it
138 * was accessed, moves the cursor to the nearest valid ancestor first. 138 * was accessed, moves the cursor to the nearest valid ancestor first.
(...skipping 30 matching lines...) Expand all
169 if (!adjustedNode) 169 if (!adjustedNode)
170 return null; 170 return null;
171 171
172 // Make no adjustments if we're within editable content. 172 // Make no adjustments if we're within editable content.
173 if (adjustedNode.state.editable) 173 if (adjustedNode.state.editable)
174 return adjustedNode; 174 return adjustedNode;
175 175
176 // Selections over line break nodes are broken. 176 // Selections over line break nodes are broken.
177 var parent = adjustedNode.parent; 177 var parent = adjustedNode.parent;
178 var grandparent = parent && parent.parent; 178 var grandparent = parent && parent.parent;
179 if (parent.role == RoleType.lineBreak) { 179 if (parent.role == RoleType.LINE_BREAK) {
180 adjustedNode = grandparent; 180 adjustedNode = grandparent;
181 } else if (grandparent.role == RoleType.lineBreak) { 181 } else if (grandparent.role == RoleType.LINE_BREAK) {
182 adjustedNode = grandparent.parent; 182 adjustedNode = grandparent.parent;
183 } else if (this.index_ == cursors.NODE_INDEX || 183 } else if (this.index_ == cursors.NODE_INDEX ||
184 adjustedNode.role == RoleType.inlineTextBox || 184 adjustedNode.role == RoleType.INLINE_TEXT_BOX ||
185 chrome.automation.NameFromType[adjustedNode.nameFrom] != 'contents') { 185 adjustedNode.nameFrom != chrome.automation.NameFromType.CONTENTS) {
186 // A node offset or unselectable character offset. 186 // A node offset or unselectable character offset.
187 adjustedNode = parent; 187 adjustedNode = parent;
188 } else { 188 } else {
189 // A character offset into content. 189 // A character offset into content.
190 adjustedNode = 190 adjustedNode =
191 adjustedNode.find({role: RoleType.staticText}) || adjustedNode; 191 adjustedNode.find({role: RoleType.STATIC_TEXT}) || adjustedNode;
192 } 192 }
193 193
194 return adjustedNode; 194 return adjustedNode || null;
195 }, 195 },
196 196
197 /** 197 /**
198 * An index appropriate for making selections. If this cursor has a 198 * An index appropriate for making selections. If this cursor has a
199 * cursors.NODE_INDEX index, the selection index is a node offset e.g. the 199 * cursors.NODE_INDEX index, the selection index is a node offset e.g. the
200 * index in parent. If not, the index is a character offset. 200 * index in parent. If not, the index is a character offset.
201 * @return {number} 201 * @return {number}
202 * @private 202 * @private
203 */ 203 */
204 get selectionIndex_() { 204 get selectionIndex_() {
205 var adjustedIndex = this.index_; 205 var adjustedIndex = this.index_;
206 206
207 if (!this.node) 207 if (!this.node)
208 return -1; 208 return -1;
209 209
210 if (this.node.state.editable) { 210 if (this.node.state.editable) {
211 return this.index_ == cursors.NODE_INDEX ? 0 : this.index_; 211 return this.index_ == cursors.NODE_INDEX ? 0 : this.index_;
212 } else if (this.node.role == RoleType.inlineTextBox && 212 } else if (this.node.role == RoleType.INLINE_TEXT_BOX &&
213 // Selections under a line break are broken. 213 // Selections under a line break are broken.
214 this.node.parent && this.node.parent.role != RoleType.lineBreak) { 214 this.node.parent && this.node.parent.role != RoleType.LINE_BREAK) {
215 if (adjustedIndex == cursors.NODE_INDEX) 215 if (adjustedIndex == cursors.NODE_INDEX)
216 adjustedIndex = 0; 216 adjustedIndex = 0;
217 217
218 var sibling = this.node.previousSibling; 218 var sibling = this.node.previousSibling;
219 while (sibling) { 219 while (sibling) {
220 adjustedIndex += sibling.name.length; 220 adjustedIndex += sibling.name.length;
221 sibling = sibling.previousSibling; 221 sibling = sibling.previousSibling;
222 } 222 }
223 } else if (this.index_ == cursors.NODE_INDEX || 223 } else if (this.index_ == cursors.NODE_INDEX ||
224 chrome.automation.NameFromType[this.node.nameFrom] != 'contents') { 224 this.node.nameFrom != chrome.automation.NameFromType.CONTENTS) {
225 // A node offset or unselectable character offset. 225 // A node offset or unselectable character offset.
226 226
227 // The selected node could have been adjusted upwards in the tree. 227 // The selected node could have been adjusted upwards in the tree.
228 var childOfSelection = this.node; 228 var childOfSelection = this.node;
229 do { 229 do {
230 adjustedIndex = childOfSelection.indexInParent; 230 adjustedIndex = childOfSelection.indexInParent || 0;
231 childOfSelection = childOfSelection.parent; 231 childOfSelection = childOfSelection.parent;
232 } while (childOfSelection && childOfSelection != this.selectionNode_); 232 } while (childOfSelection && childOfSelection != this.selectionNode_);
233 } 233 }
234 // A character offset into content is the remaining case. It requires no 234 // A character offset into content is the remaining case. It requires no
235 // adjustment. 235 // adjustment.
236 236
237 return adjustedIndex; 237 return adjustedIndex;
238 }, 238 },
239 239
240 /** 240 /**
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 newIndex = 279 newIndex =
280 dir == Dir.FORWARD ? 0 : 280 dir == Dir.FORWARD ? 0 :
281 StringUtil.previousCodePointOffset(newText, newText.length); 281 StringUtil.previousCodePointOffset(newText, newText.length);
282 newIndex = Math.max(newIndex, 0); 282 newIndex = Math.max(newIndex, 0);
283 } else { 283 } else {
284 newIndex = this.index_; 284 newIndex = this.index_;
285 } 285 }
286 } 286 }
287 break; 287 break;
288 case Unit.WORD: 288 case Unit.WORD:
289 if (newNode.role != RoleType.inlineTextBox) { 289 if (newNode.role != RoleType.INLINE_TEXT_BOX) {
290 newNode = AutomationUtil.findNextNode(newNode, 290 newNode = AutomationUtil.findNextNode(newNode,
291 Dir.FORWARD, 291 Dir.FORWARD,
292 AutomationPredicate.inlineTextBox, 292 AutomationPredicate.inlineTextBox,
293 {skipInitialSubtree: false}) || newNode; 293 {skipInitialSubtree: false}) || newNode;
294 } 294 }
295 switch (movement) { 295 switch (movement) {
296 case Movement.BOUND: 296 case Movement.BOUND:
297 if (newNode.role == RoleType.inlineTextBox) { 297 if (newNode.role == RoleType.INLINE_TEXT_BOX) {
298 var start, end; 298 var start, end;
299 for (var i = 0; i < newNode.wordStarts.length; i++) { 299 for (var i = 0; i < newNode.wordStarts.length; i++) {
300 if (newIndex >= newNode.wordStarts[i] && 300 if (newIndex >= newNode.wordStarts[i] &&
301 newIndex <= newNode.wordEnds[i]) { 301 newIndex <= newNode.wordEnds[i]) {
302 start = newNode.wordStarts[i]; 302 start = newNode.wordStarts[i];
303 end = newNode.wordEnds[i]; 303 end = newNode.wordEnds[i];
304 break; 304 break;
305 } 305 }
306 } 306 }
307 if (goog.isDef(start) && goog.isDef(end)) 307 if (goog.isDef(start) && goog.isDef(end))
308 newIndex = dir == Dir.FORWARD ? end : start; 308 newIndex = dir == Dir.FORWARD ? end : start;
309 } else { 309 } else {
310 // TODO(dtseng): Figure out what to do in this case. 310 // TODO(dtseng): Figure out what to do in this case.
311 } 311 }
312 break; 312 break;
313 case Movement.DIRECTIONAL: 313 case Movement.DIRECTIONAL:
314 if (newNode.role == RoleType.inlineTextBox) { 314 if (newNode.role == RoleType.INLINE_TEXT_BOX) {
315 var start, end; 315 var start, end;
316 for (var i = 0; i < newNode.wordStarts.length; i++) { 316 for (var i = 0; i < newNode.wordStarts.length; i++) {
317 if (newIndex >= newNode.wordStarts[i] && 317 if (newIndex >= newNode.wordStarts[i] &&
318 newIndex <= newNode.wordEnds[i]) { 318 newIndex <= newNode.wordEnds[i]) {
319 var nextIndex = dir == Dir.FORWARD ? i + 1 : i - 1; 319 var nextIndex = dir == Dir.FORWARD ? i + 1 : i - 1;
320 start = newNode.wordStarts[nextIndex]; 320 start = newNode.wordStarts[nextIndex];
321 end = newNode.wordEnds[nextIndex]; 321 end = newNode.wordEnds[nextIndex];
322 break; 322 break;
323 } 323 }
324 } 324 }
325 if (goog.isDef(start)) { 325 if (goog.isDef(start)) {
326 newIndex = start; 326 newIndex = start;
327 } else { 327 } else {
328 // The backward case is special at the beginning of nodes. 328 // The backward case is special at the beginning of nodes.
329 if (dir == Dir.BACKWARD && newIndex != 0) { 329 if (dir == Dir.BACKWARD && newIndex != 0) {
330 newIndex = 0; 330 newIndex = 0;
331 } else { 331 } else {
332 newNode = AutomationUtil.findNextNode(newNode, dir, 332 newNode = AutomationUtil.findNextNode(newNode, dir,
333 AutomationPredicate.leaf); 333 AutomationPredicate.leaf);
334 if (newNode) { 334 if (newNode) {
335 newIndex = 0; 335 newIndex = 0;
336 if (dir == Dir.BACKWARD && 336 if (dir == Dir.BACKWARD &&
337 newNode.role == RoleType.inlineTextBox) { 337 newNode.role == RoleType.INLINE_TEXT_BOX) {
338 var starts = newNode.wordStarts; 338 var starts = newNode.wordStarts;
339 newIndex = starts[starts.length - 1] || 0; 339 newIndex = starts[starts.length - 1] || 0;
340 } else { 340 } else {
341 // TODO(dtseng): Figure out what to do for general nodes. 341 // TODO(dtseng): Figure out what to do for general nodes.
342 } 342 }
343 } 343 }
344 } 344 }
345 } 345 }
346 } else { 346 } else {
347 // TODO(dtseng): Figure out what to do in this case. 347 // TODO(dtseng): Figure out what to do in this case.
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
598 598
599 /** 599 /**
600 * Returns true if this range covers inline text (i.e. each end points to an 600 * Returns true if this range covers inline text (i.e. each end points to an
601 * inlineTextBox). 601 * inlineTextBox).
602 * @return {boolean?} 602 * @return {boolean?}
603 */ 603 */
604 isInlineText: function() { 604 isInlineText: function() {
605 return this.start.node && 605 return this.start.node &&
606 this.end.node && 606 this.end.node &&
607 this.start.node.role == this.end.node.role && 607 this.start.node.role == this.end.node.role &&
608 this.start.node.role == RoleType.inlineTextBox; 608 this.start.node.role == RoleType.INLINE_TEXT_BOX;
609 }, 609 },
610 610
611 /** 611 /**
612 * Makes a Range which has been moved from this range by the given unit and 612 * Makes a Range which has been moved from this range by the given unit and
613 * direction. 613 * direction.
614 * @param {Unit} unit 614 * @param {Unit} unit
615 * @param {Dir} dir 615 * @param {Dir} dir
616 * @return {cursors.Range} 616 * @return {cursors.Range}
617 */ 617 */
618 move: function(unit, dir) { 618 move: function(unit, dir) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
650 */ 650 */
651 select: function() { 651 select: function() {
652 var startNode = this.start.selectionNode_; 652 var startNode = this.start.selectionNode_;
653 var endNode = this.end.selectionNode_; 653 var endNode = this.end.selectionNode_;
654 654
655 if (!startNode || !endNode) 655 if (!startNode || !endNode)
656 return; 656 return;
657 657
658 // Only allow selections within the same web tree. 658 // Only allow selections within the same web tree.
659 if (startNode.root && 659 if (startNode.root &&
660 startNode.root.role == RoleType.rootWebArea && 660 startNode.root.role == RoleType.ROOT_WEB_AREA &&
661 startNode.root == endNode.root) { 661 startNode.root == endNode.root) {
662 // We want to adjust to select the entire node for node offsets; 662 // We want to adjust to select the entire node for node offsets;
663 // otherwise, use the plain character offset. 663 // otherwise, use the plain character offset.
664 var startIndex = this.start.selectionIndex_; 664 var startIndex = this.start.selectionIndex_;
665 var endIndex = this.end.index_ == cursors.NODE_INDEX ? 665 var endIndex = this.end.index_ == cursors.NODE_INDEX ?
666 this.end.selectionIndex_ + 1 : this.end.selectionIndex_; 666 this.end.selectionIndex_ + 1 : this.end.selectionIndex_;
667 667
668 chrome.automation.setDocumentSelection( 668 chrome.automation.setDocumentSelection(
669 { anchorObject: startNode, 669 { anchorObject: startNode,
670 anchorOffset: startIndex, 670 anchorOffset: startIndex,
671 focusObject: endNode, 671 focusObject: endNode,
672 focusOffset: endIndex } 672 focusOffset: endIndex }
673 ); 673 );
674 } 674 }
675 }, 675 },
676 676
677 /** 677 /**
678 * Returns true if this range has either cursor end on web content. 678 * Returns true if this range has either cursor end on web content.
679 * @return {boolean} 679 * @return {boolean}
680 */ 680 */
681 isWebRange: function() { 681 isWebRange: function() {
682 return this.isValid() && 682 return this.isValid() &&
683 (this.start.node.root.role != RoleType.desktop || 683 (this.start.node.root.role != RoleType.DESKTOP ||
684 this.end.node.root.role != RoleType.desktop); 684 this.end.node.root.role != RoleType.DESKTOP);
685 }, 685 },
686 686
687 /** 687 /**
688 * Returns whether this range has valid start and end cursors. 688 * Returns whether this range has valid start and end cursors.
689 * @return {boolean} 689 * @return {boolean}
690 */ 690 */
691 isValid: function() { 691 isValid: function() {
692 return this.start.isValid() && this.end.isValid(); 692 return this.start.isValid() && this.end.isValid();
693 } 693 }
694 }; 694 };
695 695
696 }); // goog.scope 696 }); // goog.scope
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698