⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 286091 in webkit


Ignore:
Timestamp:
Nov 19, 2021, 10:40:27 PM (5 years ago)
Author:
commit-queue@webkit.org
Message:

Unreviewed, reverting r286058.
https://bugs.webkit.org/show_bug.cgi?id=233394

Speedometer2 is crashing

Reverted changeset:

"Factor child change invalidation into class"
https://bugs.webkit.org/show_bug.cgi?id=233311
https://commits.webkit.org/r286058

Location:
trunk/Source/WebCore
Files:
2 deleted
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r286086 r286091  
     12021-11-19  Commit Queue  <commit-queue@webkit.org>
     2
     3        Unreviewed, reverting r286058.
     4        https://bugs.webkit.org/show_bug.cgi?id=233394
     5
     6        Speedometer2 is crashing
     7
     8        Reverted changeset:
     9
     10        "Factor child change invalidation into class"
     11        https://bugs.webkit.org/show_bug.cgi?id=233311
     12        https://commits.webkit.org/r286058
     13
    1142021-11-19  Kiet Ho  <tho22@apple.com>
    215
  • trunk/Source/WebCore/Sources.txt

    r286086 r286091  
    25252525storage/StorageQuotaManager.cpp
    25262526style/AttributeChangeInvalidation.cpp
    2527 style/ChildChangeInvalidation.cpp
    25282527style/ClassChangeInvalidation.cpp
    25292528style/ElementRuleCollector.cpp
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r286086 r286091  
    53435343                E4C279590CF9741900E97B98 /* RenderMedia.h in Headers */ = {isa = PBXBuildFile; fileRef = E4C279570CF9741900E97B98 /* RenderMedia.h */; settings = {ATTRIBUTES = (Private, ); }; };
    53445344                E4C3B1FA0F0E4161009693F6 /* LegacyTileCache.h in Headers */ = {isa = PBXBuildFile; fileRef = E4C3B1F90F0E4161009693F6 /* LegacyTileCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
    5345                 E4C4C61A27452A7900A040E7 /* ChildChangeInvalidation.h in Headers */ = {isa = PBXBuildFile; fileRef = E4C4C61827452A7900A040E7 /* ChildChangeInvalidation.h */; };
    53465345                E4C91A0E1802343100A17F6D /* TextPaintStyle.h in Headers */ = {isa = PBXBuildFile; fileRef = E4C91A0D1802343100A17F6D /* TextPaintStyle.h */; };
    53475346                E4C91A16180999F100A17F6D /* RenderTextLineBoxes.h in Headers */ = {isa = PBXBuildFile; fileRef = E4C91A15180999F100A17F6D /* RenderTextLineBoxes.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    1704817047                E4C3B1F90F0E4161009693F6 /* LegacyTileCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LegacyTileCache.h; sourceTree = "<group>"; };
    1704917048                E4C3B1FB0F0E4170009693F6 /* LegacyTileCache.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = LegacyTileCache.mm; sourceTree = "<group>"; };
    17050                 E4C4C61827452A7900A040E7 /* ChildChangeInvalidation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ChildChangeInvalidation.h; sourceTree = "<group>"; };
    17051                 E4C4C61B27452A8A00A040E7 /* ChildChangeInvalidation.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ChildChangeInvalidation.cpp; sourceTree = "<group>"; };
    1705217049                E4C91A0D1802343100A17F6D /* TextPaintStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextPaintStyle.h; sourceTree = "<group>"; };
    1705317050                E4C91A0F1802343900A17F6D /* TextPaintStyle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextPaintStyle.cpp; sourceTree = "<group>"; };
     
    3028630283                                E4A814D91C70E10D00BF85AC /* AttributeChangeInvalidation.h */,
    3028730284                                E4ABABF42368C6EF00FA4345 /* CascadeLevel.h */,
    30288                                 E4C4C61B27452A8A00A040E7 /* ChildChangeInvalidation.cpp */,
    30289                                 E4C4C61827452A7900A040E7 /* ChildChangeInvalidation.h */,
    3029030285                                E4A814D51C6DEE8D00BF85AC /* ClassChangeInvalidation.cpp */,
    3029130286                                E4A814D31C6DEC4000BF85AC /* ClassChangeInvalidation.h */,
     
    3274332738                                97B8FFD116AE7F960038388D /* CharacterReferenceParserInlines.h in Headers */,
    3274432739                                F55B3DB21251F12D003EF269 /* CheckboxInputType.h in Headers */,
    32745                                 E4C4C61A27452A7900A040E7 /* ChildChangeInvalidation.h in Headers */,
    3274632740                                D619A308144E00BE004BC302 /* ChildListMutationScope.h in Headers */,
    3274732741                                A81872200977D3C0005826D9 /* ChildNodeList.h in Headers */,
  • trunk/Source/WebCore/dom/CharacterData.cpp

    r286058 r286091  
    2424
    2525#include "Attr.h"
    26 #include "ChildChangeInvalidation.h"
    2726#include "ElementTraversal.h"
    2827#include "EventNames.h"
     
    7574}
    7675
    77 static ContainerNode::ChildChange makeChildChange(CharacterData& characterData, ContainerNode::ChildChange::Source source)
    78 {
    79     return {
    80         ContainerNode::ChildChange::Type::TextChanged,
    81         ElementTraversal::previousSibling(characterData),
    82         ElementTraversal::nextSibling(characterData),
    83         source
    84     };
    85 }
    86 
    8776unsigned CharacterData::parserAppendData(const String& string, unsigned offset, unsigned lengthLimit)
    8877{
     
    10796        return 0;
    10897
    109     auto childChange = makeChildChange(*this, ContainerNode::ChildChange::Source::Parser);
    110     std::optional<Style::ChildChangeInvalidation> styleInvalidation;
    111     if (auto* parent = parentNode())
    112         styleInvalidation.emplace(*parent, childChange);
    113 
    11498    String oldData = m_data;
    11599    if (string.is8Bit())
     
    122106        downcast<Text>(*this).updateRendererAfterContentChange(oldLength, 0);
    123107
    124     notifyParentAfterChange(childChange);
     108    notifyParentAfterChange(ContainerNode::ChildChange::Source::Parser);
    125109
    126110    auto mutationRecipients = MutationObserverInterestGroup::createForCharacterDataMutation(*this);
     
    190174void CharacterData::setDataAndUpdate(const String& newData, unsigned offsetOfReplacedData, unsigned oldLength, unsigned newLength, UpdateLiveRanges shouldUpdateLiveRanges)
    191175{
    192     auto childChange = makeChildChange(*this, ContainerNode::ChildChange::Source::API);
    193 
    194     std::optional<Style::ChildChangeInvalidation> styleInvalidation;
    195     if (auto* parent = parentNode())
    196         styleInvalidation.emplace(*parent, childChange);
    197 
    198176    String oldData = m_data;
    199177    m_data = newData;
     
    214192        document().frame()->selection().textWasReplaced(this, offsetOfReplacedData, oldLength, newLength);
    215193
    216     notifyParentAfterChange(childChange);
     194    notifyParentAfterChange(ContainerNode::ChildChange::Source::API);
    217195
    218196    dispatchModifiedEvent(oldData);
    219197}
    220198
    221 void CharacterData::notifyParentAfterChange(const ContainerNode::ChildChange& childChange)
     199void CharacterData::notifyParentAfterChange(ContainerNode::ChildChange::Source source)
    222200{
    223201    document().incDOMTreeVersion();
     
    226204        return;
    227205
    228     parentNode()->childrenChanged(childChange);
     206    ContainerNode::ChildChange change = {
     207        ContainerNode::ChildChange::Type::TextChanged,
     208        ElementTraversal::previousSibling(*this),
     209        ElementTraversal::nextSibling(*this),
     210        source
     211    };
     212
     213    parentNode()->childrenChanged(change);
    229214}
    230215
  • trunk/Source/WebCore/dom/CharacterData.h

    r286058 r286091  
    6666    String nodeValue() const final;
    6767    ExceptionOr<void> setNodeValue(const String&) final;
    68     void notifyParentAfterChange(const ContainerNode::ChildChange&);
     68    void notifyParentAfterChange(ContainerNode::ChildChange::Source);
    6969
    7070    String m_data;
  • trunk/Source/WebCore/dom/ContainerNode.cpp

    r286058 r286091  
    2626#include "AXObjectCache.h"
    2727#include "AllDescendantsCollection.h"
    28 #include "ChildChangeInvalidation.h"
    2928#include "ChildListMutationScope.h"
    3029#include "ClassCollection.h"
     
    113112    disconnectSubframesIfNeeded(*this, DescendantsOnly);
    114113
    115     ContainerNode::ChildChange childChange { ChildChange::Type::AllChildrenRemoved, nullptr, nullptr, source };
    116 
    117114    WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates;
    118115    ScriptDisallowedScope::InMainThread scriptDisallowedScope;
    119     {
    120         Style::ChildChangeInvalidation styleInvalidation(*this, childChange);
    121 
    122         if (UNLIKELY(isShadowRoot() || isInShadowTree()))
    123             containingShadowRoot()->willRemoveAllChildren(*this);
    124 
    125         document().nodeChildrenWillBeRemoved(*this);
    126 
    127         while (RefPtr<Node> child = m_firstChild) {
    128             removeBetween(nullptr, child->nextSibling(), *child);
    129             auto subtreeObservability = notifyChildNodeRemoved(*this, *child);
    130             if (source == ChildChange::Source::API && subtreeObservability == RemovedSubtreeObservability::MaybeObservableByRefPtr)
    131                 willCreatePossiblyOrphanedTreeByRemoval(child.get());
    132         }
     116
     117    if (UNLIKELY(isShadowRoot() || isInShadowTree()))
     118        containingShadowRoot()->willRemoveAllChildren(*this);
     119
     120    document().nodeChildrenWillBeRemoved(*this);
     121
     122    while (RefPtr<Node> child = m_firstChild) {
     123        removeBetween(nullptr, child->nextSibling(), *child);
     124        auto subtreeObservability = notifyChildNodeRemoved(*this, *child);
     125        if (source == ChildChange::Source::API && subtreeObservability == RemovedSubtreeObservability::MaybeObservableByRefPtr)
     126            willCreatePossiblyOrphanedTreeByRemoval(child.get());
    133127    }
    134128
     
    136130
    137131    if (deferChildrenChanged == DeferChildrenChanged::No)
    138         childrenChanged(childChange);
     132        childrenChanged(ContainerNode::ChildChange { ChildChange::Type::AllChildrenRemoved, nullptr, nullptr, source });
    139133
    140134    return children;
    141 }
    142 
    143 static ContainerNode::ChildChange makeChildChangeForRemoval(Node& childToRemove, ContainerNode::ChildChange::Source source)
    144 {
    145     auto changeType = [&] {
    146         if (is<Element>(childToRemove))
    147             return ContainerNode::ChildChange::Type::ElementRemoved;
    148         if (is<Text>(childToRemove))
    149             return ContainerNode::ChildChange::Type::TextRemoved;
    150         return ContainerNode::ChildChange::Type::NonContentsChildRemoved;
    151     }();
    152 
    153     return {
    154         changeType,
    155         ElementTraversal::previousSibling(childToRemove),
    156         ElementTraversal::nextSibling(childToRemove),
    157         source
    158     };
    159135}
    160136
     
    187163        return false;
    188164
    189     auto childChange = makeChildChangeForRemoval(childToRemove, source);
    190 
     165    ChildChange change;
    191166    RemovedSubtreeObservability subtreeObservability;
    192167    {
    193168        WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates;
    194169        ScriptDisallowedScope::InMainThread scriptDisallowedScope;
    195         Style::ChildChangeInvalidation styleInvalidation(*this, childChange);
    196170
    197171        if (UNLIKELY(isShadowRoot() || isInShadowTree()))
     
    205179        RefPtr<Node> previousSibling = childToRemove.previousSibling();
    206180        RefPtr<Node> nextSibling = childToRemove.nextSibling();
    207 
    208181        removeBetween(previousSibling.get(), nextSibling.get(), childToRemove);
    209182        subtreeObservability = notifyChildNodeRemoved(*this, childToRemove);
     183
     184        change.type = is<Element>(childToRemove) ?
     185            ChildChange::Type::ElementRemoved :
     186            (is<Text>(childToRemove) ?
     187                ChildChange::Type::TextRemoved :
     188                ChildChange::Type::NonContentsChildRemoved);
     189        change.previousSiblingElement = (!previousSibling || is<Element>(*previousSibling)) ? downcast<Element>(previousSibling.get()) : ElementTraversal::previousSibling(*previousSibling);
     190        change.nextSiblingElement = (!nextSibling || is<Element>(*nextSibling)) ? downcast<Element>(nextSibling.get()) : ElementTraversal::nextSibling(*nextSibling);
     191        change.source = source;
    210192    }
    211193
     
    216198
    217199    // FIXME: Move childrenChanged into ScriptDisallowedScope block.
    218     childrenChanged(childChange);
     200    childrenChanged(change);
    219201
    220202    return true;
     
    223205enum class ReplacedAllChildren { No, Yes };
    224206
    225 static ContainerNode::ChildChange makeChildChangeForInsertion(ContainerNode& containerNode, Node& child, Node* beforeChild, ContainerNode::ChildChange::Source source, ReplacedAllChildren replacedAllChildren)
    226 {
    227     if (replacedAllChildren == ReplacedAllChildren::Yes)
    228         return { ContainerNode::ChildChange::Type::AllChildrenReplaced, nullptr, nullptr, source };
    229 
    230     auto changeType = [&] {
    231         if (is<Element>(child))
    232             return ContainerNode::ChildChange::Type::ElementInserted;
    233         if (is<Text>(child))
    234             return ContainerNode::ChildChange::Type::TextInserted;
    235         return ContainerNode::ChildChange::Type::NonContentsChildInserted;
    236     }();
    237 
    238     return {
    239         changeType,
    240         beforeChild ? ElementTraversal::previousSibling(*beforeChild) : ElementTraversal::lastChild(containerNode),
    241         !beforeChild || is<Element>(*beforeChild) ? downcast<Element>(beforeChild) : ElementTraversal::nextSibling(*beforeChild),
    242         source
    243     };
    244 }
    245 
    246207template<typename DOMInsertionWork>
    247 static ALWAYS_INLINE void executeNodeInsertionWithScriptAssertion(ContainerNode& containerNode, Node& child, Node* beforeChild,
     208static ALWAYS_INLINE void executeNodeInsertionWithScriptAssertion(ContainerNode& containerNode, Node& child,
    248209    ContainerNode::ChildChange::Source source, ReplacedAllChildren replacedAllChildren, DOMInsertionWork doNodeInsertion)
    249210{
    250     auto childChange = makeChildChangeForInsertion(containerNode, child, beforeChild, source, replacedAllChildren);
    251 
    252211    NodeVector postInsertionNotificationTargets;
    253212    {
    254213        WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates;
    255214        ScriptDisallowedScope::InMainThread scriptDisallowedScope;
    256         Style::ChildChangeInvalidation styleInvalidation(containerNode, childChange);
    257215
    258216        if (UNLIKELY(containerNode.isShadowRoot() || containerNode.isInShadowTree()))
     
    265223
    266224    // FIXME: Move childrenChanged into ScriptDisallowedScope block.
    267     containerNode.childrenChanged(childChange);
     225    if (replacedAllChildren == ReplacedAllChildren::Yes)
     226        containerNode.childrenChanged(ContainerNode::ChildChange { ContainerNode::ChildChange::Type::AllChildrenReplaced, nullptr, nullptr, source });
     227    else {
     228        containerNode.childrenChanged(ContainerNode::ChildChange {
     229            child.isElementNode() ?
     230                ContainerNode::ChildChange::Type::ElementInserted :
     231                (child.isTextNode() ?
     232                    ContainerNode::ChildChange::Type::TextInserted :
     233                    ContainerNode::ChildChange::Type::NonContentsChildInserted),
     234            ElementTraversal::previousSibling(child),
     235            ElementTraversal::nextSibling(child),
     236            source
     237        });
     238    }
    268239
    269240    ASSERT(ScriptDisallowedScope::InMainThread::isEventDispatchAllowedInSubtree(child));
     
    478449            break;
    479450
    480         executeNodeInsertionWithScriptAssertion(*this, child.get(), next.ptr(), ChildChange::Source::API, ReplacedAllChildren::No, [&] {
     451        executeNodeInsertionWithScriptAssertion(*this, child.get(), ChildChange::Source::API, ReplacedAllChildren::No, [&] {
    481452            child->setTreeScopeRecursively(treeScope());
    482453            insertBeforeCommon(next, child);
     
    537508        return;
    538509
    539     executeNodeInsertionWithScriptAssertion(*this, newChild, &nextChild, ChildChange::Source::Parser, ReplacedAllChildren::No, [&] {
     510    executeNodeInsertionWithScriptAssertion(*this, newChild, ChildChange::Source::Parser, ReplacedAllChildren::No, [&] {
    540511        if (&document() != &newChild.document())
    541512            document().adoptNode(newChild);
     
    611582            break;
    612583
    613         executeNodeInsertionWithScriptAssertion(*this, child.get(), refChild.get(), ChildChange::Source::API, ReplacedAllChildren::No, [&] {
     584        executeNodeInsertionWithScriptAssertion(*this, child.get(), ChildChange::Source::API, ReplacedAllChildren::No, [&] {
    614585            child->setTreeScopeRecursively(treeScope());
    615586            if (refChild)
     
    712683    removeAllChildrenWithScriptAssertion(ChildChange::Source::API, DeferChildrenChanged::Yes);
    713684
    714     executeNodeInsertionWithScriptAssertion(*this, *node, nullptr, ChildChange::Source::API, ReplacedAllChildren::Yes, [&] {
     685    executeNodeInsertionWithScriptAssertion(*this, *node, ChildChange::Source::API, ReplacedAllChildren::Yes, [&] {
    715686        InspectorInstrumentation::willInsertDOMNode(document(), *this);
    716687        node->setTreeScopeRecursively(treeScope());
     
    793764
    794765        // Append child to the end of the list
    795         executeNodeInsertionWithScriptAssertion(*this, child.get(), nullptr, ChildChange::Source::API, ReplacedAllChildren::No, [&] {
     766        executeNodeInsertionWithScriptAssertion(*this, child.get(), ChildChange::Source::API, ReplacedAllChildren::No, [&] {
    796767            child->setTreeScopeRecursively(treeScope());
    797768            appendChildCommon(child);
     
    809780    ASSERT(!hasTagName(HTMLNames::templateTag));
    810781
    811     executeNodeInsertionWithScriptAssertion(*this, newChild, nullptr, ChildChange::Source::Parser, ReplacedAllChildren::No, [&] {
     782    executeNodeInsertionWithScriptAssertion(*this, newChild, ChildChange::Source::Parser, ReplacedAllChildren::No, [&] {
    812783        if (&document() != &newChild.document())
    813784            document().adoptNode(newChild);
     
    842813    case ContainerNode::ChildChange::Type::NonContentsChildRemoved:
    843814        return false;
    844     case ContainerNode::ChildChange::Type::FinishedParsingChildren:
    845         break;
    846815    }
    847816    ASSERT_NOT_REACHED();
  • trunk/Source/WebCore/dom/ContainerNode.h

    r286058 r286091  
    7575
    7676    struct ChildChange {
    77         enum class Type : uint8_t { ElementInserted, ElementRemoved, TextInserted, TextRemoved, TextChanged, AllChildrenRemoved, NonContentsChildRemoved, NonContentsChildInserted, AllChildrenReplaced, FinishedParsingChildren };
     77        enum class Type : uint8_t { ElementInserted, ElementRemoved, TextInserted, TextRemoved, TextChanged, AllChildrenRemoved, NonContentsChildRemoved, NonContentsChildInserted, AllChildrenReplaced };
    7878        enum class Source : bool { Parser, API };
    7979
     
    9797            case ChildChange::Type::NonContentsChildRemoved:
    9898                return false;
    99             case ChildChange::Type::FinishedParsingChildren:
    100                 break;
    10199            }
    102100            ASSERT_NOT_REACHED();
  • trunk/Source/WebCore/dom/Element.cpp

    r286058 r286091  
    3131#include "AttributeChangeInvalidation.h"
    3232#include "CSSParser.h"
    33 #include "ChildChangeInvalidation.h"
    3433#include "Chrome.h"
    3534#include "ChromeClient.h"
     
    20402039}
    20412040
    2042 void invalidateForSiblingCombinators(Element* sibling)
     2041static void invalidateForSiblingCombinators(Element* sibling)
    20432042{
    20442043    for (; sibling; sibling = sibling->nextElementSibling()) {
     
    26442643    return false;
    26452644}
     2645
     2646static void checkForEmptyStyleChange(Element& element)
     2647{
     2648    if (element.styleAffectedByEmpty()) {
     2649        auto* style = element.renderStyle();
     2650        if (!style || (!style->emptyState() || element.hasChildNodes()))
     2651            element.invalidateStyleForSubtree();
     2652    }
     2653}
     2654
     2655
     2656static void invalidateForForwardPositionalRules(Element& parent, Element* elementAfterChange)
     2657{
     2658    bool childrenAffected = parent.childrenAffectedByForwardPositionalRules();
     2659    bool descendantsAffected = parent.descendantsAffectedByForwardPositionalRules();
     2660
     2661    if (!childrenAffected && !descendantsAffected)
     2662        return;
     2663
     2664    for (auto* sibling = elementAfterChange; sibling; sibling = sibling->nextElementSibling()) {
     2665        if (childrenAffected)
     2666            sibling->invalidateStyleInternal();
     2667        if (descendantsAffected) {
     2668            for (auto* siblingChild = sibling->firstElementChild(); siblingChild; siblingChild = siblingChild->nextElementSibling())
     2669                siblingChild->invalidateStyleForSubtreeInternal();
     2670        }
     2671    }
     2672}
     2673
     2674static void invalidateForBackwardPositionalRules(Element& parent, Element* elementBeforeChange)
     2675{
     2676    bool childrenAffected = parent.childrenAffectedByBackwardPositionalRules();
     2677    bool descendantsAffected = parent.descendantsAffectedByBackwardPositionalRules();
     2678
     2679    if (!childrenAffected && !descendantsAffected)
     2680        return;
     2681
     2682    for (auto* sibling = elementBeforeChange; sibling; sibling = sibling->previousElementSibling()) {
     2683        if (childrenAffected)
     2684            sibling->invalidateStyleInternal();
     2685        if (descendantsAffected) {
     2686            for (auto* siblingChild = sibling->firstElementChild(); siblingChild; siblingChild = siblingChild->nextElementSibling())
     2687                siblingChild->invalidateStyleForSubtreeInternal();
     2688        }
     2689    }
     2690}
     2691
     2692enum SiblingCheckType { FinishedParsingChildren, SiblingElementRemoved, Other };
     2693
     2694static void checkForSiblingStyleChanges(Element& parent, SiblingCheckType checkType, Element* elementBeforeChange, Element* elementAfterChange)
     2695{
     2696    // :empty selector.
     2697    checkForEmptyStyleChange(parent);
     2698
     2699    if (parent.styleValidity() >= Style::Validity::SubtreeInvalid)
     2700        return;
     2701
     2702    // :first-child.  In the parser callback case, we don't have to check anything, since we were right the first time.
     2703    // In the DOM case, we only need to do something if |afterChange| is not 0.
     2704    // |afterChange| is 0 in the parser case, so it works out that we'll skip this block.
     2705    if (parent.childrenAffectedByFirstChildRules() && elementAfterChange) {
     2706        // Find our new first child.
     2707        RefPtr<Element> newFirstElement = ElementTraversal::firstChild(parent);
     2708        // Find the first element node following |afterChange|
     2709
     2710        // This is the insert/append case.
     2711        if (newFirstElement != elementAfterChange) {
     2712            auto* style = elementAfterChange->renderStyle();
     2713            if (!style || style->firstChildState())
     2714                elementAfterChange->invalidateStyleForSubtreeInternal();
     2715        }
     2716
     2717        // We also have to handle node removal.
     2718        if (checkType == SiblingElementRemoved && newFirstElement == elementAfterChange && newFirstElement) {
     2719            auto* style = newFirstElement->renderStyle();
     2720            if (!style || !style->firstChildState())
     2721                newFirstElement->invalidateStyleForSubtreeInternal();
     2722        }
     2723    }
     2724
     2725    // :last-child.  In the parser callback case, we don't have to check anything, since we were right the first time.
     2726    // In the DOM case, we only need to do something if |afterChange| is not 0.
     2727    if (parent.childrenAffectedByLastChildRules() && elementBeforeChange) {
     2728        // Find our new last child.
     2729        RefPtr<Element> newLastElement = ElementTraversal::lastChild(parent);
     2730
     2731        if (newLastElement != elementBeforeChange) {
     2732            auto* style = elementBeforeChange->renderStyle();
     2733            if (!style || style->lastChildState())
     2734                elementBeforeChange->invalidateStyleForSubtreeInternal();
     2735        }
     2736
     2737        // We also have to handle node removal.  The parser callback case is similar to node removal as well in that we need to change the last child
     2738        // to match now.
     2739        if ((checkType == SiblingElementRemoved || checkType == FinishedParsingChildren) && newLastElement == elementBeforeChange && newLastElement) {
     2740            auto* style = newLastElement->renderStyle();
     2741            if (!style || !style->lastChildState())
     2742                newLastElement->invalidateStyleForSubtreeInternal();
     2743        }
     2744    }
     2745
     2746    invalidateForSiblingCombinators(elementAfterChange);
     2747
     2748    invalidateForForwardPositionalRules(parent, elementAfterChange);
     2749    invalidateForBackwardPositionalRules(parent, elementBeforeChange);
     2750}
     2751
    26462752void Element::childrenChanged(const ChildChange& change)
    26472753{
    26482754    ContainerNode::childrenChanged(change);
    2649 
    2650     if (auto* shadowRoot = this->shadowRoot()) {
     2755    if (change.source == ChildChange::Source::Parser)
     2756        checkForEmptyStyleChange(*this);
     2757    else {
     2758        auto checkType = change.type == ChildChange::Type::ElementRemoved ? SiblingElementRemoved : Other;
     2759        checkForSiblingStyleChanges(*this, checkType, change.previousSiblingElement, change.nextSiblingElement);
     2760    }
     2761
     2762    if (ShadowRoot* shadowRoot = this->shadowRoot()) {
    26512763        switch (change.type) {
    26522764        case ChildChange::Type::ElementInserted:
     
    26652777        case ChildChange::Type::NonContentsChildInserted:
    26662778        case ChildChange::Type::NonContentsChildRemoved:
    2667         case ChildChange::Type::FinishedParsingChildren:
    26682779            break;
    26692780        }
     
    26922803    ContainerNode::finishParsingChildren();
    26932804    setIsParsingChildrenFinished();
    2694 
    2695     Style::ChildChangeInvalidation styleInvalidation(*this, {
    2696         ChildChange::Type::FinishedParsingChildren,
    2697         ElementTraversal::lastChild(*this),
    2698         nullptr,
    2699         ChildChange::Source::Parser
    2700     });
     2805    checkForSiblingStyleChanges(*this, FinishedParsingChildren, ElementTraversal::lastChild(*this), nullptr);
    27012806}
    27022807
  • trunk/Source/WebCore/dom/Element.h

    r286058 r286091  
    764764};
    765765
    766 void invalidateForSiblingCombinators(Element* sibling);
    767 
    768766} // namespace WebCore
    769767
  • trunk/Source/WebCore/dom/ShadowRoot.cpp

    r286058 r286091  
    145145    case ChildChange::Type::AllChildrenReplaced:
    146146        break;
    147     case ChildChange::Type::FinishedParsingChildren:
    148         ASSERT_NOT_REACHED();
    149         break;
    150147    }
    151148}
  • trunk/Source/WebCore/style/StyleAdjuster.h

    r286058 r286091  
    2727
    2828#include "RenderStyleConstants.h"
    29 #include "TextSizeAdjustment.h"
    3029#include <wtf/OptionSet.h>
    3130
Note: See TracChangeset for help on using the changeset viewer.