Fixing bug 572609. Use faster version of GetElementById() from our C++ code. r=jonas@sicking.cc
☠☠ backed out by 58d4391f8725 ☠ ☠
authorJohnny Stenback <jst@mozilla.com>
Mon, 21 Jun 2010 19:58:50 -0700
changeset 43945 82a21d443b5edfe52842d93d5fc0617ae9f27ff6
parent 43944 d688a915d1d461337f5cd8401248d6afd1a22ff0
child 43946 3d65cff5c900f8d6a0d7c0add42d6cf47d85e620
child 44121 58d4391f872539c666eb01b86f98dbb09dd4bf17
push idunknown
push userunknown
push dateunknown
reviewersjonas
bugs572609
milestone1.9.3a6pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Fixing bug 572609. Use faster version of GetElementById() from our C++ code. r=jonas@sicking.cc
content/base/src/nsDocument.h
content/base/src/nsReferencedElement.cpp
content/events/src/nsXMLEventsManager.cpp
content/html/content/src/nsHTMLLabelElement.cpp
content/html/content/src/nsImageMapUtils.cpp
content/xbl/src/nsXBLWindowKeyHandler.cpp
content/xslt/src/xpath/txMozillaXPathTreeWalker.cpp
content/xul/document/src/nsXULDocument.cpp
dom/base/nsDOMClassInfo.cpp
layout/base/nsPresShell.cpp
layout/xul/base/src/nsMenuFrame.cpp
layout/xul/base/src/nsResizerFrame.cpp
layout/xul/base/src/nsXULTooltipListener.cpp
widget/src/cocoa/nsMenuItemX.mm
--- a/content/base/src/nsDocument.h
+++ b/content/base/src/nsDocument.h
@@ -947,17 +947,16 @@ protected:
   friend class nsNodeUtils;
 
   /**
    * Check that aId is not empty and log a message to the console
    * service if it is.
    * @returns PR_TRUE if aId looks correct, PR_FALSE otherwise.
    */
   static PRBool CheckGetElementByIdArg(const nsIAtom* aId);
-  nsIdentifierMapEntry* GetElementByIdInternal(nsIAtom* aID);
 
   void DispatchContentLoadedEvents();
 
   void RetrieveRelevantHeaders(nsIChannel *aChannel);
 
   static PRBool TryChannelCharset(nsIChannel *aChannel,
                                   PRInt32& aCharsetSource,
                                   nsACString& aCharset);
--- a/content/base/src/nsReferencedElement.cpp
+++ b/content/base/src/nsReferencedElement.cpp
@@ -208,25 +208,20 @@ nsReferencedElement::HaveNewDocument(nsI
       mElement = mWatchDocument->AddIDTargetObserver(mWatchID, Observe, this);
     }
     return;
   }
   
   if (!aDocument) {
     return;
   }
-  nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(aDocument);
-  NS_ASSERTION(domDoc, "Content doesn't reference a dom Document");
 
-  // XXXbz we should really have a sane GetElementById on nsIDocument.
-  nsCOMPtr<nsIDOMElement> element;
-  domDoc->GetElementById(aRef, getter_AddRefs(element));
-  if (element) {
-    nsCOMPtr<nsIContent> content = do_QueryInterface(element);
-    mElement = content->AsElement();
+  Element *e = aDocument->GetElementById(aRef);
+  if (e) {
+    mElement = e;
   }
 }
 
 void
 nsReferencedElement::Traverse(nsCycleCollectionTraversalCallback* aCB)
 {
   NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*aCB, "mWatchDocument");
   aCB->NoteXPCOMChild(mWatchDocument);
--- a/content/events/src/nsXMLEventsManager.cpp
+++ b/content/events/src/nsXMLEventsManager.cpp
@@ -42,16 +42,17 @@
 #include "nsIDOMElement.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMEventTarget.h"
 #include "nsNetUtil.h"
 #include "nsIURL.h"
 #include "nsIDOMEventListener.h"
 #include "nsINameSpaceManager.h"
 #include "nsINodeInfo.h"
+#include "mozilla/dom/Element.h"
 
 PRBool nsXMLEventsListener::InitXMLEventsListener(nsIDocument * aDocument,
                                                   nsXMLEventsManager * aManager,
                                                   nsIContent * aContent)
 {
   nsresult rv;
   PRInt32 nameSpaceID;
   if (aContent->GetDocument() != aDocument)
@@ -62,17 +63,17 @@ PRBool nsXMLEventsListener::InitXMLEvent
   else
     nameSpaceID = kNameSpaceID_XMLEvents;
   nsAutoString eventType;
   aContent->GetAttr(nameSpaceID, nsGkAtoms::event, eventType);
   if (eventType.IsEmpty())
     return PR_FALSE;
   nsAutoString handlerURIStr;
   PRBool hasHandlerURI = PR_FALSE;
-  nsCOMPtr<nsIContent> handler;
+  nsIContent *handler = nsnull;
   nsAutoString observerID;
   nsAutoString targetIdref;
   
   if (aContent->GetAttr(nameSpaceID, nsGkAtoms::handler, handlerURIStr)) {
     hasHandlerURI = PR_TRUE;
     nsCAutoString handlerRef;
     nsCOMPtr<nsIURI> handlerURI;
     PRBool equals = PR_FALSE;
@@ -82,23 +83,18 @@ PRBool nsXMLEventsListener::InitXMLEvent
     if (NS_SUCCEEDED(rv)) {
       nsCOMPtr<nsIURL> handlerURL(do_QueryInterface(handlerURI));
       if (handlerURL) {
         handlerURL->GetRef(handlerRef);
         handlerURL->SetRef(EmptyCString());
         //We support only XML Events Basic.
         docURI->Equals(handlerURL, &equals);
         if (equals) {
-          nsCOMPtr<nsIDOMDocument> doc(do_QueryInterface(aDocument));
-          if (doc) {
-            nsCOMPtr<nsIDOMElement> domhandler;
-            doc->GetElementById(NS_ConvertUTF8toUTF16(handlerRef),
-                                getter_AddRefs(domhandler));
-            handler = do_QueryInterface(domhandler);
-          }
+          handler =
+            aDocument->GetElementById(NS_ConvertUTF8toUTF16(handlerRef));
         }
       }
     }
   }
   else
     handler = aContent;
   if (!handler)
     return PR_FALSE;
@@ -115,34 +111,27 @@ PRBool nsXMLEventsListener::InitXMLEvent
   PRBool stopPropagation = 
     aContent->AttrValueIs(nameSpaceID, nsGkAtoms::propagate,
                           nsGkAtoms::stop, eCaseMatters);
 
   PRBool cancelDefault = 
     aContent->AttrValueIs(nameSpaceID, nsGkAtoms::defaultAction,
                           nsGkAtoms::cancel, eCaseMatters);
 
-  nsCOMPtr<nsIContent> observer;
+  nsIContent *observer;
   if (!hasObserver) {
     if (!hasHandlerURI) //Parent should be the observer
       observer = aContent->GetParent();
     else //We have the handler, so this is the observer
       observer = aContent;
   }
   else if (!observerID.IsEmpty()) {
-    nsCOMPtr<nsIDOMDocument> doc(do_QueryInterface(aDocument));
-    if (doc) {
-      nsCOMPtr<nsIDOMElement> el;
-      doc->GetElementById(observerID, getter_AddRefs(el));
-      observer = do_QueryInterface(el);
-    }
+    observer = aDocument->GetElementById(observerID);
   }
-  nsCOMPtr<nsIDOMEventTarget> eventObserver;
-  if (observer)
-    eventObserver = do_QueryInterface(observer);
+  nsCOMPtr<nsIDOMEventTarget> eventObserver(do_QueryInterface(observer));
   if (eventObserver) {
     nsXMLEventsListener * eli = new nsXMLEventsListener(aManager,
                                                         aContent,
                                                         observer,
                                                         handler,
                                                         eventType,
                                                         capture,
                                                         stopPropagation,
--- a/content/html/content/src/nsHTMLLabelElement.cpp
+++ b/content/html/content/src/nsHTMLLabelElement.cpp
@@ -438,17 +438,18 @@ nsHTMLLabelElement::GetControlContent()
 
   nsIContent* content = doc->GetElementById(elementId);
   if (!content) {
     return nsnull;
   }
 
   nsCOMPtr<nsIFormControl> element = do_QueryInterface(content);
   if (element && element->IsLabelableControl()) {
-    NS_ADDREF(content);
+    // Transfer the reference count of element to the returned value.
+    element.forget();
     return content;
   }
 
   return nsnull;
 }
 
 already_AddRefed<nsIContent>
 nsHTMLLabelElement::GetFirstFormControl(nsIContent *current)
--- a/content/html/content/src/nsImageMapUtils.cpp
+++ b/content/html/content/src/nsImageMapUtils.cpp
@@ -34,27 +34,25 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsString.h"
 #include "nsReadableUtils.h"
 #include "nsCOMPtr.h"
 #include "nsIDocument.h"
+#include "nsIContent.h"
 #include "nsIHTMLDocument.h"
-#include "nsIDOMDocument.h"
-#include "nsIDOMNode.h"
-#include "nsIDOMElement.h"
 #include "nsIDOMHTMLMapElement.h"
 #include "nsImageMapUtils.h"
 
 /*static*/
 already_AddRefed<nsIDOMHTMLMapElement>
 nsImageMapUtils::FindImageMap(nsIDocument *aDocument, 
-                                                    const nsAString &aUsemap)
+                              const nsAString &aUsemap)
 {
   if (!aDocument)
     return nsnull;
 
   // We used to strip the whitespace from the usemap value as a Quirk,
   // but it was too quirky and didn't really work correctly - see bug
   // 87050
 
@@ -86,23 +84,19 @@ nsImageMapUtils::FindImageMap(nsIDocumen
     return map;
   } else {
     // For XHTML elements embedded in non-XHTML documents we get the
     // map by id since XHTML requires that where a "name" attribute
     // was used in HTML 4.01, the "id" attribute must be used in
     // XHTML. The attribute "name" is officially deprecated.  This
     // simplifies our life becase we can simply get the map with
     // getElementById().
-    nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(aDocument));
-    if (domDoc) {
-      nsCOMPtr<nsIDOMElement> element;
-      domDoc->GetElementById(usemap, getter_AddRefs(element));
+    nsIContent *element = aDocument->GetElementById(usemap);
 
-      if (element) {
-        nsIDOMHTMLMapElement* map;
-        CallQueryInterface(element, &map);
-        return map;
-      }
+    if (element) {
+      nsIDOMHTMLMapElement* map;
+      CallQueryInterface(element, &map);
+      return map;
     }
   }
   
   return nsnull;
 }
--- a/content/xbl/src/nsXBLWindowKeyHandler.cpp
+++ b/content/xbl/src/nsXBLWindowKeyHandler.cpp
@@ -531,20 +531,19 @@ nsXBLWindowKeyHandler::WalkHandlersAndEx
     if (el && elt) {
       // We are.  Obtain our command attribute.
       nsAutoString command;
       elt->GetAttr(kNameSpaceID_None, nsGkAtoms::command, command);
       if (!command.IsEmpty()) {
         // Locate the command element in question.  Note that we
         // know "elt" is in a doc if we're dealing with it here.
         NS_ASSERTION(elt->IsInDoc(), "elt must be in document");
-        nsCOMPtr<nsIDOMDocument> domDoc(
-           do_QueryInterface(elt->GetCurrentDoc()));
-        if (domDoc)
-          domDoc->GetElementById(command, getter_AddRefs(commandElt));
+        nsIDocument *doc = elt->GetCurrentDoc();
+        if (doc)
+          commandElt = do_QueryInterface(doc->GetElementById(command));
 
         if (!commandElt) {
           NS_ERROR("A XUL <key> is observing a command that doesn't exist. Unable to execute key binding!");
           continue;
         }
       }
     }
 
--- a/content/xslt/src/xpath/txMozillaXPathTreeWalker.cpp
+++ b/content/xslt/src/xpath/txMozillaXPathTreeWalker.cpp
@@ -102,23 +102,17 @@ txXPathTreeWalker::moveToElementById(con
     if (aID.IsEmpty()) {
         return PR_FALSE;
     }
 
     nsIDocument* doc = mPosition.mNode->GetCurrentDoc();
 
     nsCOMPtr<nsIContent> content;
     if (doc) {
-        nsCOMPtr<nsIDOMDocument> document = do_QueryInterface(doc);
-        NS_ASSERTION(document, "QI failed");
-
-        nsCOMPtr<nsIDOMElement> element;
-        document->GetElementById(aID, getter_AddRefs(element));
-
-        content = do_QueryInterface(element);
+        content = doc->GetElementById(aID);
     }
     else {
         // We're in a disconnected subtree, search only that subtree.
         nsINode *rootNode = mPosition.Root();
 
         NS_ASSERTION(rootNode->IsNodeOfType(nsINode::eCONTENT),
                      "root of subtree wasn't an nsIContent");
 
--- a/content/xul/document/src/nsXULDocument.cpp
+++ b/content/xul/document/src/nsXULDocument.cpp
@@ -1301,28 +1301,20 @@ nsXULDocument::Persist(const nsAString& 
 {
     // If we're currently reading persisted attributes out of the
     // localstore, _don't_ re-enter and try to set them again!
     if (mApplyingPersistedAttrs)
         return NS_OK;
 
     nsresult rv;
 
-    nsCOMPtr<nsIDOMElement> domelement;
-    rv = nsDocument::GetElementById(aID, getter_AddRefs(domelement));
-    if (NS_FAILED(rv)) return rv;
-
-    if (! domelement)
+    nsIContent *element = nsDocument::GetElementById(aID);
+    if (! element)
         return NS_OK;
 
-    nsCOMPtr<nsIContent> element = do_QueryInterface(domelement);
-    NS_ASSERTION(element != nsnull, "null ptr");
-    if (! element)
-        return NS_ERROR_UNEXPECTED;
-
     nsCOMPtr<nsIAtom> tag;
     PRInt32 nameSpaceID;
 
     nsCOMPtr<nsINodeInfo> ni = element->GetExistingAttrNameFromQName(aAttr);
     if (ni) {
         tag = ni->NameAtom();
         nameSpaceID = ni->NamespaceID();
     }
@@ -3936,24 +3928,20 @@ nsXULDocument::OverlayForwardReference::
         rv = mDocument->InsertElement(root, mOverlay, notify);
         if (NS_FAILED(rv)) return eResolve_Error;
 
         target = mOverlay;
     }
     else {
         // The hook-up element has an id, try to match it with an element
         // with the same id in the base document.
-        nsCOMPtr<nsIDOMElement> domtarget;
-        rv = mDocument->GetElementById(id, getter_AddRefs(domtarget));
-        if (NS_FAILED(rv)) return eResolve_Error;
+        target = mDocument->GetElementById(id);
 
         // If we can't find the element in the document, defer the hookup
         // until later.
-        target = do_QueryInterface(domtarget);
-        NS_ASSERTION(!domtarget || target, "not an nsIContent");
         if (!target)
             return eResolve_Later;
 
         // While merging, set the default script language of the element to be
         // the language from the overlay - attributes will then be correctly
         // hooked up with the appropriate language (while child nodes ignore
         // the default language - they have it in their proto.
         PRUint32 oldDefLang = target->GetScriptTypeID();
@@ -4075,52 +4063,47 @@ nsXULDocument::OverlayForwardReference::
 
     // This must be a strong reference since it will be the only
     // reference to a content object during part of this loop.
     nsCOMPtr<nsIContent> currContent;
 
     for (i = 0; i < childCount; ++i) {
         currContent = aOverlayNode->GetChildAt(0);
 
-        nsAutoString id;
-        currContent->GetAttr(kNameSpaceID_None, nsGkAtoms::id, id);
-
-        nsCOMPtr<nsIDOMElement> nodeInDocument;
-        if (!id.IsEmpty()) {
-            nsCOMPtr<nsIDOMDocument> domDocument(
-                        do_QueryInterface(aTargetNode->GetDocument()));
-            if (!domDocument) return NS_ERROR_FAILURE;
-
-            rv = domDocument->GetElementById(id, getter_AddRefs(nodeInDocument));
-            if (NS_FAILED(rv)) return rv;
+        nsIAtom *idAtom = currContent->GetID();
+
+        nsIContent *elementInDocument = nsnull;
+        if (idAtom) {
+            nsIDocument *doc = aTargetNode->GetDocument();
+            if (!doc) return NS_ERROR_FAILURE;
+
+            elementInDocument =
+                doc->GetElementById(nsDependentAtomString(idAtom));
         }
 
         // The item has an 'id' attribute set, and we need to check with
         // the actual document to see if an item with this id exists at
         // this locale. If so, we want to merge the subtree under that
         // node. Otherwise, we just do an append as if the element had
         // no id attribute.
-        if (nodeInDocument) {
+        if (elementInDocument) {
             // Given two parents, aTargetNode and aOverlayNode, we want
             // to call merge on currContent if we find an associated
             // node in the document with the same id as currContent that
             // also has aTargetNode as its parent.
 
-            nsCOMPtr<nsIDOMNode> nodeParent;
-            rv = nodeInDocument->GetParentNode(getter_AddRefs(nodeParent));
-            if (NS_FAILED(rv)) return rv;
-            nsCOMPtr<nsIDOMElement> elementParent(do_QueryInterface(nodeParent));
-
-            nsAutoString parentID;
-            elementParent->GetAttribute(NS_LITERAL_STRING("id"), parentID);
-            if (aTargetNode->AttrValueIs(kNameSpaceID_None, nsGkAtoms::id,
-                                         parentID, eCaseMatters)) {
+            nsIContent *elementParent = elementInDocument->GetParent();
+
+            nsIAtom *parentID = elementParent->GetID();
+            if (parentID &&
+                aTargetNode->AttrValueIs(kNameSpaceID_None, nsGkAtoms::id,
+                                         nsDependentAtomString(parentID),
+                                         eCaseMatters)) {
                 // The element matches. "Go Deep!"
-                nsCOMPtr<nsIContent> childDocumentContent(do_QueryInterface(nodeInDocument));
-                rv = Merge(childDocumentContent, currContent, aNotify);
+                rv = Merge(elementInDocument, currContent, aNotify);
                 if (NS_FAILED(rv)) return rv;
                 rv = aOverlayNode->RemoveChildAt(0, PR_FALSE);
                 if (NS_FAILED(rv)) return rv;
 
                 continue;
             }
         }
 
@@ -4393,44 +4376,37 @@ nsXULDocument::InsertElement(nsIContent*
     PRBool isInsertAfter = PR_TRUE;
 
     if (posStr.IsEmpty()) {
         aChild->GetAttr(kNameSpaceID_None, nsGkAtoms::insertbefore, posStr);
         isInsertAfter = PR_FALSE;
     }
 
     if (!posStr.IsEmpty()) {
-        nsCOMPtr<nsIDOMDocument> domDocument(
-               do_QueryInterface(aParent->GetDocument()));
-        if (!domDocument) return NS_ERROR_FAILURE;
-
-        nsCOMPtr<nsIDOMElement> domElement;
+        nsIDocument *document = aParent->GetOwnerDoc();
+        if (!document) return NS_ERROR_FAILURE;
+
+        nsIContent *content = nsnull;
 
         char* str = ToNewCString(posStr);
         char* rest;
         char* token = nsCRT::strtok(str, ", ", &rest);
 
         while (token) {
-            rv = domDocument->GetElementById(NS_ConvertASCIItoUTF16(token),
-                                             getter_AddRefs(domElement));
-            if (domElement)
+            content = document->GetElementById(NS_ConvertASCIItoUTF16(token));
+            if (content)
                 break;
 
             token = nsCRT::strtok(rest, ", ", &rest);
         }
         nsMemory::Free(str);
         if (NS_FAILED(rv))
             return rv;
 
-        if (domElement) {
-            nsCOMPtr<nsIContent> content(do_QueryInterface(domElement));
-            NS_ASSERTION(content != nsnull, "null ptr");
-            if (!content)
-                return NS_ERROR_UNEXPECTED;
-
+        if (content) {
             PRInt32 pos = aParent->IndexOf(content);
 
             if (pos != -1) {
                 pos = isInsertAfter ? pos + 1 : pos;
                 rv = aParent->InsertChildAt(aChild, pos, aNotify);
                 if (NS_FAILED(rv))
                     return rv;
 
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -4793,26 +4793,17 @@ nsWindowSH::GlobalScopePolluterNewResolv
       hasProp) {
     // No prototype, or the property exists on the prototype. Do
     // nothing.
 
     return JS_TRUE;
   }
 
   nsDependentJSString str(jsstr);
-  nsCOMPtr<nsISupports> result;
-
-  {
-    nsCOMPtr<nsIDOMDocument> dom_doc(do_QueryInterface(doc));
-    nsCOMPtr<nsIDOMElement> element;
-
-    dom_doc->GetElementById(str, getter_AddRefs(element));
-
-    result = element;
-  }
+  nsCOMPtr<nsISupports> result = document->GetElementById(str);
 
   if (!result) {
     doc->ResolveName(str, nsnull, getter_AddRefs(result));
   }
 
   if (result) {
     jsval v;
     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -3718,30 +3718,23 @@ PresShell::GoToAnchor(const nsAString& a
   nsCOMPtr<nsIEventStateManager> esm = mPresContext->EventStateManager();
 
   if (aAnchorName.IsEmpty()) {
     NS_ASSERTION(!aScroll, "can't scroll to empty anchor name");
     esm->SetContentState(nsnull, NS_EVENT_STATE_URLTARGET);
     return NS_OK;
   }
 
-  nsCOMPtr<nsIDOMDocument> doc = do_QueryInterface(mDocument);
   nsCOMPtr<nsIDOMHTMLDocument> htmlDoc = do_QueryInterface(mDocument);
   nsresult rv = NS_OK;
   nsCOMPtr<nsIContent> content;
 
   // Search for an element with a matching "id" attribute
-  if (doc) {    
-    nsCOMPtr<nsIDOMElement> element;
-    rv = doc->GetElementById(aAnchorName, getter_AddRefs(element));
-    if (NS_SUCCEEDED(rv) && element) {
-      // Get the nsIContent interface, because that's what we need to
-      // get the primary frame
-      content = do_QueryInterface(element);
-    }
+  if (mDocument) {    
+    content = mDocument->GetElementById(aAnchorName);
   }
 
   // Search for an anchor element with a matching "name" attribute
   if (!content && htmlDoc) {
     nsCOMPtr<nsIDOMNodeList> list;
     // Find a matching list of named nodes
     rv = htmlDoc->GetElementsByName(aAnchorName, getter_AddRefs(list));
     if (NS_SUCCEEDED(rv) && list) {
@@ -3763,16 +3756,17 @@ PresShell::GoToAnchor(const nsAString& a
         }
       }
     }
   }
 
   // Search for anchor in the HTML namespace with a matching name
   if (!content && !htmlDoc)
   {
+    nsCOMPtr<nsIDOMDocument> doc = do_QueryInterface(mDocument);
     nsCOMPtr<nsIDOMNodeList> list;
     NS_NAMED_LITERAL_STRING(nameSpace, "http://www.w3.org/1999/xhtml");
     // Get the list of anchor elements
     rv = doc->GetElementsByTagNameNS(nameSpace, NS_LITERAL_STRING("a"), getter_AddRefs(list));
     if (NS_SUCCEEDED(rv) && list) {
       PRUint32 i;
       // Loop through the named nodes looking for the first anchor
       for (i = 0; PR_TRUE; i++) {
--- a/layout/xul/base/src/nsMenuFrame.cpp
+++ b/layout/xul/base/src/nsMenuFrame.cpp
@@ -1010,40 +1010,35 @@ nsMenuFrame::BuildAcceleratorText()
 
   // See if we have a key node and use that instead.
   nsAutoString keyValue;
   mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::key, keyValue);
   if (keyValue.IsEmpty())
     return;
 
   // Turn the document into a DOM document so we can use getElementById
-  nsCOMPtr<nsIDOMDocument> domDocument(do_QueryInterface(mContent->GetDocument()));
-  if (!domDocument)
+  nsIDocument *document = mContent->GetDocument();
+  if (!document)
     return;
 
-  nsCOMPtr<nsIDOMElement> keyDOMElement;
-  domDocument->GetElementById(keyValue, getter_AddRefs(keyDOMElement));
-  if (!keyDOMElement) {
+  nsIContent *keyElement = document->GetElementById(keyValue);
+  if (!keyElement) {
 #ifdef DEBUG
     nsAutoString label;
     mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::label, label);
     nsAutoString msg = NS_LITERAL_STRING("Key '") +
                        keyValue +
                        NS_LITERAL_STRING("' of menu item '") +
                        label +
                        NS_LITERAL_STRING("' could not be found");
     NS_WARNING(NS_ConvertUTF16toUTF8(msg).get());
 #endif
     return;
   }
 
-  nsCOMPtr<nsIContent> keyElement(do_QueryInterface(keyDOMElement));
-  if (!keyElement)
-    return;
-
   // get the string to display as accelerator text
   // check the key element's attributes in this order:
   // |keytext|, |key|, |keycode|
   nsAutoString accelString;
   keyElement->GetAttr(kNameSpaceID_None, nsGkAtoms::keytext, accelString);
 
   if (accelString.IsEmpty()) {
     keyElement->GetAttr(kNameSpaceID_None, nsGkAtoms::key, accelString);
--- a/layout/xul/base/src/nsResizerFrame.cpp
+++ b/layout/xul/base/src/nsResizerFrame.cpp
@@ -377,22 +377,17 @@ nsResizerFrame::GetContentToResize(nsIPr
   }
 
   if (elementid.EqualsLiteral("_parent")) {
     // return the parent, but skip over native anonymous content
     nsIContent* parent = mContent->GetParent();
     return parent ? parent->FindFirstNonNativeAnonymous() : nsnull;
   }
 
-  nsCOMPtr<nsIDOMDocument> doc = do_QueryInterface(aPresShell->GetDocument());
-  nsCOMPtr<nsIDOMElement> element;
-  doc->GetElementById(elementid, getter_AddRefs(element));
-
-  nsCOMPtr<nsIContent> content = do_QueryInterface(element);
-  return content.get();
+  return aPresShell->GetDocument()->GetElementById(elementid);
 }
 
 /* adjust the window position and size according to the mouse movement and
  * the resizer direction
  */
 void
 nsResizerFrame::AdjustDimensions(PRInt32* aPos, PRInt32* aSize,
                                  PRInt32 aMovement, PRInt8 aResizerDirection)
--- a/layout/xul/base/src/nsXULTooltipListener.cpp
+++ b/layout/xul/base/src/nsXULTooltipListener.cpp
@@ -603,22 +603,22 @@ GetImmediateChild(nsIContent* aContent, 
 
 nsresult
 nsXULTooltipListener::FindTooltip(nsIContent* aTarget, nsIContent** aTooltip)
 {
   if (!aTarget)
     return NS_ERROR_NULL_POINTER;
 
   // before we go on, make sure that target node still has a window
-  nsCOMPtr<nsIDocument> document = aTarget->GetDocument();
+  nsIDocument *document = aTarget->GetDocument();
   if (!document) {
     NS_WARNING("Unable to retrieve the tooltip node document.");
     return NS_ERROR_FAILURE;
   }
-  nsCOMPtr<nsPIDOMWindow> window = document->GetWindow();
+  nsPIDOMWindow *window = document->GetWindow();
   if (!window) {
     return NS_OK;
   }
 
   PRBool closed;
   window->GetClosed(&closed);
 
   if (closed) {
@@ -645,30 +645,23 @@ nsXULTooltipListener::FindTooltip(nsICon
   // if tooltip == _child, look for first <tooltip> child
   if (tooltipId.EqualsLiteral("_child")) {
     GetImmediateChild(aTarget, nsGkAtoms::tooltip, aTooltip);
     return NS_OK;
   }
 
   if (!tooltipId.IsEmpty()) {
     // tooltip must be an id, use getElementById to find it
-    nsCOMPtr<nsIDOMDocument> domDocument =
-      do_QueryInterface(document);
-    if (!domDocument) {
-      return NS_ERROR_FAILURE;
-    }
-
-    nsCOMPtr<nsIDOMElement> tooltipEl;
-    domDocument->GetElementById(tooltipId, getter_AddRefs(tooltipEl));
+    nsCOMPtr<nsIContent> tooltipEl = document->GetElementById(tooltipId);
 
     if (tooltipEl) {
 #ifdef MOZ_XUL
       mNeedTitletip = PR_FALSE;
 #endif
-      CallQueryInterface(tooltipEl, aTooltip);
+      *aTooltip = tooltipEl.forget().get();
       return NS_OK;
     }
   }
 
 #ifdef MOZ_XUL
   // titletips should just use the default tooltip
   if (mIsSourceTree && mNeedTitletip) {
     nsIRootBox* rootBox = nsIRootBox::GetRootBox(document->GetPrimaryShell());
--- a/widget/src/cocoa/nsMenuItemX.mm
+++ b/widget/src/cocoa/nsMenuItemX.mm
@@ -43,17 +43,17 @@
 #include "nsMenuUtilsX.h"
 
 #include "nsObjCExceptions.h"
 
 #include "nsCOMPtr.h"
 #include "nsWidgetAtoms.h"
 #include "nsGUIEvent.h"
 
-#include "nsIContent.h"
+#include "mozilla/dom/Element.h"
 #include "nsIWidget.h"
 #include "nsIDocument.h"
 #include "nsIDOMDocument.h"
 #include "nsIPrivateDOMEvent.h"
 #include "nsIDOMEventTarget.h"
 #include "nsIDOMDocumentEvent.h"
 #include "nsIDOMElement.h"
 
@@ -99,30 +99,29 @@ nsresult nsMenuItemX::Create(nsMenuX* aP
   mMenuParent = aParent;
   mContent = aNode;
 
   mMenuGroupOwner = aMenuGroupOwner;
   NS_ASSERTION(mMenuGroupOwner, "No menu owner given, must have one!");
 
   mMenuGroupOwner->RegisterForContentChanges(mContent, this);
 
-  nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(mContent->GetCurrentDoc()));
+  nsIDocument *doc = mContent->GetCurrentDoc();
 
   // if we have a command associated with this menu item, register for changes
   // to the command DOM node
-  if (domDoc) {
+  if (doc) {
     nsAutoString ourCommand;
     mContent->GetAttr(kNameSpaceID_None, nsWidgetAtoms::command, ourCommand);
 
     if (!ourCommand.IsEmpty()) {
-      nsCOMPtr<nsIDOMElement> commandElement;
-      domDoc->GetElementById(ourCommand, getter_AddRefs(commandElement));
+      nsIContent *commandElement = doc->GetElementById(ourCommand);
 
       if (commandElement) {
-        mCommandContent = do_QueryInterface(commandElement);
+        mCommandContent = commandElement;
         // register to observe the command DOM element
         mMenuGroupOwner->RegisterForContentChanges(mCommandContent, this);
       }
     }
   }
 
   // decide enabled state based on command content if it exists, otherwise do it based
   // on our own content
@@ -141,24 +140,22 @@ nsresult nsMenuItemX::Create(nsMenuX* aP
     mNativeMenuItem = [[NSMenuItem alloc] initWithTitle:newCocoaLabelString action:nil keyEquivalent:@""];
 
     [mNativeMenuItem setEnabled:(BOOL)isEnabled];
 
     SetChecked(mContent->AttrValueIs(kNameSpaceID_None, nsWidgetAtoms::checked,
                                      nsWidgetAtoms::_true, eCaseMatters));
 
     // Set key shortcut and modifiers
-    if (domDoc) {
+    if (doc) {
       nsAutoString keyValue;
       mContent->GetAttr(kNameSpaceID_None, nsWidgetAtoms::key, keyValue);
       if (!keyValue.IsEmpty()) {
-        nsCOMPtr<nsIDOMElement> keyElement;
-        domDoc->GetElementById(keyValue, getter_AddRefs(keyElement));
-        if (keyElement) {
-          nsCOMPtr<nsIContent> keyContent(do_QueryInterface(keyElement));
+        nsIContent *keyContent = doc->GetElementById(keyValue);
+        if (keyContent) {
           nsAutoString keyChar(NS_LITERAL_STRING(" "));
           keyContent->GetAttr(kNameSpaceID_None, nsWidgetAtoms::key, keyChar);
 
           nsAutoString modifiersStr;
           keyContent->GetAttr(kNameSpaceID_None, nsWidgetAtoms::modifiers, modifiersStr);
           PRUint8 modifiers = nsMenuUtilsX::GeckoModifiersForNodeAttribute(modifiersStr);
 
           SetKeyEquiv(modifiers, keyChar);