diff --git a/accessible/jsat/ContentControl.jsm b/accessible/jsat/ContentControl.jsm index c726fa52b7a2..fecad206f4ee 100644 --- a/accessible/jsat/ContentControl.jsm +++ b/accessible/jsat/ContentControl.jsm @@ -15,7 +15,9 @@ XPCOMUtils.defineLazyModuleGetter(this, 'Logger', XPCOMUtils.defineLazyModuleGetter(this, 'Roles', 'resource://gre/modules/accessibility/Constants.jsm'); XPCOMUtils.defineLazyModuleGetter(this, 'TraversalRules', - 'resource://gre/modules/accessibility/TraversalRules.jsm'); + 'resource://gre/modules/accessibility/Traversal.jsm'); +XPCOMUtils.defineLazyModuleGetter(this, 'TraversalHelper', + 'resource://gre/modules/accessibility/Traversal.jsm'); XPCOMUtils.defineLazyModuleGetter(this, 'Presentation', 'resource://gre/modules/accessibility/Presentation.jsm'); @@ -27,7 +29,6 @@ const MOVEMENT_GRANULARITY_PARAGRAPH = 8; this.ContentControl = function ContentControl(aContentScope) { this._contentScope = Cu.getWeakReference(aContentScope); - this._vcCache = new WeakMap(); this._childMessageSenders = new WeakMap(); }; @@ -128,7 +129,7 @@ this.ContentControl.prototype = { return; } - let moved = vc[action](TraversalRules[aMessage.json.rule]); + let moved = TraversalHelper.move(vc, action, aMessage.json.rule); if (moved) { if (origin === 'child') { diff --git a/accessible/jsat/EventManager.jsm b/accessible/jsat/EventManager.jsm index d026b519599d..365eb10833ff 100644 --- a/accessible/jsat/EventManager.jsm +++ b/accessible/jsat/EventManager.jsm @@ -18,8 +18,6 @@ XPCOMUtils.defineLazyModuleGetter(this, 'Logger', 'resource://gre/modules/accessibility/Utils.jsm'); XPCOMUtils.defineLazyModuleGetter(this, 'Presentation', 'resource://gre/modules/accessibility/Presentation.jsm'); -XPCOMUtils.defineLazyModuleGetter(this, 'TraversalRules', - 'resource://gre/modules/accessibility/TraversalRules.jsm'); XPCOMUtils.defineLazyModuleGetter(this, 'Roles', 'resource://gre/modules/accessibility/Constants.jsm'); XPCOMUtils.defineLazyModuleGetter(this, 'Events', diff --git a/accessible/jsat/TraversalRules.jsm b/accessible/jsat/Traversal.jsm similarity index 84% rename from accessible/jsat/TraversalRules.jsm rename to accessible/jsat/Traversal.jsm index 610693f3451a..1c4cd82a3bb2 100644 --- a/accessible/jsat/TraversalRules.jsm +++ b/accessible/jsat/Traversal.jsm @@ -4,14 +4,14 @@ /* global PrefCache, Roles, Prefilters, States, Filters, Utils, TraversalRules, Components, XPCOMUtils */ -/* exported TraversalRules */ +/* exported TraversalRules, TraversalHelper */ 'use strict'; const Ci = Components.interfaces; const Cu = Components.utils; -this.EXPORTED_SYMBOLS = ['TraversalRules']; // jshint ignore:line +this.EXPORTED_SYMBOLS = ['TraversalRules', 'TraversalHelper']; // jshint ignore:line Cu.import('resource://gre/modules/accessibility/Utils.jsm'); Cu.import('resource://gre/modules/XPCOMUtils.jsm'); @@ -26,7 +26,7 @@ XPCOMUtils.defineLazyModuleGetter(this, 'Prefilters', // jshint ignore:line let gSkipEmptyImages = new PrefCache('accessibility.accessfu.skip_empty_images'); -function BaseTraversalRule(aRoles, aMatchFunc, aPreFilter) { +function BaseTraversalRule(aRoles, aMatchFunc, aPreFilter, aContainerRule) { this._explicitMatchRoles = new Set(aRoles); this._matchRoles = aRoles; if (aRoles.length) { @@ -40,6 +40,7 @@ function BaseTraversalRule(aRoles, aMatchFunc, aPreFilter) { } this._matchFunc = aMatchFunc || function() { return Filters.MATCH; }; this.preFilter = aPreFilter || gSimplePreFilter; + this.containerRule = aContainerRule; } BaseTraversalRule.prototype = { @@ -221,8 +222,7 @@ this.TraversalRules = { // jshint ignore:line function Landmark_match(aAccessible) { return Utils.getLandmarkName(aAccessible) ? Filters.MATCH : Filters.IGNORE; - } - ), + }, null, true), Entry: new BaseTraversalRule( [Roles.ENTRY, @@ -276,7 +276,8 @@ this.TraversalRules = { // jshint ignore:line List: new BaseTraversalRule( [Roles.LIST, - Roles.DEFINITION_LIST]), + Roles.DEFINITION_LIST], + null, null, true), PageTab: new BaseTraversalRule( [Roles.PAGETAB]), @@ -316,3 +317,51 @@ this.TraversalRules = { // jshint ignore:line return Filters.MATCH; } }; + +this.TraversalHelper = { + _helperPivotCache: null, + + get helperPivotCache() { + delete this.helperPivotCache; + this.helperPivotCache = new WeakMap(); + return this.helperPivotCache; + }, + + getHelperPivot: function TraversalHelper_getHelperPivot(aRoot) { + let pivot = this.helperPivotCache.get(aRoot.DOMNode); + if (!pivot) { + pivot = Utils.AccRetrieval.createAccessiblePivot(aRoot); + this.helperPivotCache.set(aRoot.DOMNode, pivot); + } + + return pivot; + }, + + move: function TraversalHelper_move(aVirtualCursor, aMethod, aRule) { + let rule = TraversalRules[aRule]; + + if (rule.containerRule) { + let moved = false; + let helperPivot = this.getHelperPivot(aVirtualCursor.root); + helperPivot.position = aVirtualCursor.position; + + // We continue to step through containers until there is one with an + // atomic child (via 'Simple') on which we could land. + while (!moved) { + if (helperPivot[aMethod](rule)) { + aVirtualCursor.modalRoot = helperPivot.position; + moved = aVirtualCursor.moveFirst(TraversalRules.Simple); + aVirtualCursor.modalRoot = null; + } else { + // If we failed to step to another container, break and return false. + break; + } + } + + return moved; + } else { + return aVirtualCursor[aMethod](rule); + } + } + +}; diff --git a/accessible/jsat/content-script.js b/accessible/jsat/content-script.js index ae50adf70def..27c60d3885db 100644 --- a/accessible/jsat/content-script.js +++ b/accessible/jsat/content-script.js @@ -10,8 +10,6 @@ XPCOMUtils.defineLazyModuleGetter(this, 'Logger', 'resource://gre/modules/accessibility/Utils.jsm'); XPCOMUtils.defineLazyModuleGetter(this, 'Presentation', 'resource://gre/modules/accessibility/Presentation.jsm'); -XPCOMUtils.defineLazyModuleGetter(this, 'TraversalRules', - 'resource://gre/modules/accessibility/TraversalRules.jsm'); XPCOMUtils.defineLazyModuleGetter(this, 'Utils', 'resource://gre/modules/accessibility/Utils.jsm'); XPCOMUtils.defineLazyModuleGetter(this, 'EventManager', diff --git a/accessible/jsat/moz.build b/accessible/jsat/moz.build index 1609f6f67856..5f11ee18f6c8 100644 --- a/accessible/jsat/moz.build +++ b/accessible/jsat/moz.build @@ -13,7 +13,7 @@ EXTRA_JS_MODULES.accessibility += [ 'OutputGenerator.jsm', 'PointerAdapter.jsm', 'Presentation.jsm', - 'TraversalRules.jsm', + 'Traversal.jsm', 'Utils.jsm' ] diff --git a/accessible/tests/mochitest/jsat/a11y.ini b/accessible/tests/mochitest/jsat/a11y.ini index 44993aac7661..78143b2a0cc6 100644 --- a/accessible/tests/mochitest/jsat/a11y.ini +++ b/accessible/tests/mochitest/jsat/a11y.ini @@ -24,3 +24,4 @@ skip-if = buildapp == 'mulet' [test_tables.html] [test_pointer_relay.html] [test_traversal.html] +[test_traversal_helper.html] diff --git a/accessible/tests/mochitest/jsat/test_traversal.html b/accessible/tests/mochitest/jsat/test_traversal.html index 2da0346ce52d..7a958db16d11 100644 --- a/accessible/tests/mochitest/jsat/test_traversal.html +++ b/accessible/tests/mochitest/jsat/test_traversal.html @@ -21,7 +21,7 @@ + + + + + + + + + + + + +
+ + Mozilla Bug xxx + + +++ +