Fix for bug 799464 (Make Element.getElementsBy* return HTMLCollection). r=bz.

--HG--
extra : rebase_source : fe059b8ad3b98df9e611899832584cc866db0479
This commit is contained in:
Peter Van der Beken 2012-09-26 16:17:47 +02:00
parent 7e57f8a9fe
commit f52e02e082
12 changed files with 58 additions and 69 deletions

View File

@ -959,7 +959,7 @@ HTMLTableAccessible::HasDescendant(const nsAString& aTagName, bool aAllowEmpty)
nsCOMPtr<nsIDOMElement> tableElt(do_QueryInterface(mContent));
NS_ENSURE_TRUE(tableElt, false);
nsCOMPtr<nsIDOMNodeList> nodeList;
nsCOMPtr<nsIDOMHTMLCollection> nodeList;
tableElt->GetElementsByTagName(aTagName, getter_AddRefs(nodeList));
NS_ENSURE_TRUE(nodeList, false);

View File

@ -37,6 +37,7 @@
#include "nsCharSeparatedTokenizer.h"
#include "gfxContext.h"
#include "gfxFont.h"
#include "nsContentList.h"
#include "mozilla/AutoRestore.h"
#include "mozilla/GuardObjects.h"
@ -1814,9 +1815,16 @@ public:
* Utility method for getElementsByClassName. aRootNode is the node (either
* document or element), which getElementsByClassName was called on.
*/
static nsresult GetElementsByClassName(nsINode* aRootNode,
const nsAString& aClasses,
nsIDOMNodeList** aReturn);
static already_AddRefed<nsContentList>
GetElementsByClassName(nsINode* aRootNode, const nsAString& aClasses)
{
NS_PRECONDITION(aRootNode, "Must have root node");
return NS_GetFuncStringHTMLCollection(aRootNode, MatchClassNames,
DestroyClassNameArray,
AllocClassMatchingInfo,
aClasses);
}
/**
* Returns a presshell for this document, if there is one. This will be
@ -2180,6 +2188,12 @@ private:
static void DropFragmentParsers();
static bool MatchClassNames(nsIContent* aContent, int32_t aNamespaceID,
nsIAtom* aAtom, void* aData);
static void DestroyClassNameArray(void* aData);
static void* AllocClassMatchingInfo(nsINode* aRootNode,
const nsString* aClasses);
static nsIDOMScriptObjectFactory *sDOMScriptObjectFactory;
static nsIXPConnect *sXPConnect;

View File

@ -414,20 +414,9 @@ GetFuncStringContentList(nsINode* aRootNode,
// we have an entry
list = new ListType(aRootNode, aFunc, aDestroyFunc, aDataAllocator,
aString);
if (list && !list->AllocatedData()) {
// Failed to allocate the data
delete list;
list = nullptr;
}
if (entry) {
if (list)
entry->mContentList = list;
else
PL_DHashTableRawRemove(&gContentListHashTable, entry);
entry->mContentList = list;
}
NS_ENSURE_TRUE(list, nullptr);
}
NS_ADDREF(list);

View File

@ -479,6 +479,7 @@ typedef void* (*nsFuncStringContentListDataAllocator)(nsINode* aRootNode,
const nsString* aString);
// aDestroyFunc is allowed to be null
// aDataAllocator must always return a non-null pointer
class nsCacheableFuncStringContentList : public nsContentList {
public:
virtual ~nsCacheableFuncStringContentList();
@ -488,8 +489,6 @@ public:
mString == aKey->mString;
}
bool AllocatedData() const { return !!mData; }
#ifdef DEBUG
enum ContentListType {
eNodeList,
@ -508,6 +507,7 @@ protected:
mString(aString)
{
mData = (*aDataAllocator)(aRootNode, &mString);
MOZ_ASSERT(mData);
}
virtual void RemoveFromCaches() {

View File

@ -44,7 +44,6 @@
#include "nsIParser.h"
#include "nsIFragmentContentSink.h"
#include "nsIContentSink.h"
#include "nsContentList.h"
#include "nsIHTMLDocument.h"
#include "nsIDOMHTMLFormElement.h"
#include "nsIDOMHTMLElement.h"
@ -6245,9 +6244,10 @@ struct ClassMatchingInfo {
nsCaseTreatment mCaseTreatment;
};
static bool
MatchClassNames(nsIContent* aContent, int32_t aNamespaceID, nsIAtom* aAtom,
void* aData)
// static
bool
nsContentUtils::MatchClassNames(nsIContent* aContent, int32_t aNamespaceID,
nsIAtom* aAtom, void* aData)
{
// We can't match if there are no class names
const nsAttrValue* classAttr = aContent->GetClasses();
@ -6273,23 +6273,23 @@ MatchClassNames(nsIContent* aContent, int32_t aNamespaceID, nsIAtom* aAtom,
return true;
}
static void
DestroyClassNameArray(void* aData)
// static
void
nsContentUtils::DestroyClassNameArray(void* aData)
{
ClassMatchingInfo* info = static_cast<ClassMatchingInfo*>(aData);
delete info;
}
static void*
AllocClassMatchingInfo(nsINode* aRootNode,
const nsString* aClasses)
// static
void*
nsContentUtils::AllocClassMatchingInfo(nsINode* aRootNode,
const nsString* aClasses)
{
nsAttrValue attrValue;
attrValue.ParseAtomArray(*aClasses);
// nsAttrValue::Equals is sensitive to order, so we'll send an array
ClassMatchingInfo* info = new ClassMatchingInfo;
NS_ENSURE_TRUE(info, nullptr);
if (attrValue.Type() == nsAttrValue::eAtomArray) {
info->mClasses.SwapElements(*(attrValue.GetAtomArrayValue()));
} else if (attrValue.Type() == nsAttrValue::eAtom) {
@ -6304,26 +6304,6 @@ AllocClassMatchingInfo(nsINode* aRootNode,
// static
nsresult
nsContentUtils::GetElementsByClassName(nsINode* aRootNode,
const nsAString& aClasses,
nsIDOMNodeList** aReturn)
{
NS_PRECONDITION(aRootNode, "Must have root node");
nsContentList* elements =
NS_GetFuncStringHTMLCollection(aRootNode, MatchClassNames,
DestroyClassNameArray,
AllocClassMatchingInfo,
aClasses).get();
NS_ENSURE_TRUE(elements, NS_ERROR_OUT_OF_MEMORY);
// Transfer ownership
*aReturn = elements;
return NS_OK;
}
#ifdef DEBUG
class DebugWrapperTraversalCallback : public nsCycleCollectionTraversalCallback
{

View File

@ -3034,7 +3034,8 @@ NS_IMETHODIMP
nsDocument::GetElementsByClassName(const nsAString& aClasses,
nsIDOMNodeList** aReturn)
{
return nsContentUtils::GetElementsByClassName(this, aClasses, aReturn);
*aReturn = nsContentUtils::GetElementsByClassName(this, aClasses).get();
return NS_OK;
}
NS_IMETHODIMP

View File

@ -809,9 +809,10 @@ nsGenericElement::GetBoundingClientRect(nsIDOMClientRect** aResult)
NS_IMETHODIMP
nsGenericElement::GetElementsByClassName(const nsAString& aClasses,
nsIDOMNodeList** aReturn)
nsIDOMHTMLCollection** aReturn)
{
return nsContentUtils::GetElementsByClassName(this, aClasses, aReturn);
*aReturn = nsContentUtils::GetElementsByClassName(this, aClasses).get();
return NS_OK;
}
NS_IMETHODIMP
@ -1005,7 +1006,7 @@ nsGenericElement::RemoveAttributeNode(nsIDOMAttr* aAttribute,
nsresult
nsGenericElement::GetElementsByTagName(const nsAString& aTagname,
nsIDOMNodeList** aReturn)
nsIDOMHTMLCollection** aReturn)
{
nsContentList *list = NS_GetContentList(this, kNameSpaceID_Unknown,
aTagname).get();
@ -1135,7 +1136,7 @@ nsGenericElement::SetAttributeNodeNS(nsIDOMAttr* aNewAttr,
nsresult
nsGenericElement::GetElementsByTagNameNS(const nsAString& aNamespaceURI,
const nsAString& aLocalName,
nsIDOMNodeList** aReturn)
nsIDOMHTMLCollection** aReturn)
{
int32_t nameSpaceId = kNameSpaceID_Wildcard;

View File

@ -13,7 +13,7 @@
* http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#interface-element
*/
[scriptable, uuid(69D44CE2-B544-49A8-BB5F-87804B971EE4)]
[scriptable, uuid(f1465e67-577f-4546-a7a3-bb1293c0dd15)]
interface nsIDOMElement : nsIDOMNode
{
readonly attribute DOMString tagName;
@ -47,14 +47,14 @@ interface nsIDOMElement : nsIDOMNode
nsIDOMAttr setAttributeNodeNS(in nsIDOMAttr newAttr)
raises(DOMException);
nsIDOMNodeList getElementsByTagName(in DOMString name);
nsIDOMNodeList getElementsByTagNameNS(in DOMString namespaceURI,
in DOMString localName);
nsIDOMHTMLCollection getElementsByTagName(in DOMString name);
nsIDOMHTMLCollection getElementsByTagNameNS(in DOMString namespaceURI,
in DOMString localName);
/**
* Retrieve elements matching all classes listed in a
* space-separated string.
*/
nsIDOMNodeList getElementsByClassName(in DOMString classes);
nsIDOMHTMLCollection getElementsByClassName(in DOMString classes);
/**
* Returns a live nsIDOMNodeList of the current child elements.

View File

@ -57,6 +57,7 @@ using mozilla::DefaultXDisplay;
#include "nsIScrollableFrame.h"
#include "nsIDocShell.h"
#include "ImageContainer.h"
#include "nsIDOMHTMLCollection.h"
#include "nsContentCID.h"
#include "nsWidgetsCID.h"
@ -1142,7 +1143,7 @@ nsresult nsPluginInstanceOwner::EnsureCachedAttrParamArrays()
// Making DOM method calls can cause our frame to go away.
nsCOMPtr<nsIPluginInstanceOwner> kungFuDeathGrip(this);
nsCOMPtr<nsIDOMNodeList> allParams;
nsCOMPtr<nsIDOMHTMLCollection> allParams;
NS_NAMED_LITERAL_STRING(xhtml_ns, "http://www.w3.org/1999/xhtml");
mydomElement->GetElementsByTagNameNS(xhtml_ns, NS_LITERAL_STRING("param"),
getter_AddRefs(allParams));

View File

@ -931,7 +931,7 @@ nsTextEditRules::DidRedo(nsISelection *aSelection, nsresult aResult)
nsCOMPtr<nsIDOMElement> theRoot = do_QueryInterface(mEditor->GetRoot());
NS_ENSURE_TRUE(theRoot, NS_ERROR_FAILURE);
nsCOMPtr<nsIDOMNodeList> nodeList;
nsCOMPtr<nsIDOMHTMLCollection> nodeList;
res = theRoot->GetElementsByTagName(NS_LITERAL_STRING("br"),
getter_AddRefs(nodeList));
NS_ENSURE_SUCCESS(res, res);
@ -946,10 +946,12 @@ nsTextEditRules::DidRedo(nsISelection *aSelection, nsresult aResult)
return NS_OK;
}
nsCOMPtr<nsIContent> content = nodeList->GetNodeAt(0);
nsCOMPtr<nsIDOMNode> node;
nodeList->Item(0, getter_AddRefs(node));
nsCOMPtr<nsIContent> content = do_QueryInterface(node);
MOZ_ASSERT(content);
if (mEditor->IsMozEditorBogusNode(content)) {
mBogusNode = do_QueryInterface(content);
mBogusNode = node;
} else {
mBogusNode = nullptr;
}

View File

@ -4032,7 +4032,7 @@ nsWebBrowserPersist::SetDocumentBase(
// Find or create the BASE element
NS_NAMED_LITERAL_STRING(kBase, "base");
nsCOMPtr<nsIDOMElement> baseElement;
nsCOMPtr<nsIDOMNodeList> baseList;
nsCOMPtr<nsIDOMHTMLCollection> baseList;
if (xmlDoc)
{
headElement->GetElementsByTagNameNS(

View File

@ -21,6 +21,7 @@
#include "nsIObserver.h"
#include "nsIObserverService.h"
#include "nsIDOMElement.h"
#include "nsIDOMHTMLCollection.h"
#include "nsIDOMNode.h"
#include "nsIDOMNodeList.h"
#include "nsTArray.h"
@ -225,7 +226,7 @@ BlacklistOSToOperatingSystem(const nsAString& os)
}
static GfxDeviceFamily*
BlacklistDevicesToDeviceFamily(nsIDOMNodeList* aDevices)
BlacklistDevicesToDeviceFamily(nsIDOMHTMLCollection* aDevices)
{
uint32_t length;
if (NS_FAILED(aDevices->GetLength(&length)))
@ -323,7 +324,7 @@ BlacklistNodeGetChildByName(nsIDOMElement *element,
const nsAString& tagname,
nsIDOMNode** firstchild)
{
nsCOMPtr<nsIDOMNodeList> nodelist;
nsCOMPtr<nsIDOMHTMLCollection> nodelist;
if (NS_FAILED(element->GetElementsByTagName(tagname,
getter_AddRefs(nodelist))) ||
!nodelist) {
@ -396,7 +397,7 @@ BlacklistEntryToDriverInfo(nsIDOMNode* aBlacklistEntry,
// Get only the <device> nodes, because BlacklistDevicesToDeviceFamily
// assumes it is passed no other nodes.
nsCOMPtr<nsIDOMNodeList> devices;
nsCOMPtr<nsIDOMHTMLCollection> devices;
if (NS_SUCCEEDED(devicesElement->GetElementsByTagName(NS_LITERAL_STRING("device"),
getter_AddRefs(devices)))) {
GfxDeviceFamily* deviceIds = BlacklistDevicesToDeviceFamily(devices);
@ -445,7 +446,7 @@ BlacklistEntryToDriverInfo(nsIDOMNode* aBlacklistEntry,
}
static void
BlacklistEntriesToDriverInfo(nsIDOMNodeList* aBlacklistEntries,
BlacklistEntriesToDriverInfo(nsIDOMHTMLCollection* aBlacklistEntries,
nsTArray<GfxDriverInfo>& aDriverInfo)
{
uint32_t length;
@ -476,7 +477,7 @@ GfxInfoBase::Observe(nsISupports* aSubject, const char* aTopic,
if (strcmp(aTopic, "blocklist-data-gfxItems") == 0) {
nsCOMPtr<nsIDOMElement> gfxItems = do_QueryInterface(aSubject);
if (gfxItems) {
nsCOMPtr<nsIDOMNodeList> blacklistEntries;
nsCOMPtr<nsIDOMHTMLCollection> blacklistEntries;
if (NS_SUCCEEDED(gfxItems->
GetElementsByTagName(NS_LITERAL_STRING(BLACKLIST_ENTRY_TAG_NAME),
getter_AddRefs(blacklistEntries))) &&