https://bugs.webkit.org/show_bug.cgi?id=90322
Reviewed by Anders Carlsson.
Removed all instances of OwnPtr<HTMLCollection> except ones on ElementRareData and Document.
ElementRareData::ensureCachedHTMLCollection then polymorphically creates HTMLCollection or
its subclass as deemed necessary.
This refactoring allows us to move HTMLCollection to use the same invalidation model as
DynamicNodeList (invalidated during DOM mutations) in a follow up.
* dom/Document.cpp:
(WebCore::Document::all):
* dom/Document.h:
(Document):
* dom/Element.cpp:
(WebCore::ElementRareData::ensureCachedHTMLCollection):
(WebCore):
(WebCore::Element::cachedHTMLCollection):
* dom/Element.h:
(Element):
* dom/ElementRareData.h:
(WebCore):
(ElementRareData):
(WebCore::ElementRareData::cachedHTMLCollection):
* dom/Node.cpp:
(WebCore):
* dom/Node.h:
(Node):
* dom/NodeRareData.h:
(WebCore::NodeRareData::setItemType):
(NodeRareData):
* html/CollectionType.h:
* html/HTMLCollection.cpp:
(WebCore::shouldIncludeChildren):
(WebCore::HTMLCollection::isAcceptableElement):
* html/HTMLElement.cpp:
(WebCore):
(WebCore::HTMLElement::properties):
* html/HTMLElement.h:
(HTMLElement):
* html/HTMLFieldSetElement.cpp:
(WebCore::HTMLFieldSetElement::elements):
* html/HTMLFieldSetElement.h:
(HTMLFieldSetElement):
* html/HTMLFormCollection.cpp:
(WebCore::HTMLFormCollection::HTMLFormCollection):
(WebCore::HTMLFormCollection::create):
* html/HTMLFormCollection.h:
(HTMLFormCollection):
* html/HTMLFormElement.cpp:
(WebCore::HTMLFormElement::elements):
* html/HTMLFormElement.h:
* html/HTMLOptionsCollection.cpp:
(WebCore::HTMLOptionsCollection::HTMLOptionsCollection):
(WebCore::HTMLOptionsCollection::create):
* html/HTMLOptionsCollection.h:
(HTMLOptionsCollection):
* html/HTMLSelectElement.cpp:
(WebCore::HTMLSelectElement::selectedOptions):
(WebCore::HTMLSelectElement::options):
(WebCore::HTMLSelectElement::invalidateSelectedItems):
(WebCore::HTMLSelectElement::setRecalcListItems):
* html/HTMLSelectElement.h:
* html/HTMLTableElement.cpp:
(WebCore::HTMLTableElement::rows):
* html/HTMLTableElement.h:
* html/HTMLTableRowsCollection.cpp:
(WebCore::HTMLTableRowsCollection::HTMLTableRowsCollection):
(WebCore::HTMLTableRowsCollection::create):
* html/HTMLTableRowsCollection.h:
(HTMLTableRowsCollection):
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@121603
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2012-06-29 Ryosuke Niwa <rniwa@webkit.org>
+
+ HTMLCollection's caches should be owned by either ElementRareData or Document
+ https://bugs.webkit.org/show_bug.cgi?id=90322
+
+ Reviewed by Anders Carlsson.
+
+ Removed all instances of OwnPtr<HTMLCollection> except ones on ElementRareData and Document.
+ ElementRareData::ensureCachedHTMLCollection then polymorphically creates HTMLCollection or
+ its subclass as deemed necessary.
+
+ This refactoring allows us to move HTMLCollection to use the same invalidation model as
+ DynamicNodeList (invalidated during DOM mutations) in a follow up.
+
+ * dom/Document.cpp:
+ (WebCore::Document::all):
+ * dom/Document.h:
+ (Document):
+ * dom/Element.cpp:
+ (WebCore::ElementRareData::ensureCachedHTMLCollection):
+ (WebCore):
+ (WebCore::Element::cachedHTMLCollection):
+ * dom/Element.h:
+ (Element):
+ * dom/ElementRareData.h:
+ (WebCore):
+ (ElementRareData):
+ (WebCore::ElementRareData::cachedHTMLCollection):
+ * dom/Node.cpp:
+ (WebCore):
+ * dom/Node.h:
+ (Node):
+ * dom/NodeRareData.h:
+ (WebCore::NodeRareData::setItemType):
+ (NodeRareData):
+ * html/CollectionType.h:
+ * html/HTMLCollection.cpp:
+ (WebCore::shouldIncludeChildren):
+ (WebCore::HTMLCollection::isAcceptableElement):
+ * html/HTMLElement.cpp:
+ (WebCore):
+ (WebCore::HTMLElement::properties):
+ * html/HTMLElement.h:
+ (HTMLElement):
+ * html/HTMLFieldSetElement.cpp:
+ (WebCore::HTMLFieldSetElement::elements):
+ * html/HTMLFieldSetElement.h:
+ (HTMLFieldSetElement):
+ * html/HTMLFormCollection.cpp:
+ (WebCore::HTMLFormCollection::HTMLFormCollection):
+ (WebCore::HTMLFormCollection::create):
+ * html/HTMLFormCollection.h:
+ (HTMLFormCollection):
+ * html/HTMLFormElement.cpp:
+ (WebCore::HTMLFormElement::elements):
+ * html/HTMLFormElement.h:
+ * html/HTMLOptionsCollection.cpp:
+ (WebCore::HTMLOptionsCollection::HTMLOptionsCollection):
+ (WebCore::HTMLOptionsCollection::create):
+ * html/HTMLOptionsCollection.h:
+ (HTMLOptionsCollection):
+ * html/HTMLSelectElement.cpp:
+ (WebCore::HTMLSelectElement::selectedOptions):
+ (WebCore::HTMLSelectElement::options):
+ (WebCore::HTMLSelectElement::invalidateSelectedItems):
+ (WebCore::HTMLSelectElement::setRecalcListItems):
+ * html/HTMLSelectElement.h:
+ * html/HTMLTableElement.cpp:
+ (WebCore::HTMLTableElement::rows):
+ * html/HTMLTableElement.h:
+ * html/HTMLTableRowsCollection.cpp:
+ (WebCore::HTMLTableRowsCollection::HTMLTableRowsCollection):
+ (WebCore::HTMLTableRowsCollection::create):
+ * html/HTMLTableRowsCollection.h:
+ (HTMLTableRowsCollection):
+
2012-06-29 Ojan Vafai <ojan@chromium.org>
Add FIXMEs for vertical writing mode and override sizes.
HTMLAllCollection* Document::all()
{
- if (!m_allCollection)
- m_allCollection = HTMLAllCollection::create(this);
- return m_allCollection.get();
+ if (!m_collections[DocAll])
+ m_collections[DocAll] = HTMLAllCollection::create(this);
+ return static_cast<HTMLAllCollection*>(m_collections[DocAll].get());
}
HTMLCollection* Document::windowNamedItems(const AtomicString& name)
InheritedBool m_designMode;
OwnPtr<HTMLCollection> m_collections[NumUnnamedDocumentCachedTypes];
- OwnPtr<HTMLAllCollection> m_allCollection;
HashSet<DynamicSubtreeNodeList*> m_listsInvalidatedAtDocument;
typedef HashMap<AtomicStringImpl*, OwnPtr<HTMLNameCollection> > NamedCollectionMap;
#include "HTMLCollection.h"
#include "HTMLDocument.h"
#include "HTMLElement.h"
+#include "HTMLFormCollection.h"
#include "HTMLFrameOwnerElement.h"
#include "HTMLNames.h"
+#include "HTMLOptionsCollection.h"
#include "HTMLParserIdioms.h"
+#include "HTMLTableRowsCollection.h"
#include "InspectorInstrumentation.h"
#include "MutationObserverInterestGroup.h"
#include "MutationRecord.h"
return ensureElementRareData()->ensureCachedHTMLCollection(this, type);
}
+HTMLCollection* ElementRareData::ensureCachedHTMLCollection(Element* element, CollectionType type)
+{
+ if (!m_cachedCollections)
+ m_cachedCollections = adoptPtr(new CachedHTMLCollectionArray);
+
+ OwnPtr<HTMLCollection>& collection = (*m_cachedCollections)[type - FirstNodeCollectionType];
+ if (!collection) {
+ if (type == TableRows) {
+ ASSERT(element->hasTagName(tableTag));
+ collection = HTMLTableRowsCollection::create(element);
+ } else if (type == SelectOptions) {
+ ASSERT(element->hasTagName(selectTag));
+ collection = HTMLOptionsCollection::create(element);
+ } else if (type == FormControls) {
+ ASSERT(element->hasTagName(formTag) || element->hasTagName(fieldsetTag));
+ collection = HTMLFormCollection::create(element);
+#if ENABLE(MICRODATA)
+ } else if (type == ItemProperties) {
+ collection = HTMLPropertiesCollection::create(element);
+#endif
+ } else
+ collection = HTMLCollection::create(element, type);
+ }
+ return collection.get();
+}
+
+HTMLCollection* Element::cachedHTMLCollection(CollectionType type)
+{
+ return hasRareData() ? elementRareData()->cachedHTMLCollection(type) : 0;
+}
+
IntSize Element::savedLayerScrollOffset() const
{
return hasRareData() ? elementRareData()->m_savedLayerScrollOffset : IntSize();
virtual bool shouldRegisterAsExtraNamedItem() const { return false; }
HTMLCollection* ensureCachedHTMLCollection(CollectionType);
+ HTMLCollection* cachedHTMLCollection(CollectionType);
private:
void updateInvalidAttributes() const;
#include "DatasetDOMStringMap.h"
#include "Element.h"
#include "ElementShadow.h"
-#include "HTMLCollection.h"
#include "NamedNodeMap.h"
#include "NodeRareData.h"
#include <wtf/OwnPtr.h>
namespace WebCore {
+class HTMLCollection;
+
class ElementRareData : public NodeRareData {
public:
ElementRareData();
return m_cachedCollections;
}
- HTMLCollection* ensureCachedHTMLCollection(Element* element, CollectionType type)
+ HTMLCollection* ensureCachedHTMLCollection(Element*, CollectionType);
+ HTMLCollection* cachedHTMLCollection(CollectionType type)
{
if (!m_cachedCollections)
- m_cachedCollections = adoptPtr(new CachedHTMLCollectionArray);
+ return 0;
- OwnPtr<HTMLCollection>& collection = (*m_cachedCollections)[type - FirstNodeCollectionType];
- if (!collection)
- collection = HTMLCollection::create(element, type);
- return collection.get();
+ return (*m_cachedCollections)[type - FirstNodeCollectionType].get();
}
OwnPtr<CachedHTMLCollectionArray> m_cachedCollections;
ensureRareData()->setItemType(value);
}
-HTMLPropertiesCollection* Node::properties()
-{
- return ensureRareData()->properties(this);
-}
#endif
void NodeRareData::createNodeLists(Node* node)
DOMSettableTokenList* itemProp();
DOMSettableTokenList* itemRef();
DOMSettableTokenList* itemType();
- HTMLPropertiesCollection* properties();
#endif
#if ENABLE(MUTATION_OBSERVERS)
m_itemType->setValue(value);
}
-
- HTMLPropertiesCollection* properties(Node* node)
- {
- if (!m_properties)
- m_properties = HTMLPropertiesCollection::create(node);
-
- return m_properties.get();
- }
#endif
#if ENABLE(STYLE_SCOPED)
mutable RefPtr<DOMSettableTokenList> m_itemProp;
mutable RefPtr<DOMSettableTokenList> m_itemRef;
mutable RefPtr<DOMSettableTokenList> m_itemType;
- mutable OwnPtr<HTMLPropertiesCollection> m_properties;
#endif
#if ENABLE(STYLE_SCOPED)
NodeChildren, // first-level children (IE)
TableTBodies, // all <tbody> elements in this table
TSectionRows, // all row elements in this table section
+ TableRows,
TRCells, // all cells in this row
SelectOptions,
SelectedOptions,
ItemProperties, // Microdata item properties in the document
#endif
- FormControls,
- OtherCollection
+ FormControls
};
static const CollectionType FirstUnnamedDocumentCachedType = DocImages;
static const unsigned NumUnnamedDocumentCachedTypes = WindowNamedItems - DocImages + 1;
static const CollectionType FirstNodeCollectionType = NodeChildren;
-static const unsigned NumNodeCollectionTypes = OtherCollection - NodeChildren + 1;
+static const unsigned NumNodeCollectionTypes = FormControls - NodeChildren + 1;
} // namespace
case DocScripts:
case DocumentNamedItems:
case MapAreas:
- case OtherCollection:
+ case TableRows:
case SelectOptions:
case SelectedOptions:
case DataListOptions:
#endif
case FormControls:
case DocumentNamedItems:
- case OtherCollection:
+ case TableRows:
case WindowNamedItems:
ASSERT_NOT_REACHED();
}
{
setTextContent(value, ec);
}
+
+HTMLPropertiesCollection* HTMLElement::properties()
+{
+ return ensureCachedHTMLCollection(ItemProperties);
+}
#endif
void HTMLElement::addHTMLLengthToStyle(StylePropertySet* style, CSSPropertyID propertyID, const String& value)
#if ENABLE(MICRODATA)
void setItemValue(const String&, ExceptionCode&);
PassRefPtr<MicroDataItemValue> itemValue() const;
+ HTMLPropertiesCollection* properties();
#endif
#ifndef NDEBUG
HTMLCollection* HTMLFieldSetElement::elements()
{
- if (!m_elementsCollection)
- m_elementsCollection = HTMLFormCollection::create(this);
- return m_elementsCollection.get();
+ return ensureCachedHTMLCollection(FormControls);
}
void HTMLFieldSetElement::refreshElementsIfNeeded() const
static void invalidateDisabledStateUnder(Element*);
void refreshElementsIfNeeded() const;
- OwnPtr<HTMLFormCollection> m_elementsCollection;
mutable Vector<FormAssociatedElement*> m_associatedElements;
// When dom tree is modified, we have to refresh the m_associatedElements array.
mutable uint64_t m_documentVersion;
// Since the collections are to be "live", we have to do the
// calculation every time if anything has changed.
-HTMLFormCollection::HTMLFormCollection(HTMLElement* base)
+HTMLFormCollection::HTMLFormCollection(Element* base)
: HTMLCollection(base, FormControls)
{
+ ASSERT(base->hasTagName(formTag) || base->hasTagName(fieldsetTag));
}
-PassOwnPtr<HTMLFormCollection> HTMLFormCollection::create(HTMLElement* base)
+PassOwnPtr<HTMLFormCollection> HTMLFormCollection::create(Element* base)
{
return adoptPtr(new HTMLFormCollection(base));
}
class HTMLFormCollection : public HTMLCollection {
public:
- static PassOwnPtr<HTMLFormCollection> create(HTMLElement*);
+ static PassOwnPtr<HTMLFormCollection> create(Element*);
virtual ~HTMLFormCollection();
virtual Node* namedItem(const AtomicString& name) const;
private:
- HTMLFormCollection(HTMLElement*);
+ HTMLFormCollection(Element*);
virtual void updateNameCache() const;
virtual unsigned calcLength() const;
HTMLCollection* HTMLFormElement::elements()
{
- if (!m_elementsCollection)
- m_elementsCollection = HTMLFormCollection::create(this);
- return m_elementsCollection.get();
+ return ensureCachedHTMLCollection(FormControls);
}
String HTMLFormElement::name() const
FormSubmission::Attributes m_attributes;
OwnPtr<AliasMap> m_elementAliases;
- OwnPtr<HTMLFormCollection> m_elementsCollection;
CheckedRadioButtons m_checkedRadioButtons;
namespace WebCore {
-HTMLOptionsCollection::HTMLOptionsCollection(HTMLSelectElement* select)
+HTMLOptionsCollection::HTMLOptionsCollection(Element* select)
: HTMLCollection(select, SelectOptions)
{
+ ASSERT(select->hasTagName(HTMLNames::selectTag));
}
-PassOwnPtr<HTMLOptionsCollection> HTMLOptionsCollection::create(HTMLSelectElement* select)
+PassOwnPtr<HTMLOptionsCollection> HTMLOptionsCollection::create(Element* select)
{
return adoptPtr(new HTMLOptionsCollection(select));
}
class HTMLOptionsCollection : public HTMLCollection {
public:
- static PassOwnPtr<HTMLOptionsCollection> create(HTMLSelectElement*);
+ static PassOwnPtr<HTMLOptionsCollection> create(Element*);
void add(PassRefPtr<HTMLOptionElement>, ExceptionCode&);
void add(PassRefPtr<HTMLOptionElement>, int index, ExceptionCode&);
using HTMLCollection::invalidateCacheIfNeeded;
private:
- HTMLOptionsCollection(HTMLSelectElement*);
+ HTMLOptionsCollection(Element*);
};
} //namespace
HTMLCollection* HTMLSelectElement::selectedOptions()
{
- if (!m_selectedOptionsCollection)
- m_selectedOptionsCollection = HTMLCollection::create(this, SelectedOptions);
- return m_selectedOptionsCollection.get();
+ return ensureCachedHTMLCollection(SelectedOptions);
}
HTMLOptionsCollection* HTMLSelectElement::options()
{
- if (!m_optionsCollection)
- m_optionsCollection = HTMLOptionsCollection::create(this);
- return m_optionsCollection.get();
+ return static_cast<HTMLOptionsCollection*>(ensureCachedHTMLCollection(SelectOptions));
}
void HTMLSelectElement::updateListItemSelectedStates()
void HTMLSelectElement::invalidateSelectedItems()
{
- if (m_selectedOptionsCollection)
- m_selectedOptionsCollection->invalidateCache();
+ if (HTMLCollection* collection = cachedHTMLCollection(SelectedOptions))
+ collection->invalidateCache();
}
void HTMLSelectElement::setRecalcListItems()
m_activeSelectionAnchorIndex = -1;
setOptionsChangedOnRenderer();
setNeedsStyleRecalc();
- if (!inDocument() && m_optionsCollection)
- m_optionsCollection->invalidateCacheIfNeeded();
- if (!inDocument() && m_selectedOptionsCollection)
- m_selectedOptionsCollection->invalidateCacheIfNeeded();
+ if (!inDocument()) {
+ if (HTMLCollection* collection = cachedHTMLCollection(SelectOptions))
+ collection->invalidateCache();
+ }
+ if (!inDocument())
+ invalidateSelectedItems();
}
void HTMLSelectElement::recalcListItems(bool updateSelectedStates) const
virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
- OwnPtr<HTMLOptionsCollection> m_optionsCollection;
- OwnPtr<HTMLCollection> m_selectedOptionsCollection;
-
// m_listItems contains HTMLOptionElement, HTMLOptGroupElement, and HTMLHRElement objects.
mutable Vector<HTMLElement*> m_listItems;
Vector<bool> m_lastOnChangeSelection;
HTMLCollection* HTMLTableElement::rows()
{
- if (!m_rowsCollection)
- m_rowsCollection = HTMLTableRowsCollection::create(this);
- return m_rowsCollection.get();
+ return ensureCachedHTMLCollection(TableRows);
}
HTMLCollection* HTMLTableElement::tBodies()
// are present, to none otherwise).
unsigned short m_padding;
- OwnPtr<HTMLTableRowsCollection> m_rowsCollection;
RefPtr<StylePropertySet> m_sharedCellStyle;
};
// Must call get() on the table in case that argument is compiled before dereferencing the
// table to get at the collection cache. Order of argument evaluation is undefined and can
// differ between compilers.
-HTMLTableRowsCollection::HTMLTableRowsCollection(HTMLTableElement* table)
- : HTMLCollection(table, OtherCollection)
+HTMLTableRowsCollection::HTMLTableRowsCollection(Element* table)
+ : HTMLCollection(table, TableRows)
{
+ ASSERT(table->hasTagName(tableTag));
}
-PassOwnPtr<HTMLTableRowsCollection> HTMLTableRowsCollection::create(HTMLTableElement* table)
+PassOwnPtr<HTMLTableRowsCollection> HTMLTableRowsCollection::create(Element* table)
{
return adoptPtr(new HTMLTableRowsCollection(table));
}
class HTMLTableRowsCollection : public HTMLCollection {
public:
- static PassOwnPtr<HTMLTableRowsCollection> create(HTMLTableElement*);
+ static PassOwnPtr<HTMLTableRowsCollection> create(Element*);
static HTMLTableRowElement* rowAfter(HTMLTableElement*, HTMLTableRowElement*);
static HTMLTableRowElement* lastRow(HTMLTableElement*);
private:
- HTMLTableRowsCollection(HTMLTableElement*);
+ HTMLTableRowsCollection(Element*);
virtual Element* itemAfter(Node*) const OVERRIDE;
};