Title: [103116] trunk
Revision
103116
Author
[email protected]
Date
2011-12-16 15:15:10 -0800 (Fri, 16 Dec 2011)

Log Message

invalidateNodeListsCacheAfterAttributeChanged has too many callers
https://bugs.webkit.org/show_bug.cgi?id=74692

Reviewed by Sam Weinig.

Source/WebCore: 

Call invalidateNodeListsCacheAfterAttributeChanged in Element::updateAfterAttributeChanged instead of
parsedMappedAttribute of various elements. Also make invalidateNodeListsCacheAfterAttributeChanged take
the qualified name of the changed attribute so that we can exit early when the changed attribute isn't
one of attributes we care.

In addition, added a missing call to invalidateNodeListsCacheAfterAttributeChanged in Attr::setValue.

Test: fast/dom/Attr/invalidate-nodelist-after-attr-setvalue.html

* dom/Attr.cpp:
(WebCore::Attr::childrenChanged):
* dom/Element.cpp:
(WebCore::Element::updateAfterAttributeChanged):
* dom/NamedNodeMap.cpp:
(WebCore::NamedNodeMap::addAttribute):
(WebCore::NamedNodeMap::removeAttribute):
* dom/Node.cpp:
(WebCore::Node::invalidateNodeListsCacheAfterAttributeChanged):
* dom/Node.h:
* dom/StyledElement.cpp:
(WebCore::StyledElement::classAttributeChanged):
* html/HTMLAnchorElement.cpp:
(WebCore::HTMLAnchorElement::parseMappedAttribute):
* html/HTMLAppletElement.cpp:
(WebCore::HTMLAppletElement::parseMappedAttribute):
* html/HTMLElement.cpp:
(WebCore::HTMLElement::parseMappedAttribute):
* html/HTMLEmbedElement.cpp:
(WebCore::HTMLEmbedElement::parseMappedAttribute):
* html/HTMLFormElement.cpp:
(WebCore::HTMLFormElement::parseMappedAttribute):
* html/HTMLFrameElementBase.cpp:
(WebCore::HTMLFrameElementBase::parseMappedAttribute):
* html/HTMLIFrameElement.cpp:
(WebCore::HTMLIFrameElement::parseMappedAttribute):
* html/HTMLImageElement.cpp:
(WebCore::HTMLImageElement::parseMappedAttribute):
* html/HTMLMapElement.cpp:
(WebCore::HTMLMapElement::parseMappedAttribute):
* html/HTMLMetaElement.cpp:
(WebCore::HTMLMetaElement::parseMappedAttribute):
* html/HTMLObjectElement.cpp:
(WebCore::HTMLObjectElement::parseMappedAttribute):
* html/HTMLParamElement.cpp:
(WebCore::HTMLParamElement::parseMappedAttribute):

LayoutTests: 

Add a regression test for setting Attr's value. WebKit should invalidate the cache as needed.

* fast/dom/Attr/invalidate-nodelist-after-attr-setvalue-expected.txt: Added.
* fast/dom/Attr/invalidate-nodelist-after-attr-setvalue.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (103115 => 103116)


--- trunk/LayoutTests/ChangeLog	2011-12-16 23:11:11 UTC (rev 103115)
+++ trunk/LayoutTests/ChangeLog	2011-12-16 23:15:10 UTC (rev 103116)
@@ -1,3 +1,15 @@
+2011-12-16  Ryosuke Niwa  <[email protected]>
+
+        invalidateNodeListsCacheAfterAttributeChanged has too many callers
+        https://bugs.webkit.org/show_bug.cgi?id=74692
+
+        Reviewed by Sam Weinig.
+
+        Add a regression test for setting Attr's value. WebKit should invalidate the cache as needed.
+
+        * fast/dom/Attr/invalidate-nodelist-after-attr-setvalue-expected.txt: Added.
+        * fast/dom/Attr/invalidate-nodelist-after-attr-setvalue.html: Added.
+
 2011-12-16  Andreas Kling  <[email protected]>
 
         Cache and reuse HTMLCollections exposed by Document.

Added: trunk/LayoutTests/fast/dom/Attr/invalidate-nodelist-after-attr-setvalue-expected.txt (0 => 103116)


--- trunk/LayoutTests/fast/dom/Attr/invalidate-nodelist-after-attr-setvalue-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/Attr/invalidate-nodelist-after-attr-setvalue-expected.txt	2011-12-16 23:15:10 UTC (rev 103116)
@@ -0,0 +1,12 @@
+This tests setting the value of an attribute node after caching childNodes of the attribute node.
+The cache should be cleared and childNodes[0].data should return the new value.
+You should see PASS below:
+
+PASS nameAttrNode.childNodes.length is 1
+PASS nameAttrNode.childNodes[0] is oldValue
+PASS nameAttrNode.childNodes[0].data is "oldName"
+
+PASS nameAttrNode.value = 'newName'; nameAttrNode.value is "newName"
+PASS nameAttrNode.childNodes[0] is not oldValue
+PASS nameAttrNode.childNodes[0].data is "newName"
+

Added: trunk/LayoutTests/fast/dom/Attr/invalidate-nodelist-after-attr-setvalue.html (0 => 103116)


--- trunk/LayoutTests/fast/dom/Attr/invalidate-nodelist-after-attr-setvalue.html	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/Attr/invalidate-nodelist-after-attr-setvalue.html	2011-12-16 23:15:10 UTC (rev 103116)
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+<body>
+<p>This tests setting the value of an attribute node after caching childNodes of the attribute node.<br>
+The cache should be cleared and childNodes[0].data should return the new value.<br>
+You should see PASS below:</p>
+<div id="console"></div>
+<script src=""
+<script>
+
+var element = document.createElement('div');
+var nameAttrNode = document.createAttribute('name');
+var oldValue = document.createTextNode('oldName');
+nameAttrNode.appendChild(oldValue);
+element.setAttributeNode(nameAttrNode);
+document.body.appendChild(element);
+
+shouldBe("nameAttrNode.childNodes.length", '1');
+shouldBe('nameAttrNode.childNodes[0]', 'oldValue');
+shouldBe('nameAttrNode.childNodes[0].data', '"oldName"');
+
+debug('');
+shouldBe("nameAttrNode.value = 'newName'; nameAttrNode.value", '"newName"');
+shouldNotBe("nameAttrNode.childNodes[0]", 'oldValue');
+shouldBe("nameAttrNode.childNodes[0].data", '"newName"');
+
+</script>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (103115 => 103116)


--- trunk/Source/WebCore/ChangeLog	2011-12-16 23:11:11 UTC (rev 103115)
+++ trunk/Source/WebCore/ChangeLog	2011-12-16 23:15:10 UTC (rev 103116)
@@ -1,3 +1,56 @@
+2011-12-16  Ryosuke Niwa  <[email protected]>
+
+        invalidateNodeListsCacheAfterAttributeChanged has too many callers
+        https://bugs.webkit.org/show_bug.cgi?id=74692
+
+        Reviewed by Sam Weinig.
+
+        Call invalidateNodeListsCacheAfterAttributeChanged in Element::updateAfterAttributeChanged instead of
+        parsedMappedAttribute of various elements. Also make invalidateNodeListsCacheAfterAttributeChanged take
+        the qualified name of the changed attribute so that we can exit early when the changed attribute isn't
+        one of attributes we care.
+
+        In addition, added a missing call to invalidateNodeListsCacheAfterAttributeChanged in Attr::setValue.
+
+        Test: fast/dom/Attr/invalidate-nodelist-after-attr-setvalue.html
+
+        * dom/Attr.cpp:
+        (WebCore::Attr::childrenChanged):
+        * dom/Element.cpp:
+        (WebCore::Element::updateAfterAttributeChanged):
+        * dom/NamedNodeMap.cpp:
+        (WebCore::NamedNodeMap::addAttribute):
+        (WebCore::NamedNodeMap::removeAttribute):
+        * dom/Node.cpp:
+        (WebCore::Node::invalidateNodeListsCacheAfterAttributeChanged):
+        * dom/Node.h:
+        * dom/StyledElement.cpp:
+        (WebCore::StyledElement::classAttributeChanged):
+        * html/HTMLAnchorElement.cpp:
+        (WebCore::HTMLAnchorElement::parseMappedAttribute):
+        * html/HTMLAppletElement.cpp:
+        (WebCore::HTMLAppletElement::parseMappedAttribute):
+        * html/HTMLElement.cpp:
+        (WebCore::HTMLElement::parseMappedAttribute):
+        * html/HTMLEmbedElement.cpp:
+        (WebCore::HTMLEmbedElement::parseMappedAttribute):
+        * html/HTMLFormElement.cpp:
+        (WebCore::HTMLFormElement::parseMappedAttribute):
+        * html/HTMLFrameElementBase.cpp:
+        (WebCore::HTMLFrameElementBase::parseMappedAttribute):
+        * html/HTMLIFrameElement.cpp:
+        (WebCore::HTMLIFrameElement::parseMappedAttribute):
+        * html/HTMLImageElement.cpp:
+        (WebCore::HTMLImageElement::parseMappedAttribute):
+        * html/HTMLMapElement.cpp:
+        (WebCore::HTMLMapElement::parseMappedAttribute):
+        * html/HTMLMetaElement.cpp:
+        (WebCore::HTMLMetaElement::parseMappedAttribute):
+        * html/HTMLObjectElement.cpp:
+        (WebCore::HTMLObjectElement::parseMappedAttribute):
+        * html/HTMLParamElement.cpp:
+        (WebCore::HTMLParamElement::parseMappedAttribute):
+
 2011-12-16  Andreas Kling  <[email protected]>
 
         Cache and reuse HTMLCollections exposed by Document.

Modified: trunk/Source/WebCore/dom/Attr.cpp (103115 => 103116)


--- trunk/Source/WebCore/dom/Attr.cpp	2011-12-16 23:11:11 UTC (rev 103115)
+++ trunk/Source/WebCore/dom/Attr.cpp	2011-12-16 23:15:10 UTC (rev 103116)
@@ -126,6 +126,8 @@
     m_attribute->setValue(value);
     createTextChild();
     m_ignoreChildrenChanged--;
+
+    invalidateNodeListsCacheAfterAttributeChanged(m_attribute->name());
 }
 
 void Attr::setValue(const AtomicString& value, ExceptionCode&)
@@ -180,10 +182,10 @@
 
     Node::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
 
-    invalidateNodeListsCacheAfterAttributeChanged();
+    invalidateNodeListsCacheAfterAttributeChanged(m_attribute->name());
 
     // FIXME: We should include entity references in the value
-    
+
     String val = "";
     for (Node *n = firstChild(); n; n = n->nextSibling()) {
         if (n->isTextNode())

Modified: trunk/Source/WebCore/dom/Element.cpp (103115 => 103116)


--- trunk/Source/WebCore/dom/Element.cpp	2011-12-16 23:11:11 UTC (rev 103115)
+++ trunk/Source/WebCore/dom/Element.cpp	2011-12-16 23:15:10 UTC (rev 103116)
@@ -697,6 +697,8 @@
 
 void Element::updateAfterAttributeChanged(Attribute* attr)
 {
+    invalidateNodeListsCacheAfterAttributeChanged(attr->name());
+
     if (!AXObjectCache::accessibilityEnabled())
         return;
 

Modified: trunk/Source/WebCore/dom/NamedNodeMap.cpp (103115 => 103116)


--- trunk/Source/WebCore/dom/NamedNodeMap.cpp	2011-12-16 23:11:11 UTC (rev 103115)
+++ trunk/Source/WebCore/dom/NamedNodeMap.cpp	2011-12-16 23:15:10 UTC (rev 103116)
@@ -264,7 +264,6 @@
         m_element->attributeChanged(attribute.get());
         // Because of our updateStyleAttribute() style modification events are never sent at the right time, so don't bother sending them.
         if (attribute->name() != styleAttr) {
-            m_element->invalidateNodeListsCacheAfterAttributeChanged();
             m_element->dispatchAttrAdditionEvent(attribute.get());
             m_element->dispatchSubtreeModifiedEvent();
         }
@@ -301,7 +300,6 @@
         attr->m_value = value;
     }
     if (m_element) {
-        m_element->invalidateNodeListsCacheAfterAttributeChanged();
         m_element->dispatchAttrRemovalEvent(attr.get());
         m_element->dispatchSubtreeModifiedEvent();
     }

Modified: trunk/Source/WebCore/dom/Node.cpp (103115 => 103116)


--- trunk/Source/WebCore/dom/Node.cpp	2011-12-16 23:11:11 UTC (rev 103115)
+++ trunk/Source/WebCore/dom/Node.cpp	2011-12-16 23:15:10 UTC (rev 103116)
@@ -1020,7 +1020,7 @@
     removeNodeListCacheIfPossible(this, data);
 }
 
-void Node::invalidateNodeListsCacheAfterAttributeChanged()
+void Node::invalidateNodeListsCacheAfterAttributeChanged(const QualifiedName& attrName)
 {
     if (hasRareData() && isAttributeNode()) {
         NodeRareData* data = ""
@@ -1028,6 +1028,15 @@
         data->clearChildNodeListCache();
     }
 
+    // This list should be sync'ed with NodeListsNodeData.
+    if (attrName != classAttr
+#if ENABLE(MICRODATA)
+        && attrName != itemscopeAttr
+        && attrName != itempropAttr
+#endif
+        && attrName != nameAttr)
+        return;
+
     if (!treeScope()->hasNodeListCaches())
         return;
 

Modified: trunk/Source/WebCore/dom/Node.h (103115 => 103116)


--- trunk/Source/WebCore/dom/Node.h	2011-12-16 23:11:11 UTC (rev 103115)
+++ trunk/Source/WebCore/dom/Node.h	2011-12-16 23:15:10 UTC (rev 103116)
@@ -519,7 +519,7 @@
 
     void registerDynamicSubtreeNodeList(DynamicSubtreeNodeList*);
     void unregisterDynamicSubtreeNodeList(DynamicSubtreeNodeList*);
-    void invalidateNodeListsCacheAfterAttributeChanged();
+    void invalidateNodeListsCacheAfterAttributeChanged(const QualifiedName&);
     void invalidateNodeListsCacheAfterChildrenChanged();
     void notifyLocalNodeListsLabelChanged();
     void removeCachedClassNodeList(ClassNodeList*, const String&);

Modified: trunk/Source/WebCore/dom/StyledElement.cpp (103115 => 103116)


--- trunk/Source/WebCore/dom/StyledElement.cpp	2011-12-16 23:11:11 UTC (rev 103115)
+++ trunk/Source/WebCore/dom/StyledElement.cpp	2011-12-16 23:15:10 UTC (rev 103116)
@@ -228,7 +228,6 @@
     } else if (attributeMap())
         attributeMap()->clearClass();
     setNeedsStyleRecalc();
-    invalidateNodeListsCacheAfterAttributeChanged();
     dispatchSubtreeModifiedEvent();
 }
 

Modified: trunk/Source/WebCore/html/HTMLAnchorElement.cpp (103115 => 103116)


--- trunk/Source/WebCore/html/HTMLAnchorElement.cpp	2011-12-16 23:11:11 UTC (rev 103115)
+++ trunk/Source/WebCore/html/HTMLAnchorElement.cpp	2011-12-16 23:15:10 UTC (rev 103116)
@@ -223,9 +223,7 @@
             }
         }
         invalidateCachedVisitedLinkHash();
-    } else if (attr->name() == nameAttr) {
-        invalidateNodeListsCacheAfterAttributeChanged();
-    } else if (attr->name() == titleAttr) {
+    } else if (attr->name() == nameAttr || attr->name() == titleAttr) {
         // Do nothing.
     } else if (attr->name() == relAttr)
         setRel(attr->value());

Modified: trunk/Source/WebCore/html/HTMLAppletElement.cpp (103115 => 103116)


--- trunk/Source/WebCore/html/HTMLAppletElement.cpp	2011-12-16 23:11:11 UTC (rev 103115)
+++ trunk/Source/WebCore/html/HTMLAppletElement.cpp	2011-12-16 23:15:10 UTC (rev 103116)
@@ -64,7 +64,6 @@
             document->addNamedItem(newName);
         }
         m_name = newName;
-        invalidateNodeListsCacheAfterAttributeChanged();
     } else if (isIdAttributeName(attr->name())) {
         const AtomicString& newId = attr->value();
         if (inDocument() && document()->isHTMLDocument()) {

Modified: trunk/Source/WebCore/html/HTMLElement.cpp (103115 => 103116)


--- trunk/Source/WebCore/html/HTMLElement.cpp	2011-12-16 23:11:11 UTC (rev 103115)
+++ trunk/Source/WebCore/html/HTMLElement.cpp	2011-12-16 23:15:10 UTC (rev 103116)
@@ -210,8 +210,6 @@
             addCSSProperty(attr, CSSPropertyWebkitUserSelect, CSSValueNone);
         } else if (equalIgnoringCase(value, "false"))
             addCSSProperty(attr, CSSPropertyWebkitUserDrag, CSSValueNone);
-    } else if (attr->name() == nameAttr) {
-        invalidateNodeListsCacheAfterAttributeChanged();
 #if ENABLE(MICRODATA)
     } else if (attr->name() == itempropAttr) {
         setItemProp(attr->value());

Modified: trunk/Source/WebCore/html/HTMLEmbedElement.cpp (103115 => 103116)


--- trunk/Source/WebCore/html/HTMLEmbedElement.cpp	2011-12-16 23:11:11 UTC (rev 103115)
+++ trunk/Source/WebCore/html/HTMLEmbedElement.cpp	2011-12-16 23:15:10 UTC (rev 103116)
@@ -118,7 +118,6 @@
             document->addNamedItem(value);
         }
         m_name = value;
-        invalidateNodeListsCacheAfterAttributeChanged();
     } else
         HTMLPlugInImageElement::parseMappedAttribute(attr);
 }

Modified: trunk/Source/WebCore/html/HTMLFormElement.cpp (103115 => 103116)


--- trunk/Source/WebCore/html/HTMLFormElement.cpp	2011-12-16 23:11:11 UTC (rev 103115)
+++ trunk/Source/WebCore/html/HTMLFormElement.cpp	2011-12-16 23:15:10 UTC (rev 103116)
@@ -392,7 +392,6 @@
             document->addNamedItem(newName);
         }
         m_name = newName;
-        invalidateNodeListsCacheAfterAttributeChanged();
     } else
         HTMLElement::parseMappedAttribute(attr);
 }

Modified: trunk/Source/WebCore/html/HTMLFrameElementBase.cpp (103115 => 103116)


--- trunk/Source/WebCore/html/HTMLFrameElementBase.cpp	2011-12-16 23:11:11 UTC (rev 103115)
+++ trunk/Source/WebCore/html/HTMLFrameElementBase.cpp	2011-12-16 23:15:10 UTC (rev 103116)
@@ -141,7 +141,6 @@
         m_frameName = attr->value();
     } else if (attr->name() == nameAttr) {
         m_frameName = attr->value();
-        invalidateNodeListsCacheAfterAttributeChanged();
         // FIXME: If we are already attached, this doesn't actually change the frame's name.
         // FIXME: If we are already attached, this doesn't check for frame name
         // conflicts and generate a unique frame name.

Modified: trunk/Source/WebCore/html/HTMLIFrameElement.cpp (103115 => 103116)


--- trunk/Source/WebCore/html/HTMLIFrameElement.cpp	2011-12-16 23:11:11 UTC (rev 103115)
+++ trunk/Source/WebCore/html/HTMLIFrameElement.cpp	2011-12-16 23:15:10 UTC (rev 103116)
@@ -84,7 +84,6 @@
             document->addExtraNamedItem(newName);
         }
         m_name = newName;
-        invalidateNodeListsCacheAfterAttributeChanged();
     } else if (attr->name() == frameborderAttr) {
         // Frame border doesn't really match the HTML4 spec definition for iframes.  It simply adds
         // a presentational hint that the border should be off if set to zero.

Modified: trunk/Source/WebCore/html/HTMLImageElement.cpp (103115 => 103116)


--- trunk/Source/WebCore/html/HTMLImageElement.cpp	2011-12-16 23:11:11 UTC (rev 103115)
+++ trunk/Source/WebCore/html/HTMLImageElement.cpp	2011-12-16 23:15:10 UTC (rev 103116)
@@ -141,7 +141,6 @@
             document->addNamedItem(newName);
         }
         m_name = newName;
-        invalidateNodeListsCacheAfterAttributeChanged();
     } else if (isIdAttributeName(attr->name())) {
         const AtomicString& newId = attr->value();
         if (inDocument() && document()->isHTMLDocument()) {

Modified: trunk/Source/WebCore/html/HTMLMapElement.cpp (103115 => 103116)


--- trunk/Source/WebCore/html/HTMLMapElement.cpp	2011-12-16 23:11:11 UTC (rev 103115)
+++ trunk/Source/WebCore/html/HTMLMapElement.cpp	2011-12-16 23:15:10 UTC (rev 103116)
@@ -120,8 +120,6 @@
         if (inDocument())
             treeScope()->addImageMap(this);
 
-        if (attrName == nameAttr)
-            invalidateNodeListsCacheAfterAttributeChanged();
         return;
     }
 

Modified: trunk/Source/WebCore/html/HTMLMetaElement.cpp (103115 => 103116)


--- trunk/Source/WebCore/html/HTMLMetaElement.cpp	2011-12-16 23:11:11 UTC (rev 103115)
+++ trunk/Source/WebCore/html/HTMLMetaElement.cpp	2011-12-16 23:15:10 UTC (rev 103116)
@@ -49,7 +49,7 @@
     else if (attr->name() == contentAttr)
         process();
     else if (attr->name() == nameAttr) {
-        invalidateNodeListsCacheAfterAttributeChanged();
+        // Do nothing
     } else
         HTMLElement::parseMappedAttribute(attr);
 }

Modified: trunk/Source/WebCore/html/HTMLObjectElement.cpp (103115 => 103116)


--- trunk/Source/WebCore/html/HTMLObjectElement.cpp	2011-12-16 23:11:11 UTC (rev 103115)
+++ trunk/Source/WebCore/html/HTMLObjectElement.cpp	2011-12-16 23:15:10 UTC (rev 103116)
@@ -122,7 +122,6 @@
             document->addNamedItem(newName);
         }
         m_name = newName;
-        invalidateNodeListsCacheAfterAttributeChanged();
     } else if (attr->name() == borderAttr)
         applyBorderAttribute(attr);
     else if (isIdAttributeName(attr->name())) {

Modified: trunk/Source/WebCore/html/HTMLParamElement.cpp (103115 => 103116)


--- trunk/Source/WebCore/html/HTMLParamElement.cpp	2011-12-16 23:11:11 UTC (rev 103115)
+++ trunk/Source/WebCore/html/HTMLParamElement.cpp	2011-12-16 23:15:10 UTC (rev 103116)
@@ -57,7 +57,6 @@
         m_name = attr->value();
     } else if (attr->name() == nameAttr) {
         m_name = attr->value();
-        invalidateNodeListsCacheAfterAttributeChanged();
     } else if (attr->name() == valueAttr) {
         m_value = attr->value();
     } else
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to