Fixing bug 572609. Use faster version of GetElementById() from our C++ code. r=jonas@sicking.cc
authorJohnny Stenback <jst@mozilla.com>
Wed, 23 Jun 2010 14:35:57 -0700
changeset 44209 f269bf14f264d32f92e008bfe0651d481fa13e36
parent 44208 9666ea595351377465b74a2bdbf140d9471abb2b
child 44210 890b78ea868dde224e31d04caaa1233f7c9c62eb
push idunknown
push userunknown
push dateunknown
reviewersjonas
bugs572609
milestone1.9.3a6pre
Fixing bug 572609. Use faster version of GetElementById() from our C++ code. r=jonas@sicking.cc
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/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
@@ -1297,28 +1297,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();
     }
@@ -3920,24 +3912,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();
@@ -4059,52 +4047,50 @@ 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) {
+            nsDependentAtomString id(idAtom);
+
+            if (!id.IsEmpty()) {
+                nsIDocument *doc = aTargetNode->GetDocument();
+                if (!doc) return NS_ERROR_FAILURE;
+
+                elementInDocument = doc->GetElementById(id);
+            }
         }
 
         // 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;
             }
         }
 
@@ -4358,80 +4344,72 @@ nsXULDocument::CheckBroadcasterHookup(El
 #endif
 
     *aNeedsHookup = PR_FALSE;
     *aDidResolve = PR_TRUE;
     return NS_OK;
 }
 
 nsresult
-nsXULDocument::InsertElement(nsIContent* aParent, nsIContent* aChild, PRBool aNotify)
+nsXULDocument::InsertElement(nsIContent* aParent, nsIContent* aChild,
+                             PRBool aNotify)
 {
     // Insert aChild appropriately into aParent, accounting for a
     // 'pos' attribute set on aChild.
-    nsresult rv;
 
     nsAutoString posStr;
     PRBool wasInserted = PR_FALSE;
 
     // insert after an element of a given id
     aChild->GetAttr(kNameSpaceID_None, nsGkAtoms::insertafter, posStr);
     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);
+                nsresult rv = aParent->InsertChildAt(aChild, pos, aNotify);
                 if (NS_FAILED(rv))
                     return rv;
 
                 wasInserted = PR_TRUE;
             }
         }
     }
 
     if (!wasInserted) {
 
         aChild->GetAttr(kNameSpaceID_None, nsGkAtoms::position, posStr);
         if (!posStr.IsEmpty()) {
+            nsresult rv;
             // Positions are one-indexed.
             PRInt32 pos = posStr.ToInteger(reinterpret_cast<PRInt32*>(&rv));
             // Note: if the insertion index (which is |pos - 1|) would be less
             // than 0 or greater than the number of children aParent has, then
             // don't insert, since the position is bogus.  Just skip on to
             // appending.
             if (NS_SUCCEEDED(rv) && pos > 0 &&
                 PRUint32(pos - 1) <= aParent->GetChildCount()) {
@@ -4441,19 +4419,18 @@ nsXULDocument::InsertElement(nsIContent*
                 // If the insertion fails, then we should still
                 // attempt an append.  Thus, rather than returning rv
                 // immediately, we fall through to the final
                 // "catch-all" case that just does an AppendChildTo.
             }
         }
     }
 
-    if (! wasInserted) {
-        rv = aParent->AppendChildTo(aChild, aNotify);
-        if (NS_FAILED(rv)) return rv;
+    if (!wasInserted) {
+        return aParent->AppendChildTo(aChild, aNotify);
     }
     return NS_OK;
 }
 
 nsresult
 nsXULDocument::RemoveElement(nsIContent* aParent, nsIContent* aChild)
 {
     PRInt32 nodeOffset = aParent->IndexOf(aChild);
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -4886,26 +4886,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);