diff --git a/mozilla/accessible/public/nsIAccessibleRetrieval.idl b/mozilla/accessible/public/nsIAccessibleRetrieval.idl index eb49b215334..5fafb13b41f 100644 --- a/mozilla/accessible/public/nsIAccessibleRetrieval.idl +++ b/mozilla/accessible/public/nsIAccessibleRetrieval.idl @@ -56,7 +56,7 @@ interface nsIDOMDOMStringList; * * @status UNDER_REVIEW */ -[scriptable, uuid(2d8c1b1b-7a3f-4962-8a88-81ca019c11e9)] +[scriptable, uuid(56c34b1a-d390-44f4-89c3-6935c0e4e3fa)] interface nsIAccessibleRetrieval : nsISupports { /** @@ -141,21 +141,30 @@ interface nsIAccessibleRetrieval : nsISupports * an accessible does not already exist for this DOM node. */ nsIAccessible getCachedAccessible(in nsIDOMNode aNode, in nsIWeakReference aShell); - + /** * Returns accessible role as a string. * * @param aRole - the accessible role constants. */ AString getStringRole(in unsigned long aRole); - + /** * Returns list which contains accessible states as a strings. * * @param aStates - accessible states. * @param aExtraStates - accessible extra states. */ - nsIDOMDOMStringList getStringStates(in unsigned long aStates, in unsigned long aExtraStates); + nsIDOMDOMStringList getStringStates(in unsigned long aStates, + in unsigned long aExtraStates); + + /** + * Get the type of accessible event as a string. + * + * @param aEventType - the accessible event type constant + * @return - accessible event type presented as human readable string + */ + AString getStringEventType(in unsigned long aEventType); }; diff --git a/mozilla/accessible/src/base/nsAccessibilityService.cpp b/mozilla/accessible/src/base/nsAccessibilityService.cpp index 5780fab1b14..cc0050af8a8 100644 --- a/mozilla/accessible/src/base/nsAccessibilityService.cpp +++ b/mozilla/accessible/src/base/nsAccessibilityService.cpp @@ -1040,6 +1040,20 @@ nsAccessibilityService::GetStringStates(PRUint32 aStates, PRUint32 aExtraStates, return NS_OK; } +// nsIAccessibleRetrieval::getStringEventType() +NS_IMETHODIMP +nsAccessibilityService::GetStringEventType(PRUint32 aEventType, + nsAString& aString) +{ + if ( aEventType >= NS_ARRAY_LENGTH(kEventTypeNames)) { + aString.AssignLiteral("unknown"); + return NS_OK; + } + + CopyUTF8toUTF16(kEventTypeNames[aEventType], aString); + return NS_OK; +} + /** * GetAccessibleFor - get an nsIAccessible from a DOM node */ diff --git a/mozilla/accessible/src/base/nsAccessibilityService.h b/mozilla/accessible/src/base/nsAccessibilityService.h index 58772e6ddb9..162cac1aabe 100644 --- a/mozilla/accessible/src/base/nsAccessibilityService.h +++ b/mozilla/accessible/src/base/nsAccessibilityService.h @@ -52,6 +52,79 @@ class nsIDocShell; class nsIPresShell; class nsIContent; +class nsAccessibilityService : public nsIAccessibilityService, + public nsIObserver, + public nsIWebProgressListener, + public nsSupportsWeakReference +{ +public: + nsAccessibilityService(); + virtual ~nsAccessibilityService(); + + NS_DECL_ISUPPORTS + NS_DECL_NSIACCESSIBLERETRIEVAL + NS_DECL_NSIACCESSIBILITYSERVICE + NS_DECL_NSIOBSERVER + NS_DECL_NSIWEBPROGRESSLISTENER + + /** + * Return presentation shell for the given node. + * + * @param aNode - the given DOM node. + */ + static nsresult GetShellFromNode(nsIDOMNode *aNode, + nsIWeakReference **weakShell); + + /** + * Return accessibility service (static instance of this class). + */ + static nsresult GetAccessibilityService(nsIAccessibilityService** aResult); + +private: + /** + * Return presentation shell, DOM node for the given frame. + * + * @param aFrame - the given frame + * @param aRealFrame [out] - the given frame casted to nsIFrame + * @param aShell [out] - presentation shell for DOM node associated with the + * given frame + * @param aContent [out] - DOM node associated with the given frame + */ + nsresult GetInfo(nsISupports *aFrame, nsIFrame **aRealFrame, + nsIWeakReference **aShell, + nsIDOMNode **aContent); + + /** + * Initialize an accessible and cache it. The method should be called for + * every created accessible. + * + * @param aAccessibleIn - accessible to initialize. + */ + nsresult InitAccessible(nsIAccessible *aAccessibleIn, nsIAccessible **aAccessibleOut); + + /** + * Return accessible object for elements implementing nsIAccessibleProvider + * interface. + * + * @param aNode - DOM node that accessible is returned for. + */ + nsresult GetAccessibleByType(nsIDOMNode *aNode, nsIAccessible **aAccessible); + + /** + * Return accessible object if parent is a deck frame. + * + * @param aNode - DOMNode that accessible is returned for. + */ + nsresult GetAccessibleForDeckChildren(nsIDOMNode *aNode, + nsIAccessible **aAccessible); + + static nsAccessibilityService *gAccessibilityService; +}; + +/** + * Map nsIAccessibleRole constants to strings. Used by + * nsIAccessibleRetrieval::getStringRole() method. + */ static const char kRoleNames[][20] = { "nothing", //ROLE_NOTHING "titlebar", //ROLE_TITLEBAR @@ -172,42 +245,102 @@ static const char kRoleNames[][20] = { "image map" //ROLE_IMAGE_MAP }; -class nsAccessibilityService : public nsIAccessibilityService, - public nsIObserver, - public nsIWebProgressListener, - public nsSupportsWeakReference -{ -public: - nsAccessibilityService(); - virtual ~nsAccessibilityService(); - - NS_DECL_ISUPPORTS - NS_DECL_NSIACCESSIBLERETRIEVAL - NS_DECL_NSIACCESSIBILITYSERVICE - NS_DECL_NSIOBSERVER - NS_DECL_NSIWEBPROGRESSLISTENER - - static nsresult GetShellFromNode(nsIDOMNode *aNode, nsIWeakReference **weakShell); - static nsresult GetAccessibilityService(nsIAccessibilityService** aResult); - -private: - nsresult GetInfo(nsISupports* aFrame, nsIFrame** aRealFrame, nsIWeakReference** aShell, nsIDOMNode** aContent); - void GetOwnerFor(nsIPresShell *aPresShell, nsIPresShell **aOwnerShell, nsIContent **aOwnerContent); - nsIContent* FindContentForDocShell(nsIPresShell* aPresShell, nsIContent* aContent, nsIDocShell* aDocShell); - static nsAccessibilityService *gAccessibilityService; - nsresult InitAccessible(nsIAccessible *aAccessibleIn, nsIAccessible **aAccessibleOut); - - /** - * Return accessible object for elements implementing nsIAccessibleProvider - * interface. - */ - nsresult GetAccessibleByType(nsIDOMNode *aNode, nsIAccessible **aAccessible); - PRBool HasListener(nsIContent *aContent, nsAString& aEventType); - - /** - * Return accessible object if parent is a deck frame - */ - nsresult GetAccessibleForDeckChildren(nsIDOMNode *aNode, nsIAccessible **aAccessible); +/** + * Map nsIAccessibleEvents constants to strings. Used by + * nsIAccessibleRetrieval::getStringEventType() method. + */ +static const char kEventTypeNames[][40] = { + "unknown", // + "DOM node create", // EVENT_DOM_CREATE + "DOM node destroy", // EVENT_DOM_DESTROY + "DOM node significant change", // EVENT_DOM_SIGNIFICANT_CHANGE + "async show", // EVENT_ASYNCH_SHOW + "async hide", // EVENT_ASYNCH_HIDE + "async significant change", // EVENT_ASYNCH_SIGNIFICANT_CHANGE + "active decendent change", // EVENT_ACTIVE_DECENDENT_CHANGED + "focus", // EVENT_FOCUS + "state change", // EVENT_STATE_CHANGE + "location change", // EVENT_LOCATION_CHANGE + "name changed", // EVENT_NAME_CHANGE + "description change", // EVENT_DESCRIPTION_CHANGE + "value change", // EVENT_VALUE_CHANGE + "help change", // EVENT_HELP_CHANGE + "default action change", // EVENT_DEFACTION_CHANGE + "action change", // EVENT_ACTION_CHANGE + "accelerator change", // EVENT_ACCELERATOR_CHANGE + "selection", // EVENT_SELECTION + "selection add", // EVENT_SELECTION_ADD + "selection remove", // EVENT_SELECTION_REMOVE + "selection within", // EVENT_SELECTION_WITHIN + "alert", // EVENT_ALERT + "foreground", // EVENT_FOREGROUND + "menu start", // EVENT_MENU_START + "menu end", // EVENT_MENU_END + "menupopup start", // EVENT_MENUPOPUP_START + "menupopup end", // EVENT_MENUPOPUP_END + "capture start", // EVENT_CAPTURE_START + "capture end", // EVENT_CAPTURE_END + "movesize start", // EVENT_MOVESIZE_START + "movesize end", // EVENT_MOVESIZE_END + "contexthelp start", // EVENT_CONTEXTHELP_START + "contexthelp end", // EVENT_CONTEXTHELP_END + "dragdrop start", // EVENT_DRAGDROP_START + "dragdrop end", // EVENT_DRAGDROP_END + "dialog start", // EVENT_DIALOG_START + "dialog end", // EVENT_DIALOG_END + "scrolling start", // EVENT_SCROLLING_START + "scrolling end", // EVENT_SCROLLING_END + "minimize start", // EVENT_MINIMIZE_START + "minimize end", // EVENT_MINIMIZE_END + "document load start", // EVENT_DOCUMENT_LOAD_START + "document load complete", // EVENT_DOCUMENT_LOAD_COMPLETE + "document reload", // EVENT_DOCUMENT_RELOAD + "document load stopped", // EVENT_DOCUMENT_LOAD_STOPPED + "document attributes changed", // EVENT_DOCUMENT_ATTRIBUTES_CHANGED + "document content changed", // EVENT_DOCUMENT_CONTENT_CHANGED + "property changed", // EVENT_PROPERTY_CHANGED + "selection changed", // EVENT_SELECTION_CHANGED + "text attribute changed", // EVENT_TEXT_ATTRIBUTE_CHANGED + "text caret moved", // EVENT_TEXT_CARET_MOVED + "text changed", // EVENT_TEXT_CHANGED + "text inserted", // EVENT_TEXT_INSERTED + "text removed", // EVENT_TEXT_REMOVED + "text updated", // EVENT_TEXT_UPDATED + "text selection changed", // EVENT_TEXT_SELECTION_CHANGED + "visible data changed", // EVENT_VISIBLE_DATA_CHANGED + "text column changed", // EVENT_TEXT_COLUMN_CHANGED + "section changed", // EVENT_SECTION_CHANGED + "table caption changed", // EVENT_TABLE_CAPTION_CHANGED + "table model changed", // EVENT_TABLE_MODEL_CHANGED + "table summary changed", // EVENT_TABLE_SUMMARY_CHANGED + "table row description changed", // EVENT_TABLE_ROW_DESCRIPTION_CHANGED + "table row header changed", // EVENT_TABLE_ROW_HEADER_CHANGED + "table row insert", // EVENT_TABLE_ROW_INSERT + "table row delete", // EVENT_TABLE_ROW_DELETE + "table row reorder", // EVENT_TABLE_ROW_REORDER + "table column description changed", // EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED + "table column header changed", // EVENT_TABLE_COLUMN_HEADER_CHANGED + "table column insert", // EVENT_TABLE_COLUMN_INSERT + "table column delete", // EVENT_TABLE_COLUMN_DELETE + "table column reorder", // EVENT_TABLE_COLUMN_REORDER + "window activate", // EVENT_WINDOW_ACTIVATE + "window create", // EVENT_WINDOW_CREATE + "window deactivate", // EVENT_WINDOW_DEACTIVATE + "window destroy", // EVENT_WINDOW_DESTROY + "window maximize", // EVENT_WINDOW_MAXIMIZE + "window minimize", // EVENT_WINDOW_MINIMIZE + "window resize", // EVENT_WINDOW_RESIZE + "window restore", // EVENT_WINDOW_RESTORE + "hyperlink end index changed", // EVENT_HYPERLINK_END_INDEX_CHANGED + "hyperlink number of anchors changed", // EVENT_HYPERLINK_NUMBER_OF_ANCHORS_CHANGED + "hyperlink selected link changed", // EVENT_HYPERLINK_SELECTED_LINK_CHANGED + "hypertext link activated", // EVENT_HYPERTEXT_LINK_ACTIVATED + "hypertext link selected", // EVENT_HYPERTEXT_LINK_SELECTED + "hyperlink start index changed", // EVENT_HYPERLINK_START_INDEX_CHANGED + "hypertext changed", // EVENT_HYPERTEXT_CHANGED + "hypertext links count changed", // EVENT_HYPERTEXT_NLINKS_CHANGED + "object attribute changed", // EVENT_OBJECT_ATTRIBUTE_CHANGED + "internal load" // EVENT_INTERNAL_LOAD }; #endif /* __nsIAccessibilityService_h__ */ diff --git a/mozilla/extensions/inspector/jar.mn b/mozilla/extensions/inspector/jar.mn index 5429a378785..7179862c172 100644 --- a/mozilla/extensions/inspector/jar.mn +++ b/mozilla/extensions/inspector/jar.mn @@ -64,6 +64,8 @@ inspector.jar: content/inspector/prefs/prefsOverlay.xul (resources/content/prefs/prefsOverlay.xul) content/inspector/prefs/pref-sidebar.js (resources/content/prefs/pref-sidebar.js) content/inspector/tests/allskin.xul (resources/content/tests/allskin.xul) + content/inspector/viewers/accessibleEvents/accessibleEvents.js (resources/content/viewers/accessibleEvents/accessibleEvents.js) + content/inspector/viewers/accessibleEvents/accessibleEvents.xul (resources/content/viewers/accessibleEvents/accessibleEvents.xul) content/inspector/viewers/accessibleObject/accessibleObject.js (resources/content/viewers/accessibleObject/accessibleObject.js) content/inspector/viewers/accessibleObject/accessibleObject.xul (resources/content/viewers/accessibleObject/accessibleObject.xul) content/inspector/viewers/accessibleProps/accessibleProps.js (resources/content/viewers/accessibleProps/accessibleProps.js) diff --git a/mozilla/extensions/inspector/resources/content/res/viewer-registry.rdf b/mozilla/extensions/inspector/resources/content/res/viewer-registry.rdf index d7a382f2dca..8e000602f98 100644 --- a/mozilla/extensions/inspector/resources/content/res/viewer-registry.rdf +++ b/mozilla/extensions/inspector/resources/content/res/viewer-registry.rdf @@ -100,7 +100,8 @@ !(object instanceof Components.interfaces.nsIDOMNode)) return false; - if (linkedViewer.uid != "accessibleTree" && + if (linkedViewer.uid != "accessibleEvents" && + linkedViewer.uid != "accessibleTree" && (linkedViewer.uid != "dom" || !linkedViewer.getAccessibleNodes())) return false; @@ -126,7 +127,8 @@ !(object instanceof Components.interfaces.nsIDOMNode)) return false; - if (linkedViewer.uid != "accessibleTree" && + if (linkedViewer.uid != "accessibleEvents" && + linkedViewer.uid != "accessibleTree" && (linkedViewer.uid != "dom" || !linkedViewer.getAccessibleNodes())) return false; @@ -143,6 +145,27 @@ + + + + + + (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 ***** */ + +/*************************************************************** +* AccessibleEventsViewer -------------------------------------------- +* The viewer for the accessible events occured on a document accessible. +* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +* REQUIRED IMPORTS: +* chrome://inspector/content/jsutil/xpcom/XPCU.js +****************************************************************/ + +/////////////////////////////////////////////////////////////////////////////// +//// Global Variables + +var viewer; + +/////////////////////////////////////////////////////////////////////////////// +//// Global Constants + +const kObserverServiceCID = "@mozilla.org/observer-service;1"; +const kAccessibleRetrievalCID = "@mozilla.org/accessibleRetrieval;1"; + +const nsIObserverService = Components.interfaces.nsIObserverService; +const nsIAccessibleRetrieval = Components.interfaces.nsIAccessibleRetrieval; +const nsIAccessibleEvent = Components.interfaces.nsIAccessibleEvent; +const nsIAccessNode = Components.interfaces.nsIAccessNode; + +/////////////////////////////////////////////////////////////////////////////// +//// Initialization + +window.addEventListener("load", AccessibleEventsViewer_initialize, false); + +function AccessibleEventsViewer_initialize() +{ + viewer = new AccessibleEventsViewer(); + viewer.initialize(parent.FrameExchange.receiveData(window)); +} + +/////////////////////////////////////////////////////////////////////////////// +//// class AccessibleEventsViewer + +function AccessibleEventsViewer() +{ + this.mURL = window.location; + this.mObsMan = new ObserverManager(this); + + this.mTree = document.getElementById("olAccessibleEvents"); + this.mOlBox = this.mTree.treeBoxObject; +} + +AccessibleEventsViewer.prototype = +{ + // initialization + + mSubject: null, + mPane: null, + mView: null, + + // interface inIViewer + + get uid() { return "accessibleEvents"; }, + get pane() { return this.mPane; }, + get selection() { return this.mSelection; }, + + get subject() { return this.mSubject; }, + set subject(aObject) + { + this.mView = new AccessibleEventsView(aObject); + this.mOlBox.view = this.mView; + this.mObsMan.dispatchEvent("subjectChange", { subject: aObject }); + }, + + initialize: function initialize(aPane) + { + this.mPane = aPane; + aPane.notifyViewerReady(this); + }, + + destroy: function destroy() + { + this.mView.destroy(); + this.mOlBox.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; + this.mSelection = this.mView.getDOMNode(idx); + this.mObsMan.dispatchEvent("selectionChange", + { selection: this.mSelection } ); + }, + + clearEventsList: function clearEventsList() + { + this.mView.clear(); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +//// AccessibleEventsView + +function AccessibleEventsView(aDocument) +{ + this.mDocument = aDocument; + this.mEvents = []; + this.mRowCount = 0; + + this.mAccService = XPCU.getService(kAccessibleRetrievalCID, + nsIAccessibleRetrieval); + + this.mAccDocument = this.mAccService.getAccessibleFor(this.mDocument); + this.mObserverService = XPCU.getService(kObserverServiceCID, + nsIObserverService); + + this.mObserverService.addObserver(this, "accessible-event", false); +} + +AccessibleEventsView.prototype = new inBaseTreeView(); + +AccessibleEventsView.prototype.observe = +function observe(aSubject, aTopic, aData) +{ + var event = XPCU.QI(aSubject, nsIAccessibleEvent); + var accessible = event.accessible; + if (!accessible) + return; + + var accessnode = XPCU.QI(accessible, nsIAccessNode); + var accDocument = accessnode.accessibleDocument; + if (accDocument != this.mAccDocument) + return; + + var type = event.eventType; + var date = new Date(); + var node = accessnode.DOMNode; + + var eventObj = { + event: event, + accessnode: accessnode, + node: node, + nodename: node ? node.nodeName : "", + type: this.mAccService.getStringEventType(type), + time: date.toLocaleTimeString() + }; + + this.mEvents.unshift(eventObj); + ++this.mRowCount; + this.mTree.rowCountChanged(0, 1); +} + +AccessibleEventsView.prototype.destroy = +function destroy() +{ + this.mObserverService.removeObserver(this, "accessible-event"); +} + +AccessibleEventsView.prototype.clear = +function clear() +{ + var count = this.mRowCount; + this.mRowCount = 0; + this.mEvents = []; + this.mTree.rowCountChanged(0, -count); +} + +AccessibleEventsView.prototype.getDOMNode = +function getDOMNode(aRow) +{ + return this.mEvents[aRow].node; +} + +AccessibleEventsView.prototype.getCellText = +function getCellText(aRow, aCol) +{ + if (aCol.id == "olcEventType") + return this.mEvents[aRow].type; + if (aCol.id == "olcEventTime") + return this.mEvents[aRow].time; + if (aCol.id == "olcEventTargetNodeName") + return this.mEvents[aRow].nodename; + return ""; +} + diff --git a/mozilla/extensions/inspector/resources/content/viewers/accessibleEvents/accessibleEvents.xul b/mozilla/extensions/inspector/resources/content/viewers/accessibleEvents/accessibleEvents.xul new file mode 100644 index 00000000000..3f8b1bb9b2b --- /dev/null +++ b/mozilla/extensions/inspector/resources/content/viewers/accessibleEvents/accessibleEvents.xul @@ -0,0 +1,90 @@ + + + + + %dtd1; + %dtd2; + %dtd3; +]> + + + + + +