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
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/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);