Skip to content
Permalink
Browse files
Factor child change invalidation into class
https://bugs.webkit.org/show_bug.cgi?id=233311

Reviewed by Alan Bujtas.

Use similar pattern as ClassChangeInvalidation and others where we create a stack object scoped
over a DOM mutation. This will allow more sophisticated ruleset based invalidation in
future.

This patch moves the invalidation code from childrenChanged() to the new ChildChangeInvalidation class.
ChildChangeInvalidation is instantiated in ContainerNode and CharacterData mutation functions
that call childrenChanged(). It uses the same ChildChange argument type as childrenChanged().

There are no changes to invalidation functionality in this patch.

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* dom/CharacterData.cpp:
(WebCore::makeChildChange):
(WebCore::CharacterData::parserAppendData):
(WebCore::CharacterData::setDataAndUpdate):
(WebCore::CharacterData::notifyParentAfterChange):
* dom/CharacterData.h:
* dom/ContainerNode.cpp:
(WebCore::ContainerNode::removeAllChildrenWithScriptAssertion):
(WebCore::makeChildChangeForRemoval):
(WebCore::ContainerNode::removeNodeWithScriptAssertion):
(WebCore::makeChildChangeForInsertion):
(WebCore::executeNodeInsertionWithScriptAssertion):
(WebCore::ContainerNode::insertBefore):
(WebCore::ContainerNode::parserInsertBefore):
(WebCore::ContainerNode::replaceChild):
(WebCore::ContainerNode::replaceAll):
(WebCore::ContainerNode::appendChildWithoutPreInsertionValidityCheck):
(WebCore::ContainerNode::parserAppendChild):
(WebCore::affectsElements):
* dom/Element.cpp:
(WebCore::invalidateForSiblingCombinators):
(WebCore::Element::childTypeAllowed const):
(WebCore::Element::childrenChanged):
(WebCore::Element::finishParsingChildren):
(WebCore::checkForEmptyStyleChange): Deleted.
(WebCore::invalidateForForwardPositionalRules): Deleted.
(WebCore::invalidateForBackwardPositionalRules): Deleted.
(WebCore::checkForSiblingStyleChanges): Deleted.
* dom/Element.h:
* style/ChildChangeInvalidation.cpp: Added.
(WebCore::Style::ChildChangeInvalidation::ChildChangeInvalidation):
(WebCore::Style::ChildChangeInvalidation::~ChildChangeInvalidation):
(WebCore::Style::ChildChangeInvalidation::invalidateAfterChange):
(WebCore::Style::ChildChangeInvalidation::checkForEmptyStyleChange):
(WebCore::Style::invalidateForForwardPositionalRules):
(WebCore::Style::invalidateForBackwardPositionalRules):
(WebCore::Style::ChildChangeInvalidation::checkForSiblingStyleChanges):
* style/ChildChangeInvalidation.h: Added.
(WebCore::Style::ChildChangeInvalidation::parentElement):
* style/StyleAdjuster.h:



Canonical link: https://commits.webkit.org/244499@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@286112 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
anttijk committed Nov 22, 2021
1 parent d9197df commit 5cd2dc853c7dea8ed851158780390bf28e22f8f6
Showing 11 changed files with 405 additions and 169 deletions.
@@ -1,3 +1,63 @@
2021-11-22 Antti Koivisto <antti@apple.com>

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

Reviewed by Alan Bujtas.

Use similar pattern as ClassChangeInvalidation and others where we create a stack object scoped
over a DOM mutation. This will allow more sophisticated ruleset based invalidation in
future.

This patch moves the invalidation code from childrenChanged() to the new ChildChangeInvalidation class.
ChildChangeInvalidation is instantiated in ContainerNode and CharacterData mutation functions
that call childrenChanged(). It uses the same ChildChange argument type as childrenChanged().

There are no changes to invalidation functionality in this patch.

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* dom/CharacterData.cpp:
(WebCore::makeChildChange):
(WebCore::CharacterData::parserAppendData):
(WebCore::CharacterData::setDataAndUpdate):
(WebCore::CharacterData::notifyParentAfterChange):
* dom/CharacterData.h:
* dom/ContainerNode.cpp:
(WebCore::ContainerNode::removeAllChildrenWithScriptAssertion):
(WebCore::makeChildChangeForRemoval):
(WebCore::ContainerNode::removeNodeWithScriptAssertion):
(WebCore::makeChildChangeForInsertion):
(WebCore::executeNodeInsertionWithScriptAssertion):
(WebCore::ContainerNode::insertBefore):
(WebCore::ContainerNode::parserInsertBefore):
(WebCore::ContainerNode::replaceChild):
(WebCore::ContainerNode::replaceAll):
(WebCore::ContainerNode::appendChildWithoutPreInsertionValidityCheck):
(WebCore::ContainerNode::parserAppendChild):
(WebCore::affectsElements):
* dom/Element.cpp:
(WebCore::invalidateForSiblingCombinators):
(WebCore::Element::childTypeAllowed const):
(WebCore::Element::childrenChanged):
(WebCore::Element::finishParsingChildren):
(WebCore::checkForEmptyStyleChange): Deleted.
(WebCore::invalidateForForwardPositionalRules): Deleted.
(WebCore::invalidateForBackwardPositionalRules): Deleted.
(WebCore::checkForSiblingStyleChanges): Deleted.
* dom/Element.h:
* style/ChildChangeInvalidation.cpp: Added.
(WebCore::Style::ChildChangeInvalidation::ChildChangeInvalidation):
(WebCore::Style::ChildChangeInvalidation::~ChildChangeInvalidation):
(WebCore::Style::ChildChangeInvalidation::invalidateAfterChange):
(WebCore::Style::ChildChangeInvalidation::checkForEmptyStyleChange):
(WebCore::Style::invalidateForForwardPositionalRules):
(WebCore::Style::invalidateForBackwardPositionalRules):
(WebCore::Style::ChildChangeInvalidation::checkForSiblingStyleChanges):
* style/ChildChangeInvalidation.h: Added.
(WebCore::Style::ChildChangeInvalidation::parentElement):
* style/StyleAdjuster.h:

2021-11-21 Alan Bujtas <zalan@apple.com>

[LFC][Integration] Enable bidi content for non-inline-box cases
@@ -2524,6 +2524,7 @@ storage/StorageMap.cpp
storage/StorageNamespaceProvider.cpp
storage/StorageQuotaManager.cpp
style/AttributeChangeInvalidation.cpp
style/ChildChangeInvalidation.cpp
style/ClassChangeInvalidation.cpp
style/ElementRuleCollector.cpp
style/IdChangeInvalidation.cpp
@@ -5342,6 +5342,7 @@
E4C1789B0EE6903800824D69 /* CSSSelectorList.h in Headers */ = {isa = PBXBuildFile; fileRef = E4C178960EE6903800824D69 /* CSSSelectorList.h */; settings = {ATTRIBUTES = (Private, ); }; };
E4C279590CF9741900E97B98 /* RenderMedia.h in Headers */ = {isa = PBXBuildFile; fileRef = E4C279570CF9741900E97B98 /* RenderMedia.h */; settings = {ATTRIBUTES = (Private, ); }; };
E4C3B1FA0F0E4161009693F6 /* LegacyTileCache.h in Headers */ = {isa = PBXBuildFile; fileRef = E4C3B1F90F0E4161009693F6 /* LegacyTileCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
E4C4C61A27452A7900A040E7 /* ChildChangeInvalidation.h in Headers */ = {isa = PBXBuildFile; fileRef = E4C4C61827452A7900A040E7 /* ChildChangeInvalidation.h */; };
E4C91A0E1802343100A17F6D /* TextPaintStyle.h in Headers */ = {isa = PBXBuildFile; fileRef = E4C91A0D1802343100A17F6D /* TextPaintStyle.h */; };
E4C91A16180999F100A17F6D /* RenderTextLineBoxes.h in Headers */ = {isa = PBXBuildFile; fileRef = E4C91A15180999F100A17F6D /* RenderTextLineBoxes.h */; settings = {ATTRIBUTES = (Private, ); }; };
E4D33F3B252AEECD00837D05 /* InlineRunAndOffset.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D33F39252AEECC00837D05 /* InlineRunAndOffset.h */; };
@@ -17046,6 +17047,8 @@
E4C279570CF9741900E97B98 /* RenderMedia.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderMedia.h; sourceTree = "<group>"; };
E4C3B1F90F0E4161009693F6 /* LegacyTileCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LegacyTileCache.h; sourceTree = "<group>"; };
E4C3B1FB0F0E4170009693F6 /* LegacyTileCache.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = LegacyTileCache.mm; sourceTree = "<group>"; };
E4C4C61827452A7900A040E7 /* ChildChangeInvalidation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ChildChangeInvalidation.h; sourceTree = "<group>"; };
E4C4C61B27452A8A00A040E7 /* ChildChangeInvalidation.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ChildChangeInvalidation.cpp; sourceTree = "<group>"; };
E4C91A0D1802343100A17F6D /* TextPaintStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextPaintStyle.h; sourceTree = "<group>"; };
E4C91A0F1802343900A17F6D /* TextPaintStyle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextPaintStyle.cpp; sourceTree = "<group>"; };
E4C91A15180999F100A17F6D /* RenderTextLineBoxes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderTextLineBoxes.h; sourceTree = "<group>"; };
@@ -30282,6 +30285,8 @@
E4A814D71C70E10500BF85AC /* AttributeChangeInvalidation.cpp */,
E4A814D91C70E10D00BF85AC /* AttributeChangeInvalidation.h */,
E4ABABF42368C6EF00FA4345 /* CascadeLevel.h */,
E4C4C61B27452A8A00A040E7 /* ChildChangeInvalidation.cpp */,
E4C4C61827452A7900A040E7 /* ChildChangeInvalidation.h */,
E4A814D51C6DEE8D00BF85AC /* ClassChangeInvalidation.cpp */,
E4A814D31C6DEC4000BF85AC /* ClassChangeInvalidation.h */,
FBDB619A16D6032A00BB3394 /* ElementRuleCollector.cpp */,
@@ -32737,6 +32742,7 @@
93F2CC932427FB9C005851D8 /* CharacterRange.h in Headers */,
97B8FFD116AE7F960038388D /* CharacterReferenceParserInlines.h in Headers */,
F55B3DB21251F12D003EF269 /* CheckboxInputType.h in Headers */,
E4C4C61A27452A7900A040E7 /* ChildChangeInvalidation.h in Headers */,
D619A308144E00BE004BC302 /* ChildListMutationScope.h in Headers */,
A81872200977D3C0005826D9 /* ChildNodeList.h in Headers */,
14D823520AF92A790004F057 /* Chrome.h in Headers */,
@@ -23,6 +23,7 @@
#include "CharacterData.h"

#include "Attr.h"
#include "ChildChangeInvalidation.h"
#include "ElementTraversal.h"
#include "EventNames.h"
#include "FrameSelection.h"
@@ -73,6 +74,16 @@ ExceptionOr<String> CharacterData::substringData(unsigned offset, unsigned count
return m_data.substring(offset, count);
}

static ContainerNode::ChildChange makeChildChange(CharacterData& characterData, ContainerNode::ChildChange::Source source)
{
return {
ContainerNode::ChildChange::Type::TextChanged,
ElementTraversal::previousSibling(characterData),
ElementTraversal::nextSibling(characterData),
source
};
}

unsigned CharacterData::parserAppendData(const String& string, unsigned offset, unsigned lengthLimit)
{
unsigned oldLength = m_data.length();
@@ -95,6 +106,11 @@ unsigned CharacterData::parserAppendData(const String& string, unsigned offset,
if (!characterLengthLimit)
return 0;

auto childChange = makeChildChange(*this, ContainerNode::ChildChange::Source::Parser);
std::optional<Style::ChildChangeInvalidation> styleInvalidation;
if (auto* parent = parentNode())
styleInvalidation.emplace(*parent, childChange);

String oldData = m_data;
if (string.is8Bit())
m_data.append(string.characters8() + offset, characterLengthLimit);
@@ -105,7 +121,7 @@ unsigned CharacterData::parserAppendData(const String& string, unsigned offset,
if (is<Text>(*this))
downcast<Text>(*this).updateRendererAfterContentChange(oldLength, 0);

notifyParentAfterChange(ContainerNode::ChildChange::Source::Parser);
notifyParentAfterChange(childChange);

auto mutationRecipients = MutationObserverInterestGroup::createForCharacterDataMutation(*this);
if (UNLIKELY(mutationRecipients))
@@ -173,6 +189,12 @@ ExceptionOr<void> CharacterData::setNodeValue(const String& nodeValue)

void CharacterData::setDataAndUpdate(const String& newData, unsigned offsetOfReplacedData, unsigned oldLength, unsigned newLength, UpdateLiveRanges shouldUpdateLiveRanges)
{
auto childChange = makeChildChange(*this, ContainerNode::ChildChange::Source::API);

std::optional<Style::ChildChangeInvalidation> styleInvalidation;
if (auto* parent = parentNode())
styleInvalidation.emplace(*parent, childChange);

String oldData = m_data;
m_data = newData;

@@ -191,26 +213,19 @@ void CharacterData::setDataAndUpdate(const String& newData, unsigned offsetOfRep
if (document().frame())
document().frame()->selection().textWasReplaced(this, offsetOfReplacedData, oldLength, newLength);

notifyParentAfterChange(ContainerNode::ChildChange::Source::API);
notifyParentAfterChange(childChange);

dispatchModifiedEvent(oldData);
}

void CharacterData::notifyParentAfterChange(ContainerNode::ChildChange::Source source)
void CharacterData::notifyParentAfterChange(const ContainerNode::ChildChange& childChange)
{
document().incDOMTreeVersion();

if (!parentNode())
return;

ContainerNode::ChildChange change = {
ContainerNode::ChildChange::Type::TextChanged,
ElementTraversal::previousSibling(*this),
ElementTraversal::nextSibling(*this),
source
};

parentNode()->childrenChanged(change);
parentNode()->childrenChanged(childChange);
}

void CharacterData::dispatchModifiedEvent(const String& oldData)
@@ -65,7 +65,7 @@ class CharacterData : public Node {
private:
String nodeValue() const final;
ExceptionOr<void> setNodeValue(const String&) final;
void notifyParentAfterChange(ContainerNode::ChildChange::Source);
void notifyParentAfterChange(const ContainerNode::ChildChange&);

String m_data;
};

0 comments on commit 5cd2dc8

Please sign in to comment.