зеркало из https://github.com/mozilla/gecko-dev.git
Fix for bug 560462 (Use fast unwrapping for more quickstubs) - add non-addrefing GetElementById and GetBody, add nsContentList-returning GetElementsByTagName(NS) and GetElementsByName. r=jst.
This commit is contained in:
Родитель
86ecf361a5
Коммит
dff32db5c4
|
@ -3914,26 +3914,47 @@ nsDocument::GetElementByIdInternal(nsIAtom* aID)
|
|||
return entry;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocument::GetElementById(const nsAString& aElementId,
|
||||
nsIDOMElement** aReturn)
|
||||
Element*
|
||||
nsDocument::GetElementById(const nsAString& aElementId, nsresult *aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aReturn);
|
||||
*aReturn = nsnull;
|
||||
|
||||
nsCOMPtr<nsIAtom> idAtom(do_GetAtom(aElementId));
|
||||
NS_ENSURE_TRUE(idAtom, NS_ERROR_OUT_OF_MEMORY);
|
||||
if (!CheckGetElementByIdArg(idAtom))
|
||||
return NS_OK;
|
||||
if (!idAtom) {
|
||||
*aResult = NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
if (!CheckGetElementByIdArg(idAtom)) {
|
||||
*aResult = NS_OK;
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsIdentifierMapEntry *entry = GetElementByIdInternal(idAtom);
|
||||
NS_ENSURE_TRUE(entry, NS_ERROR_OUT_OF_MEMORY);
|
||||
if (!entry) {
|
||||
*aResult = NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
Element *e = entry->GetIdElement();
|
||||
if (!e)
|
||||
return NS_OK;
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
return CallQueryInterface(e, aReturn);
|
||||
*aResult = NS_OK;
|
||||
|
||||
return entry->GetIdElement();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocument::GetElementById(const nsAString& aId, nsIDOMElement** aReturn)
|
||||
{
|
||||
nsresult rv;
|
||||
Element *content = GetElementById(aId, &rv);
|
||||
if (content) {
|
||||
rv = CallQueryInterface(content, aReturn);
|
||||
}
|
||||
else {
|
||||
*aReturn = nsnull;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsIContent*
|
||||
|
@ -4385,25 +4406,38 @@ nsDocument::CreateEntityReference(const nsAString& aName,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
already_AddRefed<nsContentList>
|
||||
nsDocument::GetElementsByTagName(const nsAString& aTagname)
|
||||
{
|
||||
nsCOMPtr<nsIAtom> nameAtom = do_GetAtom(aTagname);
|
||||
if (IsHTML()) {
|
||||
nsAutoString tmp(aTagname);
|
||||
ToLowerCase(tmp); // HTML elements are lower case internally.
|
||||
nameAtom = do_GetAtom(tmp);
|
||||
}
|
||||
else {
|
||||
nameAtom = do_GetAtom(aTagname);
|
||||
}
|
||||
NS_ENSURE_TRUE(nameAtom, nsnull);
|
||||
|
||||
return NS_GetContentList(this, nameAtom, kNameSpaceID_Unknown);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocument::GetElementsByTagName(const nsAString& aTagname,
|
||||
nsIDOMNodeList** aReturn)
|
||||
{
|
||||
nsCOMPtr<nsIAtom> nameAtom = do_GetAtom(aTagname);
|
||||
NS_ENSURE_TRUE(nameAtom, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsContentList *list = NS_GetContentList(this, nameAtom, kNameSpaceID_Unknown).get();
|
||||
nsRefPtr<nsContentList> list = GetElementsByTagName(aTagname);
|
||||
NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
// transfer ref to aReturn
|
||||
*aReturn = list;
|
||||
*aReturn = list.forget().get();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
already_AddRefed<nsContentList>
|
||||
nsDocument::GetElementsByTagNameNS(const nsAString& aNamespaceURI,
|
||||
const nsAString& aLocalName,
|
||||
nsIDOMNodeList** aReturn)
|
||||
const nsAString& aLocalName)
|
||||
{
|
||||
PRInt32 nameSpaceId = kNameSpaceID_Wildcard;
|
||||
|
||||
|
@ -4411,17 +4445,26 @@ nsDocument::GetElementsByTagNameNS(const nsAString& aNamespaceURI,
|
|||
nsresult rv =
|
||||
nsContentUtils::NameSpaceManager()->RegisterNameSpace(aNamespaceURI,
|
||||
nameSpaceId);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_SUCCESS(rv, nsnull);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAtom> nameAtom = do_GetAtom(aLocalName);
|
||||
NS_ENSURE_TRUE(nameAtom, NS_ERROR_OUT_OF_MEMORY);
|
||||
NS_ENSURE_TRUE(nameAtom, nsnull);
|
||||
|
||||
nsContentList *list = NS_GetContentList(this, nameAtom, nameSpaceId).get();
|
||||
return NS_GetContentList(this, nameAtom, nameSpaceId);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocument::GetElementsByTagNameNS(const nsAString& aNamespaceURI,
|
||||
const nsAString& aLocalName,
|
||||
nsIDOMNodeList** aReturn)
|
||||
{
|
||||
nsRefPtr<nsContentList> list = GetElementsByTagNameNS(aNamespaceURI,
|
||||
aLocalName);
|
||||
NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
// transfer ref to aReturn
|
||||
*aReturn = list;
|
||||
*aReturn = list.forget().get();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -930,6 +930,15 @@ public:
|
|||
// Only BlockOnload should call this!
|
||||
void AsyncBlockOnload();
|
||||
|
||||
already_AddRefed<nsContentList>
|
||||
GetElementsByTagName(const nsAString& aTagName);
|
||||
already_AddRefed<nsContentList>
|
||||
GetElementsByTagNameNS(const nsAString& aNamespaceURI,
|
||||
const nsAString& aLocalName);
|
||||
|
||||
virtual mozilla::dom::Element *GetElementById(const nsAString& aElementId,
|
||||
nsresult *aResult);
|
||||
|
||||
protected:
|
||||
friend class nsNodeUtils;
|
||||
void RegisterNamedItems(nsIContent *aContent);
|
||||
|
|
|
@ -1389,11 +1389,7 @@ NS_IMETHODIMP
|
|||
nsHTMLDocument::GetElementsByTagName(const nsAString& aTagname,
|
||||
nsIDOMNodeList** aReturn)
|
||||
{
|
||||
nsAutoString tmp(aTagname);
|
||||
if (IsHTML()) {
|
||||
ToLowerCase(tmp); // HTML elements are lower case internally.
|
||||
}
|
||||
return nsDocument::GetElementsByTagName(tmp, aReturn);
|
||||
return nsDocument::GetElementsByTagName(aTagname, aReturn);
|
||||
}
|
||||
|
||||
// nsIDOM3Document interface implementation
|
||||
|
@ -1581,37 +1577,42 @@ nsHTMLDocument::GetURL(nsAString& aURL)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLDocument::GetBody(nsIDOMHTMLElement** aBody)
|
||||
nsIContent*
|
||||
nsHTMLDocument::GetBody()
|
||||
{
|
||||
*aBody = nsnull;
|
||||
|
||||
Element* body = GetBodyElement();
|
||||
|
||||
if (body) {
|
||||
// There is a body element, return that as the body.
|
||||
return CallQueryInterface(body, aBody);
|
||||
return body;
|
||||
}
|
||||
|
||||
// The document is most likely a frameset document so look for the
|
||||
// outer most frameset element
|
||||
nsCOMPtr<nsIDOMNodeList> nodeList;
|
||||
nsRefPtr<nsContentList> nodeList;
|
||||
|
||||
nsresult rv;
|
||||
if (IsHTML()) {
|
||||
rv = GetElementsByTagName(NS_LITERAL_STRING("frameset"),
|
||||
getter_AddRefs(nodeList));
|
||||
nodeList = nsDocument::GetElementsByTagName(NS_LITERAL_STRING("frameset"));
|
||||
} else {
|
||||
rv = GetElementsByTagNameNS(NS_LITERAL_STRING("http://www.w3.org/1999/xhtml"),
|
||||
NS_LITERAL_STRING("frameset"),
|
||||
getter_AddRefs(nodeList));
|
||||
nodeList =
|
||||
nsDocument::GetElementsByTagNameNS(NS_LITERAL_STRING("http://www.w3.org/1999/xhtml"),
|
||||
NS_LITERAL_STRING("frameset"));
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
nodeList->Item(0, getter_AddRefs(node));
|
||||
return nodeList ? nodeList->GetNodeAt(0) : nsnull;
|
||||
}
|
||||
|
||||
return node ? CallQueryInterface(node, aBody) : NS_OK;
|
||||
NS_IMETHODIMP
|
||||
nsHTMLDocument::GetBody(nsIDOMHTMLElement** aBody)
|
||||
{
|
||||
nsIContent *body = GetBody();
|
||||
if (!body) {
|
||||
*aBody = nsnull;
|
||||
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return CallQueryInterface(body, aBody);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -2287,18 +2288,11 @@ NS_IMETHODIMP
|
|||
nsHTMLDocument::GetElementsByName(const nsAString& aElementName,
|
||||
nsIDOMNodeList** aReturn)
|
||||
{
|
||||
nsString* elementNameData = new nsString(aElementName);
|
||||
NS_ENSURE_TRUE(elementNameData, NS_ERROR_OUT_OF_MEMORY);
|
||||
nsContentList* elements =
|
||||
NS_GetFuncStringContentList(this,
|
||||
MatchNameAttribute,
|
||||
nsContentUtils::DestroyMatchString,
|
||||
elementNameData,
|
||||
*elementNameData).get();
|
||||
NS_ENSURE_TRUE(elements, NS_ERROR_OUT_OF_MEMORY);
|
||||
nsRefPtr<nsContentList> list = GetElementsByName(aElementName);
|
||||
NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
// Transfer ownership
|
||||
*aReturn = elements;
|
||||
list.forget(aReturn);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -160,6 +160,17 @@ public:
|
|||
nsIDOMNodeList **_retval);
|
||||
virtual nsresult GetDocumentAllResult(const nsAString& aID,
|
||||
nsISupports** aResult);
|
||||
nsIContent *GetBody();
|
||||
already_AddRefed<nsContentList> GetElementsByName(const nsAString & aName)
|
||||
{
|
||||
nsString* elementNameData = new nsString(aName);
|
||||
|
||||
return NS_GetFuncStringContentList(this,
|
||||
MatchNameAttribute,
|
||||
nsContentUtils::DestroyMatchString,
|
||||
elementNameData,
|
||||
*elementNameData);
|
||||
}
|
||||
|
||||
// nsIDOMNSHTMLDocument interface
|
||||
NS_DECL_NSIDOMNSHTMLDOCUMENT
|
||||
|
@ -228,6 +239,12 @@ public:
|
|||
|
||||
virtual NS_HIDDEN_(void) RemovedFromDocShell();
|
||||
|
||||
virtual mozilla::dom::Element *GetElementById(const nsAString& aElementId,
|
||||
nsresult *aResult)
|
||||
{
|
||||
return nsDocument::GetElementById(aElementId, aResult);
|
||||
}
|
||||
|
||||
protected:
|
||||
nsresult GetBodySize(PRInt32* aWidth,
|
||||
PRInt32* aHeight);
|
||||
|
|
|
@ -187,10 +187,10 @@ struct BroadcastListener {
|
|||
nsCOMPtr<nsIAtom> mAttribute;
|
||||
};
|
||||
|
||||
nsIContent*
|
||||
nsRefMapEntry::GetFirstContent()
|
||||
Element*
|
||||
nsRefMapEntry::GetFirstElement()
|
||||
{
|
||||
return static_cast<nsIContent*>(mRefContentList.SafeElementAt(0));
|
||||
return static_cast<Element*>(mRefContentList.SafeElementAt(0));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -202,17 +202,17 @@ nsRefMapEntry::AppendAll(nsCOMArray<nsIContent>* aElements)
|
|||
}
|
||||
|
||||
PRBool
|
||||
nsRefMapEntry::AddContent(nsIContent* aContent)
|
||||
nsRefMapEntry::AddElement(Element* aElement)
|
||||
{
|
||||
if (mRefContentList.IndexOf(aContent) >= 0)
|
||||
if (mRefContentList.IndexOf(aElement) >= 0)
|
||||
return PR_TRUE;
|
||||
return mRefContentList.AppendElement(aContent);
|
||||
return mRefContentList.AppendElement(aElement);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsRefMapEntry::RemoveContent(nsIContent* aContent)
|
||||
nsRefMapEntry::RemoveElement(Element* aElement)
|
||||
{
|
||||
mRefContentList.RemoveElement(aContent);
|
||||
mRefContentList.RemoveElement(aElement);
|
||||
return mRefContentList.Count() == 0;
|
||||
}
|
||||
|
||||
|
@ -978,7 +978,7 @@ nsXULDocument::AttributeWillChange(nsIDocument* aDocument,
|
|||
// See if we need to update our ref map.
|
||||
if (aAttribute == nsGkAtoms::ref ||
|
||||
(aAttribute == nsGkAtoms::id && !aContent->GetIDAttributeName())) {
|
||||
RemoveElementFromRefMap(aContent);
|
||||
RemoveElementFromRefMap(aContent->AsElement());
|
||||
}
|
||||
|
||||
nsXMLDocument::AttributeWillChange(aDocument, aContent, aNameSpaceID,
|
||||
|
@ -1323,7 +1323,7 @@ nsXULDocument::Persist(const nsAString& aID,
|
|||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> domelement;
|
||||
rv = GetElementById(aID, getter_AddRefs(domelement));
|
||||
rv = nsDocument::GetElementById(aID, getter_AddRefs(domelement));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (! domelement)
|
||||
|
@ -1660,33 +1660,34 @@ nsXULDocument::GetCommandDispatcher(nsIDOMXULCommandDispatcher** aTracker)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULDocument::GetElementById(const nsAString& aId,
|
||||
nsIDOMElement** aReturn)
|
||||
Element*
|
||||
nsXULDocument::GetElementById(const nsAString& aId, nsresult *aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aReturn);
|
||||
*aReturn = nsnull;
|
||||
nsCOMPtr<nsIAtom> atom(do_GetAtom(aId));
|
||||
if (!atom) {
|
||||
*aResult = NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
nsCOMPtr<nsIAtom> atom = do_GetAtom(aId);
|
||||
if (!atom)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
*aResult = NS_OK;
|
||||
|
||||
if (!CheckGetElementByIdArg(atom))
|
||||
return NS_OK;
|
||||
return nsnull;
|
||||
|
||||
nsIdentifierMapEntry *entry = mIdentifierMap.GetEntry(atom);
|
||||
if (entry) {
|
||||
Element* element = entry->GetIdElement();
|
||||
if (element)
|
||||
return CallQueryInterface(element, aReturn);
|
||||
return element;
|
||||
}
|
||||
nsRefMapEntry* refEntry = mRefMap.GetEntry(atom);
|
||||
if (refEntry) {
|
||||
NS_ASSERTION(refEntry->GetFirstContent(),
|
||||
NS_ASSERTION(refEntry->GetFirstElement(),
|
||||
"nsRefMapEntries should have nonempty content lists");
|
||||
return CallQueryInterface(refEntry->GetFirstContent(), aReturn);
|
||||
return refEntry->GetFirstElement();
|
||||
}
|
||||
return NS_OK;
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -1898,7 +1899,7 @@ nsXULDocument::GetTemplateBuilderFor(nsIContent* aContent,
|
|||
}
|
||||
|
||||
static void
|
||||
GetRefMapAttribute(nsIContent* aElement, nsAutoString* aValue)
|
||||
GetRefMapAttribute(Element* aElement, nsAutoString* aValue)
|
||||
{
|
||||
aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::ref, *aValue);
|
||||
if (aValue->IsEmpty() && !aElement->GetIDAttributeName()) {
|
||||
|
@ -1907,7 +1908,7 @@ GetRefMapAttribute(nsIContent* aElement, nsAutoString* aValue)
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsXULDocument::AddElementToRefMap(nsIContent* aElement)
|
||||
nsXULDocument::AddElementToRefMap(Element* aElement)
|
||||
{
|
||||
// Look at the element's 'ref' attribute, and if set,
|
||||
// add an entry in the resource-to-element map to the element.
|
||||
|
@ -1920,7 +1921,7 @@ nsXULDocument::AddElementToRefMap(nsIContent* aElement)
|
|||
nsRefMapEntry *entry = mRefMap.PutEntry(atom);
|
||||
if (!entry)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
if (!entry->AddContent(aElement))
|
||||
if (!entry->AddElement(aElement))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
|
@ -1928,7 +1929,7 @@ nsXULDocument::AddElementToRefMap(nsIContent* aElement)
|
|||
}
|
||||
|
||||
void
|
||||
nsXULDocument::RemoveElementFromRefMap(nsIContent* aElement)
|
||||
nsXULDocument::RemoveElementFromRefMap(Element* aElement)
|
||||
{
|
||||
// Remove the element from the resource-to-element map.
|
||||
nsAutoString value;
|
||||
|
@ -1940,7 +1941,7 @@ nsXULDocument::RemoveElementFromRefMap(nsIContent* aElement)
|
|||
nsRefMapEntry *entry = mRefMap.GetEntry(atom);
|
||||
if (!entry)
|
||||
return;
|
||||
if (entry->RemoveContent(aElement)) {
|
||||
if (entry->RemoveElement(aElement)) {
|
||||
mRefMap.RemoveEntry(atom);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -90,17 +90,17 @@ public:
|
|||
NS_ERROR("Should never be called");
|
||||
}
|
||||
|
||||
nsIContent* GetFirstContent();
|
||||
mozilla::dom::Element* GetFirstElement();
|
||||
void AppendAll(nsCOMArray<nsIContent>* aElements);
|
||||
/**
|
||||
* @return true if aContent was added, false if we failed due to OOM
|
||||
* @return true if aElement was added, false if we failed due to OOM
|
||||
*/
|
||||
PRBool AddContent(nsIContent* aContent);
|
||||
PRBool AddElement(mozilla::dom::Element* aElement);
|
||||
/**
|
||||
* @return true if aContent was removed and it was the last content for
|
||||
* @return true if aElement was removed and it was the last content for
|
||||
* this ref, so this entry should be removed from the map
|
||||
*/
|
||||
PRBool RemoveContent(nsIContent* aContent);
|
||||
PRBool RemoveElement(mozilla::dom::Element* aElement);
|
||||
|
||||
private:
|
||||
nsSmallVoidArray mRefContentList;
|
||||
|
@ -165,9 +165,13 @@ public:
|
|||
// nsIDOMNode interface overrides
|
||||
NS_IMETHOD CloneNode(PRBool deep, nsIDOMNode **_retval);
|
||||
|
||||
// nsIDOMDocument interface overrides
|
||||
NS_IMETHOD GetElementById(const nsAString & elementId,
|
||||
nsIDOMElement **_retval);
|
||||
// nsDocument interface overrides
|
||||
NS_IMETHOD GetElementById(const nsAString& aId, nsIDOMElement** aReturn)
|
||||
{
|
||||
return nsDocument::GetElementById(aId, aReturn);
|
||||
}
|
||||
virtual mozilla::dom::Element* GetElementById(const nsAString & elementId,
|
||||
nsresult *aResult);
|
||||
|
||||
// nsIDOMXULDocument interface
|
||||
NS_DECL_NSIDOMXULDOCUMENT
|
||||
|
@ -207,9 +211,9 @@ protected:
|
|||
nsresult StartLayout(void);
|
||||
|
||||
nsresult
|
||||
AddElementToRefMap(nsIContent* aElement);
|
||||
AddElementToRefMap(mozilla::dom::Element* aElement);
|
||||
void
|
||||
RemoveElementFromRefMap(nsIContent* aElement);
|
||||
RemoveElementFromRefMap(mozilla::dom::Element* aElement);
|
||||
|
||||
nsresult GetViewportSize(PRInt32* aWidth, PRInt32* aHeight);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче