| 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 An abstract class for walking at the sub-element level. | 6 * @fileoverview An abstract class for walking at the sub-element level. |
| 7 * For example, walking at the sentence, word, or character level. | 7 * For example, walking at the sentence, word, or character level. |
| 8 * This class is an adapter around TraverseContent which exposes the interface | 8 * This class is an adapter around TraverseContent which exposes the interface |
| 9 * required by walkers. Subclasses must override the this.grain attribute | 9 * required by walkers. Subclasses must override the this.grain attribute |
| 10 * on initialization. | 10 * on initialization. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 goog.require('cvox.TraverseContent'); | 21 goog.require('cvox.TraverseContent'); |
| 22 | 22 |
| 23 /** | 23 /** |
| 24 * @constructor | 24 * @constructor |
| 25 * @extends {cvox.AbstractWalker} | 25 * @extends {cvox.AbstractWalker} |
| 26 */ | 26 */ |
| 27 cvox.AbstractSelectionWalker = function() { | 27 cvox.AbstractSelectionWalker = function() { |
| 28 cvox.AbstractWalker.call(this); | 28 cvox.AbstractWalker.call(this); |
| 29 this.objWalker_ = new cvox.BareObjectWalker(); | 29 this.objWalker_ = new cvox.BareObjectWalker(); |
| 30 this.tc_ = cvox.TraverseContent.getInstance(); | 30 this.tc_ = cvox.TraverseContent.getInstance(); |
| 31 this.grain /** @protected */ = ''; // child must override | 31 this.grain /** @protected */ = ''; // child must override |
| 32 }; | 32 }; |
| 33 goog.inherits(cvox.AbstractSelectionWalker, cvox.AbstractWalker); | 33 goog.inherits(cvox.AbstractSelectionWalker, cvox.AbstractWalker); |
| 34 | 34 |
| 35 /** | 35 /** |
| 36 * @override | 36 * @override |
| 37 */ | 37 */ |
| 38 cvox.AbstractSelectionWalker.prototype.next = function(sel) { | 38 cvox.AbstractSelectionWalker.prototype.next = function(sel) { |
| 39 var r = sel.isReversed(); | 39 var r = sel.isReversed(); |
| 40 this.tc_.syncToCursorSelection(sel.clone().setReversed(false)); | 40 this.tc_.syncToCursorSelection(sel.clone().setReversed(false)); |
| 41 var ret = r ? this.tc_.prevElement(this.grain) : | 41 var ret = |
| 42 this.tc_.nextElement(this.grain); | 42 r ? this.tc_.prevElement(this.grain) : this.tc_.nextElement(this.grain); |
| 43 if (ret == null) { | 43 if (ret == null) { |
| 44 // Unfortunately, we can't trust TraverseContent; fall back to ObjectWalker. | 44 // Unfortunately, we can't trust TraverseContent; fall back to ObjectWalker. |
| 45 return this.objWalker_.next(sel); | 45 return this.objWalker_.next(sel); |
| 46 } | 46 } |
| 47 var retSel = this.tc_.getCurrentCursorSelection().setReversed(r); | 47 var retSel = this.tc_.getCurrentCursorSelection().setReversed(r); |
| 48 var objSel = this.objWalker_.next(sel); | 48 var objSel = this.objWalker_.next(sel); |
| 49 objSel = objSel ? objSel.setReversed(r) : null; | 49 objSel = objSel ? objSel.setReversed(r) : null; |
| 50 | 50 |
| 51 // ObjectWalker wins when there's a discrepancy between it and | 51 // ObjectWalker wins when there's a discrepancy between it and |
| 52 // TraverseContent. The only exception is with an end cursor on a text node. | 52 // TraverseContent. The only exception is with an end cursor on a text node. |
| 53 // In all other cases, this makes sure we visit the same selections as | 53 // In all other cases, this makes sure we visit the same selections as |
| 54 // object walker. | 54 // object walker. |
| 55 if (objSel && | 55 if (objSel && |
| 56 (retSel.end.node.constructor.name != 'Text' || | 56 (retSel.end.node.constructor.name != 'Text' || |
| 57 objSel.end.node.constructor.name != 'Text') && | 57 objSel.end.node.constructor.name != 'Text') && |
| 58 !cvox.DomUtil.isDescendantOfNode(retSel.end.node, sel.end.node) && | 58 !cvox.DomUtil.isDescendantOfNode(retSel.end.node, sel.end.node) && |
| 59 !cvox.DomUtil.isDescendantOfNode(retSel.end.node, objSel.end.node)) { | 59 !cvox.DomUtil.isDescendantOfNode(retSel.end.node, objSel.end.node)) { |
| 60 return objSel; | 60 return objSel; |
| 61 } | 61 } |
| 62 return retSel; | 62 return retSel; |
| 63 }; | 63 }; |
| 64 | 64 |
| 65 /** | 65 /** |
| 66 * @override | 66 * @override |
| 67 */ | 67 */ |
| 68 cvox.AbstractSelectionWalker.prototype.sync = function(sel) { | 68 cvox.AbstractSelectionWalker.prototype.sync = function(sel) { |
| 69 var r = sel.isReversed(); | 69 var r = sel.isReversed(); |
| 70 var newSel = null; | 70 var newSel = null; |
| 71 if (sel.start.equals(sel.end) && sel.start.node.constructor.name != 'Text') { | 71 if (sel.start.equals(sel.end) && sel.start.node.constructor.name != 'Text') { |
| 72 var node = sel.start.node; | 72 var node = sel.start.node; |
| 73 | 73 |
| 74 // Find the deepest visible node; written specifically here because we want | 74 // Find the deepest visible node; written specifically here because we want |
| 75 // to move across siblings if necessary and take the deepest node which can | 75 // to move across siblings if necessary and take the deepest node which can |
| 76 // be BODY. | 76 // be BODY. |
| 77 while (node && | 77 while (node && cvox.DomUtil.directedFirstChild(node, r) && |
| 78 cvox.DomUtil.directedFirstChild(node, r) && | 78 !cvox.TraverseUtil.treatAsLeafNode(node)) { |
| 79 !cvox.TraverseUtil.treatAsLeafNode(node)) { | |
| 80 var child = cvox.DomUtil.directedFirstChild(node, r); | 79 var child = cvox.DomUtil.directedFirstChild(node, r); |
| 81 | 80 |
| 82 // Find the first visible child. | 81 // Find the first visible child. |
| 83 while (child) { | 82 while (child) { |
| 84 if (cvox.DomUtil.isVisible(child, | 83 if (cvox.DomUtil.isVisible( |
| 85 {checkAncestors: false, checkDescendants: false})) { | 84 child, {checkAncestors: false, checkDescendants: false})) { |
| 86 node = child; | 85 node = child; |
| 87 break; | 86 break; |
| 88 } else { | 87 } else { |
| 89 child = cvox.DomUtil.directedNextSibling(child, r); | 88 child = cvox.DomUtil.directedNextSibling(child, r); |
| 90 } | 89 } |
| 91 } | 90 } |
| 92 | 91 |
| 93 // node has no visible children; it's therefore the deepest visible node. | 92 // node has no visible children; it's therefore the deepest visible node. |
| 94 if (!child) { | 93 if (!child) { |
| 95 break; | 94 break; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 116 objSel = objSel ? objSel.setReversed(r) : null; | 115 objSel = objSel ? objSel.setReversed(r) : null; |
| 117 | 116 |
| 118 if (!newSel) { | 117 if (!newSel) { |
| 119 return objSel; | 118 return objSel; |
| 120 } | 119 } |
| 121 | 120 |
| 122 newSel.setReversed(r); | 121 newSel.setReversed(r); |
| 123 | 122 |
| 124 if (objSel && | 123 if (objSel && |
| 125 (newSel.end.node.constructor.name != 'Text' || | 124 (newSel.end.node.constructor.name != 'Text' || |
| 126 objSel.end.node.constructor.name != 'Text') && | 125 objSel.end.node.constructor.name != 'Text') && |
| 127 !cvox.DomUtil.isDescendantOfNode(newSel.end.node, sel.end.node) && | 126 !cvox.DomUtil.isDescendantOfNode(newSel.end.node, sel.end.node) && |
| 128 !cvox.DomUtil.isDescendantOfNode(newSel.end.node, objSel.end.node)) { | 127 !cvox.DomUtil.isDescendantOfNode(newSel.end.node, objSel.end.node)) { |
| 129 return objSel; | 128 return objSel; |
| 130 } | 129 } |
| 131 return newSel; | 130 return newSel; |
| 132 }; | 131 }; |
| 133 | 132 |
| 134 /** | 133 /** |
| 135 * @override | 134 * @override |
| 136 */ | 135 */ |
| 137 cvox.AbstractSelectionWalker.prototype.getDescription = function(prevSel, sel) { | 136 cvox.AbstractSelectionWalker.prototype.getDescription = function(prevSel, sel) { |
| 138 var description = cvox.DescriptionUtil.getDescriptionFromAncestors( | 137 var description = cvox.DescriptionUtil.getDescriptionFromAncestors( |
| 139 cvox.DomUtil.getUniqueAncestors(prevSel.end.node, sel.start.node), | 138 cvox.DomUtil.getUniqueAncestors(prevSel.end.node, sel.start.node), true, |
| 140 true, | |
| 141 cvox.ChromeVox.verbosity); | 139 cvox.ChromeVox.verbosity); |
| 142 description.text = sel.getText() || description.text; | 140 description.text = sel.getText() || description.text; |
| 143 return [description]; | 141 return [description]; |
| 144 }; | 142 }; |
| 145 | 143 |
| 146 /** | 144 /** |
| 147 * @override | 145 * @override |
| 148 */ | 146 */ |
| 149 cvox.AbstractSelectionWalker.prototype.getBraille = function(prevSel, sel) { | 147 cvox.AbstractSelectionWalker.prototype.getBraille = function(prevSel, sel) { |
| 150 var node = sel.absStart().node; | 148 var node = sel.absStart().node; |
| 151 var text = cvox.TraverseUtil.getNodeText(node); | 149 var text = cvox.TraverseUtil.getNodeText(node); |
| 152 var spannable = new Spannable(text); | 150 var spannable = new Spannable(text); |
| 153 spannable.setSpan(node, 0, text.length); | 151 spannable.setSpan(node, 0, text.length); |
| 154 return new cvox.NavBraille({ | 152 return new cvox.NavBraille({ |
| 155 text: spannable, | 153 text: spannable, |
| 156 startIndex: sel.absStart().index, | 154 startIndex: sel.absStart().index, |
| 157 endIndex: sel.absEnd().index | 155 endIndex: sel.absEnd().index |
| 158 }); | 156 }); |
| 159 }; | 157 }; |
| OLD | NEW |