Fixing bug 572609. Use faster version of GetElementById() from our C++ code. r=jonas@sicking.cc

This commit is contained in:
Johnny Stenback 2010-06-21 19:58:50 -07:00
Родитель 163467f9c7
Коммит c50fb5d521
14 изменённых файлов: 68 добавлений и 156 удалений

Просмотреть файл

@ -952,7 +952,6 @@ protected:
* @returns PR_TRUE if aId looks correct, PR_FALSE otherwise.
*/
static PRBool CheckGetElementByIdArg(const nsIAtom* aId);
nsIdentifierMapEntry* GetElementByIdInternal(nsIAtom* aID);
void DispatchContentLoadedEvents();

Просмотреть файл

@ -213,15 +213,10 @@ nsReferencedElement::HaveNewDocument(nsIDocument* aDocument, PRBool aWatch,
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;
}
}

Просмотреть файл

@ -47,6 +47,7 @@
#include "nsIDOMEventListener.h"
#include "nsINameSpaceManager.h"
#include "nsINodeInfo.h"
#include "mozilla/dom/Element.h"
PRBool nsXMLEventsListener::InitXMLEventsListener(nsIDocument * aDocument,
nsXMLEventsManager * aManager,
@ -67,7 +68,7 @@ PRBool nsXMLEventsListener::InitXMLEventsListener(nsIDocument * aDocument,
return PR_FALSE;
nsAutoString handlerURIStr;
PRBool hasHandlerURI = PR_FALSE;
nsCOMPtr<nsIContent> handler;
nsIContent *handler = nsnull;
nsAutoString observerID;
nsAutoString targetIdref;
@ -87,13 +88,8 @@ PRBool nsXMLEventsListener::InitXMLEventsListener(nsIDocument * aDocument,
//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));
}
}
}
@ -120,7 +116,7 @@ PRBool nsXMLEventsListener::InitXMLEventsListener(nsIDocument * aDocument,
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();
@ -128,16 +124,9 @@ PRBool nsXMLEventsListener::InitXMLEventsListener(nsIDocument * aDocument,
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,

Просмотреть файл

@ -443,7 +443,8 @@ nsHTMLLabelElement::GetControlContent()
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;
}

Просмотреть файл

@ -39,17 +39,15 @@
#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;
@ -91,16 +89,12 @@ nsImageMapUtils::FindImageMap(nsIDocument *aDocument,
// 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;
}
}

Просмотреть файл

@ -536,10 +536,9 @@ nsXBLWindowKeyHandler::WalkHandlersAndExecute(nsIDOMKeyEvent* aKeyEvent,
// 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!");

Просмотреть файл

@ -107,13 +107,7 @@ txXPathTreeWalker::moveToElementById(const nsAString& aID)
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.

Просмотреть файл

@ -1306,17 +1306,9 @@ nsXULDocument::Persist(const nsAString& aID,
nsresult rv;
nsCOMPtr<nsIDOMElement> domelement;
rv = nsDocument::GetElementById(aID, getter_AddRefs(domelement));
if (NS_FAILED(rv)) return rv;
if (! domelement)
return NS_OK;
nsCOMPtr<nsIContent> element = do_QueryInterface(domelement);
NS_ASSERTION(element != nsnull, "null ptr");
nsIContent *element = nsDocument::GetElementById(aID);
if (! element)
return NS_ERROR_UNEXPECTED;
return NS_OK;
nsCOMPtr<nsIAtom> tag;
PRInt32 nameSpaceID;
@ -3941,14 +3933,10 @@ nsXULDocument::OverlayForwardReference::Resolve()
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;
@ -4080,17 +4068,15 @@ nsXULDocument::OverlayForwardReference::Merge(nsIContent* aTargetNode,
for (i = 0; i < childCount; ++i) {
currContent = aOverlayNode->GetChildAt(0);
nsAutoString id;
currContent->GetAttr(kNameSpaceID_None, nsGkAtoms::id, id);
nsIAtom *idAtom = currContent->GetID();
nsCOMPtr<nsIDOMElement> nodeInDocument;
if (!id.IsEmpty()) {
nsCOMPtr<nsIDOMDocument> domDocument(
do_QueryInterface(aTargetNode->GetDocument()));
if (!domDocument) return NS_ERROR_FAILURE;
nsIContent *elementInDocument = nsnull;
if (idAtom) {
nsIDocument *doc = aTargetNode->GetDocument();
if (!doc) return NS_ERROR_FAILURE;
rv = domDocument->GetElementById(id, getter_AddRefs(nodeInDocument));
if (NS_FAILED(rv)) return rv;
elementInDocument =
doc->GetElementById(nsDependentAtomString(idAtom));
}
// The item has an 'id' attribute set, and we need to check with
@ -4098,24 +4084,21 @@ nsXULDocument::OverlayForwardReference::Merge(nsIContent* aTargetNode,
// 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));
nsIContent *elementParent = elementInDocument->GetParent();
nsAutoString parentID;
elementParent->GetAttribute(NS_LITERAL_STRING("id"), parentID);
if (aTargetNode->AttrValueIs(kNameSpaceID_None, nsGkAtoms::id,
parentID, eCaseMatters)) {
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;
@ -4398,20 +4381,18 @@ nsXULDocument::InsertElement(nsIContent* aParent, nsIContent* aChild, PRBool aNo
}
if (!posStr.IsEmpty()) {
nsCOMPtr<nsIDOMDocument> domDocument(
do_QueryInterface(aParent->GetDocument()));
if (!domDocument) return NS_ERROR_FAILURE;
nsIDocument *document = aParent->GetOwnerDoc();
if (!document) return NS_ERROR_FAILURE;
nsCOMPtr<nsIDOMElement> domElement;
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);
@ -4420,12 +4401,7 @@ nsXULDocument::InsertElement(nsIContent* aParent, nsIContent* aChild, PRBool aNo
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) {

Просмотреть файл

@ -4798,16 +4798,7 @@ nsWindowSH::GlobalScopePolluterNewResolve(JSContext *cx, JSObject *obj,
}
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));

Просмотреть файл

@ -3723,20 +3723,13 @@ PresShell::GoToAnchor(const nsAString& aAnchorName, PRBool aScroll)
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
@ -3768,6 +3761,7 @@ PresShell::GoToAnchor(const nsAString& aAnchorName, PRBool aScroll)
// 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

Просмотреть файл

@ -1015,13 +1015,12 @@ nsMenuFrame::BuildAcceleratorText()
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);
@ -1035,10 +1034,6 @@ nsMenuFrame::BuildAcceleratorText()
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|

Просмотреть файл

@ -382,12 +382,7 @@ nsResizerFrame::GetContentToResize(nsIPresShell* aPresShell, nsIBaseWindow** aWi
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

Просмотреть файл

@ -608,12 +608,12 @@ nsXULTooltipListener::FindTooltip(nsIContent* aTarget, nsIContent** aTooltip)
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;
}
@ -650,20 +650,13 @@ nsXULTooltipListener::FindTooltip(nsIContent* aTarget, nsIContent** aTooltip)
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;
}
}

Просмотреть файл

@ -48,7 +48,7 @@
#include "nsWidgetAtoms.h"
#include "nsGUIEvent.h"
#include "nsIContent.h"
#include "mozilla/dom/Element.h"
#include "nsIWidget.h"
#include "nsIDocument.h"
#include "nsIDOMDocument.h"
@ -104,20 +104,19 @@ nsresult nsMenuItemX::Create(nsMenuX* aParent, const nsString& aLabel, EMenuItem
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);
}
@ -146,14 +145,12 @@ nsresult nsMenuItemX::Create(nsMenuX* aParent, const nsString& aLabel, EMenuItem
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);