зеркало из https://github.com/mozilla/gecko-dev.git
Bug 963373 - Update cursor after scroll. r=yzen
This commit is contained in:
Родитель
856768782f
Коммит
bdc0b9383b
|
@ -57,6 +57,7 @@ this.EventManager.prototype = {
|
|||
this.webProgress.addProgressListener(this,
|
||||
(Ci.nsIWebProgress.NOTIFY_STATE_ALL |
|
||||
Ci.nsIWebProgress.NOTIFY_LOCATION));
|
||||
this.addEventListener('wheel', this, true);
|
||||
this.addEventListener('scroll', this, true);
|
||||
this.addEventListener('resize', this, true);
|
||||
}
|
||||
|
@ -77,6 +78,7 @@ this.EventManager.prototype = {
|
|||
AccessibilityEventObserver.removeListener(this);
|
||||
try {
|
||||
this.webProgress.removeProgressListener(this);
|
||||
this.removeEventListener('wheel', this, true);
|
||||
this.removeEventListener('scroll', this, true);
|
||||
this.removeEventListener('resize', this, true);
|
||||
} catch (x) {
|
||||
|
@ -89,6 +91,23 @@ this.EventManager.prototype = {
|
|||
handleEvent: function handleEvent(aEvent) {
|
||||
try {
|
||||
switch (aEvent.type) {
|
||||
case 'wheel':
|
||||
{
|
||||
let attempts = 0;
|
||||
let vc = Utils.getVirtualCursor(this.contentScope.content.document);
|
||||
let intervalId = this.contentScope.content.setInterval(() => {
|
||||
if (!Utils.isAliveAndVisible(vc.position, true)) {
|
||||
this.contentScope.content.clearInterval(intervalId);
|
||||
let delta = aEvent.deltaX || aEvent.deltaY;
|
||||
this.contentScope.content.setTimeout(() => {
|
||||
vc[delta > 0 ? 'moveNext' : 'movePrevious'](TraversalRules.SimpleOnScreen);
|
||||
}, 100);
|
||||
} else if (++attempts > 5) {
|
||||
this.contentScope.content.clearInterval(intervalId);
|
||||
}
|
||||
}, 150);
|
||||
break;
|
||||
}
|
||||
case 'scroll':
|
||||
case 'resize':
|
||||
{
|
||||
|
|
|
@ -22,13 +22,14 @@ XPCOMUtils.defineLazyModuleGetter(this, 'States',
|
|||
|
||||
let gSkipEmptyImages = new PrefCache('accessibility.accessfu.skip_empty_images');
|
||||
|
||||
function BaseTraversalRule(aRoles, aMatchFunc) {
|
||||
function BaseTraversalRule(aRoles, aMatchFunc, aPreFilter) {
|
||||
this._explicitMatchRoles = new Set(aRoles);
|
||||
this._matchRoles = aRoles;
|
||||
if (aRoles.indexOf(Roles.LABEL) < 0) {
|
||||
this._matchRoles.push(Roles.LABEL);
|
||||
}
|
||||
this._matchFunc = aMatchFunc || function (acc) { return Filters.MATCH; };
|
||||
this.preFilter = aPreFilter || gSimplePreFilter;
|
||||
}
|
||||
|
||||
BaseTraversalRule.prototype = {
|
||||
|
@ -37,11 +38,6 @@ BaseTraversalRule.prototype = {
|
|||
return aRules.value.length;
|
||||
},
|
||||
|
||||
preFilter: Ci.nsIAccessibleTraversalRule.PREFILTER_DEFUNCT |
|
||||
Ci.nsIAccessibleTraversalRule.PREFILTER_INVISIBLE |
|
||||
Ci.nsIAccessibleTraversalRule.PREFILTER_ARIA_HIDDEN |
|
||||
Ci.nsIAccessibleTraversalRule.PREFILTER_TRANSPARENT,
|
||||
|
||||
match: function BaseTraversalRule_match(aAccessible)
|
||||
{
|
||||
let role = aAccessible.role;
|
||||
|
@ -96,59 +92,71 @@ var gSimpleTraversalRoles =
|
|||
// Used for traversing in to child OOP frames.
|
||||
Roles.INTERNAL_FRAME];
|
||||
|
||||
this.TraversalRules = {
|
||||
Simple: new BaseTraversalRule(
|
||||
gSimpleTraversalRoles,
|
||||
function Simple_match(aAccessible) {
|
||||
function hasZeroOrSingleChildDescendants () {
|
||||
for (let acc = aAccessible; acc.childCount > 0; acc = acc.firstChild) {
|
||||
if (acc.childCount > 1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (aAccessible.role) {
|
||||
case Roles.COMBOBOX:
|
||||
// We don't want to ignore the subtree because this is often
|
||||
// where the list box hangs out.
|
||||
return Filters.MATCH;
|
||||
case Roles.TEXT_LEAF:
|
||||
{
|
||||
// Nameless text leaves are boring, skip them.
|
||||
let name = aAccessible.name;
|
||||
if (name && name.trim())
|
||||
return Filters.MATCH;
|
||||
else
|
||||
return Filters.IGNORE;
|
||||
}
|
||||
case Roles.STATICTEXT:
|
||||
{
|
||||
let parent = aAccessible.parent;
|
||||
// Ignore prefix static text in list items. They are typically bullets or numbers.
|
||||
if (parent.childCount > 1 && aAccessible.indexInParent == 0 &&
|
||||
parent.role == Roles.LISTITEM)
|
||||
return Filters.IGNORE;
|
||||
|
||||
return Filters.MATCH;
|
||||
}
|
||||
case Roles.GRAPHIC:
|
||||
return TraversalRules._shouldSkipImage(aAccessible);
|
||||
case Roles.LINK:
|
||||
case Roles.HEADER:
|
||||
case Roles.HEADING:
|
||||
return hasZeroOrSingleChildDescendants() ?
|
||||
(Filters.MATCH | Filters.IGNORE_SUBTREE) : (Filters.IGNORE);
|
||||
default:
|
||||
// Ignore the subtree, if there is one. So that we don't land on
|
||||
// the same content that was already presented by its parent.
|
||||
return Filters.MATCH |
|
||||
Filters.IGNORE_SUBTREE;
|
||||
var gSimpleMatchFunc = function gSimpleMatchFunc(aAccessible) {
|
||||
function hasZeroOrSingleChildDescendants () {
|
||||
for (let acc = aAccessible; acc.childCount > 0; acc = acc.firstChild) {
|
||||
if (acc.childCount > 1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
),
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (aAccessible.role) {
|
||||
case Roles.COMBOBOX:
|
||||
// We don't want to ignore the subtree because this is often
|
||||
// where the list box hangs out.
|
||||
return Filters.MATCH;
|
||||
case Roles.TEXT_LEAF:
|
||||
{
|
||||
// Nameless text leaves are boring, skip them.
|
||||
let name = aAccessible.name;
|
||||
if (name && name.trim())
|
||||
return Filters.MATCH;
|
||||
else
|
||||
return Filters.IGNORE;
|
||||
}
|
||||
case Roles.STATICTEXT:
|
||||
{
|
||||
let parent = aAccessible.parent;
|
||||
// Ignore prefix static text in list items. They are typically bullets or numbers.
|
||||
if (parent.childCount > 1 && aAccessible.indexInParent == 0 &&
|
||||
parent.role == Roles.LISTITEM)
|
||||
return Filters.IGNORE;
|
||||
|
||||
return Filters.MATCH;
|
||||
}
|
||||
case Roles.GRAPHIC:
|
||||
return TraversalRules._shouldSkipImage(aAccessible);
|
||||
case Roles.LINK:
|
||||
case Roles.HEADER:
|
||||
case Roles.HEADING:
|
||||
return hasZeroOrSingleChildDescendants() ?
|
||||
(Filters.MATCH | Filters.IGNORE_SUBTREE) : (Filters.IGNORE);
|
||||
default:
|
||||
// Ignore the subtree, if there is one. So that we don't land on
|
||||
// the same content that was already presented by its parent.
|
||||
return Filters.MATCH |
|
||||
Filters.IGNORE_SUBTREE;
|
||||
}
|
||||
};
|
||||
|
||||
var gSimplePreFilter = Ci.nsIAccessibleTraversalRule.PREFILTER_DEFUNCT |
|
||||
Ci.nsIAccessibleTraversalRule.PREFILTER_INVISIBLE |
|
||||
Ci.nsIAccessibleTraversalRule.PREFILTER_ARIA_HIDDEN |
|
||||
Ci.nsIAccessibleTraversalRule.PREFILTER_TRANSPARENT;
|
||||
|
||||
this.TraversalRules = {
|
||||
Simple: new BaseTraversalRule(gSimpleTraversalRoles, gSimpleMatchFunc),
|
||||
|
||||
SimpleOnScreen: new BaseTraversalRule(
|
||||
gSimpleTraversalRoles, gSimpleMatchFunc,
|
||||
Ci.nsIAccessibleTraversalRule.PREFILTER_DEFUNCT |
|
||||
Ci.nsIAccessibleTraversalRule.PREFILTER_INVISIBLE |
|
||||
Ci.nsIAccessibleTraversalRule.PREFILTER_ARIA_HIDDEN |
|
||||
Ci.nsIAccessibleTraversalRule.PREFILTER_TRANSPARENT |
|
||||
Ci.nsIAccessibleTraversalRule.PREFILTER_OFFSCREEN),
|
||||
|
||||
Anchor: new BaseTraversalRule(
|
||||
[Roles.LINK],
|
||||
|
|
|
@ -269,7 +269,7 @@ this.Utils = {
|
|||
return false;
|
||||
},
|
||||
|
||||
isAliveAndVisible: function isAliveAndVisible(aAccessible) {
|
||||
isAliveAndVisible: function isAliveAndVisible(aAccessible, aIsOnScreen) {
|
||||
if (!aAccessible) {
|
||||
return false;
|
||||
}
|
||||
|
@ -277,6 +277,7 @@ this.Utils = {
|
|||
try {
|
||||
let state = this.getState(aAccessible);
|
||||
if (state.contains(States.DEFUNCT) || state.contains(States.INVISIBLE) ||
|
||||
(aIsOnScreen && state.contains(States.OFFSCREEN)) ||
|
||||
Utils.inHiddenSubtree(aAccessible)) {
|
||||
return false;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче