Index: Source/core/dom/Element.cpp |
diff --git a/Source/core/dom/Element.cpp b/Source/core/dom/Element.cpp |
index 0aedfeca43c66160a8b0836989d23c7891ca88c4..680bcf5b53df0e18f19b60a11ebbd05fcac35268 100644 |
--- a/Source/core/dom/Element.cpp |
+++ b/Source/core/dom/Element.cpp |
@@ -43,6 +43,7 @@ |
#include "core/css/resolver/StyleResolver.h" |
#include "core/dom/Attr.h" |
#include "core/dom/Attribute.h" |
+#include "core/dom/CSSSelectorWatch.h" |
#include "core/dom/ClientRect.h" |
#include "core/dom/ClientRectList.h" |
#include "core/dom/CustomElement.h" |
@@ -1337,6 +1338,8 @@ void Element::attach(const AttachContext& context) |
NodeRenderingContext(this, context.resolvedStyle).createRendererForElementIfNeeded(); |
+ updateCallbackSelectors(Add); |
+ |
createPseudoElementIfNeeded(BEFORE); |
// When a shadow root exists, it does the work of attaching the children. |
@@ -1378,6 +1381,7 @@ void Element::detach(const AttachContext& context) |
WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates; |
unregisterNamedFlowContentNode(); |
cancelFocusAppearanceUpdate(); |
+ updateCallbackSelectors(Remove); |
if (hasRareData()) { |
ElementRareData* data = elementRareData(); |
data->setPseudoElement(BEFORE, 0); |
@@ -1461,6 +1465,24 @@ bool Element::recalcStyle(StyleChange change) |
if (hasCustomStyleCallbacks()) |
willRecalcStyle(change); |
+ class SelectorWatchUpdater { |
+ public: |
+ SelectorWatchUpdater(Element* element) |
+ : m_element(element) |
+ { |
+ m_element->updateCallbackSelectors(Remove); |
+ } |
+ |
+ ~SelectorWatchUpdater() |
+ { |
+ m_element->updateCallbackSelectors(Add); |
+ } |
+ |
+ private: |
+ Element* const m_element; |
+ }; |
+ SelectorWatchUpdater watchUpdater(this); |
+ |
// Ref currentStyle in case it would otherwise be deleted when setting the new style in the renderer. |
RefPtr<RenderStyle> currentStyle = renderStyle(); |
bool hasParentStyle = static_cast<bool>(parentRenderStyle()); |
@@ -2446,6 +2468,33 @@ void Element::cancelFocusAppearanceUpdate() |
document()->cancelFocusAppearanceUpdate(); |
} |
+void Element::updateCallbackSelectors(AddOrRemove addOrRemove) |
+{ |
+ if (!renderStyle()) |
+ return; |
+ const Vector<String>& callbackSelectors = renderStyle()->callbackSelectors(); |
+ if (callbackSelectors.isEmpty()) |
+ return; |
+ |
+ CSSSelectorWatch* selectorWatch = CSSSelectorWatch::from(document()); |
+ switch (addOrRemove) { |
+ case Add: { |
+ ElementRareData* rareData = ensureElementRareData(); |
+ if (!rareData->renderStyleWatchedSelectorsRepresentedInSelectorWatch()) { |
+ selectorWatch->addSelectorMatches(callbackSelectors); |
+ rareData->setRenderStyleWatchedSelectorsRepresentedInSelectorWatch(true); |
+ } |
+ break; |
+ } |
+ case Remove: |
+ if (hasRareData() && elementRareData()->renderStyleWatchedSelectorsRepresentedInSelectorWatch()) { |
+ selectorWatch->removeSelectorMatches(callbackSelectors); |
+ elementRareData()->setRenderStyleWatchedSelectorsRepresentedInSelectorWatch(false); |
+ } |
+ break; |
+ } |
+} |
+ |
void Element::normalizeAttributes() |
{ |
if (!hasAttributes()) |