Chromium Code Reviews| Index: Source/core/dom/Element.cpp |
| diff --git a/Source/core/dom/Element.cpp b/Source/core/dom/Element.cpp |
| index ce5e91a04f284c071f7fabb080953e601ae0b4b1..8cdfa4a77ecd7c653cc60df687592be13b5bf016 100644 |
| --- a/Source/core/dom/Element.cpp |
| +++ b/Source/core/dom/Element.cpp |
| @@ -44,6 +44,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" |
| @@ -1326,6 +1327,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. |
| @@ -1367,6 +1370,7 @@ void Element::detach(const AttachContext& context) |
| WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates; |
| unregisterNamedFlowContentNode(); |
| cancelFocusAppearanceUpdate(); |
| + updateCallbackSelectors(Remove); |
| if (hasRareData()) { |
| ElementRareData* data = elementRareData(); |
| data->setPseudoElement(BEFORE, 0); |
| @@ -1450,6 +1454,24 @@ bool Element::recalcStyle(StyleChange change) |
| if (hasCustomStyleCallbacks()) |
| willRecalcStyle(change); |
| + class SelectorWatchUpdater { |
|
esprehn
2013/09/04 06:08:28
Don't put classes inside methods. This needs to be
Jeffrey Yasskin
2013/09/12 22:09:59
It's no longer necessary. :)
|
| + public: |
| + SelectorWatchUpdater(Element* element) |
| + : m_element(element) |
| + { |
| + m_element->updateCallbackSelectors(Remove); |
|
esprehn
2013/09/04 06:08:28
This is not right, why are you removing and adding
Jeffrey Yasskin
2013/09/12 22:09:59
Yep, using recalcOwnStyle() cleaned this up a lot.
|
| + } |
| + |
| + ~SelectorWatchUpdater() |
| + { |
| + m_element->updateCallbackSelectors(Add); |
| + } |
| + |
| + private: |
| + Element* const m_element; |
| + }; |
| + SelectorWatchUpdater watchUpdater(this); |
| + |
| if (hasRareData() && (change > NoChange || needsStyleRecalc())) { |
| ElementRareData* data = elementRareData(); |
| data->resetStyleState(); |
| @@ -2435,6 +2457,33 @@ void Element::cancelFocusAppearanceUpdate() |
| document()->cancelFocusAppearanceUpdate(); |
| } |
| +void Element::updateCallbackSelectors(AddOrRemove addOrRemove) |
| +{ |
| + if (!renderStyle()) |
| + return; |
|
esprehn
2013/09/04 06:08:28
Don't call RenderStyle repeatedly, you want to cal
Jeffrey Yasskin
2013/09/12 22:09:59
Obsolete. :)
|
| + const Vector<String>& callbackSelectors = renderStyle()->callbackSelectors(); |
| + if (callbackSelectors.isEmpty()) |
|
esprehn
2013/09/04 06:08:28
The check should be outside the function call sinc
Jeffrey Yasskin
2013/09/12 22:09:59
Done.
|
| + return; |
| + |
| + CSSSelectorWatch* selectorWatch = CSSSelectorWatch::from(document()); |
| + switch (addOrRemove) { |
| + case Add: { |
| + ElementRareData* rareData = ensureElementRareData(); |
| + if (!rareData->renderStyleWatchedSelectorsRepresentedInSelectorWatch()) { |
| + selectorWatch->addSelectorMatches(callbackSelectors); |
| + rareData->setRenderStyleWatchedSelectorsRepresentedInSelectorWatch(true); |
| + } |
| + break; |
|
esprehn
2013/09/04 06:08:28
These should be two separate methods and get rid o
Jeffrey Yasskin
2013/09/12 22:09:59
Refactored away.
|
| + } |
| + case Remove: |
| + if (hasRareData() && elementRareData()->renderStyleWatchedSelectorsRepresentedInSelectorWatch()) { |
| + selectorWatch->removeSelectorMatches(callbackSelectors); |
| + elementRareData()->setRenderStyleWatchedSelectorsRepresentedInSelectorWatch(false); |
| + } |
| + break; |
| + } |
| +} |
| + |
| void Element::normalizeAttributes() |
| { |
| if (!hasAttributes()) |