Title: [126349] trunk
Revision
126349
Author
a...@chromium.org
Date
2012-08-22 14:19:29 -0700 (Wed, 22 Aug 2012)

Log Message

Changing class attribute is not reflected in the classList property
https://bugs.webkit.org/show_bug.cgi?id=93665

Reviewed by Ojan Vafai.

Before this change classAttributeChanged was only called for StyledElement. With this refactoring
it gets called for all Elements when the class attribute changes.

Source/WebCore:

Test: fast/dom/Element/class-list-update.html

* css/StyleResolver.cpp:
(WebCore::StyleResolver::collectMatchingRules): To match the old behavior we only include StyledElements.
* dom/ClassNodeList.cpp:
(WebCore::ClassNodeList::nodeMatches): Ditto.
* dom/Element.cpp:
(WebCore::Element::attributeChanged): Moved the call to parseAttribute here, from StyledElement::attributeChanged.
(WebCore::Element::parseAttribute): Moved from StyledElement.
(WebCore):
(WebCore::Element::classAttributeChanged): Ditto.
* dom/Element.h:
(Element):
(WebCore::Element::classNames): Ditto.
(WebCore):
* dom/StyledElement.cpp:
(WebCore::StyledElement::attributeChanged): Let Element::attributeChanged call parseAttribtue instead.
(WebCore::StyledElement::parseAttribute): Move the class attribute handling to Element::parseAttribute.
* dom/StyledElement.h:
(StyledElement):

LayoutTests:

* fast/dom/Element/class-list-update-expected.txt: Added.
* fast/dom/Element/class-list-update.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (126348 => 126349)


--- trunk/LayoutTests/ChangeLog	2012-08-22 21:14:11 UTC (rev 126348)
+++ trunk/LayoutTests/ChangeLog	2012-08-22 21:19:29 UTC (rev 126349)
@@ -1,3 +1,16 @@
+2012-08-22  Erik Arvidsson  <a...@chromium.org>
+
+        Changing class attribute is not reflected in the classList property
+        https://bugs.webkit.org/show_bug.cgi?id=93665
+
+        Reviewed by Ojan Vafai.
+
+        Before this change classAttributeChanged was only called for StyledElement. With this refactoring
+        it gets called for all Elements when the class attribute changes.
+
+        * fast/dom/Element/class-list-update-expected.txt: Added.
+        * fast/dom/Element/class-list-update.html: Added.
+
 2012-08-22  Kenneth Russell  <k...@google.com>
 
         [Chromium] Need baselines for new paged-x and paged-y tests in fast/overflow after r126343

Added: trunk/LayoutTests/fast/dom/Element/class-list-update-expected.txt (0 => 126349)


--- trunk/LayoutTests/fast/dom/Element/class-list-update-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/Element/class-list-update-expected.txt	2012-08-22 21:19:29 UTC (rev 126349)
@@ -0,0 +1,15 @@
+Tests that modifying the class attribute updates the classList on non HTMLElements
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS htmlElement.classList.length is 1
+PASS htmlElement.classList.length is 0
+PASS svgElement.classList.length is 1
+PASS svgElement.classList.length is 0
+PASS xmlElement.classList.length is 1
+PASS xmlElement.classList.length is 0
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/dom/Element/class-list-update.html (0 => 126349)


--- trunk/LayoutTests/fast/dom/Element/class-list-update.html	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/Element/class-list-update.html	2012-08-22 21:19:29 UTC (rev 126349)
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<script src=""
+<script>
+description('Tests that modifying the class attribute updates the classList on non HTMLElements');
+
+function updateAndTestClassAttr(varName) {
+    eval(varName + '.setAttribute("class", "' + varName + '")');
+    shouldBe(varName + '.classList.length', '1');
+    eval(varName + '.setAttribute("class", "")');
+    shouldBe(varName + '.classList.length', '0');
+}
+
+var htmlElement = document.createElement('div');
+updateAndTestClassAttr('htmlElement');
+
+var svgElement = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
+updateAndTestClassAttr('svgElement');
+
+var xmlElement = document.createElementNS('http://www.example.com', 'xml');
+updateAndTestClassAttr('xmlElement');
+
+</script>
+<script src=""

Modified: trunk/Source/WebCore/ChangeLog (126348 => 126349)


--- trunk/Source/WebCore/ChangeLog	2012-08-22 21:14:11 UTC (rev 126348)
+++ trunk/Source/WebCore/ChangeLog	2012-08-22 21:19:29 UTC (rev 126349)
@@ -1,3 +1,34 @@
+2012-08-22  Erik Arvidsson  <a...@chromium.org>
+
+        Changing class attribute is not reflected in the classList property
+        https://bugs.webkit.org/show_bug.cgi?id=93665
+
+        Reviewed by Ojan Vafai.
+
+        Before this change classAttributeChanged was only called for StyledElement. With this refactoring
+        it gets called for all Elements when the class attribute changes.
+
+        Test: fast/dom/Element/class-list-update.html
+
+        * css/StyleResolver.cpp:
+        (WebCore::StyleResolver::collectMatchingRules): To match the old behavior we only include StyledElements.
+        * dom/ClassNodeList.cpp:
+        (WebCore::ClassNodeList::nodeMatches): Ditto.
+        * dom/Element.cpp:
+        (WebCore::Element::attributeChanged): Moved the call to parseAttribute here, from StyledElement::attributeChanged.
+        (WebCore::Element::parseAttribute): Moved from StyledElement.
+        (WebCore):
+        (WebCore::Element::classAttributeChanged): Ditto.
+        * dom/Element.h:
+        (Element):
+        (WebCore::Element::classNames): Ditto.
+        (WebCore):
+        * dom/StyledElement.cpp:
+        (WebCore::StyledElement::attributeChanged): Let Element::attributeChanged call parseAttribtue instead.
+        (WebCore::StyledElement::parseAttribute): Move the class attribute handling to Element::parseAttribute.
+        * dom/StyledElement.h:
+        (StyledElement):
+
 2012-08-22  Kentaro Hara  <hara...@chromium.org>
 
         [V8] Replace v8::String::NewSymbol() in CodeGeneratorV8.pm with v8String()

Modified: trunk/Source/WebCore/css/StyleResolver.cpp (126348 => 126349)


--- trunk/Source/WebCore/css/StyleResolver.cpp	2012-08-22 21:14:11 UTC (rev 126348)
+++ trunk/Source/WebCore/css/StyleResolver.cpp	2012-08-22 21:19:29 UTC (rev 126349)
@@ -886,8 +886,7 @@
     // then sort the buffer.
     if (m_element->hasID())
         collectMatchingRulesForList(rules->idRules(m_element->idForStyleResolution().impl()), firstRuleIndex, lastRuleIndex, options);
-    if (m_element->hasClass()) {
-        ASSERT(m_styledElement);
+    if (m_styledElement && m_styledElement->hasClass()) {
         for (size_t i = 0; i < m_styledElement->classNames().size(); ++i)
             collectMatchingRulesForList(rules->classRules(m_styledElement->classNames()[i].impl()), firstRuleIndex, lastRuleIndex, options);
     }

Modified: trunk/Source/WebCore/dom/ClassNodeList.cpp (126348 => 126349)


--- trunk/Source/WebCore/dom/ClassNodeList.cpp	2012-08-22 21:14:11 UTC (rev 126348)
+++ trunk/Source/WebCore/dom/ClassNodeList.cpp	2012-08-22 21:19:29 UTC (rev 126349)
@@ -54,8 +54,11 @@
         return false;
     if (!m_classNames.size())
         return false;
-    ASSERT(testNode->isStyledElement());
-    return static_cast<StyledElement*>(testNode)->classNames().containsAll(m_classNames);
+    // FIXME: DOM4 allows getElementsByClassName to return non StyledElement.
+    // https://bugs.webkit.org/show_bug.cgi?id=94718
+    if (!testNode->isStyledElement())
+        return false;
+    return testNode->classNames().containsAll(m_classNames);
 }
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/dom/Element.cpp (126348 => 126349)


--- trunk/Source/WebCore/dom/Element.cpp	2012-08-22 21:14:11 UTC (rev 126348)
+++ trunk/Source/WebCore/dom/Element.cpp	2012-08-22 21:19:29 UTC (rev 126349)
@@ -696,6 +696,8 @@
 
 void Element::attributeChanged(const Attribute& attribute)
 {
+    parseAttribute(attribute);
+
     document()->incDOMTreeVersion();
 
     if (isIdAttributeName(attribute.name())) {
@@ -747,6 +749,34 @@
         document()->axObjectCache()->postNotification(this, AXObjectCache::AXInvalidStatusChanged, true);
 }
 
+void Element::parseAttribute(const Attribute& attribute)
+{
+    if (attribute.name() == classAttr)
+        classAttributeChanged(attribute.value());
+}
+
+void Element::classAttributeChanged(const AtomicString& newClassString)
+{
+    const UChar* characters = newClassString.characters();
+    unsigned length = newClassString.length();
+    unsigned i;
+    for (i = 0; i < length; ++i) {
+        if (isNotHTMLSpace(characters[i]))
+            break;
+    }
+    bool hasClass = i < length;
+    if (hasClass) {
+        const bool shouldFoldCase = document()->inQuirksMode();
+        ensureAttributeData()->setClass(newClassString, shouldFoldCase);
+    } else if (attributeData())
+        mutableAttributeData()->clearClass();
+
+    if (DOMTokenList* classList = optionalClassList())
+        static_cast<ClassList*>(classList)->reset(newClassString);
+
+    setNeedsStyleRecalc();
+}
+
 // Returns true is the given attribute is an event handler.
 // We consider an event handler any attribute that begins with "on".
 // It is a simple solution that has the advantage of not requiring any

Modified: trunk/Source/WebCore/dom/Element.h (126348 => 126349)


--- trunk/Source/WebCore/dom/Element.h	2012-08-22 21:14:11 UTC (rev 126348)
+++ trunk/Source/WebCore/dom/Element.h	2012-08-22 21:19:29 UTC (rev 126349)
@@ -246,6 +246,7 @@
 
     // This method is called whenever an attribute is added, changed or removed.
     virtual void attributeChanged(const Attribute&);
+    virtual void parseAttribute(const Attribute&);
 
     // Only called by the parser immediately after element construction.
     void parserSetAttributes(const Vector<Attribute>&, FragmentScriptingPermission);
@@ -428,6 +429,7 @@
 
     bool hasID() const;
     bool hasClass() const;
+    const SpaceSplitString& classNames() const;
 
     IntSize savedLayerScrollOffset() const;
     void setSavedLayerScrollOffset(const IntSize&);
@@ -461,6 +463,11 @@
     PassRefPtr<HTMLCollection> ensureCachedHTMLCollection(CollectionType);
     HTMLCollection* cachedHTMLCollection(CollectionType);
 
+    // classAttributeChanged() exists to share code between
+    // parseAttribute (called via setAttribute()) and
+    // svgAttributeChanged (called when element.className.baseValue is set)
+    void classAttributeChanged(const AtomicString& newClassString);
+
 private:
     void updateInvalidAttributes() const;
 
@@ -687,6 +694,13 @@
     setAttribute(document()->idAttributeName(), value);
 }
 
+inline const SpaceSplitString& Element::classNames() const
+{
+    ASSERT(hasClass());
+    ASSERT(attributeData());
+    return attributeData()->classNames();
+}
+
 inline size_t Element::attributeCount() const
 {
     ASSERT(attributeData());

Modified: trunk/Source/WebCore/dom/StyledElement.cpp (126348 => 126349)


--- trunk/Source/WebCore/dom/StyledElement.cpp	2012-08-22 21:14:11 UTC (rev 126348)
+++ trunk/Source/WebCore/dom/StyledElement.cpp	2012-08-22 21:19:29 UTC (rev 126349)
@@ -147,8 +147,6 @@
 
 void StyledElement::attributeChanged(const Attribute& attribute)
 {
-    parseAttribute(attribute);
-
     if (isPresentationAttribute(attribute.name())) {
         setAttributeStyleDirty();
         setNeedsStyleRecalc(InlineStyleChange);
@@ -157,28 +155,6 @@
     Element::attributeChanged(attribute);
 }
 
-void StyledElement::classAttributeChanged(const AtomicString& newClassString)
-{
-    const UChar* characters = newClassString.characters();
-    unsigned length = newClassString.length();
-    unsigned i;
-    for (i = 0; i < length; ++i) {
-        if (isNotHTMLSpace(characters[i]))
-            break;
-    }
-    bool hasClass = i < length;
-    if (hasClass) {
-        const bool shouldFoldCase = document()->inQuirksMode();
-        ensureAttributeData()->setClass(newClassString, shouldFoldCase);
-    } else if (attributeData())
-        mutableAttributeData()->clearClass();
-
-    if (DOMTokenList* classList = optionalClassList())
-        static_cast<ClassList*>(classList)->reset(newClassString);
-
-    setNeedsStyleRecalc();
-}
-
 void StyledElement::styleAttributeChanged(const AtomicString& newStyleString, ShouldReparseStyleAttribute shouldReparse)
 {
     if (shouldReparse) {
@@ -197,10 +173,10 @@
 
 void StyledElement::parseAttribute(const Attribute& attribute)
 {
-    if (attribute.name() == classAttr)
-        classAttributeChanged(attribute.value());
-    else if (attribute.name() == styleAttr)
+    if (attribute.name() == styleAttr)
         styleAttributeChanged(attribute.value());
+    else
+        Element::parseAttribute(attribute);
 }
 
 void StyledElement::inlineStyleChanged()

Modified: trunk/Source/WebCore/dom/StyledElement.h (126348 => 126349)


--- trunk/Source/WebCore/dom/StyledElement.h	2012-08-22 21:14:11 UTC (rev 126348)
+++ trunk/Source/WebCore/dom/StyledElement.h	2012-08-22 21:19:29 UTC (rev 126349)
@@ -53,8 +53,6 @@
 
     const StylePropertySet* attributeStyle();
 
-    const SpaceSplitString& classNames() const;
-
     virtual void collectStyleForAttribute(const Attribute&, StylePropertySet*) { }
 
     // May be called by ElementAttributeData::cloneDataFrom().
@@ -65,7 +63,7 @@
     StyledElement(const QualifiedName&, Document*, ConstructionType);
 
     virtual void attributeChanged(const Attribute&) OVERRIDE;
-    virtual void parseAttribute(const Attribute&);
+    virtual void parseAttribute(const Attribute&) OVERRIDE;
 
     virtual bool isPresentationAttribute(const QualifiedName&) const { return false; }
 
@@ -75,11 +73,6 @@
 
     virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
 
-    // classAttributeChanged() exists to share code between
-    // parseAttribute (called via setAttribute()) and
-    // svgAttributeChanged (called when element.className.baseValue is set)
-    void classAttributeChanged(const AtomicString& newClassString);
-
 private:
     virtual void updateStyleAttribute() const;
     void inlineStyleChanged();
@@ -94,13 +87,6 @@
     }
 };
 
-inline const SpaceSplitString& StyledElement::classNames() const
-{
-    ASSERT(hasClass());
-    ASSERT(attributeData());
-    return attributeData()->classNames();
-}
-
 inline void StyledElement::invalidateStyleAttribute()
 {
     clearIsStyleAttributeValid();
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to