зеркало из https://github.com/mozilla/pjs.git
Bug 756287 - Introduce PresenterContext in AccessFu. r=davidb
This commit is contained in:
Родитель
48e27631de
Коммит
d53e34ef99
|
@ -215,12 +215,10 @@ var AccessFu = {
|
|||
doc.defaultView, null, Ci.nsIFocusManager.MOVEFOCUS_CARET, 0);
|
||||
}
|
||||
|
||||
let newContext = this.getNewContext(event.oldAccessible,
|
||||
pivot.position);
|
||||
let presenterContext = new PresenterContext(pivot.position,
|
||||
event.oldAccessible);
|
||||
this.presenters.forEach(
|
||||
function(p) {
|
||||
p.pivotChanged(pivot.position, newContext);
|
||||
});
|
||||
function(p) { p.pivotChanged(presenterContext); });
|
||||
break;
|
||||
}
|
||||
case Ci.nsIAccessibleEvent.EVENT_STATE_CHANGE:
|
||||
|
@ -313,8 +311,13 @@ var AccessFu = {
|
|||
{
|
||||
if (this._isBrowserDoc(aEvent.accessible)) {
|
||||
// The document recieved focus, call tabSelected to present current tab.
|
||||
let docContext = new PresenterContext(aEvent.accessible, null);
|
||||
let cursorable = aEvent.accessible.
|
||||
QueryInterface(Ci.nsIAccessibleCursorable);
|
||||
let vcContext = new PresenterContext(
|
||||
(cursorable) ? cursorable.virtualCursor.position : null, null);
|
||||
this.presenters.forEach(
|
||||
function(p) { p.tabSelected(aEvent.accessible); });
|
||||
function(p) { p.tabSelected(docContext, vcContext); });
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -383,41 +386,6 @@ var AccessFu = {
|
|||
return location.protocol != "about:";
|
||||
},
|
||||
|
||||
getNewContext: function getNewContext(aOldObject, aNewObject) {
|
||||
let newLineage = [];
|
||||
let oldLineage = [];
|
||||
|
||||
let parent = aNewObject;
|
||||
while ((parent = parent.parent))
|
||||
newLineage.push(parent);
|
||||
|
||||
if (aOldObject) {
|
||||
parent = aOldObject;
|
||||
while ((parent = parent.parent))
|
||||
oldLineage.push(parent);
|
||||
}
|
||||
|
||||
// newLineage.reverse();
|
||||
// oldLineage.reverse();
|
||||
|
||||
let i = 0;
|
||||
let newContext = [];
|
||||
|
||||
while (true) {
|
||||
let newAncestor = newLineage.pop();
|
||||
let oldAncestor = oldLineage.pop();
|
||||
|
||||
if (newAncestor == undefined)
|
||||
break;
|
||||
|
||||
if (newAncestor != oldAncestor)
|
||||
newContext.push(newAncestor);
|
||||
i++;
|
||||
}
|
||||
|
||||
return newContext;
|
||||
},
|
||||
|
||||
// A hash of documents that don't yet have an accessible tree.
|
||||
_pendingDocuments: {},
|
||||
|
||||
|
|
|
@ -14,7 +14,8 @@ Cu.import('resource://gre/modules/Services.jsm');
|
|||
|
||||
var EXPORTED_SYMBOLS = ['VisualPresenter',
|
||||
'AndroidPresenter',
|
||||
'DummyAndroidPresenter'];
|
||||
'DummyAndroidPresenter',
|
||||
'PresenterContext'];
|
||||
|
||||
/**
|
||||
* The interface for all presenter classes. A presenter could be, for example,
|
||||
|
@ -36,11 +37,10 @@ Presenter.prototype = {
|
|||
|
||||
/**
|
||||
* The virtual cursor's position changed.
|
||||
* @param {nsIAccessible} aObject the new position.
|
||||
* @param {nsIAccessible[]} aNewContext the ancestry of the new position that
|
||||
* is different from the old virtual cursor position.
|
||||
* @param {PresenterContext} aContext the context object for the new pivot
|
||||
* position.
|
||||
*/
|
||||
pivotChanged: function pivotChanged(aObject, aNewContext) {},
|
||||
pivotChanged: function pivotChanged(aContext) {},
|
||||
|
||||
/**
|
||||
* An object's action has been invoked.
|
||||
|
@ -78,11 +78,12 @@ Presenter.prototype = {
|
|||
|
||||
/**
|
||||
* The current tab has changed.
|
||||
* @param {nsIAccessible} aObject the document contained by the tab
|
||||
* accessible, or null if it is a new tab with no attached
|
||||
* document yet.
|
||||
* @param {PresenterContext} aDocContext context object for tab's
|
||||
* document.
|
||||
* @param {PresenterContext} aVCContext context object for tab's current
|
||||
* virtual cursor position.
|
||||
*/
|
||||
tabSelected: function tabSelected(aDocObj) {},
|
||||
tabSelected: function tabSelected(aDocContext, aVCContext) {},
|
||||
|
||||
/**
|
||||
* The viewport has changed, either a scroll, pan, zoom, or
|
||||
|
@ -139,34 +140,32 @@ VisualPresenter.prototype = {
|
|||
this._highlight(this._currentObject);
|
||||
},
|
||||
|
||||
pivotChanged: function VisualPresenter_pivotChanged(aObject, aNewContext) {
|
||||
this._currentObject = aObject;
|
||||
pivotChanged: function VisualPresenter_pivotChanged(aContext) {
|
||||
this._currentObject = aContext.accessible;
|
||||
|
||||
if (!aObject) {
|
||||
if (!aContext.accessible) {
|
||||
this._hide();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
aObject.scrollTo(Ci.nsIAccessibleScrollType.SCROLL_TYPE_ANYWHERE);
|
||||
this._highlight(aObject);
|
||||
aContext.accessible.scrollTo(
|
||||
Ci.nsIAccessibleScrollType.SCROLL_TYPE_ANYWHERE);
|
||||
this._highlight(aContext.accessible);
|
||||
} catch (e) {
|
||||
dump('Error getting bounds: ' + e);
|
||||
return;
|
||||
}
|
||||
},
|
||||
|
||||
tabSelected: function VisualPresenter_tabSelected(aDocObj) {
|
||||
let vcPos = aDocObj ? aDocObj.QueryInterface(Ci.nsIAccessibleCursorable).
|
||||
virtualCursor.position : null;
|
||||
|
||||
this.pivotChanged(vcPos);
|
||||
tabSelected: function VisualPresenter_tabSelected(aDocContext, aVCContext) {
|
||||
this.pivotChanged(aVCContext);
|
||||
},
|
||||
|
||||
tabStateChanged: function VisualPresenter_tabStateChanged(aDocObj,
|
||||
aPageState) {
|
||||
if (aPageState == 'newdoc')
|
||||
this.pivotChanged(null);
|
||||
this._hide();
|
||||
},
|
||||
|
||||
// Internals
|
||||
|
@ -234,14 +233,15 @@ AndroidPresenter.prototype = {
|
|||
ANDROID_VIEW_TEXT_CHANGED: 0x10,
|
||||
ANDROID_WINDOW_STATE_CHANGED: 0x20,
|
||||
|
||||
pivotChanged: function AndroidPresenter_pivotChanged(aObject, aNewContext) {
|
||||
pivotChanged: function AndroidPresenter_pivotChanged(aContext) {
|
||||
let output = [];
|
||||
for (let i in aNewContext)
|
||||
output.push.apply(output,
|
||||
UtteranceGenerator.genForObject(aNewContext[i]));
|
||||
for (let i in aContext.newAncestry)
|
||||
output.push.apply(
|
||||
output, UtteranceGenerator.genForObject(aContext.newAncestry[i]));
|
||||
|
||||
output.push.apply(output,
|
||||
UtteranceGenerator.genForObject(aObject, true));
|
||||
UtteranceGenerator.genForObject(aContext.accessible,
|
||||
true));
|
||||
|
||||
this.sendMessageToJava({
|
||||
gecko: {
|
||||
|
@ -262,21 +262,9 @@ AndroidPresenter.prototype = {
|
|||
});
|
||||
},
|
||||
|
||||
tabSelected: function AndroidPresenter_tabSelected(aDocObj) {
|
||||
tabSelected: function AndroidPresenter_tabSelected(aDocContext, aVCContext) {
|
||||
// Send a pivot change message with the full context utterance for this doc.
|
||||
let vcDoc = aDocObj.QueryInterface(Ci.nsIAccessibleCursorable);
|
||||
let context = [];
|
||||
|
||||
let parent = vcDoc.virtualCursor.position || aDocObj;
|
||||
while ((parent = parent.parent)) {
|
||||
context.push(parent);
|
||||
if (parent == aDocObj)
|
||||
break;
|
||||
}
|
||||
|
||||
context.reverse();
|
||||
|
||||
this.pivotChanged(vcDoc.virtualCursor.position || aDocObj, context);
|
||||
this.pivotChanged(aVCContext);
|
||||
},
|
||||
|
||||
tabStateChanged: function AndroidPresenter_tabStateChanged(aDocObj,
|
||||
|
@ -342,3 +330,62 @@ DummyAndroidPresenter.prototype = {
|
|||
dump(JSON.stringify(aMsg, null, 2) + '\n');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* PresenterContext: An object that generates and caches context information
|
||||
* for a given accessible and its relationship with another accessible.
|
||||
*/
|
||||
function PresenterContext(aAccessible, aOldAccessible) {
|
||||
this._accessible = aAccessible;
|
||||
this._oldAccessible = aOldAccessible;
|
||||
}
|
||||
|
||||
PresenterContext.prototype = {
|
||||
get accessible() {
|
||||
return this._accessible;
|
||||
},
|
||||
|
||||
get oldAccessible() {
|
||||
return this._oldAccessible;
|
||||
},
|
||||
|
||||
/*
|
||||
* This is a list of the accessible's ancestry up to the common ancestor
|
||||
* of the accessible and the old accessible. It is useful for giving the
|
||||
* user context as to where they are in the heirarchy.
|
||||
*/
|
||||
get newAncestry() {
|
||||
if (!this._newAncestry) {
|
||||
let newLineage = [];
|
||||
let oldLineage = [];
|
||||
|
||||
let parent = this._accessible;
|
||||
while ((parent = parent.parent))
|
||||
newLineage.push(parent);
|
||||
|
||||
if (this._oldAccessible) {
|
||||
parent = this._oldAccessible;
|
||||
while ((parent = parent.parent))
|
||||
oldLineage.push(parent);
|
||||
}
|
||||
|
||||
let i = 0;
|
||||
this._newAncestry = [];
|
||||
|
||||
while (true) {
|
||||
let newAncestor = newLineage.pop();
|
||||
let oldAncestor = oldLineage.pop();
|
||||
|
||||
if (newAncestor == undefined)
|
||||
break;
|
||||
|
||||
if (newAncestor != oldAncestor)
|
||||
this._newAncestry.push(newAncestor);
|
||||
i++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return this._newAncestry;
|
||||
}
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче