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();