Unreviewed, rolling out r196470.
https://bugs.webkit.org/show_bug.cgi?id=154167

Broke some tests (Requested by anttik on #webkit).

Reverted changeset:

"Factor class change style invalidation code into a class"
https://bugs.webkit.org/show_bug.cgi?id=154163
http://trac.webkit.org/changeset/196470

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@196473 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/CMakeLists.txt b/Source/WebCore/CMakeLists.txt
index 0e722fb..7b52306 100644
--- a/Source/WebCore/CMakeLists.txt
+++ b/Source/WebCore/CMakeLists.txt
@@ -2621,7 +2621,6 @@
     storage/StorageMap.cpp
     storage/StorageNamespaceProvider.cpp
 
-    style/ClassChangeInvalidation.cpp
     style/InlineTextBoxStyle.cpp
     style/RenderTreePosition.cpp
     style/StyleChange.cpp
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 429d344..0b59aa8 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,16 @@
+2016-02-12  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r196470.
+        https://bugs.webkit.org/show_bug.cgi?id=154167
+
+        Broke some tests (Requested by anttik on #webkit).
+
+        Reverted changeset:
+
+        "Factor class change style invalidation code into a class"
+        https://bugs.webkit.org/show_bug.cgi?id=154163
+        http://trac.webkit.org/changeset/196470
+
 2016-02-12  Antti Koivisto  <antti@apple.com>
 
         Factor class change style invalidation code into a class
diff --git a/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj b/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj
index 47f883f..c5b47ec 100644
--- a/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj
+++ b/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj
@@ -19225,7 +19225,6 @@
     <ClCompile Include="..\storage\StorageEventDispatcher.cpp" />
     <ClCompile Include="..\storage\StorageMap.cpp" />
     <ClCompile Include="..\storage\StorageNamespaceProvider.cpp" />
-    <ClCompile Include="..\style\ClassChangeInvalidation.cpp" />
     <ClCompile Include="..\style\InlineTextBoxStyle.cpp" />
     <ClCompile Include="..\style\RenderTreePosition.cpp" />
     <ClCompile Include="..\style\StyleChange.cpp" />
@@ -22792,7 +22791,6 @@
     <ClInclude Include="..\storage\StorageMap.h" />
     <ClInclude Include="..\storage\StorageNamespace.h" />
     <ClInclude Include="..\storage\StorageNamespaceProvider.h" />
-    <ClInclude Include="..\style\ClassChangeInvalidation.h" />
     <ClInclude Include="..\style\InlineTextBoxStyle.h" />
     <ClInclude Include="..\style\RenderTreePosition.h" />
     <ClInclude Include="..\style\StyleChange.h" />
diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
index bce896e..87a9c30 100644
--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
@@ -6617,8 +6617,6 @@
 		E49BDA0B131FD3E5003C56F0 /* CSSValuePool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E49BDA0A131FD3E5003C56F0 /* CSSValuePool.cpp */; };
 		E4A007831B820EC8002C5A6E /* DataURLDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = E4A007821B820EC8002C5A6E /* DataURLDecoder.h */; };
 		E4A007851B820ED3002C5A6E /* DataURLDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4A007841B820ED3002C5A6E /* DataURLDecoder.cpp */; };
-		E4A814D41C6DEC4000BF85AC /* ClassChangeInvalidation.h in Headers */ = {isa = PBXBuildFile; fileRef = E4A814D31C6DEC4000BF85AC /* ClassChangeInvalidation.h */; };
-		E4A814D61C6DEE8D00BF85AC /* ClassChangeInvalidation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4A814D51C6DEE8D00BF85AC /* ClassChangeInvalidation.cpp */; };
 		E4AE7C1617D1BB950009FB31 /* ElementIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = E4AE7C1517D1BB950009FB31 /* ElementIterator.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E4AE7C1A17D232350009FB31 /* ElementAncestorIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = E4AE7C1917D232350009FB31 /* ElementAncestorIterator.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E4AFCFA50DAF29A300F5F55C /* UnitBezier.h in Headers */ = {isa = PBXBuildFile; fileRef = E4AFCFA40DAF29A300F5F55C /* UnitBezier.h */; };
@@ -14603,8 +14601,6 @@
 		E49BDA0A131FD3E5003C56F0 /* CSSValuePool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSSValuePool.cpp; sourceTree = "<group>"; };
 		E4A007821B820EC8002C5A6E /* DataURLDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataURLDecoder.h; sourceTree = "<group>"; };
 		E4A007841B820ED3002C5A6E /* DataURLDecoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DataURLDecoder.cpp; sourceTree = "<group>"; };
-		E4A814D31C6DEC4000BF85AC /* ClassChangeInvalidation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ClassChangeInvalidation.h; sourceTree = "<group>"; };
-		E4A814D51C6DEE8D00BF85AC /* ClassChangeInvalidation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ClassChangeInvalidation.cpp; sourceTree = "<group>"; };
 		E4AE7C1517D1BB950009FB31 /* ElementIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ElementIterator.h; sourceTree = "<group>"; };
 		E4AE7C1917D232350009FB31 /* ElementAncestorIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ElementAncestorIterator.h; sourceTree = "<group>"; };
 		E4AFCFA40DAF29A300F5F55C /* UnitBezier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnitBezier.h; sourceTree = "<group>"; };
@@ -23381,8 +23377,6 @@
 		E4763D4A17B2704900D35206 /* style */ = {
 			isa = PBXGroup;
 			children = (
-				E4A814D51C6DEE8D00BF85AC /* ClassChangeInvalidation.cpp */,
-				E4A814D31C6DEC4000BF85AC /* ClassChangeInvalidation.h */,
 				1C0106FE192594DF008A4201 /* InlineTextBoxStyle.cpp */,
 				1C0106FF192594DF008A4201 /* InlineTextBoxStyle.h */,
 				5824ABA81AE849C8009074B7 /* RenderTreePosition.cpp */,
@@ -25934,7 +25928,6 @@
 				B2C3DA6C0D006CD600EF6F26 /* GlyphBuffer.h in Headers */,
 				C5D4AA7A116BAFB60069CA93 /* GlyphMetricsMap.h in Headers */,
 				0873B86B136064EA00A522C2 /* GlyphPage.h in Headers */,
-				E4A814D41C6DEC4000BF85AC /* ClassChangeInvalidation.h in Headers */,
 				BC53C5F50DA56B920021EB5D /* Gradient.h in Headers */,
 				B22279640D00BF220071B782 /* GradientAttributes.h in Headers */,
 				2D481F04146B5C6B00AA7834 /* GradientImage.h in Headers */,
@@ -30209,7 +30202,6 @@
 				511EF2C717F0FD3500E4FA16 /* JSIDBObjectStore.cpp in Sources */,
 				511EF2D117F0FDF100E4FA16 /* JSIDBObjectStoreCustom.cpp in Sources */,
 				511EF2C817F0FD3500E4FA16 /* JSIDBOpenDBRequest.cpp in Sources */,
-				E4A814D61C6DEE8D00BF85AC /* ClassChangeInvalidation.cpp in Sources */,
 				511EF2C917F0FD3500E4FA16 /* JSIDBRequest.cpp in Sources */,
 				511EF2CA17F0FD3500E4FA16 /* JSIDBTransaction.cpp in Sources */,
 				511EF2CB17F0FD3500E4FA16 /* JSIDBVersionChangeEvent.cpp in Sources */,
diff --git a/Source/WebCore/dom/Element.cpp b/Source/WebCore/dom/Element.cpp
index 7f9af01..4088d84 100644
--- a/Source/WebCore/dom/Element.cpp
+++ b/Source/WebCore/dom/Element.cpp
@@ -31,7 +31,6 @@
 #include "CSSParser.h"
 #include "Chrome.h"
 #include "ChromeClient.h"
-#include "ClassChangeInvalidation.h"
 #include "ClientRect.h"
 #include "ClientRectList.h"
 #include "ComposedTreeAncestorIterator.h"
@@ -77,6 +76,7 @@
 #include "ScrollLatchingState.h"
 #include "SelectorQuery.h"
 #include "Settings.h"
+#include "StyleInvalidationAnalysis.h"
 #include "StyleProperties.h"
 #include "StyleResolver.h"
 #include "StyleTreeResolver.h"
@@ -1299,6 +1299,91 @@
     return classStringHasClassName(newClassString.characters16(), length);
 }
 
+static Vector<AtomicStringImpl*, 4> collectClasses(const SpaceSplitString& classes)
+{
+    Vector<AtomicStringImpl*, 4> result;
+    result.reserveCapacity(classes.size());
+    for (unsigned i = 0; i < classes.size(); ++i)
+        result.uncheckedAppend(classes[i].impl());
+    return result;
+}
+
+struct ClassChange {
+    Vector<AtomicStringImpl*, 4> added;
+    Vector<AtomicStringImpl*, 4> removed;
+};
+
+static ClassChange computeClassChange(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses)
+{
+    ClassChange classChange;
+
+    unsigned oldSize = oldClasses.size();
+    unsigned newSize = newClasses.size();
+
+    if (!oldSize) {
+        classChange.added = collectClasses(newClasses);
+        return classChange;
+    }
+    if (!newSize) {
+        classChange.removed = collectClasses(oldClasses);
+        return classChange;
+    }
+
+    BitVector remainingClassBits;
+    remainingClassBits.ensureSize(oldSize);
+    // Class vectors tend to be very short. This is faster than using a hash table.
+    for (unsigned i = 0; i < newSize; ++i) {
+        bool foundFromBoth = false;
+        for (unsigned j = 0; j < oldSize; ++j) {
+            if (newClasses[i] == oldClasses[j]) {
+                remainingClassBits.quickSet(j);
+                foundFromBoth = true;
+            }
+        }
+        if (foundFromBoth)
+            continue;
+        classChange.added.append(newClasses[i].impl());
+    }
+    for (unsigned i = 0; i < oldSize; ++i) {
+        // If the bit is not set the the corresponding class has been removed.
+        if (remainingClassBits.quickGet(i))
+            continue;
+        classChange.removed.append(oldClasses[i].impl());
+    }
+
+    return classChange;
+}
+
+static void invalidateStyleForClassChange(Element& element, const Vector<AtomicStringImpl*, 4>& changedClasses, const DocumentRuleSets& ruleSets)
+{
+    Vector<AtomicStringImpl*, 4> changedClassesAffectingStyle;
+    for (auto* changedClass : changedClasses) {
+        if (ruleSets.features().classesInRules.contains(changedClass))
+            changedClassesAffectingStyle.append(changedClass);
+    };
+
+    if (changedClassesAffectingStyle.isEmpty())
+        return;
+
+    if (element.shadowRoot() && ruleSets.authorStyle()->hasShadowPseudoElementRules()) {
+        element.setNeedsStyleRecalc(FullStyleChange);
+        return;
+    }
+
+    element.setNeedsStyleRecalc(InlineStyleChange);
+
+    if (!element.firstElementChild())
+        return;
+
+    for (auto* changedClass : changedClassesAffectingStyle) {
+        auto* ancestorClassRules = ruleSets.ancestorClassRules(changedClass);
+        if (!ancestorClassRules)
+            continue;
+        StyleInvalidationAnalysis invalidationAnalysis(*ancestorClassRules);
+        invalidationAnalysis.invalidateStyle(element);
+    }
+}
+
 void Element::classAttributeChanged(const AtomicString& newClassString)
 {
     // Note: We'll need ElementData, but it doesn't have to be UniqueElementData.
@@ -1310,9 +1395,22 @@
 
     auto oldClassNames = elementData()->classNames();
     auto newClassNames = newStringHasClasses ? SpaceSplitString(newClassString, shouldFoldCase) : SpaceSplitString();
-    {
-        Style::ClassChangeInvalidation styleInvalidation(*this, oldClassNames, newClassNames);
-        elementData()->setClassNames(newClassNames);
+
+    StyleResolver* styleResolver = document().styleResolverIfExists();
+    bool shouldInvalidateStyle = inRenderedDocument() && styleResolver && styleChangeType() < FullStyleChange;
+
+    ClassChange classChange;
+    if (shouldInvalidateStyle) {
+        classChange = computeClassChange(oldClassNames, newClassNames);
+        if (!classChange.removed.isEmpty())
+            invalidateStyleForClassChange(*this, classChange.removed, styleResolver->ruleSets());
+    }
+
+    elementData()->setClassNames(newClassNames);
+
+    if (shouldInvalidateStyle) {
+        if (!classChange.added.isEmpty())
+            invalidateStyleForClassChange(*this, classChange.added, styleResolver->ruleSets());
     }
 
     if (hasRareData()) {
diff --git a/Source/WebCore/style/ClassChangeInvalidation.cpp b/Source/WebCore/style/ClassChangeInvalidation.cpp
deleted file mode 100644
index b1c740d..0000000
--- a/Source/WebCore/style/ClassChangeInvalidation.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "ClassChangeInvalidation.h"
-
-#include "DocumentRuleSets.h"
-#include "ElementChildIterator.h"
-#include "SpaceSplitString.h"
-#include "StyleInvalidationAnalysis.h"
-
-namespace WebCore {
-namespace Style {
-
-auto ClassChangeInvalidation::collectClasses(const SpaceSplitString& classes) -> ClassChangeVector
-{
-    ClassChangeVector result;
-    result.reserveCapacity(classes.size());
-    for (unsigned i = 0; i < classes.size(); ++i)
-        result.uncheckedAppend(classes[i].impl());
-    return result;
-}
-
-void ClassChangeInvalidation::computeClassChange(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses)
-{
-    unsigned oldSize = oldClasses.size();
-    unsigned newSize = newClasses.size();
-
-    if (!oldSize) {
-        m_addedClasses = collectClasses(newClasses);
-        return;
-    }
-    if (!newSize) {
-        m_removedClasses = collectClasses(oldClasses);
-        return;
-    }
-
-    BitVector remainingClassBits;
-    remainingClassBits.ensureSize(oldSize);
-    // Class vectors tend to be very short. This is faster than using a hash table.
-    for (unsigned i = 0; i < newSize; ++i) {
-        bool foundFromBoth = false;
-        for (unsigned j = 0; j < oldSize; ++j) {
-            if (newClasses[i] == oldClasses[j]) {
-                remainingClassBits.quickSet(j);
-                foundFromBoth = true;
-            }
-        }
-        if (foundFromBoth)
-            continue;
-        m_addedClasses.append(newClasses[i].impl());
-    }
-    for (unsigned i = 0; i < oldSize; ++i) {
-        // If the bit is not set the the corresponding class has been removed.
-        if (remainingClassBits.quickGet(i))
-            continue;
-        m_removedClasses.append(oldClasses[i].impl());
-    }
-}
-
-void ClassChangeInvalidation::invalidateStyle(const ClassChangeVector& changedClasses)
-{
-    auto& ruleSets = m_element.styleResolver().ruleSets();
-
-    Vector<AtomicStringImpl*, 4> changedClassesAffectingStyle;
-    for (auto* changedClass : changedClasses) {
-        if (ruleSets.features().classesInRules.contains(changedClass))
-            changedClassesAffectingStyle.append(changedClass);
-    };
-
-    if (changedClassesAffectingStyle.isEmpty())
-        return;
-
-    if (m_element.shadowRoot() && ruleSets.authorStyle()->hasShadowPseudoElementRules()) {
-        m_element.setNeedsStyleRecalc(FullStyleChange);
-        return;
-    }
-
-    m_element.setNeedsStyleRecalc(InlineStyleChange);
-
-    if (!childrenOfType<Element>(m_element).first())
-        return;
-
-    for (auto* changedClass : changedClassesAffectingStyle) {
-        auto* ancestorClassRules = ruleSets.ancestorClassRules(changedClass);
-        if (!ancestorClassRules)
-            continue;
-        StyleInvalidationAnalysis invalidationAnalysis(*ancestorClassRules);
-        invalidationAnalysis.invalidateStyle(m_element);
-    }
-}
-
-}
-}
diff --git a/Source/WebCore/style/ClassChangeInvalidation.h b/Source/WebCore/style/ClassChangeInvalidation.h
deleted file mode 100644
index 955a761..0000000
--- a/Source/WebCore/style/ClassChangeInvalidation.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ClassChangeInvalidation_h
-#define ClassChangeInvalidation_h
-
-#include "Document.h"
-#include "Element.h"
-#include "StyleResolver.h"
-#include <wtf/Vector.h>
-
-namespace WebCore {
-
-class DocumentRuleSets;
-class SpaceSplitString;
-
-namespace Style {
-
-class ClassChangeInvalidation {
-public:
-    ClassChangeInvalidation(Element&, const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses);
-    ~ClassChangeInvalidation();
-
-private:
-    using ClassChangeVector = Vector<AtomicStringImpl*, 4>;
-
-    static bool needsInvalidation(const Element&);
-    void computeClassChange(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses);
-    void invalidateStyle(const ClassChangeVector&);
-
-    static ClassChangeVector collectClasses(const SpaceSplitString&);
-
-    const bool m_isEnabled;
-    Element& m_element;
-
-    ClassChangeVector m_addedClasses;
-    ClassChangeVector m_removedClasses;
-};
-
-inline bool ClassChangeInvalidation::needsInvalidation(const Element& element)
-{
-    if (!element.inRenderedDocument())
-        return false;
-    if (element.styleChangeType() >= FullStyleChange)
-        return false;
-    if (!element.document().styleResolverIfExists() && &element.treeScope() == &element.document())
-        return false;
-    return true;
-}
-
-inline ClassChangeInvalidation::ClassChangeInvalidation(Element& element, const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses)
-    : m_isEnabled(needsInvalidation(element))
-    , m_element(element)
-
-{
-    if (!m_isEnabled)
-        return;
-    computeClassChange(oldClasses, newClasses);
-    invalidateStyle(m_removedClasses);
-}
-
-inline ClassChangeInvalidation::~ClassChangeInvalidation()
-{
-    if (!m_isEnabled)
-        return;
-    invalidateStyle(m_addedClasses);
-}
-    
-}
-}
-
-#endif
-