Chromium Code Reviews| 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 |