- Revision
- 122873
- Author
- [email protected]
- Date
- 2012-07-17 13:56:32 -0700 (Tue, 17 Jul 2012)
Log Message
invalidateNodeListCachesInAncestors walks up ancestors even when an attribute that doesn't invalidate node lists changes
https://bugs.webkit.org/show_bug.cgi?id=91530
Reviewed by Ojan Vafai.
Source/WebCore:
The bug was caused by invalidateNodeListCachesInAncestors not calling Document::shouldInvalidateNodeListCaches with
attrName. Done that.
This chance revealed a bug in shouldInvalidateTypeOnAttributeChange that we weren't checking form attribute changes for
RadioNodeList and HTMLCollection, so fixed the bug.
Also renamed Document::clearNodeListCaches to invalidateNodeListCaches to match the name convention used elsewhere,
and added a new version of DynamicNodeListCacheBase::invalidateCache that takes attrName to reduce the code duplication.
Test: fast/forms/elements-invalidate-on-form-attribute-invalidation.html
* dom/Document.cpp:
(WebCore::Document::invalidateNodeListCaches):
* dom/Document.h:
(Document):
* dom/DynamicNodeList.h:
(WebCore::DynamicNodeListCacheBase::invalidateCache):
(WebCore::DynamicNodeListCacheBase::shouldInvalidateTypeOnAttributeChange):
* dom/Node.cpp:
(WebCore::Node::invalidateNodeListCachesInAncestors):
(WebCore::NodeListsNodeData::invalidateCaches):
LayoutTests:
Add a regression test for invalidating HTMLFormColletion on form attribute changes. This invalidation worked before
because we weren't properly exiting early in Node::invalidateNodeListCachesInAncestors and
Document::invalidateNodeListCaches invalidated all node lists regardless of the attribute type.
* fast/forms/elements-invalidate-on-form-attribute-invalidation-expected.txt: Added.
* fast/forms/elements-invalidate-on-form-attribute-invalidation.html: Added.
Modified Paths
Added Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (122872 => 122873)
--- trunk/LayoutTests/ChangeLog 2012-07-17 20:44:40 UTC (rev 122872)
+++ trunk/LayoutTests/ChangeLog 2012-07-17 20:56:32 UTC (rev 122873)
@@ -1,3 +1,17 @@
+2012-07-17 Ryosuke Niwa <[email protected]>
+
+ invalidateNodeListCachesInAncestors walks up ancestors even when an attribute that doesn't invalidate node lists changes
+ https://bugs.webkit.org/show_bug.cgi?id=91530
+
+ Reviewed by Ojan Vafai.
+
+ Add a regression test for invalidating HTMLFormColletion on form attribute changes. This invalidation worked before
+ because we weren't properly exiting early in Node::invalidateNodeListCachesInAncestors and
+ Document::invalidateNodeListCaches invalidated all node lists regardless of the attribute type.
+
+ * fast/forms/elements-invalidate-on-form-attribute-invalidation-expected.txt: Added.
+ * fast/forms/elements-invalidate-on-form-attribute-invalidation.html: Added.
+
2012-07-17 Florin Malita <[email protected]>
SVG getBBox does not update bound after path data change
Added: trunk/LayoutTests/fast/forms/elements-invalidate-on-form-attribute-invalidation-expected.txt (0 => 122873)
--- trunk/LayoutTests/fast/forms/elements-invalidate-on-form-attribute-invalidation-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/forms/elements-invalidate-on-form-attribute-invalidation-expected.txt 2012-07-17 20:56:32 UTC (rev 122873)
@@ -0,0 +1,10 @@
+Tests form.elements is invalidated when input element's form attribute is changed.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+collection = document.getElementById('someForm').elements;
+PASS collection.length is 1
+PASS collection.length; input.setAttribute('form', 'otherForm'); collection.length is 0
+PASS collection.length; input.setAttribute('form', 'someForm'); collection.length is 1
+
Added: trunk/LayoutTests/fast/forms/elements-invalidate-on-form-attribute-invalidation.html (0 => 122873)
--- trunk/LayoutTests/fast/forms/elements-invalidate-on-form-attribute-invalidation.html (rev 0)
+++ trunk/LayoutTests/fast/forms/elements-invalidate-on-form-attribute-invalidation.html 2012-07-17 20:56:32 UTC (rev 122873)
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<body>
+<div id="container">
+<form id="someForm"></form>
+<input type="text" name="someName" form="someForm">
+</div>
+<script src=""
+<script>
+
+description("Tests form.elements is invalidated when input element's form attribute is changed.");
+
+var input = document.querySelector('input');
+var collection;
+evalAndLog("collection = document.getElementById('someForm').elements;");
+shouldBe("collection.length", "1");
+shouldBe("collection.length; input.setAttribute('form', 'otherForm'); collection.length", "0");
+shouldBe("collection.length; input.setAttribute('form', 'someForm'); collection.length", "1");
+
+container.style.display = 'none';
+
+</script>
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (122872 => 122873)
--- trunk/Source/WebCore/ChangeLog 2012-07-17 20:44:40 UTC (rev 122872)
+++ trunk/Source/WebCore/ChangeLog 2012-07-17 20:56:32 UTC (rev 122873)
@@ -1,3 +1,32 @@
+2012-07-17 Ryosuke Niwa <[email protected]>
+
+ invalidateNodeListCachesInAncestors walks up ancestors even when an attribute that doesn't invalidate node lists changes
+ https://bugs.webkit.org/show_bug.cgi?id=91530
+
+ Reviewed by Ojan Vafai.
+
+ The bug was caused by invalidateNodeListCachesInAncestors not calling Document::shouldInvalidateNodeListCaches with
+ attrName. Done that.
+
+ This chance revealed a bug in shouldInvalidateTypeOnAttributeChange that we weren't checking form attribute changes for
+ RadioNodeList and HTMLCollection, so fixed the bug.
+
+ Also renamed Document::clearNodeListCaches to invalidateNodeListCaches to match the name convention used elsewhere,
+ and added a new version of DynamicNodeListCacheBase::invalidateCache that takes attrName to reduce the code duplication.
+
+ Test: fast/forms/elements-invalidate-on-form-attribute-invalidation.html
+
+ * dom/Document.cpp:
+ (WebCore::Document::invalidateNodeListCaches):
+ * dom/Document.h:
+ (Document):
+ * dom/DynamicNodeList.h:
+ (WebCore::DynamicNodeListCacheBase::invalidateCache):
+ (WebCore::DynamicNodeListCacheBase::shouldInvalidateTypeOnAttributeChange):
+ * dom/Node.cpp:
+ (WebCore::Node::invalidateNodeListCachesInAncestors):
+ (WebCore::NodeListsNodeData::invalidateCaches):
+
2012-07-17 Max Vujovic <[email protected]>
Update ANGLE in WebKit
Modified: trunk/Source/WebCore/dom/Document.cpp (122872 => 122873)
--- trunk/Source/WebCore/dom/Document.cpp 2012-07-17 20:44:40 UTC (rev 122872)
+++ trunk/Source/WebCore/dom/Document.cpp 2012-07-17 20:56:32 UTC (rev 122873)
@@ -3904,11 +3904,11 @@
return false;
}
-void Document::clearNodeListCaches()
+void Document::invalidateNodeListCaches(const QualifiedName* attrName)
{
HashSet<DynamicNodeListCacheBase*>::iterator end = m_listsInvalidatedAtDocument.end();
for (HashSet<DynamicNodeListCacheBase*>::iterator it = m_listsInvalidatedAtDocument.begin(); it != end; ++it)
- (*it)->invalidateCache();
+ (*it)->invalidateCache(attrName);
}
void Document::attachNodeIterator(NodeIterator* ni)
Modified: trunk/Source/WebCore/dom/Document.h (122872 => 122873)
--- trunk/Source/WebCore/dom/Document.h 2012-07-17 20:44:40 UTC (rev 122872)
+++ trunk/Source/WebCore/dom/Document.h 2012-07-17 20:56:32 UTC (rev 122873)
@@ -738,7 +738,7 @@
void registerNodeListCache(DynamicNodeListCacheBase*);
void unregisterNodeListCache(DynamicNodeListCacheBase*);
bool shouldInvalidateNodeListCaches(const QualifiedName* attrName = 0) const;
- void clearNodeListCaches();
+ void invalidateNodeListCaches(const QualifiedName* attrName);
void attachNodeIterator(NodeIterator*);
void detachNodeIterator(NodeIterator*);
Modified: trunk/Source/WebCore/dom/DynamicNodeList.h (122872 => 122873)
--- trunk/Source/WebCore/dom/DynamicNodeList.h 2012-07-17 20:44:40 UTC (rev 122872)
+++ trunk/Source/WebCore/dom/DynamicNodeList.h 2012-07-17 20:56:32 UTC (rev 122873)
@@ -68,6 +68,11 @@
ALWAYS_INLINE NodeListInvalidationType invalidationType() const { return static_cast<NodeListInvalidationType>(m_invalidationType); }
ALWAYS_INLINE CollectionType type() const { return static_cast<CollectionType>(m_collectionType); }
+ ALWAYS_INLINE void invalidateCache(const QualifiedName* attrName) const
+ {
+ if (!attrName || shouldInvalidateTypeOnAttributeChange(invalidationType(), *attrName))
+ invalidateCache();
+ }
void invalidateCache() const;
static bool shouldInvalidateTypeOnAttributeChange(NodeListInvalidationType, const QualifiedName&);
@@ -124,7 +129,8 @@
case InvalidateOnForAttrChange:
return attrName == HTMLNames::forAttr;
case InvalidateForFormControls:
- return attrName == HTMLNames::nameAttr || attrName == HTMLNames::idAttr || attrName == HTMLNames::forAttr || attrName == HTMLNames::typeAttr;
+ return attrName == HTMLNames::nameAttr || attrName == HTMLNames::idAttr || attrName == HTMLNames::forAttr
+ || attrName == HTMLNames::formAttr || attrName == HTMLNames::typeAttr;
case InvalidateOnHRefAttrChange:
return attrName == HTMLNames::hrefAttr;
case InvalidateOnItemAttrChange:
Modified: trunk/Source/WebCore/dom/Node.cpp (122872 => 122873)
--- trunk/Source/WebCore/dom/Node.cpp 2012-07-17 20:44:40 UTC (rev 122872)
+++ trunk/Source/WebCore/dom/Node.cpp 2012-07-17 20:56:32 UTC (rev 122873)
@@ -974,7 +974,7 @@
if (!document()->shouldInvalidateNodeListCaches())
return;
- document()->clearNodeListCaches();
+ document()->invalidateNodeListCaches(attrName);
for (Node* node = this; node; node = node->parentNode()) {
if (!node->hasRareData())
@@ -2214,18 +2214,12 @@
void NodeListsNodeData::invalidateCaches(const QualifiedName* attrName)
{
NodeListAtomicNameCacheMap::const_iterator atomicNameCacheEnd = m_atomicNameCaches.end();
- for (NodeListAtomicNameCacheMap::const_iterator it = m_atomicNameCaches.begin(); it != atomicNameCacheEnd; ++it) {
- DynamicNodeList* list = it->second;
- if (!attrName || DynamicNodeListCacheBase::shouldInvalidateTypeOnAttributeChange(list->invalidationType(), *attrName))
- list->invalidateCache();
- }
+ for (NodeListAtomicNameCacheMap::const_iterator it = m_atomicNameCaches.begin(); it != atomicNameCacheEnd; ++it)
+ it->second->invalidateCache(attrName);
NodeListNameCacheMap::const_iterator nameCacheEnd = m_nameCaches.end();
- for (NodeListNameCacheMap::const_iterator it = m_nameCaches.begin(); it != nameCacheEnd; ++it) {
- DynamicNodeList* list = it->second;
- if (!attrName || DynamicNodeListCacheBase::shouldInvalidateTypeOnAttributeChange(list->invalidationType(), *attrName))
- list->invalidateCache();
- }
+ for (NodeListNameCacheMap::const_iterator it = m_nameCaches.begin(); it != nameCacheEnd; ++it)
+ it->second->invalidateCache(attrName);
if (!attrName)
return;