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

Unified Diff: chrome/browser/resources/chromeos/chromevox/cvox2/background/panel_menu.js

Issue 2443103004: Defer creating ChromeVox node menus to make menus open more quickly. (Closed)
Patch Set: Call finish from all codepaths Created 4 years, 1 month 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/resources/chromeos/chromevox/cvox2/background/panel.js ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/resources/chromeos/chromevox/cvox2/background/panel_menu.js
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/panel_menu.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/panel_menu.js
index f160480783052f7ac7af4e9c20cd3572ef3a8094..1cf338574d7c0449dd4441ae759c658b1e1fc0a8 100644
--- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/panel_menu.js
+++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/panel_menu.js
@@ -9,6 +9,7 @@
goog.provide('PanelMenu');
goog.provide('PanelNodeMenu');
+goog.require('AutomationTreeWalker');
goog.require('Output');
goog.require('PanelMenuItem');
goog.require('constants');
@@ -229,45 +230,26 @@ PanelMenu.prototype = {
* @param {string} menuMsg The msg id of the menu.
* @param {chrome.automation.AutomationNode} node ChromeVox's current position.
* @param {AutomationPredicate.Unary} pred Filter to use on the document.
+ * @param {boolean} async If true, populates the menu asynchronously by
+ * posting a task after searching each chunk of nodes.
* @extends {PanelMenu}
* @constructor
*/
-PanelNodeMenu = function(menuMsg, node, pred) {
+PanelNodeMenu = function(menuMsg, node, pred, async) {
PanelMenu.call(this, menuMsg);
- var nodes = [];
- var selectNext = false;
- var activeIndex = -1;
- AutomationUtil.findNodePre(node.root, constants.Dir.FORWARD,
- /** @type {AutomationPredicate.Unary} */(function(n) {
- if (n === node)
- selectNext = true;
-
- if (pred(n)) {
- var output = new Output();
- var range = cursors.Range.fromNode(n);
- output.withSpeech(range, range, Output.EventType.NAVIGATE);
- var label = output.toString();
- this.addMenuItem(label, '', function() {
- chrome.extension.getBackgroundPage().ChromeVoxState
- .instance['navigateToRange'](cursors.Range.fromNode(n));
- });
- if (selectNext) {
- activeIndex = this.items_.length - 1;
- selectNext = false;
- }
- }
- }).bind(this)
- );
-
- if (!this.items_.length) {
- this.addMenuItem(
- Msgs.getMsg('panel_menu_item_none'), '', function() {});
- this.activateItem(0);
- }
- if (activeIndex >= 0)
- this.activateItem(activeIndex);
+ this.node_ = node;
+ this.pred_ = pred;
+ this.async_ = async;
+ this.populate_();
};
+/**
+ * The number of nodes to search before posting a task to finish
+ * searching.
+ * @const {number}
+ */
+PanelNodeMenu.MAX_NODES_BEFORE_ASYNC = 100;
+
PanelNodeMenu.prototype = {
__proto__: PanelMenu.prototype,
@@ -276,5 +258,88 @@ PanelNodeMenu.prototype = {
var activeItem = this.activeIndex_;
PanelMenu.prototype.activate.call(this);
this.activateItem(activeItem);
+ },
+
+ /**
+ * Create the AutomationTreeWalker and kick off the search to find
+ * nodes that match the predicate for this menu.
+ * @private
+ */
+ populate_: function() {
+ if (!this.node_) {
+ this.finish_();
+ return;
+ }
+
+ var root = AutomationUtil.getTopLevelRoot(this.node_);
+ if (!root) {
+ this.finish_();
+ return;
+ }
+
+ this.walker_ = new AutomationTreeWalker(
+ root,
+ constants.Dir.FORWARD,
+ {visit: function(node) {
+ return !AutomationPredicate.shouldIgnoreNode(node);
+ }});
+ this.nodeCount_ = 0;
+ this.selectNext_ = false;
+ this.findMoreNodes_();
+ },
+
+ /**
+ * Iterate over nodes from the tree walker. If a node matches the
+ * predicate, add an item to the menu.
+ *
+ * If |this.async_| is true, then after MAX_NODES_BEFORE_ASYNC nodes
+ * have been scanned, call setTimeout to defer searching. This frees
+ * up the main event loop to keep the panel menu responsive, otherwise
+ * it basically freezes up until all of the nodes have been found.
+ * @private
+ */
+ findMoreNodes_: function() {
+ while (this.walker_.next().node) {
+ var node = this.walker_.node;
+ if (node == this.node_)
+ this.selectNext_ = true;
+ if (this.pred_(node)) {
+ var output = new Output();
+ var range = cursors.Range.fromNode(node);
+ output.withSpeech(range, range, Output.EventType.NAVIGATE);
+ var label = output.toString();
+ this.addMenuItem(label, '', function() {
+ chrome.extension.getBackgroundPage().ChromeVoxState
+ .instance['navigateToRange'](cursors.Range.fromNode(node));
+ });
+ if (this.selectNext_) {
+ this.activateItem(this.items_.length - 1);
+ this.selectNext_ = false;
+ }
+ }
+
+ if (this.async_) {
+ this.nodeCount_++;
+ if (this.nodeCount_ >= PanelNodeMenu.MAX_NODES_BEFORE_ASYNC) {
+ this.nodeCount_ = 0;
+ window.setTimeout(this.findMoreNodes_.bind(this), 0);
+ return;
+ }
+ }
+ }
+ this.finish_();
+ },
+
+ /**
+ * Called when we've finished searching for nodes. If no matches were
+ * found, adds an item to the menu indicating none were found.
+ * @private
+ */
+ finish_: function() {
+ if (!this.items_.length) {
+ this.addMenuItem(
+ Msgs.getMsg('panel_menu_item_none'), '', function() {});
+ this.activateItem(0);
+ }
}
};
« no previous file with comments | « chrome/browser/resources/chromeos/chromevox/cvox2/background/panel.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698