Commit 23ad56ac authored by kling@webkit.org's avatar kling@webkit.org

Simplify HTMLCollection ownership model.

<http://webkit.org/b/75437>

Reviewed by Sam Weinig.

Source/WebCore: 

Remove HTMLCollection's inheritance from RefCounted and use OwnPtr to store it.
Added ref()/deref() methods that forward to the collection's base node, these
are only ever used by DOM wrappers.

This is a behavior change, HTMLCollection wrappers now keep the base node alive.

Test: fast/dom/htmlcollection-protects-base.html

* html/HTMLCollection.h:
(WebCore::HTMLCollection::ref):
(WebCore::HTMLCollection::deref):

    Removed inheritance from RefCounted. Added ref/deref that forward the refs
    to the collection's base Node.

* dom/Element.cpp:
(WebCore::Element::~Element):
* dom/Document.h:
* dom/Document.cpp:
(WebCore::Document::~Document):
* html/HTMLFormElement.cpp:
(WebCore::HTMLFormElement::~HTMLFormElement):
* html/HTMLSelectElement.h:
* html/HTMLSelectElement.cpp:

    Remove HTMLCollection::detachFromNode() and call sites.

* html/HTMLAllCollection.cpp:
(WebCore::HTMLAllCollection::namedItemWithIndex):
* html/HTMLCollection.cpp:
(WebCore::HTMLCollection::HTMLCollection):
(WebCore::HTMLCollection::invalidateCacheIfNeeded):
(WebCore::HTMLCollection::itemAfter):
(WebCore::HTMLCollection::calcLength):
(WebCore::HTMLCollection::length):
(WebCore::HTMLCollection::item):
(WebCore::HTMLCollection::nextItem):
(WebCore::HTMLCollection::namedItem):
(WebCore::HTMLCollection::updateNameCache):
(WebCore::HTMLCollection::hasNamedItem):
(WebCore::HTMLCollection::namedItems):
(WebCore::HTMLCollection::tags):
* html/HTMLFormCollection.cpp:
(WebCore::HTMLFormCollection::calcLength):
(WebCore::HTMLFormCollection::item):
(WebCore::HTMLFormCollection::getNamedItem):
(WebCore::HTMLFormCollection::namedItem):
(WebCore::HTMLFormCollection::updateNameCache):
* html/HTMLNameCollection.cpp:
(WebCore::HTMLNameCollection::itemAfter):
* html/HTMLOptionsCollection.cpp:
(WebCore::HTMLOptionsCollection::add):
(WebCore::HTMLOptionsCollection::remove):
(WebCore::HTMLOptionsCollection::selectedIndex):
(WebCore::HTMLOptionsCollection::setSelectedIndex):
(WebCore::HTMLOptionsCollection::setLength):
* html/HTMLPropertiesCollection.cpp:
(WebCore::HTMLPropertiesCollection::length):
(WebCore::HTMLPropertiesCollection::item):
(WebCore::HTMLPropertiesCollection::names):

    Removed base node null-checks and assertions. Added one assertion to
    the HTMLCollection constructor (that m_base is non-null.)

* dom/Document.h:
* dom/Document.cpp:
(WebCore::Document::openSearchDescriptionURL):
(WebCore::Document::cachedCollection):
(WebCore::Document::images):
(WebCore::Document::applets):
(WebCore::Document::embeds):
(WebCore::Document::plugins):
(WebCore::Document::objects):
(WebCore::Document::scripts):
(WebCore::Document::links):
(WebCore::Document::forms):
(WebCore::Document::anchors):
(WebCore::Document::all):
(WebCore::Document::windowNamedItems):
(WebCore::Document::documentNamedItems):
* bindings/js/JSDOMWindowCustom.cpp:
(WebCore::namedItemGetter):
* bindings/js/JSHTMLDocumentCustom.cpp:
(WebCore::JSHTMLDocument::nameGetter):
(WebCore::JSHTMLDocument::all):
* bindings/v8/custom/V8DOMWindowCustom.cpp:
(WebCore::V8DOMWindow::namedPropertyGetter):
* bindings/v8/custom/V8HTMLDocumentCustom.cpp:
(WebCore::V8HTMLDocument::GetNamedProperty):
* dom/ElementRareData.h:
(WebCore::ElementRareData::ensureCachedHTMLCollection):
* dom/NodeRareData.h:
(WebCore::NodeRareData::properties):
* html/HTMLAllCollection.h:
* html/HTMLAllCollection.cpp:
(WebCore::HTMLAllCollection::create):
* html/HTMLCollection.h:
* html/HTMLCollection.cpp:
(WebCore::HTMLCollection::create):
(WebCore::HTMLCollection::HTMLCollection):
* html/HTMLDataListElement.cpp:
(WebCore::HTMLDataListElement::options):
* html/HTMLDataListElement.h:
* html/HTMLElement.cpp:
(WebCore::HTMLElement::children):
* html/HTMLElement.h:
* html/HTMLSelectElement.h:
(WebCore::HTMLSelectElement::options):
* html/HTMLFormCollection.h:
* html/HTMLFormElement.h:
* html/HTMLFormElement.cpp:
(WebCore::HTMLFormElement::elements):
* html/HTMLNameCollection.h:
(WebCore::HTMLNameCollection::create):
* html/HTMLFormCollection.cpp:
(WebCore::HTMLFormCollection::create):
* html/HTMLMapElement.cpp:
(WebCore::HTMLMapElement::imageElement):
(WebCore::HTMLMapElement::areas):
* html/HTMLMapElement.h:
* html/HTMLPropertiesCollection.h:
* html/HTMLTableElement.cpp:
(WebCore::HTMLTableElement::rows):
(WebCore::HTMLTableElement::tBodies):
* html/HTMLTableElement.h:
* html/HTMLTableRowElement.cpp:
(WebCore::HTMLTableRowElement::insertCell):
(WebCore::HTMLTableRowElement::deleteCell):
(WebCore::HTMLTableRowElement::cells):
* html/HTMLTableRowElement.h:
* html/HTMLTableRowsCollection.cpp:
(WebCore::HTMLTableRowsCollection::create):
(WebCore::HTMLTableRowsCollection::itemAfter):
* html/HTMLTableRowsCollection.h:
* html/HTMLTableSectionElement.h:
* html/HTMLTableSectionElement.cpp:
(WebCore::HTMLTableSectionElement::insertRow):
(WebCore::HTMLTableSectionElement::deleteRow):
(WebCore::HTMLTableSectionElement::rows):
* html/HTMLInputElement.cpp:
(WebCore::HTMLInputElement::selectedOption):
* html/HTMLOptionsCollection.h:
* html/HTMLOptionsCollection.cpp:
(WebCore::HTMLOptionsCollection::create):
* html/HTMLPropertiesCollection.cpp:
(WebCore::HTMLPropertiesCollection::create):

    Store cached HTMLCollections in OwnPtrs. Methods that used to return
    PassRefPtr<HTMLCollection> now simply return HTMLCollection*.
    Updated call sites as appropriate.

LayoutTests: 

- Removed fast/dom/htmlcollection-zombies.html since it was testing bogus behavior.
- Added a test to verify that HTMLCollection protects its base node from GC.

* fast/dom/htmlcollection-protects-base-expected.txt: Added.
* fast/dom/htmlcollection-protects-base.html: Added.
* fast/dom/htmlcollection-zombies-expected.txt: Removed.
* fast/dom/htmlcollection-zombies.html: Removed.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@104373 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 3766b020
2012-01-06 Andreas Kling <awesomekling@apple.com>
Simplify HTMLCollection ownership model.
<http://webkit.org/b/75437>
Reviewed by Sam Weinig.
- Removed fast/dom/htmlcollection-zombies.html since it was testing bogus behavior.
- Added a test to verify that HTMLCollection protects its base node from GC.
* fast/dom/htmlcollection-protects-base-expected.txt: Added.
* fast/dom/htmlcollection-protects-base.html: Added.
* fast/dom/htmlcollection-zombies-expected.txt: Removed.
* fast/dom/htmlcollection-zombies.html: Removed.
2012-01-06 Dmitry Lomov <dslomov@google.com>
Unreviewed: more rebaselines in chromium after r104240.
This test verifies that a HTMLCollection protects its base node from being GC'd.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
PASS options[0].parentNode.getAttribute('foo') is 'bar'
PASS successfullyParsed is true
TEST COMPLETE
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="../js/resources/js-test-pre.js"></script>
</head>
<body>
<select foo="bar">
<option name="A">A</option>
</select>
<script>
description("This test verifies that a HTMLCollection protects its base node from being GC'd.");
options = document.getElementsByTagName("select")[0].options;
document.body.removeChild(document.getElementsByTagName("select")[0]);
gc();
options[0] = new Option("bik", "bok");
shouldBe("options[0].parentNode.getAttribute('foo')", "'bar'");
</script>
<script src="../js/resources/js-test-post.js"></script>
</body>
</html>
This test tests the behavior of collections after their base node has been destroyed.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
Testing selectElement's options collection.
PASS collection.length is 2
PASS collection[0].getAttribute('name') is 'foo'
PASS collection[1].getAttribute('name') is 'bar'
Destroying selectElement
PASS collection.length is 0
PASS collection[0] is undefined
Testing formElement's elements collection.
PASS collection.length is 2
PASS collection[0].getAttribute('name') is 'foo'
PASS collection[1].getAttribute('name') is 'bar'
Destroying formElement
PASS collection.length is 0
PASS collection[0] is undefined
Testing tableElement's rows collection.
PASS collection.length is 2
PASS collection[0].getAttribute('name') is 'foo'
PASS collection[1].getAttribute('name') is 'bar'
Destroying tableElement
PASS collection.length is 0
PASS collection[0] is undefined
PASS successfullyParsed is true
TEST COMPLETE
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="../js/resources/js-test-pre.js"></script>
</head>
<body>
<select id="selectElement">
<option name="foo"/>
<option name="bar"/>
</select>
<form id="formElement">
<input name="foo"/>
<input name="bar"/>
</form>
<table id="tableElement">
<tr name="foo"></tr>
<tr name="bar"></tr>
</table>
<script>
description("This test tests the behavior of collections after their base node has been destroyed.");
var element;
var collection;
function testZombieBehavior(id, collectionGetterName)
{
debug("Testing " + id + "'s " + collectionGetterName + " collection.");
element = document.getElementById(id);
collection = eval("element." + collectionGetterName);
shouldBe("collection.length", "2");
shouldBe("collection[0].getAttribute('name')", "'foo'");
shouldBe("collection[1].getAttribute('name')", "'bar'");
debug("Destroying " + id);
document.body.removeChild(element);
element = null;
gc();
shouldBe("collection.length", "0");
shouldBe("collection[0]", "undefined");
}
testZombieBehavior("selectElement", "options");
testZombieBehavior("formElement", "elements");
testZombieBehavior("tableElement", "rows");
</script>
<script src="../js/resources/js-test-post.js"></script>
</body>
</html>
2012-01-06 Andreas Kling <awesomekling@apple.com>
Simplify HTMLCollection ownership model.
<http://webkit.org/b/75437>
Reviewed by Sam Weinig.
Remove HTMLCollection's inheritance from RefCounted and use OwnPtr to store it.
Added ref()/deref() methods that forward to the collection's base node, these
are only ever used by DOM wrappers.
This is a behavior change, HTMLCollection wrappers now keep the base node alive.
Test: fast/dom/htmlcollection-protects-base.html
* html/HTMLCollection.h:
(WebCore::HTMLCollection::ref):
(WebCore::HTMLCollection::deref):
Removed inheritance from RefCounted. Added ref/deref that forward the refs
to the collection's base Node.
* dom/Element.cpp:
(WebCore::Element::~Element):
* dom/Document.h:
* dom/Document.cpp:
(WebCore::Document::~Document):
* html/HTMLFormElement.cpp:
(WebCore::HTMLFormElement::~HTMLFormElement):
* html/HTMLSelectElement.h:
* html/HTMLSelectElement.cpp:
Remove HTMLCollection::detachFromNode() and call sites.
* html/HTMLAllCollection.cpp:
(WebCore::HTMLAllCollection::namedItemWithIndex):
* html/HTMLCollection.cpp:
(WebCore::HTMLCollection::HTMLCollection):
(WebCore::HTMLCollection::invalidateCacheIfNeeded):
(WebCore::HTMLCollection::itemAfter):
(WebCore::HTMLCollection::calcLength):
(WebCore::HTMLCollection::length):
(WebCore::HTMLCollection::item):
(WebCore::HTMLCollection::nextItem):
(WebCore::HTMLCollection::namedItem):
(WebCore::HTMLCollection::updateNameCache):
(WebCore::HTMLCollection::hasNamedItem):
(WebCore::HTMLCollection::namedItems):
(WebCore::HTMLCollection::tags):
* html/HTMLFormCollection.cpp:
(WebCore::HTMLFormCollection::calcLength):
(WebCore::HTMLFormCollection::item):
(WebCore::HTMLFormCollection::getNamedItem):
(WebCore::HTMLFormCollection::namedItem):
(WebCore::HTMLFormCollection::updateNameCache):
* html/HTMLNameCollection.cpp:
(WebCore::HTMLNameCollection::itemAfter):
* html/HTMLOptionsCollection.cpp:
(WebCore::HTMLOptionsCollection::add):
(WebCore::HTMLOptionsCollection::remove):
(WebCore::HTMLOptionsCollection::selectedIndex):
(WebCore::HTMLOptionsCollection::setSelectedIndex):
(WebCore::HTMLOptionsCollection::setLength):
* html/HTMLPropertiesCollection.cpp:
(WebCore::HTMLPropertiesCollection::length):
(WebCore::HTMLPropertiesCollection::item):
(WebCore::HTMLPropertiesCollection::names):
Removed base node null-checks and assertions. Added one assertion to
the HTMLCollection constructor (that m_base is non-null.)
* dom/Document.h:
* dom/Document.cpp:
(WebCore::Document::openSearchDescriptionURL):
(WebCore::Document::cachedCollection):
(WebCore::Document::images):
(WebCore::Document::applets):
(WebCore::Document::embeds):
(WebCore::Document::plugins):
(WebCore::Document::objects):
(WebCore::Document::scripts):
(WebCore::Document::links):
(WebCore::Document::forms):
(WebCore::Document::anchors):
(WebCore::Document::all):
(WebCore::Document::windowNamedItems):
(WebCore::Document::documentNamedItems):
* bindings/js/JSDOMWindowCustom.cpp:
(WebCore::namedItemGetter):
* bindings/js/JSHTMLDocumentCustom.cpp:
(WebCore::JSHTMLDocument::nameGetter):
(WebCore::JSHTMLDocument::all):
* bindings/v8/custom/V8DOMWindowCustom.cpp:
(WebCore::V8DOMWindow::namedPropertyGetter):
* bindings/v8/custom/V8HTMLDocumentCustom.cpp:
(WebCore::V8HTMLDocument::GetNamedProperty):
* dom/ElementRareData.h:
(WebCore::ElementRareData::ensureCachedHTMLCollection):
* dom/NodeRareData.h:
(WebCore::NodeRareData::properties):
* html/HTMLAllCollection.h:
* html/HTMLAllCollection.cpp:
(WebCore::HTMLAllCollection::create):
* html/HTMLCollection.h:
* html/HTMLCollection.cpp:
(WebCore::HTMLCollection::create):
(WebCore::HTMLCollection::HTMLCollection):
* html/HTMLDataListElement.cpp:
(WebCore::HTMLDataListElement::options):
* html/HTMLDataListElement.h:
* html/HTMLElement.cpp:
(WebCore::HTMLElement::children):
* html/HTMLElement.h:
* html/HTMLSelectElement.h:
(WebCore::HTMLSelectElement::options):
* html/HTMLFormCollection.h:
* html/HTMLFormElement.h:
* html/HTMLFormElement.cpp:
(WebCore::HTMLFormElement::elements):
* html/HTMLNameCollection.h:
(WebCore::HTMLNameCollection::create):
* html/HTMLFormCollection.cpp:
(WebCore::HTMLFormCollection::create):
* html/HTMLMapElement.cpp:
(WebCore::HTMLMapElement::imageElement):
(WebCore::HTMLMapElement::areas):
* html/HTMLMapElement.h:
* html/HTMLPropertiesCollection.h:
* html/HTMLTableElement.cpp:
(WebCore::HTMLTableElement::rows):
(WebCore::HTMLTableElement::tBodies):
* html/HTMLTableElement.h:
* html/HTMLTableRowElement.cpp:
(WebCore::HTMLTableRowElement::insertCell):
(WebCore::HTMLTableRowElement::deleteCell):
(WebCore::HTMLTableRowElement::cells):
* html/HTMLTableRowElement.h:
* html/HTMLTableRowsCollection.cpp:
(WebCore::HTMLTableRowsCollection::create):
(WebCore::HTMLTableRowsCollection::itemAfter):
* html/HTMLTableRowsCollection.h:
* html/HTMLTableSectionElement.h:
* html/HTMLTableSectionElement.cpp:
(WebCore::HTMLTableSectionElement::insertRow):
(WebCore::HTMLTableSectionElement::deleteRow):
(WebCore::HTMLTableSectionElement::rows):
* html/HTMLInputElement.cpp:
(WebCore::HTMLInputElement::selectedOption):
* html/HTMLOptionsCollection.h:
* html/HTMLOptionsCollection.cpp:
(WebCore::HTMLOptionsCollection::create):
* html/HTMLPropertiesCollection.cpp:
(WebCore::HTMLPropertiesCollection::create):
Store cached HTMLCollections in OwnPtrs. Methods that used to return
PassRefPtr<HTMLCollection> now simply return HTMLCollection*.
Updated call sites as appropriate.
2012-01-06 Adam Barth <abarth@webkit.org>
DOMWindow should be a FrameDestructionObserver
......@@ -115,10 +115,10 @@ static JSValue namedItemGetter(ExecState* exec, JSValue slotBase, const Identifi
ASSERT(document);
ASSERT(document->isHTMLDocument());
RefPtr<HTMLCollection> collection = document->windowNamedItems(identifierToAtomicString(propertyName));
HTMLCollection* collection = document->windowNamedItems(identifierToAtomicString(propertyName));
if (collection->length() == 1)
return toJS(exec, thisObj, collection->firstItem());
return toJS(exec, thisObj, collection.get());
return toJS(exec, thisObj, collection);
}
bool JSDOMWindow::getOwnPropertySlot(JSCell* cell, ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
......
......@@ -61,7 +61,7 @@ JSValue JSHTMLDocument::nameGetter(ExecState* exec, JSValue slotBase, const Iden
JSHTMLDocument* thisObj = static_cast<JSHTMLDocument*>(asObject(slotBase));
HTMLDocument* document = static_cast<HTMLDocument*>(thisObj->impl());
RefPtr<HTMLCollection> collection = document->documentNamedItems(identifierToAtomicString(propertyName));
HTMLCollection* collection = document->documentNamedItems(identifierToAtomicString(propertyName));
unsigned length = collection->length();
if (!length)
......@@ -77,7 +77,7 @@ JSValue JSHTMLDocument::nameGetter(ExecState* exec, JSValue slotBase, const Iden
return toJS(exec, thisObj->globalObject(), node);
}
return toJS(exec, thisObj->globalObject(), collection.get());
return toJS(exec, thisObj->globalObject(), collection);
}
// Custom attributes
......@@ -89,7 +89,7 @@ JSValue JSHTMLDocument::all(ExecState* exec) const
if (v)
return v;
return toJS(exec, globalObject(), static_cast<HTMLDocument*>(impl())->all().get());
return toJS(exec, globalObject(), static_cast<HTMLDocument*>(impl())->all());
}
void JSHTMLDocument::setAll(ExecState* exec, JSValue value)
......
......@@ -512,11 +512,11 @@ v8::Handle<v8::Value> V8DOMWindow::namedPropertyGetter(v8::Local<v8::String> nam
if (doc && doc->isHTMLDocument()) {
if (static_cast<HTMLDocument*>(doc)->hasNamedItem(propName.impl()) || doc->hasElementWithId(propName.impl())) {
RefPtr<HTMLCollection> items = doc->windowNamedItems(propName);
HTMLCollection* items = doc->windowNamedItems(propName);
if (items->length() >= 1) {
if (items->length() == 1)
return toV8(items->firstItem());
return toV8(items.release());
return toV8(items);
}
}
}
......
......@@ -79,7 +79,7 @@ v8::Handle<v8::Value> V8HTMLDocument::GetNamedProperty(HTMLDocument* htmlDocumen
if (!htmlDocument->hasNamedItem(key.impl()) && !htmlDocument->hasExtraNamedItem(key.impl()))
return v8::Handle<v8::Value>();
RefPtr<HTMLCollection> items = htmlDocument->documentNamedItems(key);
HTMLCollection* items = htmlDocument->documentNamedItems(key);
if (!items->length())
return v8::Handle<v8::Value>();
......@@ -92,7 +92,7 @@ v8::Handle<v8::Value> V8HTMLDocument::GetNamedProperty(HTMLDocument* htmlDocumen
return toV8(node);
}
return toV8(items.release());
return toV8(items);
}
// HTMLDocument ----------------------------------------------------------------
......
......@@ -567,14 +567,6 @@ Document::~Document()
if (m_mediaQueryMatcher)
m_mediaQueryMatcher->documentDestroyed();
for (unsigned i = 0; i < NumUnnamedDocumentCachedTypes; ++i) {
if (m_collections[i])
m_collections[i]->detachFromNode();
}
if (m_allCollection)
m_allCollection->detachFromNode();
}
void Document::removedLastRef()
......@@ -4176,7 +4168,7 @@ KURL Document::openSearchDescriptionURL()
if (!head())
return KURL();
RefPtr<HTMLCollection> children = head()->children();
HTMLCollection* children = head()->children();
for (Node* child = children->firstItem(); child; child = children->nextItem()) {
if (!child->hasTagName(linkTag))
continue;
......@@ -4301,81 +4293,81 @@ bool Document::hasSVGRootNode() const
}
#endif
const RefPtr<HTMLCollection>& Document::cachedCollection(CollectionType type)
HTMLCollection* Document::cachedCollection(CollectionType type)
{
ASSERT(static_cast<unsigned>(type) < NumUnnamedDocumentCachedTypes);
if (!m_collections[type])
m_collections[type] = HTMLCollection::create(this, type);
return m_collections[type];
return m_collections[type].get();
}
PassRefPtr<HTMLCollection> Document::images()
HTMLCollection* Document::images()
{
return cachedCollection(DocImages);
}
PassRefPtr<HTMLCollection> Document::applets()
HTMLCollection* Document::applets()
{
return cachedCollection(DocApplets);
}
PassRefPtr<HTMLCollection> Document::embeds()
HTMLCollection* Document::embeds()
{
return cachedCollection(DocEmbeds);
}
PassRefPtr<HTMLCollection> Document::plugins()
HTMLCollection* Document::plugins()
{
// This is an alias for embeds() required for the JS DOM bindings.
return cachedCollection(DocEmbeds);
}
PassRefPtr<HTMLCollection> Document::objects()
HTMLCollection* Document::objects()
{
return cachedCollection(DocObjects);
}
PassRefPtr<HTMLCollection> Document::scripts()
HTMLCollection* Document::scripts()
{
return cachedCollection(DocScripts);
}
PassRefPtr<HTMLCollection> Document::links()
HTMLCollection* Document::links()
{
return cachedCollection(DocLinks);
}
PassRefPtr<HTMLCollection> Document::forms()
HTMLCollection* Document::forms()
{
return cachedCollection(DocForms);
}
PassRefPtr<HTMLCollection> Document::anchors()
HTMLCollection* Document::anchors()
{
return cachedCollection(DocAnchors);
}
PassRefPtr<HTMLAllCollection> Document::all()
HTMLAllCollection* Document::all()
{
if (!m_allCollection)
m_allCollection = HTMLAllCollection::create(this);
return m_allCollection;
return m_allCollection.get();
}
PassRefPtr<HTMLCollection> Document::windowNamedItems(const AtomicString& name)
HTMLCollection* Document::windowNamedItems(const AtomicString& name)
{
RefPtr<HTMLNameCollection>& collection = m_windowNamedItemCollections.add(name.impl(), 0).first->second;
OwnPtr<HTMLNameCollection>& collection = m_windowNamedItemCollections.add(name.impl(), nullptr).first->second;
if (!collection)
collection = HTMLNameCollection::create(this, WindowNamedItems, name);
return collection;
return collection.get();
}
PassRefPtr<HTMLCollection> Document::documentNamedItems(const AtomicString& name)
HTMLCollection* Document::documentNamedItems(const AtomicString& name)
{
RefPtr<HTMLNameCollection>& collection = m_documentNamedItemCollections.add(name.impl(), 0).first->second;
OwnPtr<HTMLNameCollection>& collection = m_documentNamedItemCollections.add(name.impl(), nullptr).first->second;
if (!collection)
collection = HTMLNameCollection::create(this, DocumentNamedItems, name);
return collection;
return collection.get();
}
void Document::finishedParsing()
......
......@@ -410,19 +410,19 @@ public:
PassRefPtr<Node> adoptNode(PassRefPtr<Node> source, ExceptionCode&);
PassRefPtr<HTMLCollection> images();
PassRefPtr<HTMLCollection> embeds();
PassRefPtr<HTMLCollection> plugins(); // an alias for embeds() required for the JS DOM bindings.
PassRefPtr<HTMLCollection> applets();
PassRefPtr<HTMLCollection> links();
PassRefPtr<HTMLCollection> forms();
PassRefPtr<HTMLCollection> anchors();
PassRefPtr<HTMLCollection> objects();
PassRefPtr<HTMLCollection> scripts();
PassRefPtr<HTMLCollection> windowNamedItems(const AtomicString& name);
PassRefPtr<HTMLCollection> documentNamedItems(const AtomicString& name);
PassRefPtr<HTMLAllCollection> all();
HTMLCollection* images();
HTMLCollection* embeds();
HTMLCollection* plugins(); // an alias for embeds() required for the JS DOM bindings.
HTMLCollection* applets();
HTMLCollection* links();
HTMLCollection* forms();
HTMLCollection* anchors();
HTMLCollection* objects();
HTMLCollection* scripts();
HTMLCollection* windowNamedItems(const AtomicString& name);
HTMLCollection* documentNamedItems(const AtomicString& name);
HTMLAllCollection* all();
// Other methods (not part of DOM)
bool isHTMLDocument() const { return m_isHTML; }
......@@ -1182,7 +1182,7 @@ private:
PageVisibilityState visibilityState() const;
#endif
const RefPtr<HTMLCollection>& cachedCollection(CollectionType);
HTMLCollection* cachedCollection(CollectionType);
int m_guardRefCount;
......@@ -1365,10 +1365,10 @@ private:
CheckedRadioButtons m_checkedRadioButtons;
RefPtr<HTMLCollection> m_collections[NumUnnamedDocumentCachedTypes];
RefPtr<HTMLAllCollection> m_allCollection;
OwnPtr<HTMLCollection> m_collections[NumUnnamedDocumentCachedTypes];
OwnPtr<HTMLAllCollection> m_allCollection;
typedef HashMap<AtomicStringImpl*, RefPtr<HTMLNameCollection> > NamedCollectionMap;
typedef HashMap<AtomicStringImpl*, OwnPtr<HTMLNameCollection> > NamedCollectionMap;
NamedCollectionMap m_documentNamedItemCollections;
NamedCollectionMap m_windowNamedItemCollections;
......
......@@ -123,16 +123,6 @@ Element::~Element()
removeShadowRoot();
if (m_attributeMap)
m_attributeMap->detachFromElement();
if (hasRareData()) {
ElementRareData* elementRareData = rareData();
if (elementRareData->hasCachedHTMLCollections()) {
for (unsigned type = 0; type < NumNodeCollectionTypes; ++type) {
if (HTMLCollection* collection = elementRareData->cachedHTMLCollection(static_cast<CollectionType>(FirstNodeCollectionType + type)))
collection->detachFromNode();
}
}
}
}
inline ElementRareData* Element::rareData() const
......
......@@ -43,25 +43,19 @@ public:
using NodeRareData::needsFocusAppearanceUpdateSoonAfterAttach;
using NodeRareData::setNeedsFocusAppearanceUpdateSoonAfterAttach;
typedef FixedArray<RefPtr<HTMLCollection>, NumNodeCollectionTypes> CachedHTMLCollectionArray;
typedef FixedArray<OwnPtr<HTMLCollection>, NumNodeCollectionTypes> CachedHTMLCollectionArray;
bool hasCachedHTMLCollections() const
{
return m_cachedCollections;
}
HTMLCollection* cachedHTMLCollection(CollectionType type) const
{
ASSERT(m_cachedCollections);
return (*m_cachedCollections)[type - FirstNodeCollectionType].get();
}
HTMLCollection* ensureCachedHTMLCollection(Element* element, CollectionType type)
{
if (!m_cachedCollections)
m_cachedCollections = adoptPtr(new CachedHTMLCollectionArray);
RefPtr<HTMLCollection>& collection = (*m_cachedCollections)[type - FirstNodeCollectionType];
OwnPtr<HTMLCollection>& collection = (*m_cachedCollections)[type - FirstNodeCollectionType];
if (!collection)
collection = HTMLCollection::create(element, type);
return collection.get();
......
......@@ -221,7 +221,7 @@ public:
HTMLPropertiesCollection* properties(Node* node)
{
if (!m_properties)
m_properties = HTMLPropertiesCollection::create(node);
m_properties = adoptPtr(HTMLPropertiesCollection::create(node));
return m_properties.get();
}
......@@ -256,7 +256,7 @@ private:
mutable RefPtr<DOMSettableTokenList> m_itemProp;
mutable RefPtr<DOMSettableTokenList> m_itemRef;
mutable RefPtr<DOMSettableTokenList> m_itemType;