OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 Objects related to incremental search. | 6 * @fileoverview Objects related to incremental search. |
7 */ | 7 */ |
8 | 8 |
9 goog.provide('ISearch'); | 9 goog.provide('ISearch'); |
10 goog.provide('ISearchHandler'); | 10 goog.provide('ISearchHandler'); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
45 | 45 |
46 /** | 46 /** |
47 * Controls an incremental search. | 47 * Controls an incremental search. |
48 * @param {!AutomationNode} initialNode | 48 * @param {!AutomationNode} initialNode |
49 * @constructor | 49 * @constructor |
50 */ | 50 */ |
51 ISearch = function(initialNode) { | 51 ISearch = function(initialNode) { |
52 var leaf = AutomationUtil.findNodePre( | 52 var leaf = AutomationUtil.findNodePre( |
53 initialNode, Dir.FORWARD, AutomationPredicate.leaf) || initialNode; | 53 initialNode, Dir.FORWARD, AutomationPredicate.leaf) || initialNode; |
54 | 54 |
55 /** @type {!AutomationNode} @private */ | 55 /** @type {!cursors.Cursor} */ |
56 this.node_ = leaf; | 56 this.cursor = cursors.Cursor.fromNode(leaf); |
57 | 57 |
58 /** | 58 /** |
59 * This tracks the id of a search that is in progress. | 59 * This tracks the id of a search that is in progress. |
60 * @type {number} @private | 60 * @type {number} @private |
61 */ | 61 */ |
62 this.pendingSearchId_ = 0; | 62 this.pendingSearchId_ = 0; |
63 | 63 |
64 // Global exports. | 64 // Global exports. |
65 /** Exported for this background script. */ | 65 /** Exported for this background script. */ |
66 cvox.ChromeVox = chrome.extension.getBackgroundPage()['cvox']['ChromeVox']; | 66 cvox.ChromeVox = chrome.extension.getBackgroundPage()['cvox']['ChromeVox']; |
(...skipping 16 matching lines...) Expand all Loading... | |
83 searchStr = searchStr.toLocaleLowerCase(); | 83 searchStr = searchStr.toLocaleLowerCase(); |
84 // Keep things responsive by chunking cursor moves up into discrete | 84 // Keep things responsive by chunking cursor moves up into discrete |
85 // blocks. We can, if needed, simulate getting interrupted by the enter key. | 85 // blocks. We can, if needed, simulate getting interrupted by the enter key. |
86 var currentSearchId = ++this.pendingSearchId_; | 86 var currentSearchId = ++this.pendingSearchId_; |
87 var move = function(curNode) { | 87 var move = function(curNode) { |
88 var cur = cursors.Cursor.fromNode(curNode); | 88 var cur = cursors.Cursor.fromNode(curNode); |
89 var prev = cur; | 89 var prev = cur; |
90 cur = | 90 cur = |
91 cur.move(cursors.Unit.NODE, cursors.Movement.DIRECTIONAL, dir); | 91 cur.move(cursors.Unit.NODE, cursors.Movement.DIRECTIONAL, dir); |
92 if (prev.equals(cur)) { | 92 if (prev.equals(cur)) { |
93 this.handler_.onSearchReachedBoundary(this.node_); | 93 this.handler_.onSearchReachedBoundary(this.cursor.node); |
94 return; | 94 return; |
95 } | 95 } |
96 | 96 |
97 if (cur.getText().toLocaleLowerCase().indexOf(searchStr) != -1) { | 97 if (cur.getText().toLocaleLowerCase().indexOf(searchStr) != -1) { |
98 this.node_ = cur.node; | 98 this.cursor = cur; |
99 this.handler_.onSearchResultChanged(this.node_); | 99 this.handler_.onSearchResultChanged(this.cursor.node); |
100 return; | 100 return; |
101 } | 101 } |
102 if (this.pendingSearchId_ == currentSearchId) | 102 if (this.pendingSearchId_ == currentSearchId) |
103 window.setTimeout(move.bind(this, cur.node), 0); | 103 window.setTimeout(move.bind(this, cur.node), 0); |
104 }; | 104 }; |
105 window.setTimeout(move.bind(this, this.node_), 0); | 105 window.setTimeout(move.bind(this, this.cursor.node), 0); |
106 } | 106 } |
107 }; | 107 }; |
108 | 108 |
109 /** | 109 /** |
110 * @param {Element} input | 110 * @param {Element} input |
111 * @constructor | 111 * @constructor |
112 * @implements {ISearchHandler} | 112 * @implements {ISearchHandler} |
113 */ | 113 */ |
114 ISearchUI = function(input) { | 114 ISearchUI = function(input) { |
115 /** @type {ChromeVoxState} @private */ | 115 /** @type {ChromeVoxState} @private */ |
116 this.background_ = | 116 this.background_ = |
117 chrome.extension.getBackgroundPage()['ChromeVoxState']['instance']; | 117 chrome.extension.getBackgroundPage()['ChromeVoxState']['instance']; |
118 this.iSearch_ = new ISearch(this.background_.currentRange.start.node); | 118 this.iSearch_ = new ISearch(this.background_.currentRange.start.node); |
dmazzoni
2017/01/10 16:07:15
How about if you have the ISearch constructor take
| |
119 this.input_ = input; | 119 this.input_ = input; |
120 this.dir_ = Dir.FORWARD; | 120 this.dir_ = Dir.FORWARD; |
121 this.iSearch_.handler = this; | 121 this.iSearch_.handler = this; |
122 | 122 |
123 this.onKeyDown = this.onKeyDown.bind(this); | 123 this.onKeyDown = this.onKeyDown.bind(this); |
124 this.onTextInput = this.onTextInput.bind(this); | 124 this.onTextInput = this.onTextInput.bind(this); |
125 | 125 |
126 input.addEventListener('keydown', this.onKeyDown, true); | 126 input.addEventListener('keydown', this.onKeyDown, true); |
127 input.addEventListener('textInput', this.onTextInput, true); | 127 input.addEventListener('textInput', this.onTextInput, true); |
128 }; | 128 }; |
129 | 129 |
130 /** | 130 /** |
131 * @param {Element} input | 131 * @param {Element} input |
132 * @return {ISearchUI} | 132 * @return {ISearchUI} |
133 */ | 133 */ |
134 ISearchUI.get = function(input) { | 134 ISearchUI.init = function(input) { |
135 if (ISearchUI.instance_) | 135 if (ISearchUI.instance_) |
136 ISearchUI.instance_.destroy(); | 136 ISearchUI.instance_.destroy(); |
137 | |
138 if (!input) | |
139 return null; | |
140 | |
137 ISearchUI.instance_ = new ISearchUI(input); | 141 ISearchUI.instance_ = new ISearchUI(input); |
138 input.focus(); | 142 input.focus(); |
143 input.select(); | |
139 return ISearchUI.instance_; | 144 return ISearchUI.instance_; |
140 }; | 145 }; |
141 | 146 |
142 ISearchUI.prototype = { | 147 ISearchUI.prototype = { |
143 /** | 148 /** |
144 * Listens to key down events. | 149 * Listens to key down events. |
145 * @param {Event} evt | 150 * @param {Event} evt |
146 * @return {boolean} | 151 * @return {boolean} |
147 */ | 152 */ |
148 onKeyDown: function(evt) { | 153 onKeyDown: function(evt) { |
149 switch (evt.key) { | 154 switch (evt.key) { |
150 case 'ArrowUp': | 155 case 'ArrowUp': |
151 this.dir_ = Dir.BACKWARD; | 156 this.dir_ = Dir.BACKWARD; |
152 break; | 157 break; |
153 case 'ArrowDown': | 158 case 'ArrowDown': |
154 this.dir_ = Dir.FORWARD; | 159 this.dir_ = Dir.FORWARD; |
155 break; | 160 break; |
156 case 'Escape': | 161 case 'Escape': |
157 this.pendingSearchId_ = 0; | 162 this.pendingSearchId_ = 0; |
158 Panel.closeMenusAndRestoreFocus(); | 163 Panel.closeMenusAndRestoreFocus(); |
159 return false; | 164 return false; |
160 case 'Enter': | 165 case 'Enter': |
161 this.pendingSearchId_ = 0; | 166 this.pendingSearchId_ = 0; |
167 Panel.setPendingCallback(function() { | |
168 var node = this.iSearch_.cursor.node; | |
169 if (!node) | |
170 return; | |
171 chrome.extension.getBackgroundPage().ChromeVoxState.instance[ | |
172 'navigateToRange']( | |
173 cursors.Range.fromNode(node)); | |
174 }.bind(this)); | |
162 Panel.closeMenusAndRestoreFocus(); | 175 Panel.closeMenusAndRestoreFocus(); |
163 return false; | 176 return false; |
164 default: | 177 default: |
165 this.pendingSearchId_ = 0; | 178 this.pendingSearchId_ = 0; |
166 return false; | 179 return false; |
167 } | 180 } |
168 this.iSearch_.search(this.input_.value, this.dir_); | 181 this.iSearch_.search(this.input_.value, this.dir_); |
169 evt.preventDefault(); | 182 evt.preventDefault(); |
170 evt.stopPropagation(); | 183 evt.stopPropagation(); |
171 return false; | 184 return false; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
213 this.iSearch_.handler_ = null; | 226 this.iSearch_.handler_ = null; |
214 this.iSearch_ = null; | 227 this.iSearch_ = null; |
215 var input = this.input_; | 228 var input = this.input_; |
216 this.input_ = null; | 229 this.input_ = null; |
217 input.removeEventListener('keydown', this.onKeyDown, true); | 230 input.removeEventListener('keydown', this.onKeyDown, true); |
218 input.removeEventListener('textInput', this.onTextInput, true); | 231 input.removeEventListener('textInput', this.onTextInput, true); |
219 } | 232 } |
220 }; | 233 }; |
221 | 234 |
222 }); // goog.scope | 235 }); // goog.scope |
OLD | NEW |