Bug 337674. Make it possible to inspect accessibles (nsIAccessible) objects. Patch thanks to Alexander Surkov. r=timeless, sr=neil
authoraaronleventhal%moonset.net
Mon, 07 Aug 2006 15:54:30 -0400
changeset 506 695c41c00fa5
parent 505 c0944f13ad87
child 507 bac6261b3648
push id1
push usersdwilsh@shawnwilsher.com
push dateTue, 08 Jul 2008 16:35:39 +0000
reviewerstimeless, neil
bugs337674
Bug 337674. Make it possible to inspect accessibles (nsIAccessible) objects. Patch thanks to Alexander Surkov. r=timeless, sr=neil
jar.mn
resources/content/ViewerRegistry.js
resources/content/inspector.js
resources/content/inspector.xml
resources/content/prefs/inspector.js
resources/content/res/viewer-registry.rdf
resources/content/viewers/accessibleObject/accessibleObject.js
resources/content/viewers/accessibleObject/accessibleObject.xul
resources/content/viewers/dom/commandOverlay.xul
resources/content/viewers/dom/dom.js
resources/content/viewers/dom/popupOverlay.xul
resources/content/viewers/jsObject/jsObject.js
resources/content/viewers/jsObject/jsObject.xul
resources/content/viewers/jsObject/jsObjectViewer.js
resources/content/viewers/jsObject/jsObjectViewer.xul
resources/locale/ca/viewers/dom.dtd
resources/locale/cs-CZ/viewers/dom.dtd
resources/locale/da/viewers/dom.dtd
resources/locale/de/viewers/dom.dtd
resources/locale/el/viewers/dom.dtd
resources/locale/en-US/viewers/dom.dtd
resources/locale/fr/viewers/dom.dtd
resources/locale/ga-IE/viewers/dom.dtd
resources/locale/hu/viewers/dom.dtd
resources/locale/nb-NO/viewers/dom.dtd
resources/locale/pl/viewers/dom.dtd
resources/locale/pt-BR/viewers/dom.dtd
resources/locale/ru/viewers/dom.dtd
resources/locale/sk/viewers/dom.dtd
resources/locale/sv-SE/viewers/dom.dtd
resources/locale/zh-CN/viewers/dom.dtd
resources/locale/zh-TW/viewers/dom.dtd
resources/skin/classic/viewers/dom/dom.css
resources/skin/modern/viewers/dom/dom.css
--- a/jar.mn
+++ b/jar.mn
@@ -71,16 +71,18 @@ inspector.jar:
   content/inspector/search/modules/popupOverlay.xul                   (resources/content/search/modules/popupOverlay.xul)
   content/inspector/search/modules/findFiles/dialog.js                (resources/content/search/modules/findFiles/dialog.js)
   content/inspector/search/modules/findFiles/dialog.xul               (resources/content/search/modules/findFiles/dialog.xul)
   content/inspector/search/modules/findFiles/findFiles.xml            (resources/content/search/modules/findFiles/findFiles.xml)
   content/inspector/search/modules/junkImgs/dialog.js                 (resources/content/search/modules/junkImgs/dialog.js)
   content/inspector/search/modules/junkImgs/dialog.xul                (resources/content/search/modules/junkImgs/dialog.xul)
   content/inspector/search/modules/junkImgs/junkImgs.xml              (resources/content/search/modules/junkImgs/junkImgs.xml)
   content/inspector/tests/allskin.xul                                 (resources/content/tests/allskin.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/computedStyle/computedStyle.js            (resources/content/viewers/computedStyle/computedStyle.js)
   content/inspector/viewers/computedStyle/computedStyle.xul           (resources/content/viewers/computedStyle/computedStyle.xul)
   content/inspector/viewers/dom/FindDialog.js                         (resources/content/viewers/dom/FindDialog.js)
   content/inspector/viewers/dom/columnsDialog.js                      (resources/content/viewers/dom/columnsDialog.js)
   content/inspector/viewers/dom/columnsDialog.xul                     (resources/content/viewers/dom/columnsDialog.xul)
   content/inspector/viewers/dom/commandOverlay.xul                    (resources/content/viewers/dom/commandOverlay.xul)
   content/inspector/viewers/dom/findDialog.xul                        (resources/content/viewers/dom/findDialog.xul)
   content/inspector/viewers/dom/keysetOverlay.xul                     (resources/content/viewers/dom/keysetOverlay.xul)
@@ -88,16 +90,18 @@ inspector.jar:
   content/inspector/viewers/dom/dom.xul                               (resources/content/viewers/dom/dom.xul)
   content/inspector/viewers/dom/dom.js                                (resources/content/viewers/dom/dom.js)
   content/inspector/viewers/dom/pseudoClassDialog.js                  (resources/content/viewers/dom/pseudoClassDialog.js)
   content/inspector/viewers/dom/pseudoClassDialog.xul                 (resources/content/viewers/dom/pseudoClassDialog.xul)
   content/inspector/viewers/boxModel/boxModel.js                      (resources/content/viewers/boxModel/boxModel.js)
   content/inspector/viewers/boxModel/boxModel.xul                     (resources/content/viewers/boxModel/boxModel.xul)
   content/inspector/viewers/jsObject/jsObject.js                      (resources/content/viewers/jsObject/jsObject.js)
   content/inspector/viewers/jsObject/jsObject.xul                     (resources/content/viewers/jsObject/jsObject.xul)
+  content/inspector/viewers/jsObject/jsObjectViewer.js                (resources/content/viewers/jsObject/jsObjectViewer.js)
+  content/inspector/viewers/jsObject/jsObjectViewer.xul               (resources/content/viewers/jsObject/jsObjectViewer.xul)
   content/inspector/viewers/jsObject/evalExprDialog.js                (resources/content/viewers/jsObject/evalExprDialog.js)
   content/inspector/viewers/jsObject/evalExprDialog.xul               (resources/content/viewers/jsObject/evalExprDialog.xul)
   content/inspector/viewers/domNode/domNode.js                        (resources/content/viewers/domNode/domNode.js)
   content/inspector/viewers/domNode/domNode.xul                       (resources/content/viewers/domNode/domNode.xul)
   content/inspector/viewers/styleRules/commandOverlay.xul             (resources/content/viewers/styleRules/commandOverlay.xul)
   content/inspector/viewers/styleRules/keysetOverlay.xul              (resources/content/viewers/styleRules/keysetOverlay.xul)
   content/inspector/viewers/styleRules/popupOverlay.xul               (resources/content/viewers/styleRules/popupOverlay.xul)
   content/inspector/viewers/styleRules/styleRules.js                  (resources/content/viewers/styleRules/styleRules.js)
--- a/resources/content/ViewerRegistry.js
+++ b/resources/content/ViewerRegistry.js
@@ -94,27 +94,27 @@ ViewerRegistry.prototype =
 
   onLoad: function(aDS)
   {
     this.mDS = aDS;
     this.prepareRegistry();
     this.mObserver.onViewerRegistryLoad();
   },
 
-  prepareRegistry: function()
+  prepareRegistry: function prepareRegistry()
   {
     this.mViewerDS = RDFArray.fromContainer(this.mDS, "inspector:viewers", kInspectorNSURI);
-    
+
     // create and cache the filter functions
     var js, fn;
     this.mFilters = [];
     for (var i = 0; i < this.mViewerDS.length; ++i) {
       js = this.getEntryProperty(i, "filter");
       try {
-        fn = new Function("object", js);
+        fn = new Function("object", "linkedViewer", js);
       } catch (ex) {
         fn = new Function("return false");
         debug("### ERROR - Syntax error in filter for viewer \"" + this.getEntryProperty(i, "description") + "\"\n");
       }
       this.mFilters.push(fn);
     }
   },
 
@@ -127,56 +127,62 @@ ViewerRegistry.prototype =
   getEntryURL: function(aIndex)
   {
     var uid = this.getEntryProperty(aIndex, "uid");
     return kViewerURLPrefix + uid + "/" + uid + ".xul";
   },
 
   //// Lookup Methods
 
-  ///////////////////////////////////////////////////////////////////////////
-  // Searches the viewer registry for all viewers that can view a particular
-  // object.
-  //
-  // @param Object aObject - the object being searched against
-  // @param String aPanelId - the id of the panel requesting viewers
-  // @return nsIRDFResource[] - array of entries in the viewer registry
-  ///////////////////////////////////////////////////////////////////////////
-  findViewersForObject: function(aObject, aPanelId)
+  /**
+   * Searches the viewer registry for all viewers that can view a particular
+   * object.
+   *
+   * @param Object aObject - the object being searched against
+   * @param String aPanelId - the id of the panel requesting viewers
+   * @param Object aLinkedViewer - the view object of linked panel
+   *
+   * @return nsIRDFResource[] - array of entries in the viewer registry
+   */
+  findViewersForObject: function findViewersForObject(aObject, aPanelId,
+                                                      aLinkedViewer)
   {
     // check each entry in the registry
     var len = this.mViewerDS.length;
     var entry;
     var urls = [];
     for (var i = 0; i < len; ++i) {
       if (this.getEntryProperty(i, "panels").indexOf(aPanelId) == -1) {
         continue;
       }
-      if (this.objectMatchesEntry(aObject, i)) {
+      if (this.objectMatchesEntry(aObject, aLinkedViewer, i)) {
         if (this.getEntryProperty(i, "important")) {
-          urls.unshift(i); 
+          urls.unshift(i);
         } else {
           urls.push(i);
         }
       }
     }
 
     return urls;
   },
 
-  ///////////////////////////////////////////////////////////////////////////
-  // Determines if an object is eligible to be viewed by a particular viewer.
-  //
-  // @param Object aObject - the object being checked for eligibility
-  // @param long aIndex - the index of the entry
-  // @return boolean - true if object can be viewed
-  ///////////////////////////////////////////////////////////////////////////
-  objectMatchesEntry: function(aObject, aIndex)
+  /**
+   * Determines if an object is eligible to be viewed by a particular viewer.
+   *
+   * @param Object aObject - the object being checked for eligibility
+   * @param Object aLinkedViewer - the view object of linked panel
+   * @param long aIndex - the index of the entry
+   *
+   * @return boolean - true if object can be viewed
+   */
+  objectMatchesEntry: function objectMatchesEntry(aObject, aLinkedViewer,
+                                                  aIndex)
   {
-    return this.mFilters[aIndex](aObject);
+    return this.mFilters[aIndex](aObject, aLinkedViewer);
   },
 
   ///////////////////////////////////////////////////////////////////////////
   // Notifies the registry that a viewer has been instantiated, and that
   // it corresponds to a particular entry in the viewer registry.
   //
   // @param 
   ///////////////////////////////////////////////////////////////////////////
--- a/resources/content/inspector.js
+++ b/resources/content/inspector.js
@@ -124,16 +124,23 @@ InspectorApp.prototype =
     this.mPanelSet.addObserver("panelsetready", this, false);
     this.mPanelSet.initialize();
 
     this.mInspectDocumentMenu = document.getElementById("listDocuments-popup");
 
     document.getElementById("cmdToggleChrome").setAttribute("checked",
                                                PrefUtils.getPref("inspector.showChrome"));
 
+    // check if accessibility service is available
+    var cmd = document.getElementById("cmd:toggleAccessibleNodes");
+    if (cmd) {
+      if (!("@mozilla.org/accessibilityService;1" in Components.classes))
+        cmd.setAttribute("disabled", "true");
+    }
+
     if (aURI) {
       this.gotoURL(aURI);
     }
   },
 
   destroy: function()
   {
     InsUtil.persistAll("bxDocPanel");
--- a/resources/content/inspector.xml
+++ b/resources/content/inspector.xml
@@ -567,16 +567,17 @@
           this.mLinkedPanel = val;
 
           if (val)
             val.addObserver("viewerChange", this);
         </setter>
       </property>
 
       <field name="mLinkedPanel">null</field>
+      <field name="mLinkedViewer">null</field>
       <field name="mCurrentViewer">null</field>
       <field name="mCurrentEntry">null</field>
       
       <method name="initialize">
         <body><![CDATA[
           this.mListEl = document.getAnonymousElementByAttribute(this, "anonid", "viewer-list");
           this.mTitleEl = document.getAnonymousElementByAttribute(this, "anonid", "viewer-title");
           this.mMenuEl = document.getAnonymousElementByAttribute(this, "anonid", "viewer-menu");
@@ -656,17 +657,18 @@
 
       <method name="setSubject">
         <parameter name="aObject"/>
         <body><![CDATA[
           this.mSubject = aObject;
           this.mParams = null;
           
           // get the list of viewers which match the node
-          var entries = this.registry.findViewersForObject(aObject, this.id);
+          var entries = this.registry.findViewersForObject(aObject, this.id,
+                                                           this.mLinkedViewer);
           this.rebuildViewerList(entries);
 
           if (entries.length == 0) {
             this.switchViewer(-1);
             this.setAttribute("disabled", "true");
           } else if (!this.entryInList(this.mCurrentEntry, entries)) {
             this.switchViewer(entries[0]);
             this.removeAttribute("disabled");
--- a/resources/content/prefs/inspector.js
+++ b/resources/content/prefs/inspector.js
@@ -38,9 +38,10 @@
 pref("inspector.blink.border-color", "#CC0000");
 pref("inspector.blink.border-width", 2);
 pref("inspector.blink.duration", 1200);
 pref("inspector.blink.on", true);
 pref("inspector.blink.speed", 100);
 pref("inspector.blink.invert", false);
 pref("inspector.dom.showAnon", true);
 pref("inspector.dom.showWhitespaceNodes", true);
+pref("inspector.dom.showAccessibleNodes", false);
 pref("inspector.showChrome", false);
--- a/resources/content/res/viewer-registry.rdf
+++ b/resources/content/res/viewer-registry.rdf
@@ -15,20 +15,27 @@
                 bxObjectPanel or bxObjPanel.
 
   ins:description
                 This sets a title for the viewer.
 
   ins:icon      This sets an icon for the viewer.  Currently unused.
 
   ins:filter    This determines which nodes (or in the case of JavaScript Object
-                viewer, values), the viewer referenced is valid for. For example,
-                ins:filter="return object instanceof Components.interfaces.nsIDOMDocument;"
-                is a JavaScript fragment ViewerRegistry.js uses to define a filter
-                function if the panel's subject node is an instance of nsIDOMDocument.
+                viewer, values), the viewer referenced is valid for.
+
+                @param object - nsIDOMNode object (or in the case of JavaScript
+                  Object viewer, JavaScript object).
+                @param linkedViewer - linked viewer object.
+
+                For example, ins:filter=
+                "return object instanceof Components.interfaces.nsIDOMDocument;"
+                is a JavaScript fragment ViewerRegistry.js uses to define a
+                filter function if the panel's subject node is an instance of
+                nsIDOMDocument.
 -->
 
   <rdf:Seq about="inspector:viewers">
     <rdf:li><rdf:Description 
       ins:uid="dom"
       ins:panels="bxDocPanel"
       ins:description="DOM Nodes"
       ins:icon="chrome://inspector/content/viewers/dom/dom-icon.gif"
@@ -79,11 +86,32 @@
 
     <rdf:li><rdf:Description 
       ins:uid="jsObject"
       ins:panels="bxDocPanel bxObjectPanel bxObjPanel"
       ins:description="Javascript Object"
       ins:filter="return true;"/>
     </rdf:li>
 
+    <rdf:li>
+      <rdf:Description ins:uid="accessibleObject"
+                       ins:panels="bxObjectPanel bxObjPanel"
+                       ins:description="Accessible Object">
+        <ins:filter><![CDATA[
+          if (!linkedViewer || linkedViewer.uid != "dom" ||
+              !linkedViewer.getAccessibleNodes() ||
+              !(object instanceof Components.interfaces.nsIDOMNode))
+            return false;
+
+          try {
+            var accService =
+              Components.classes['@mozilla.org/accessibilityService;1']
+                        .getService(Components.interfaces.nsIAccessibilityService);
+            return accService.getAccessibleFor(object);
+          } catch(e) {
+            return false;
+          }
+        ]]></ins:filter>
+      </rdf:Description>
+    </rdf:li>
   </rdf:Seq>
 
 </rdf:RDF>
new file mode 100644
--- /dev/null
+++ b/resources/content/viewers/accessibleObject/accessibleObject.js
@@ -0,0 +1,97 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is DOM Inspector.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Alexander Surkov <surkov.alexander@gmail.com> (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 ***** */
+
+/***************************************************************
+* AccessibleObjectViewer --------------------------------------------
+*  The viewer for the accessible object.
+* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+* REQUIRED IMPORTS:
+*   chrome://inspector/content/jsutil/events/ObserverManager.js
+****************************************************************/
+
+//////////// global variables /////////////////////
+
+var viewer;
+var bundle;
+var accService;
+
+//////////// global constants ////////////////////
+//////////////////////////////////////////////////
+
+window.addEventListener("load", AccessibleObjectViewer_initialize, false);
+
+function AccessibleObjectViewer_initialize()
+{
+  bundle = document.getElementById("inspector-bundle");
+  accService = Components.classes['@mozilla.org/accessibilityService;1']
+                         .getService(Components.interfaces.nsIAccessibilityService);
+
+  viewer = new JSObjectViewer();
+
+  viewer.__defineGetter__(
+    "uid",
+    function uidGetter()
+    {
+      return "accessibleObject";
+    }
+  );
+
+  viewer.__defineSetter__(
+    "subject",
+    function subjectSetter(aObject)
+    {
+      var accObject = null;
+      try {
+        accObject = accService.getAccessibleFor(aObject);
+      } catch(e) {
+        dump("Failed to get accessible object for node.");
+      }
+
+      this.mSubject = accObject;
+      this.emptyTree(this.mTreeKids);
+      var ti = this.addTreeItem(this.mTreeKids,
+                                bundle.getString("root.title"),
+                                accObject,
+                                accObject);
+      ti.setAttribute("open", "true");
+
+      this.mObsMan.dispatchEvent("subjectChange", { subject: accObject });
+    }
+   );
+
+  viewer.initialize(parent.FrameExchange.receiveData(window));
+}
new file mode 100644
--- /dev/null
+++ b/resources/content/viewers/accessibleObject/accessibleObject.xul
@@ -0,0 +1,53 @@
+<?xml version="1.0"?>
+
+<!-- ***** BEGIN LICENSE BLOCK *****
+   - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+   -
+   - The contents of this file are subject to the Mozilla Public License Version
+   - 1.1 (the "License"); you may not use this file except in compliance with
+   - the License. You may obtain a copy of the License at
+   - http://www.mozilla.org/MPL/
+   -
+   - Software distributed under the License is distributed on an "AS IS" basis,
+   - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+   - for the specific language governing rights and limitations under the
+   - License.
+   -
+   - The Original Code is DOM Inspector.
+   -
+   - The Initial Developer of the Original Code is
+   - Mozilla Foundation.
+   - Portions created by the Initial Developer are Copyright (C) 2006
+   - the Initial Developer. All Rights Reserved.
+   -
+   - Contributor(s):
+   -  Alexander Surkov <surkov.alexander@gmail.com>
+   -
+   - 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 ***** --> 
+
+<?xul-overlay href="chrome://inspector/content/viewers/jsObject/jsObjectViewer.xul"?>
+
+<page id="winAccessibleObject"
+      xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+  <script type="application/javascript"
+          src="chrome://inspector/content/viewers/accessibleObject/accessibleObject.js"/>
+
+  <stringbundle id="inspector-bundle"/>
+  <commandset id="cmdsJSObjectViewer"/>
+
+  <popup id="popupContext"/>
+  <tree id="treeJSObject"/>
+</page>
--- a/resources/content/viewers/dom/commandOverlay.xul
+++ b/resources/content/viewers/dom/commandOverlay.xul
@@ -18,16 +18,19 @@
              oncommand="inspector.getViewer('dom').findNext()"/>
 
     <command id="cmd:toggleAnon" viewer="dom"
              oncommand="inspector.getViewer('dom').toggleAnonContent(true)"/>
 
     <command id="cmd:toggleSubDocs" viewer="dom"
              oncommand="inspector.getViewer('dom').toggleSubDocs()"/>
 
+    <command id="cmd:toggleAccessibleNodes" viewer="dom"
+             oncommand="inspector.getViewer('dom').toggleAccessibleNodes(true);"/>
+
     <command id="cmd:toggleWhitespaceNodes" viewer="dom"
              oncommand="inspector.getViewer('dom').toggleWhitespaceNodes()"/>
 
     <command id="cmd:flashSelected" viewer="dom"
              oncommand="inspector.getViewer('dom').toggleFlashSelected()"/>
       
     <command id="cmd:toggleAttributes" viewer="dom"
              oncommand="inspector.getViewer('dom').toggleAttributes()"/>
--- a/resources/content/viewers/dom/dom.js
+++ b/resources/content/viewers/dom/dom.js
@@ -129,16 +129,17 @@ DOMViewer.prototype =
   initialize: function(aPane)
   {
     //this.initColumns();
 
     this.mPanel = aPane;
     aPane.notifyViewerReady(this);
 
     this.setAnonContent(PrefUtils.getPref("inspector.dom.showAnon"), false);
+    this.setAccessibleNodes(PrefUtils.getPref("inspector.dom.showAccessibleNodes"), false);
     this.setWhitespaceNodes(PrefUtils.getPref("inspector.dom.showWhitespaceNodes"));
     this.setFlashSelected(PrefUtils.getPref("inspector.blink.on"));
   },
 
   destroy: function()
   {
     this.mDOMTree.treeBoxObject.view = null;
   },
@@ -283,16 +284,56 @@ DOMViewer.prototype =
 
   toggleSubDocs: function()
   {
     var val = !this.mDOMView.showSubDocuments;
     this.mDOMView.showSubDocuments = val;
     this.mPanel.panelset.setCommandAttribute("cmd:toggleSubDocs", "checked", val);
   },
 
+  /**
+   * Toggle state of 'Show Accessible Nodes' option.
+   *
+   * @param Boolean aRebuild - if true then DOM nodes tree will be rebuilded.
+   */
+  toggleAccessibleNodes: function toggleAccessibleNodes(aRebuild)
+  {
+    this.setAccessibleNodes(!this.getAccessibleNodes(), aRebuild);
+  },
+
+  /**
+   * Set state of 'Show Accessible Nodes' option.
+   *
+   * @param Boolean aValue - if true then accessible nodes will be shown
+   * @param Boolean aRebuild - if true then DOM nodes tree will be rebuilded.
+   */
+  setAccessibleNodes: function setAccessibleNodes(aValue, aRebuild)
+  {
+    if (!("@mozilla.org/accessibilityService;1" in Components.classes))
+      aValue = false;
+
+    this.mDOMView.showAccessibleNodes = aValue;
+    this.mPanel.panelset.setCommandAttribute("cmd:toggleAccessibleNodes",
+                                             "checked", aValue);
+    PrefUtils.setPref("inspector.dom.showAccessibleNodes", aValue);
+
+    if (aRebuild) {
+      this.rebuild();
+    }
+    this.onItemSelected();
+  },
+
+  /**
+   * Return state of 'Show Accessible Nodes' option.
+   */
+  getAccessibleNodes: function getAccessibleNodes()
+  {
+    return this.mDOMView.showAccessibleNodes;
+  },
+
   setWhitespaceNodes: function(aValue)
   {
     // Do this first so we ensure the checkmark is set in the case
     // we are starting with whitespace nodes enabled.
     this.mPanel.panelset.setCommandAttribute("cmd:toggleWhitespaceNodes", "checked", aValue);
 
     // The rest of the stuff is redundant to do if we are not changing
     // the value, so just bail here if we're setting the same value.
--- a/resources/content/viewers/dom/popupOverlay.xul
+++ b/resources/content/viewers/dom/popupOverlay.xul
@@ -29,16 +29,23 @@
 
       <menuitem id="item:toggleAnon"
         class="menuitem-iconic"
         type="checkbox"
         label="&cmdToggleAnonContent.label;"
         accesskey="&cmdToggleAnonContent.accesskey;"
         observes="cmd:toggleAnon"/>
 
+      <menuitem id="item:toggleAccessibleNodes"
+                class="menuitem-iconic"
+                type="checkbox"
+                label="&cmdToggleAccessibleNodes.label;"
+                accesskey="&cmdToggleAccessibleNodes.accesskey;"
+                observes="cmd:toggleAccessibleNodes"/>
+
       <menuitem id="item:toggleWhitespaceNodes"
         class="menuitem-iconic"
         type="checkbox"
         label="&cmdToggleWhitespaceNodes.label;"
         accesskey="&cmdToggleWhitespaceNodes.accesskey;"
         observes="cmd:toggleWhitespaceNodes"/>
 
     </menupopup>
@@ -74,16 +81,23 @@
               
     <menuitem id="item:toggleAnon"
               class="menuitem-iconic"
               type="checkbox"
               label="&cmdToggleAnonContent.label;"
               accesskey="&cmdToggleAnonContent.accesskey;"
               observes="cmd:toggleAnon"/>
 
+    <menuitem id="item:toggleAccessibleNodes"
+              class="menuitem-iconic"
+              type="checkbox"
+              label="&cmdToggleAccessibleNodes.label;"
+              accesskey="&cmdToggleAccessibleNodes.accesskey;"
+              observes="cmd:toggleAccessibleNodes"/>
+
     <menuitem id="item:toggleWhitespaceNodes"
               class="menuitem-iconic"
               type="checkbox"
               label="&cmdToggleWhitespaceNodes.label;"
               accesskey="&cmdToggleWhitespaceNodes.accesskey;"
               observes="cmd:toggleWhitespaceNodes"/>
   </menupopup>
 
--- a/resources/content/viewers/jsObject/jsObject.js
+++ b/resources/content/viewers/jsObject/jsObject.js
@@ -43,250 +43,18 @@
 *   chrome://inspector/content/jsutil/xpcom/XPCU.js
 ****************************************************************/
 
 //////////// global variables /////////////////////
 
 var viewer;
 var bundle;
 
-//////////// global constants ////////////////////
-
-const kClipboardHelperCID  = "@mozilla.org/widget/clipboardhelper;1";
-
 //////////////////////////////////////////////////
 
 window.addEventListener("load", JSObjectViewer_initialize, false);
 
 function JSObjectViewer_initialize()
 {
   bundle = document.getElementById("inspector-bundle");
   viewer = new JSObjectViewer();
   viewer.initialize(parent.FrameExchange.receiveData(window));
 }
-
-////////////////////////////////////////////////////////////////////////////
-//// class JSObjectViewer
-
-function JSObjectViewer()
-{
-  this.mObsMan = new ObserverManager(this);
-}
-
-JSObjectViewer.prototype = 
-{
-  ////////////////////////////////////////////////////////////////////////////
-  //// Initialization
-  
-  mSubject: null,
-  mPane: null,
-
-  ////////////////////////////////////////////////////////////////////////////
-  //// interface inIViewer
-
-  get uid() { return "jsObject" },
-  get pane() { return this.mPane },
-
-  get selection() { return this.mSelection },
-  
-  get subject() { return this.mSubject },
-  set subject(aObject) 
-  {
-    this.mSubject = aObject;
-    this.emptyTree(this.mTreeKids);
-    var ti = this.addTreeItem(this.mTreeKids, bundle.getString("root.title"), aObject, aObject);
-    ti.setAttribute("open", "true");
-
-    this.mObsMan.dispatchEvent("subjectChange", { subject: aObject });
-  },
-
-  initialize: function(aPane)
-  {
-    this.mPane = aPane;
-    this.mTree = document.getElementById("treeJSObject");
-    this.mTreeKids = document.getElementById("trchJSObject");
-    
-    aPane.notifyViewerReady(this);
-  },
-
-  destroy: function()
-  {
-  },
-  
-  isCommandEnabled: function(aCommand)
-  {
-    return false;
-  },
-  
-  getCommand: function(aCommand)
-  {
-    return null;
-  },
-  
-  ////////////////////////////////////////////////////////////////////////////
-  //// event dispatching
-
-  addObserver: function(aEvent, aObserver) { this.mObsMan.addObserver(aEvent, aObserver); },
-  removeObserver: function(aEvent, aObserver) { this.mObsMan.removeObserver(aEvent, aObserver); },
-
-  ////////////////////////////////////////////////////////////////////////////
-  //// UI Commands
-
-  cmdCopyValue: function()
-  {
-    var sel = getSelectedItem();
-    if (sel) {
-      var val = sel.__JSValue__;
-      if (val) {
-        var helper = XPCU.getService(kClipboardHelperCID, "nsIClipboardHelper");
-        helper.copyString(val);
-      }
-    }
-  },
-  
-  cmdEvalExpr: function()
-  {
-    var sel = getSelectedItem();
-    if (sel) {
-      var win = openDialog("chrome://inspector/content/viewers/jsObject/evalExprDialog.xul", 
-                           "_blank", "chrome", this, sel);
-    }
-  },  
-  
-  doEvalExpr: function(aExpr, aItem, aNewView)
-  {
-    // TODO: I should really write some C++ code to execute the 
-    // js code in the js context of the inspected window
-    
-    try {
-      var f = Function("target", aExpr);
-      var result = f(aItem.__JSValue__);
-      
-      if (result) {
-        if (aNewView) {
-          inspectObject(result);
-        } else {
-          this.subject = result;
-        }
-      }
-    } catch (ex) {
-      dump("Error in expression.\n");
-      throw (ex);
-    }
-  },  
-  
-  cmdInspectInNewView: function()
-  {
-    var sel = getSelectedItem();
-    if (sel)
-      inspectObject(sel.__JSValue__);
-  },
-  
-  ////////////////////////////////////////////////////////////////////////////
-  //// tree construction
-
-  emptyTree: function(aTreeKids)
-  {
-    while (aTreeKids.hasChildNodes()) {
-      aTreeKids.removeChild(aTreeKids.lastChild);
-    }
-  },
-  
-  buildPropertyTree: function(aTreeChildren, aObject)
-  {
-    for (var prop in aObject) {
-      try {
-        this.addTreeItem(aTreeChildren, prop, aObject[prop], aObject);
-      } catch (ex) {
-        // hide unsightly NOT YET IMPLEMENTED errors when accessing certain properties
-      }
-    }
-  },
-  
-  addTreeItem: function(aTreeChildren, aName, aValue, aObject)
-  {
-    var ti = document.createElement("treeitem");
-    ti.__JSObject__ = aObject;
-    ti.__JSValue__ = aValue;
-    
-    var value;
-    if (aValue === null) {
-      value = "(null)";
-    } else if (aValue === undefined) {
-      value = "(undefined)";
-    } else {
-      try {
-        value = aValue.toString();
-        value = value.replace(/\n|\r|\t|\v/g, " ");
-      } catch (ex) {
-        value = "";
-      }
-    }
-    
-    ti.setAttribute("typeOf", typeof(aValue));
-
-    if (typeof(aValue) == "object" && aValue !== null) {
-      ti.setAttribute("container", "true");
-    } else if (typeof(aValue) == "string")
-      value = "\"" + value + "\"";
-    
-    var tr = document.createElement("treerow");
-    ti.appendChild(tr);
-    
-    var tc = document.createElement("treecell");
-    tc.setAttribute("label", aName);
-    tr.appendChild(tc);
-    tc = document.createElement("treecell");
-    tc.setAttribute("label", value);
-    if (aValue === null) {
-      tc.setAttribute("class", "inspector-null-value-treecell");
-    }
-    if (aName == "nodeType")
-      tc.setAttribute("tooltiptext", nodeTypeToText(aValue));
-    tr.appendChild(tc);
-    
-    aTreeChildren.appendChild(ti);
-
-    // listen for changes to open attribute
-    this.mTreeKids.addEventListener("DOMAttrModified", onTreeItemAttrModified, false);
-    
-    return ti;
-  },
-  
-  openTreeItem: function(aItem)
-  {
-    var treechildren = aItem.getElementsByTagName("treechildren").item(0);
-    if (!treechildren) {
-      treechildren = document.createElement("treechildren");
-      this.buildPropertyTree(treechildren, aItem.__JSValue__);
-      aItem.appendChild(treechildren);
-    }
-  },
-  
-  onCreateContext: function(aPopup)
-  {
-  }
-  
-};
-
-function onTreeItemAttrModified(aEvent)
-{
-  if (aEvent.attrName == "open")
-    viewer.openTreeItem(aEvent.target);
-}
-
-function getSelectedItem()
-{
-  var tree = document.getElementById("treeJSObject");
-  if (tree.view.selection.count)
-    return tree.contentView.getItemAtIndex(tree.currentIndex);
-  else 
-    return null;    
-}
-
-function toggleItem(aItem)
-{
-  var tree = document.getElementById("treeJSObject");
-  var row = tree.currentView.getIndexOfItem(aItem);
-  if (row >= 0) {
-    tree.view.toggleOpenState(row);
-  }
-}
--- a/resources/content/viewers/jsObject/jsObject.xul
+++ b/resources/content/viewers/jsObject/jsObject.xul
@@ -1,47 +1,15 @@
 <?xml version="1.0"?>
 
-<!DOCTYPE page [
-  <!ENTITY % dtd1 SYSTEM "chrome://inspector/locale/inspector.dtd"> %dtd1;
-  <!ENTITY % dtd2 SYSTEM "chrome://inspector/content/util.dtd"> %dtd2;
-  <!ENTITY % dtd3 SYSTEM "chrome://inspector/locale/viewers/jsObject.dtd"> %dtd3;
-]>
-
-<?xml-stylesheet href="chrome://inspector/skin/"?>
+<?xul-overlay href="chrome://inspector/content/viewers/jsObject/jsObjectViewer.xul"?>
 
 <page id="winJSObject"
       xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
   <script type="application/x-javascript" src="chrome://inspector/content/viewers/jsObject/jsObject.js"/>
-  <script type="application/x-javascript" src="chrome://inspector/content/jsutil/xpcom/XPCU.js"/>
-  <script type="application/x-javascript" src="chrome://inspector/content/jsutil/events/ObserverManager.js"/>
-  <script type="application/x-javascript" src="chrome://inspector/content/hooks.js"/>
-  <script type="application/x-javascript" src="chrome://inspector/content/utils.js"/>
-  
-  <stringbundle id="inspector-bundle" src="chrome://inspector/locale/inspector.properties"/>
-  
-  <commandset>
-    <command id="cmdCopyValue" oncommand="viewer.cmdCopyValue()"/>
-    <command id="cmdEvalExpr" oncommand="viewer.cmdEvalExpr()"/>
-    <command id="cmdInspectInNewView" oncommand="viewer.cmdInspectInNewView()"/>
-  </commandset>
-  
-  <popupset>
-    <popup id="popupContext">
-      <menuitem label="&inspectNewWindow.label;" observes="cmdInspectInNewView"/>
-      <menuseparator/>
-      <menuitem label="&jsCopyValue.label;" observes="cmdCopyValue"/>
-      <menuitem label="&jsEval.label;" observes="cmdEvalExpr"/>
-    </popup>
-  </popupset>
-  
-  <tree id="treeJSObject" flex="1" context="popupContext">
-    <treecols>
-      <treecol id="colProp" flex="1" primary="true" label="&jsProperty.label;"/>
-      <splitter class="tree-splitter"/>
-      <treecol id="colVal" flex="1" label="&jsValue.label;"/>
-    </treecols>
+
+  <stringbundle id="inspector-bundle"/>
+  <commandset id="cmdsJSObjectViewer"/>
 
-    <treechildren id="trchJSObject"/>
-  </tree>
-
+  <popup id="popupContext"/>
+  <tree id="treeJSObject"/>
 </page>
--- a/resources/content/viewers/jsObject/jsObjectViewer.js
+++ b/resources/content/viewers/jsObject/jsObjectViewer.js
@@ -38,36 +38,20 @@
 /***************************************************************
 * JSObjectViewer --------------------------------------------
 *  The viewer for all facets of a javascript object.
 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
 * REQUIRED IMPORTS:
 *   chrome://inspector/content/jsutil/xpcom/XPCU.js
 ****************************************************************/
 
-//////////// global variables /////////////////////
-
-var viewer;
-var bundle;
-
 //////////// global constants ////////////////////
 
 const kClipboardHelperCID  = "@mozilla.org/widget/clipboardhelper;1";
 
-//////////////////////////////////////////////////
-
-window.addEventListener("load", JSObjectViewer_initialize, false);
-
-function JSObjectViewer_initialize()
-{
-  bundle = document.getElementById("inspector-bundle");
-  viewer = new JSObjectViewer();
-  viewer.initialize(parent.FrameExchange.receiveData(window));
-}
-
 ////////////////////////////////////////////////////////////////////////////
 //// class JSObjectViewer
 
 function JSObjectViewer()
 {
   this.mObsMan = new ObserverManager(this);
 }
 
new file mode 100644
--- /dev/null
+++ b/resources/content/viewers/jsObject/jsObjectViewer.xul
@@ -0,0 +1,87 @@
+<?xml version="1.0"?>
+
+<!-- ***** BEGIN LICENSE BLOCK *****
+   - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+   -
+   - The contents of this file are subject to the Mozilla Public License Version
+   - 1.1 (the "License"); you may not use this file except in compliance with
+   - the License. You may obtain a copy of the License at
+   - http://www.mozilla.org/MPL/
+   -
+   - Software distributed under the License is distributed on an "AS IS" basis,
+   - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+   - for the specific language governing rights and limitations under the
+   - License.
+   -
+   - The Original Code is DOM Inspector.
+   -
+   - The Initial Developer of the Original Code is
+   - Netscape Communications Corporation.
+   - Portions created by the Initial Developer are Copyright (C) 2001
+   - the Initial Developer. All Rights Reserved.
+   -
+   - Contributor(s):
+   -  Joe Hewitt <hewitt@netscape.com>
+   -
+   - 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 ***** -->
+
+<!DOCTYPE page [
+  <!ENTITY % dtd1 SYSTEM "chrome://inspector/locale/inspector.dtd"> %dtd1;
+  <!ENTITY % dtd2 SYSTEM "chrome://inspector/content/util.dtd"> %dtd2;
+  <!ENTITY % dtd3 SYSTEM "chrome://inspector/locale/viewers/jsObject.dtd"> %dtd3;
+]>
+
+<?xml-stylesheet href="chrome://inspector/skin/inspector.css"?>
+
+<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+  <script type="application/javascript"
+          src="chrome://inspector/content/viewers/jsObject/jsObjectViewer.js"/>
+  <script type="application/javascript"
+          src="chrome://inspector/content/jsutil/xpcom/XPCU.js"/>
+  <script type="application/javascript"
+          src="chrome://inspector/content/jsutil/events/ObserverManager.js"/>
+  <script type="application/javascript"
+          src="chrome://inspector/content/hooks.js"/>
+  <script type="application/javascript"
+          src="chrome://inspector/content/utils.js"/>
+
+  <stringbundle id="inspector-bundle"
+                src="chrome://inspector/locale/inspector.properties"/>
+
+  <commandset id="cmdsJSObjectViewer">
+    <command id="cmdCopyValue" oncommand="viewer.cmdCopyValue();"/>
+    <command id="cmdEvalExpr" oncommand="viewer.cmdEvalExpr();"/>
+    <command id="cmdInspectInNewView"
+             oncommand="viewer.cmdInspectInNewView();"/>
+  </commandset>
+
+  <popup id="popupContext">
+    <menuitem label="&inspectNewWindow.label;" observes="cmdInspectInNewView"/>
+    <menuseparator/>
+    <menuitem label="&jsCopyValue.label;" observes="cmdCopyValue"/>
+    <menuitem label="&jsEval.label;" observes="cmdEvalExpr"/>
+  </popup>
+
+  <tree id="treeJSObject" flex="1" context="popupContext">
+    <treecols>
+      <treecol id="colProp" flex="1" primary="true" label="&jsProperty.label;"/>
+      <splitter class="tree-splitter"/>
+      <treecol id="colVal" flex="1" label="&jsValue.label;"/>
+    </treecols>
+
+    <treechildren id="trchJSObject"/>
+  </tree>
+</overlay>
--- a/resources/locale/ca/viewers/dom.dtd
+++ b/resources/locale/ca/viewers/dom.dtd
@@ -47,16 +47,19 @@
 <!ENTITY cmdFindNext.accesskey "g">
 
 <!ENTITY cmdToggleAnonContent.label "Mostra el contingut anònim">
 <!ENTITY cmdToggleAnonContent.accesskey "a">
 
 <!ENTITY cmdToggleWhitespaceNodes.label "Mostra els nodes d'espais blancs">
 <!ENTITY cmdToggleWhitespaceNodes.accesskey "b">
 
+<!ENTITY cmdToggleAccessibleNodes.label "Show Accessible Nodes">
+<!ENTITY cmdToggleAccessibleNodes.accesskey "c">
+
 <!ENTITY cmdFlashSelected.label "Marca l'element seleccionat">
 
 <!ENTITY cmdToggleAttributes.label "Mostra els atributs">
 <!ENTITY cmdToggleAttributes.accesskey "r">
 
 <!ENTITY cmdSelectByClick.label "Selecciona l'element amb un clic">
 <!ENTITY cmdSelectByClick.accesskey "S">
 
--- a/resources/locale/cs-CZ/viewers/dom.dtd
+++ b/resources/locale/cs-CZ/viewers/dom.dtd
@@ -39,16 +39,18 @@
 <!ENTITY cmdShowFindDialog.accesskey "N">
 <!ENTITY cmdShowFindDialog.accelkey "f">
 <!ENTITY cmdFindNext.label "Najít další">
 <!ENTITY cmdFindNext.accesskey "N">
 <!ENTITY cmdToggleAnonContent.label "Zobrazit anonymní obsah">
 <!ENTITY cmdToggleAnonContent.accesskey "a">
 <!ENTITY cmdToggleWhitespaceNodes.label "Zobrazit prázdné uzly">
 <!ENTITY cmdToggleWhitespaceNodes.accesskey "p">
+<!ENTITY cmdToggleAccessibleNodes.label "Show Accessible Nodes">
+<!ENTITY cmdToggleAccessibleNodes.accesskey "c">
 <!ENTITY cmdFlashSelected.label "Zvýraznit vybraný prvek">
 <!ENTITY cmdToggleAttributes.label "Zobrazit atributy">
 <!ENTITY cmdToggleAttributes.accesskey "r">
 <!ENTITY cmdSelectByClick.label "Vybrat prvek klepnutím">
 <!ENTITY cmdSelectByClick.accesskey "V">
 <!ENTITY ColumnsDialog.title "Sloupce">
 <!ENTITY cmdShowColumnsDialog.label "Sloupce">
 <!ENTITY cmdShowColumnsDialog.accesskey "c">
--- a/resources/locale/da/viewers/dom.dtd
+++ b/resources/locale/da/viewers/dom.dtd
@@ -44,16 +44,19 @@
   <!ENTITY cmdFindNext.accesskey "n">
 
   <!ENTITY cmdToggleAnonContent.label "Vis anonymt indhold">
   <!ENTITY cmdToggleAnonContent.accesskey "a">
 
   <!ENTITY cmdToggleWhitespaceNodes.label "Vis blanke noder">
   <!ENTITY cmdToggleWhitespaceNodes.accesskey "b">
 
+  <!ENTITY cmdToggleAccessibleNodes.label "Show Accessible Nodes">
+  <!ENTITY cmdToggleAccessibleNodes.accesskey "c">
+
   <!ENTITY cmdFlashSelected.label "Blink valgte element">
 
   <!ENTITY cmdToggleAttributes.label "Vis attributer">
   <!ENTITY cmdToggleAttributes.accesskey "r">
 
   <!ENTITY cmdSelectByClick.label "Vælg element ved klik">
   <!ENTITY cmdSelectByClick.accesskey "V">
 
--- a/resources/locale/de/viewers/dom.dtd
+++ b/resources/locale/de/viewers/dom.dtd
@@ -44,16 +44,19 @@
   <!ENTITY cmdFindNext.accesskey "t">
 
   <!ENTITY cmdToggleAnonContent.label "Anonymen Inhalt anzeigen">
   <!ENTITY cmdToggleAnonContent.accesskey "A">
 
   <!ENTITY cmdToggleWhitespaceNodes.label "Leere Textknoten anzeigen">
   <!ENTITY cmdToggleWhitespaceNodes.accesskey "x">
 
+  <!ENTITY cmdToggleAccessibleNodes.label "Show Accessible Nodes">
+  <!ENTITY cmdToggleAccessibleNodes.accesskey "c">
+
   <!ENTITY cmdFlashSelected.label "Ausgewähltes Element blinken lassen">
 
   <!ENTITY cmdToggleAttributes.label "Attribute anzeigen">
   <!ENTITY cmdToggleAttributes.accesskey "t">
 
   <!ENTITY cmdSelectByClick.label "Element durch Klick auswählen">
   <!ENTITY cmdSelectByClick.accesskey "K">
 
--- a/resources/locale/el/viewers/dom.dtd
+++ b/resources/locale/el/viewers/dom.dtd
@@ -42,16 +42,19 @@
   <!ENTITY cmdFindNext.accesskey "ν">
 
   <!ENTITY cmdToggleAnonContent.label "Προβολή ανώνυμου περιεχομένου">
   <!ENTITY cmdToggleAnonContent.accesskey "α">
 
   <!ENTITY cmdToggleWhitespaceNodes.label "Προβολή Whitespace Nodes">
   <!ENTITY cmdToggleWhitespaceNodes.accesskey "W">
 
+  <!ENTITY cmdToggleAccessibleNodes.label "Show Accessible Nodes">
+  <!ENTITY cmdToggleAccessibleNodes.accesskey "c">
+
   <!ENTITY cmdFlashSelected.label "Αναβόσβημα επιλεγμένου στοιχείου">
 
   <!ENTITY cmdToggleAttributes.label "Προβολή γνωρισμάτων">
   <!ENTITY cmdToggleAttributes.accesskey "γ">
 
   <!ENTITY cmdSelectByClick.label "Επιλογή στοιχείου με κλικ">
   <!ENTITY cmdSelectByClick.accesskey "λ">
 
--- a/resources/locale/en-US/viewers/dom.dtd
+++ b/resources/locale/en-US/viewers/dom.dtd
@@ -44,16 +44,19 @@
   <!ENTITY cmdFindNext.accesskey "n">
 
   <!ENTITY cmdToggleAnonContent.label "Show Anonymous Content">
   <!ENTITY cmdToggleAnonContent.accesskey "a">
 
   <!ENTITY cmdToggleWhitespaceNodes.label "Show Whitespace Nodes">
   <!ENTITY cmdToggleWhitespaceNodes.accesskey "W">
 
+  <!ENTITY cmdToggleAccessibleNodes.label "Show Accessible Nodes">
+  <!ENTITY cmdToggleAccessibleNodes.accesskey "c">
+
   <!ENTITY cmdFlashSelected.label "Blink Selected Element">
 
   <!ENTITY cmdToggleAttributes.label "Show Attributes">
   <!ENTITY cmdToggleAttributes.accesskey "r">
 
   <!ENTITY cmdSelectByClick.label "Select Element By Click">
   <!ENTITY cmdSelectByClick.accesskey "s">
 
--- a/resources/locale/fr/viewers/dom.dtd
+++ b/resources/locale/fr/viewers/dom.dtd
@@ -44,16 +44,19 @@
   <!ENTITY cmdFindNext.accesskey "s">
 
   <!ENTITY cmdToggleAnonContent.label "Afficher le contenu anonyme">
   <!ENTITY cmdToggleAnonContent.accesskey "a">
 
   <!ENTITY cmdToggleWhitespaceNodes.label "Voir les nœuds vides">
   <!ENTITY cmdToggleWhitespaceNodes.accesskey "V">
 
+  <!ENTITY cmdToggleAccessibleNodes.label "Show Accessible Nodes">
+  <!ENTITY cmdToggleAccessibleNodes.accesskey "c">
+
   <!ENTITY cmdFlashSelected.label "Faire clignoter l'élément sélectionné">
 
   <!ENTITY cmdToggleAttributes.label "Afficher les attributs">
   <!ENTITY cmdToggleAttributes.accesskey "t">
 
   <!ENTITY cmdSelectByClick.label "Sélectionner l'élément par un clic">
   <!ENTITY cmdSelectByClick.accesskey "c">
 
--- a/resources/locale/ga-IE/viewers/dom.dtd
+++ b/resources/locale/ga-IE/viewers/dom.dtd
@@ -39,16 +39,18 @@
 <!ENTITY cmdShowFindDialog.accesskey "A">
 <!ENTITY cmdShowFindDialog.accelkey "f">
 <!ENTITY cmdFindNext.label "An Chéad Cheann Eile">
 <!ENTITY cmdFindNext.accesskey "n">
 <!ENTITY cmdToggleAnonContent.label "Taispeáin Innechar gan Ainm">
 <!ENTITY cmdToggleAnonContent.accesskey "A">
 <!ENTITY cmdToggleWhitespaceNodes.label "Taispeáin Nóid Spáis Bháin">
 <!ENTITY cmdToggleWhitespaceNodes.accesskey "B">
+<!ENTITY cmdToggleAccessibleNodes.label "Show Accessible Nodes">
+<!ENTITY cmdToggleAccessibleNodes.accesskey "c">
 <!ENTITY cmdFlashSelected.label "Cuir Eilimint Roghnaithe ag Caochadh">
 <!ENTITY cmdToggleAttributes.label "Taispeáin Aitreabúidí">
 <!ENTITY cmdToggleAttributes.accesskey "r">
 <!ENTITY cmdSelectByClick.label "Roghnaigh Eilimint trí Ghliogáil">
 <!ENTITY cmdSelectByClick.accesskey "R">
 <!ENTITY ColumnsDialog.title "Colúin">
 <!ENTITY cmdShowColumnsDialog.label "Colúin...">
 <!ENTITY cmdShowColumnsDialog.accesskey "C">
--- a/resources/locale/hu/viewers/dom.dtd
+++ b/resources/locale/hu/viewers/dom.dtd
@@ -44,16 +44,19 @@
   <!ENTITY cmdFindNext.accesskey "K">
 
   <!ENTITY cmdToggleAnonContent.label "Névtelen tartalom megjelenítése">
   <!ENTITY cmdToggleAnonContent.accesskey "v">
 
   <!ENTITY cmdToggleWhitespaceNodes.label "Üres csomópontok megjelenítése">
   <!ENTITY cmdToggleWhitespaceNodes.accesskey "r">
 
+  <!ENTITY cmdToggleAccessibleNodes.label "Show Accessible Nodes">
+  <!ENTITY cmdToggleAccessibleNodes.accesskey "c">
+
   <!ENTITY cmdFlashSelected.label "Kijelölt elem villogtatása">
 
   <!ENTITY cmdToggleAttributes.label "Attribútumok megjelenítése">
   <!ENTITY cmdToggleAttributes.accesskey "A">
 
   <!ENTITY cmdSelectByClick.label "Elem kiválasztása kattintással">
   <!ENTITY cmdSelectByClick.accesskey "E">
 
--- a/resources/locale/nb-NO/viewers/dom.dtd
+++ b/resources/locale/nb-NO/viewers/dom.dtd
@@ -44,16 +44,19 @@
   <!ENTITY cmdFindNext.accesskey "n">
 
   <!ENTITY cmdToggleAnonContent.label "Vis anonymt innhold">
   <!ENTITY cmdToggleAnonContent.accesskey "a">
 
   <!ENTITY cmdToggleWhitespaceNodes.label "Vis blanke noder">
   <!ENTITY cmdToggleWhitespaceNodes.accesskey "b">
 
+  <!ENTITY cmdToggleAccessibleNodes.label "Show Accessible Nodes">
+  <!ENTITY cmdToggleAccessibleNodes.accesskey "c">
+
   <!ENTITY cmdFlashSelected.label "Blink valgt element">
 
   <!ENTITY cmdToggleAttributes.label "Vis egenskaper">
   <!ENTITY cmdToggleAttributes.accesskey "v">
 
   <!ENTITY cmdSelectByClick.label "Velg elementer ved å klikke">
   <!ENTITY cmdSelectByClick.accesskey "V">
 
--- a/resources/locale/pl/viewers/dom.dtd
+++ b/resources/locale/pl/viewers/dom.dtd
@@ -44,16 +44,19 @@
   <!ENTITY cmdFindNext.accesskey "n">
 
   <!ENTITY cmdToggleAnonContent.label "Pokaż anonimową zawartość">
   <!ENTITY cmdToggleAnonContent.accesskey "a">
 
   <!ENTITY cmdToggleWhitespaceNodes.label "Pokaż węzły zawierające niewidoczne znaki">
   <!ENTITY cmdToggleWhitespaceNodes.accesskey "W">
 
+  <!ENTITY cmdToggleAccessibleNodes.label "Show Accessible Nodes">
+  <!ENTITY cmdToggleAccessibleNodes.accesskey "c">
+
   <!ENTITY cmdFlashSelected.label "Wyróżnij wybrany element">
 
   <!ENTITY cmdToggleAttributes.label "Pokaż atrybuty">
   <!ENTITY cmdToggleAttributes.accesskey "r">
 
   <!ENTITY cmdSelectByClick.label "Wybierz element poprzez kliknięcie">
   <!ENTITY cmdSelectByClick.accesskey "W">
 
--- a/resources/locale/pt-BR/viewers/dom.dtd
+++ b/resources/locale/pt-BR/viewers/dom.dtd
@@ -45,16 +45,19 @@
   <!ENTITY cmdFindNext.accesskey "L">
 
   <!ENTITY cmdToggleAnonContent.label "Exibir conteúdo anônimo">
   <!ENTITY cmdToggleAnonContent.accesskey "E">
 
   <!ENTITY cmdToggleWhitespaceNodes.label "Exibir nós de espaços em branco">
   <!ENTITY cmdToggleWhitespaceNodes.accesskey "x">
 
+  <!ENTITY cmdToggleAccessibleNodes.label "Show Accessible Nodes">
+  <!ENTITY cmdToggleAccessibleNodes.accesskey "c">
+
   <!ENTITY cmdFlashSelected.label "Piscar elemento selecionado">
 
   <!ENTITY cmdToggleAttributes.label "Exibir atributos">
   <!ENTITY cmdToggleAttributes.accesskey "a">
 
   <!ENTITY cmdSelectByClick.label "Selecionar elemento pelo clique">
   <!ENTITY cmdSelectByClick.accesskey "S">
 
--- a/resources/locale/ru/viewers/dom.dtd
+++ b/resources/locale/ru/viewers/dom.dtd
@@ -18,16 +18,18 @@
 <!ENTITY cmdShowPseudoClasses.accesskey "У">
 <!ENTITY cmdShowPseudoClasses.label "Указать псевдоклассы...">
 <!ENTITY cmdToggleAnonContent.accesskey "о">
 <!ENTITY cmdToggleAnonContent.label "Показывать неизвестное содержимое">
 <!ENTITY cmdToggleAttributes.accesskey "а">
 <!ENTITY cmdToggleAttributes.label "Показать атрибуты">
 <!ENTITY cmdToggleWhitespaceNodes.accesskey "П">
 <!ENTITY cmdToggleWhitespaceNodes.label "Показывать пробельные узлы">
+<!ENTITY cmdToggleAccessibleNodes.label "Show Accessible Nodes">
+<!ENTITY cmdToggleAccessibleNodes.accesskey "c">
 <!ENTITY findNodes.title "Найти узлы">
 <!ENTITY findNodesByAttr.label "Атрибут">
 <!ENTITY findNodesByAttrValue.label "Значение">
 <!ENTITY findNodesById.label "Идентификатор">
 <!ENTITY findNodesByTag.label "Тег">
 <!ENTITY findNodesCancel.label "Отмена">
 <!ENTITY findNodesDirection.label "Направление">
 <!ENTITY findNodesDirectionDown.label "Вниз">
--- a/resources/locale/sk/viewers/dom.dtd
+++ b/resources/locale/sk/viewers/dom.dtd
@@ -44,16 +44,19 @@
 <!ENTITY cmdFindNext.accesskey "n">
 
 <!ENTITY cmdToggleAnonContent.label "Zobraziť anonymný obsah">
 <!ENTITY cmdToggleAnonContent.accesskey "a">
 
 <!ENTITY cmdToggleWhitespaceNodes.label "Zobraziť prázdne uzly">
 <!ENTITY cmdToggleWhitespaceNodes.accesskey "p">
 
+<!ENTITY cmdToggleAccessibleNodes.label "Show Accessible Nodes">
+<!ENTITY cmdToggleAccessibleNodes.accesskey "c">
+
 <!ENTITY cmdFlashSelected.label "Zvýrazniť vybratý prvok">
 
 <!ENTITY cmdToggleAttributes.label "Zobraziť atribúty">
 <!ENTITY cmdToggleAttributes.accesskey "r">
 
 <!ENTITY cmdSelectByClick.label "Vybrať prvok kliknutím">
 <!ENTITY cmdSelectByClick.accesskey "v">
 
--- a/resources/locale/sv-SE/viewers/dom.dtd
+++ b/resources/locale/sv-SE/viewers/dom.dtd
@@ -45,16 +45,19 @@
   <!ENTITY cmdFindNext.accesskey "n">
 
   <!ENTITY cmdToggleAnonContent.label "Visa anonymt innehåll">
   <!ENTITY cmdToggleAnonContent.accesskey "V">
 
   <!ENTITY cmdToggleWhitespaceNodes.label "Visa tomma noder">
   <!ENTITY cmdToggleWhitespaceNodes.accesskey "t">
 
+  <!ENTITY cmdToggleAccessibleNodes.label "Show Accessible Nodes">
+  <!ENTITY cmdToggleAccessibleNodes.accesskey "c">
+
   <!ENTITY cmdFlashSelected.label "Blinka med det markerade elementet">
 
   <!ENTITY cmdToggleAttributes.label "Visa attribut">
   <!ENTITY cmdToggleAttributes.accesskey "a">
 
   <!ENTITY cmdSelectByClick.label "Välj ett element genom att klicka">
   <!ENTITY cmdSelectByClick.accesskey "k">
 
--- a/resources/locale/zh-CN/viewers/dom.dtd
+++ b/resources/locale/zh-CN/viewers/dom.dtd
@@ -18,16 +18,18 @@
 <!ENTITY cmdShowPseudoClasses.accesskey "p">
 <!ENTITY cmdShowPseudoClasses.label "设置伪类...">
 <!ENTITY cmdToggleAnonContent.accesskey "a">
 <!ENTITY cmdToggleAnonContent.label "显示匿名内容">
 <!ENTITY cmdToggleAttributes.accesskey "r">
 <!ENTITY cmdToggleAttributes.label "显示属性">
 <!ENTITY cmdToggleWhitespaceNodes.accesskey "W">
 <!ENTITY cmdToggleWhitespaceNodes.label "显示空白节点">
+<!ENTITY cmdToggleAccessibleNodes.label "Show Accessible Nodes">
+<!ENTITY cmdToggleAccessibleNodes.accesskey "c">
 <!ENTITY findNodes.title "查找节点">
 <!ENTITY findNodesByAttr.label "属性">
 <!ENTITY findNodesByAttrValue.label "值">
 <!ENTITY findNodesById.label "Id">
 <!ENTITY findNodesByTag.label "标记">
 <!ENTITY findNodesCancel.label "取消">
 <!ENTITY findNodesDirection.label "方向">
 <!ENTITY findNodesDirectionDown.label "下">
--- a/resources/locale/zh-TW/viewers/dom.dtd
+++ b/resources/locale/zh-TW/viewers/dom.dtd
@@ -3,16 +3,18 @@
 <!ENTITY cmdShowFindDialog.accesskey "f">
 <!ENTITY cmdShowFindDialog.accelkey "f">
 <!ENTITY cmdFindNext.label "尋找下一個">
 <!ENTITY cmdFindNext.accesskey "n">
 <!ENTITY cmdToggleAnonContent.label "顯示未命名內容">
 <!ENTITY cmdToggleAnonContent.accesskey "a">
 <!ENTITY cmdToggleWhitespaceNodes.label "顯示空白節點">
 <!ENTITY cmdToggleWhitespaceNodes.accesskey "W">
+<!ENTITY cmdToggleAccessibleNodes.label "Show Accessible Nodes">
+<!ENTITY cmdToggleAccessibleNodes.accesskey "c">
 <!ENTITY cmdFlashSelected.label "閃爍已選項目">
 <!ENTITY cmdToggleAttributes.label "顯示屬性">
 <!ENTITY cmdToggleAttributes.accesskey "r">
 <!ENTITY cmdSelectByClick.label "下次點選項目">
 <!ENTITY cmdSelectByClick.accesskey "s">
 <!ENTITY ColumnsDialog.title "欄">
 <!ENTITY cmdShowColumnsDialog.label "欄...">
 <!ENTITY cmdShowColumnsDialog.accesskey "c">
--- a/resources/skin/classic/viewers/dom/dom.css
+++ b/resources/skin/classic/viewers/dom/dom.css
@@ -34,16 +34,20 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 @import url("chrome://inspector/skin");
 
 /* :::::::: node type color coding :::::::: */
 
+treechildren::-moz-tree-cell-text(ACCESSIBLE_NODE) {
+  font-weight: bold;
+}
+
 treechildren::-moz-tree-cell-text(ELEMENT_NODE) {
   color: #000000;
 }
 
 treechildren::-moz-tree-cell-text(ATTRIBUTE_NODE) {
   color: #556b2f;
 }
 
--- a/resources/skin/modern/viewers/dom/dom.css
+++ b/resources/skin/modern/viewers/dom/dom.css
@@ -34,16 +34,20 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 @import url("chrome://inspector/skin");
 
 /* :::::::: node type color coding :::::::: */
 
+treechildren::-moz-tree-cell-text(ACCESSIBLE_NODE) {
+  font-weight: bold;
+}
+
 treechildren::-moz-tree-cell-text(ELEMENT_NODE) {
   color: #000000;
 }
 
 treechildren::-moz-tree-cell-text(ATTRIBUTE_NODE) {
   color: #556b2f;
 }