From d1f2927376f6df7869d1bdcfd6bf10581c00e0ef Mon Sep 17 00:00:00 2001 From: "surkov.alexander%gmail.com" Date: Thu, 11 Oct 2007 02:02:11 +0000 Subject: [PATCH] Bug 347792 - expose accessible relations in DOM inspector, r=sdwilsh, ajvincent, evan.yan, sr=neil, a=dsicore --- accessible/public/nsIAccessibleRetrieval.idl | 10 +- .../src/base/nsAccessibilityService.cpp | 15 + accessible/src/base/nsAccessibilityService.h | 25 ++ extensions/inspector/jar.mn | 2 + extensions/inspector/resources/Makefile.in | 5 - .../resources/content/res/viewer-registry.rdf | 27 ++ .../accessibleEvents/accessibleEvents.js | 5 +- .../accessibleRelations.js | 270 ++++++++++++++++++ .../accessibleRelations.xul | 116 ++++++++ .../en-US/viewers/accessibleRelations.dtd | 43 +++ extensions/inspector/resources/locale/jar.mn | 35 +-- 11 files changed, 529 insertions(+), 24 deletions(-) create mode 100644 extensions/inspector/resources/content/viewers/accessibleRelations/accessibleRelations.js create mode 100644 extensions/inspector/resources/content/viewers/accessibleRelations/accessibleRelations.xul create mode 100644 extensions/inspector/resources/locale/en-US/viewers/accessibleRelations.dtd diff --git a/accessible/public/nsIAccessibleRetrieval.idl b/accessible/public/nsIAccessibleRetrieval.idl index 5fafb13b41f..fab95f620e6 100644 --- a/accessible/public/nsIAccessibleRetrieval.idl +++ b/accessible/public/nsIAccessibleRetrieval.idl @@ -56,7 +56,7 @@ interface nsIDOMDOMStringList; * * @status UNDER_REVIEW */ -[scriptable, uuid(56c34b1a-d390-44f4-89c3-6935c0e4e3fa)] +[scriptable, uuid(244e4c67-a1d3-44f2-9cab-cdaa31b68046)] interface nsIAccessibleRetrieval : nsISupports { /** @@ -165,6 +165,14 @@ interface nsIAccessibleRetrieval : nsISupports * @return - accessible event type presented as human readable string */ AString getStringEventType(in unsigned long aEventType); + + /** + * Get the type of accessible relation as a string. + * + * @param aRelationType - the accessible relation type constant + * @return - accessible relation type presented as human readable string + */ + AString getStringRelationType(in unsigned long aRelationType); }; diff --git a/accessible/src/base/nsAccessibilityService.cpp b/accessible/src/base/nsAccessibilityService.cpp index 8e2309cf381..92ded97cfde 100644 --- a/accessible/src/base/nsAccessibilityService.cpp +++ b/accessible/src/base/nsAccessibilityService.cpp @@ -1056,6 +1056,21 @@ nsAccessibilityService::GetStringEventType(PRUint32 aEventType, return NS_OK; } +// nsIAccessibleRetrieval::getStringRelationType() +NS_IMETHODIMP +nsAccessibilityService::GetStringRelationType(PRUint32 aRelationType, + nsAString& aString) +{ + if (aRelationType >= NS_ARRAY_LENGTH(kRelationTypeNames)) { + aString.AssignLiteral("unknown"); + return NS_OK; + } + + CopyUTF8toUTF16(kRelationTypeNames[aRelationType], aString); + return NS_OK; +} + + /** * GetAccessibleFor - get an nsIAccessible from a DOM node */ diff --git a/accessible/src/base/nsAccessibilityService.h b/accessible/src/base/nsAccessibilityService.h index 837aa7a6f33..82e0ad30eaa 100644 --- a/accessible/src/base/nsAccessibilityService.h +++ b/accessible/src/base/nsAccessibilityService.h @@ -355,4 +355,29 @@ static const char kEventTypeNames[][40] = { "reorder" // EVENT_REORDER }; +/** + * Map nsIAccessibleRelation constants to strings. Used by + * nsIAccessibleRetrieval::getStringRelationType() method. + */ +static const char kRelationTypeNames[][20] = { + "unknown", // RELATION_NUL + "controlled by", // RELATION_CONTROLLED_BY + "controller for", // RELATION_CONTROLLER_FOR + "label for", // RELATION_LABEL_FOR + "labelled by", // RELATION_LABELLED_BY + "member of", // RELATION_MEMBER_OF + "node child of", // RELATION_NODE_CHILD_OF + "flows to", // RELATION_FLOWS_TO + "flows from", // RELATION_FLOWS_FROM + "subwindow of", // RELATION_SUBWINDOW_OF + "embeds", // RELATION_EMBEDS + "embedded by", // RELATION_EMBEDDED_BY + "popup for", // RELATION_POPUP_FOR + "parent window of", // RELATION_PARENT_WINDOW_OF + "described by", // RELATION_DESCRIBED_BY + "description for", // RELATION_DESCRIPTION_FOR + "default button" // RELATION_DEFAULT_BUTTON +}; + #endif /* __nsIAccessibilityService_h__ */ + diff --git a/extensions/inspector/jar.mn b/extensions/inspector/jar.mn index 7179862c172..14731d4c5b1 100644 --- a/extensions/inspector/jar.mn +++ b/extensions/inspector/jar.mn @@ -70,6 +70,8 @@ inspector.jar: content/inspector/viewers/accessibleObject/accessibleObject.xul (resources/content/viewers/accessibleObject/accessibleObject.xul) content/inspector/viewers/accessibleProps/accessibleProps.js (resources/content/viewers/accessibleProps/accessibleProps.js) content/inspector/viewers/accessibleProps/accessibleProps.xul (resources/content/viewers/accessibleProps/accessibleProps.xul) + content/inspector/viewers/accessibleRelations/accessibleRelations.js (resources/content/viewers/accessibleRelations/accessibleRelations.js) + content/inspector/viewers/accessibleRelations/accessibleRelations.xul (resources/content/viewers/accessibleRelations/accessibleRelations.xul) content/inspector/viewers/accessibleTree/accessibleTree.js (resources/content/viewers/accessibleTree/accessibleTree.js) content/inspector/viewers/accessibleTree/accessibleTree.xul (resources/content/viewers/accessibleTree/accessibleTree.xul) content/inspector/viewers/computedStyle/computedStyle.js (resources/content/viewers/computedStyle/computedStyle.js) diff --git a/extensions/inspector/resources/Makefile.in b/extensions/inspector/resources/Makefile.in index 9a23bcc306d..24d68e8cf7f 100644 --- a/extensions/inspector/resources/Makefile.in +++ b/extensions/inspector/resources/Makefile.in @@ -46,11 +46,6 @@ include $(DEPTH)/config/autoconf.mk ALL_LOCALES = \ en-US \ - pl \ - fr \ - nb-NO \ - ru \ - sv-SE \ $(NULL) include $(topsrcdir)/config/config.mk diff --git a/extensions/inspector/resources/content/res/viewer-registry.rdf b/extensions/inspector/resources/content/res/viewer-registry.rdf index 1603763ae81..eced9d21553 100644 --- a/extensions/inspector/resources/content/res/viewer-registry.rdf +++ b/extensions/inspector/resources/content/res/viewer-registry.rdf @@ -145,6 +145,33 @@ + + + + + + (original author) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/*************************************************************** +* AccessibleRelationsViewer -------------------------------------------- +* The viewer for the accessible relations for the inspected accessible. +* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +* REQUIRED IMPORTS: +* chrome://inspector/content/jsutil/xpcom/XPCU.js +****************************************************************/ + +/////////////////////////////////////////////////////////////////////////////// +//// Global Variables + +var viewer; +var gAccService = null; + +/////////////////////////////////////////////////////////////////////////////// +//// Global Constants + +const kAccessibleRetrievalCID = "@mozilla.org/accessibleRetrieval;1"; + +const nsIAccessibleRetrieval = Components.interfaces.nsIAccessibleRetrieval; +const nsIAccessibleRelation = Components.interfaces.nsIAccessibleRelation; +const nsIAccessNode = Components.interfaces.nsIAccessNode; +const nsIAccessible = Components.interfaces.nsIAccessible; + +/////////////////////////////////////////////////////////////////////////////// +//// Initialization + +window.addEventListener("load", AccessibleRelationsViewer_initialize, false); + +function AccessibleRelationsViewer_initialize() +{ + gAccService = XPCU.getService(kAccessibleRetrievalCID, + nsIAccessibleRetrieval); + + viewer = new AccessibleRelationsViewer(); + viewer.initialize(parent.FrameExchange.receiveData(window)); +} + +/////////////////////////////////////////////////////////////////////////////// +//// class AccessibleRelationsViewer + +function AccessibleRelationsViewer() +{ + this.mURL = window.location; + this.mObsMan = new ObserverManager(this); + + this.mTree = document.getElementById("olAccessibleRelations"); + this.mTreeBox = this.mTree.treeBoxObject; + + this.mTargetsTree = document.getElementById("olAccessibleTargets"); + this.mTargetsTreeBox = this.mTargetsTree.treeBoxObject; +} + +AccessibleRelationsViewer.prototype = +{ + ///////////////////////// + //// initialization + + mSubject: null, + mPane: null, + mView: null, + mTargetsView: null, + + ///////////////////////// + //// interface inIViewer + + get uid() { return "accessibleRelations"; }, + get pane() { return this.mPane; }, + get selection() { return this.mSelection; }, + + get subject() { return this.mSubject; }, + set subject(aObject) + { + this.mView = new AccessibleRelationsView(aObject); + this.mTreeBox.view = this.mView; + this.mObsMan.dispatchEvent("subjectChange", { subject: aObject }); + }, + + initialize: function initialize(aPane) + { + this.mPane = aPane; + aPane.notifyViewerReady(this); + }, + + destroy: function destroy() + { + this.mTreeBox.view = null; + this.mTargetsTreeBox.view = null; + }, + + isCommandEnabled: function isCommandEnabled(aCommand) + { + return false; + }, + + getCommand: function getCommand(aCommand) + { + return null; + }, + + ///////////////////////// + //// event dispatching + + addObserver: function addObserver(aEvent, aObserver) + { + this.mObsMan.addObserver(aEvent, aObserver); + }, + removeObserver: function removeObserver(aEvent, aObserver) + { + this.mObsMan.removeObserver(aEvent, aObserver); + }, + + ///////////////////////// + //// utils + + onItemSelected: function onItemSelected() + { + var idx = this.mTree.currentIndex; + var relation = this.mView.getRelationObject(idx); + this.mTargetsView = new AccessibleTargetsView(relation); + this.mTargetsTreeBox.view = this.mTargetsView; + }, + + cmdInspectInNewView: function cmdInspectInNewView() + { + var idx = this.mTargetsTree.currentIndex; + if (idx >= 0) { + var node = this.mTargetsView.getDOMNode(idx); + if (node) + inspectObject(node); + } + } +}; + +/////////////////////////////////////////////////////////////////////////////// +//// AccessibleRelationsView + +function AccessibleRelationsView(aNode) +{ + this.mNode = aNode; + + this.mAccessible = aNode.getUserData("accessible"); + if (this.mAccessible) + XPCU.QI(this.mAccessible, nsIAccessible); + else + this.mAccessible = gAccService.getAccessibleFor(aNode); + + this.mRelations = this.mAccessible.getRelations(); +} + +AccessibleRelationsView.prototype = new inBaseTreeView(); + +AccessibleRelationsView.prototype.__defineGetter__("rowCount", +function rowCount() +{ + return this.mRelations.length; +}); + +AccessibleRelationsView.prototype.getRelationObject = +function getRelationObject(aRow) +{ + return this.mRelations.queryElementAt(aRow, nsIAccessibleRelation); +} + +AccessibleRelationsView.prototype.getCellText = +function getCellText(aRow, aCol) +{ + if (aCol.id == "olcRelationType") { + var relation = this.getRelationObject(aRow); + if (relation) + return gAccService.getStringRelationType(relation.relationType); + } + + return ""; +} + +/////////////////////////////////////////////////////////////////////////////// +//// AccessibleTargetsView + +function AccessibleTargetsView(aRelation) +{ + this.mRelation = aRelation; + this.mTargets = this.mRelation.getTargets(); +} + +/////////////////////////////////////////////////////////////////////////////// +//// AccessibleTargetsView. nsITreeView + +AccessibleTargetsView.prototype = new inBaseTreeView(); + +AccessibleTargetsView.prototype.__defineGetter__("rowCount", +function rowCount() +{ + return this.mTargets.length; +}); + +AccessibleTargetsView.prototype.getCellText = +function getCellText(aRow, aCol) +{ + if (aCol.id == "olcRole") { + var accessible = this.getAccessible(aRow); + if (accessible) + return gAccService.getStringRole(accessible.finalRole); + } else if (aCol.id == "olcNodeName") { + var node = this.getDOMNode(aRow); + if (node) + return node.nodeName; + } + + return ""; +} + +/////////////////////////////////////////////////////////////////////////////// +//// AccessibleTargetsView. Utils + +AccessibleTargetsView.prototype.getAccessible = +function getAccessible(aRow) +{ + return this.mTargets.queryElementAt(aRow, nsIAccessible); +} + +AccessibleTargetsView.prototype.getDOMNode = +function getDOMNode(aRow) +{ + var accessNode = this.mTargets.queryElementAt(aRow, nsIAccessNode); + if (!accessNode) + return null; + + var DOMNode = accessNode.DOMNode; + DOMNode.setUserData("accessible", accessNode, null); + return DOMNode; +} + diff --git a/extensions/inspector/resources/content/viewers/accessibleRelations/accessibleRelations.xul b/extensions/inspector/resources/content/viewers/accessibleRelations/accessibleRelations.xul new file mode 100644 index 00000000000..b070e84c2ec --- /dev/null +++ b/extensions/inspector/resources/content/viewers/accessibleRelations/accessibleRelations.xul @@ -0,0 +1,116 @@ + + + + + %dtd1; + %dtd2; + %dtd3; +]> + + + + + +