Skip to content
Permalink
Browse files
[Shadow DOM] Distribution related code on ElementShadow should be min…
…imized.

https://bugs.webkit.org/show_bug.cgi?id=106294

Reviewed by Dimitri Glazkov.

.:

* Source/autotools/symbols.filter:

Source/WebCore:

This change moves ElementShadow::m_selectFeatures,
m_shouldCollectSelectFeatureSet and related methods to
ContentDistributor.

There are also some renaming and small refactorings for better fit
on new place:

- shouldCollectSelectFeatureSet is renamed needsSelectorRuleSet for conciseness.
- setShouldCollectSelectFeatureSet() which used recursion morphed into
  iterative willAffectSelector().
- ensureDistributionFromDocument() becomes a static method.

No new tests. Refactoring.

* WebCore.exp.in:
* dom/Element.cpp:
(WebCore::Element::shouldInvalidateDistributionWhenAttributeChanged):
* dom/ElementShadow.cpp:
(WebCore::ElementShadow::addShadowRoot):
(WebCore::ElementShadow::removeAllShadowRoots):
* dom/ElementShadow.h:
(ElementShadow):
(WebCore::ElementShadow::invalidateDistribution):
(WebCore::ElementShadow::ensureDistribution):
(WebCore::ElementShadow::didAffectSelector):
(WebCore::ElementShadow::willAffectSelector):
(WebCore::ElementShadow::containingShadow):
(WebCore):
* html/shadow/ContentDistributor.cpp:
(WebCore::ScopeContentDistribution::registerInsertionPoint):
(WebCore::ScopeContentDistribution::unregisterInsertionPoint):
(WebCore::ContentDistributor::ContentDistributor):
(WebCore::ContentDistributor::ensureDistribution):
(WebCore):
(WebCore::ContentDistributor::ensureDistributionFromDocument):
(WebCore::ContentDistributor::invalidateDistribution):
(WebCore::ContentDistributor::ensureSelectFeatureSet):
(WebCore::ContentDistributor::collectSelectFeatureSetFrom):
(WebCore::ContentDistributor::didAffectSelector):
(WebCore::ContentDistributor::willAffectSelector):
(WebCore::ContentDistributor::didShadowBoundaryChange):
* html/shadow/ContentDistributor.h:
(ScopeContentDistribution):
(WebCore::ContentDistributor::needsSelectFeatureSet):
(WebCore::ContentDistributor::setNeedsSelectFeatureSet):
(ContentDistributor):
(WebCore::ContentDistributor::setValidity):
(WebCore::ContentDistributor::needsInvalidation):
* html/shadow/HTMLContentElement.cpp:
(WebCore::HTMLContentElement::parseAttribute):
* html/shadow/HTMLContentElement.h:
* html/shadow/HTMLShadowElement.cpp:
(WebCore::HTMLShadowElement::olderShadowRoot):
* html/shadow/InsertionPoint.cpp:
(WebCore::InsertionPoint::getDistributedNodes):
(WebCore::InsertionPoint::insertedInto):
(WebCore::InsertionPoint::removedFrom):
* html/shadow/InsertionPoint.h:
(WebCore::InsertionPoint::canAffectSelector):
* testing/Internals.cpp:
(WebCore::Internals::hasSelectorForIdInShadow):
(WebCore::Internals::hasSelectorForClassInShadow):
(WebCore::Internals::hasSelectorForAttributeInShadow):
(WebCore::Internals::hasSelectorForPseudoClassInShadow):

Source/WebKit/win:

* WebKit.vcproj/WebKit.def.in:


Canonical link: https://commits.webkit.org/124717@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@139269 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
omo committed Jan 10, 2013
1 parent 4d25d9f commit ed2ee449e5469e054df08092387037537b6c20d7
Showing 17 changed files with 251 additions and 182 deletions.
@@ -1,3 +1,12 @@
2013-01-09 Hajime Morrita <morrita@google.com>

[Shadow DOM] Distribution related code on ElementShadow should be minimized.
https://bugs.webkit.org/show_bug.cgi?id=106294

Reviewed by Dimitri Glazkov.

* Source/autotools/symbols.filter:

2013-01-08 Zan Dobersek <zandobersek@gmail.com>

Add an Autoconf macro that checks whether a given feature is enabled
@@ -1,3 +1,75 @@
2013-01-09 Hajime Morrita <morrita@google.com>

[Shadow DOM] Distribution related code on ElementShadow should be minimized.
https://bugs.webkit.org/show_bug.cgi?id=106294

Reviewed by Dimitri Glazkov.

This change moves ElementShadow::m_selectFeatures,
m_shouldCollectSelectFeatureSet and related methods to
ContentDistributor.

There are also some renaming and small refactorings for better fit
on new place:

- shouldCollectSelectFeatureSet is renamed needsSelectorRuleSet for conciseness.
- setShouldCollectSelectFeatureSet() which used recursion morphed into
iterative willAffectSelector().
- ensureDistributionFromDocument() becomes a static method.

No new tests. Refactoring.

* WebCore.exp.in:
* dom/Element.cpp:
(WebCore::Element::shouldInvalidateDistributionWhenAttributeChanged):
* dom/ElementShadow.cpp:
(WebCore::ElementShadow::addShadowRoot):
(WebCore::ElementShadow::removeAllShadowRoots):
* dom/ElementShadow.h:
(ElementShadow):
(WebCore::ElementShadow::invalidateDistribution):
(WebCore::ElementShadow::ensureDistribution):
(WebCore::ElementShadow::didAffectSelector):
(WebCore::ElementShadow::willAffectSelector):
(WebCore::ElementShadow::containingShadow):
(WebCore):
* html/shadow/ContentDistributor.cpp:
(WebCore::ScopeContentDistribution::registerInsertionPoint):
(WebCore::ScopeContentDistribution::unregisterInsertionPoint):
(WebCore::ContentDistributor::ContentDistributor):
(WebCore::ContentDistributor::ensureDistribution):
(WebCore):
(WebCore::ContentDistributor::ensureDistributionFromDocument):
(WebCore::ContentDistributor::invalidateDistribution):
(WebCore::ContentDistributor::ensureSelectFeatureSet):
(WebCore::ContentDistributor::collectSelectFeatureSetFrom):
(WebCore::ContentDistributor::didAffectSelector):
(WebCore::ContentDistributor::willAffectSelector):
(WebCore::ContentDistributor::didShadowBoundaryChange):
* html/shadow/ContentDistributor.h:
(ScopeContentDistribution):
(WebCore::ContentDistributor::needsSelectFeatureSet):
(WebCore::ContentDistributor::setNeedsSelectFeatureSet):
(ContentDistributor):
(WebCore::ContentDistributor::setValidity):
(WebCore::ContentDistributor::needsInvalidation):
* html/shadow/HTMLContentElement.cpp:
(WebCore::HTMLContentElement::parseAttribute):
* html/shadow/HTMLContentElement.h:
* html/shadow/HTMLShadowElement.cpp:
(WebCore::HTMLShadowElement::olderShadowRoot):
* html/shadow/InsertionPoint.cpp:
(WebCore::InsertionPoint::getDistributedNodes):
(WebCore::InsertionPoint::insertedInto):
(WebCore::InsertionPoint::removedFrom):
* html/shadow/InsertionPoint.h:
(WebCore::InsertionPoint::canAffectSelector):
* testing/Internals.cpp:
(WebCore::Internals::hasSelectorForIdInShadow):
(WebCore::Internals::hasSelectorForClassInShadow):
(WebCore::Internals::hasSelectorForAttributeInShadow):
(WebCore::Internals::hasSelectorForPseudoClassInShadow):

2013-01-09 Shinya Kawanaka <shinyak@chromium.org>

Assert triggered in SelectorChecker::checkOneSelector when scrollbar (e.g. :horizontal) selector is specified.
@@ -217,7 +217,6 @@ __ZN7WebCore13AXObjectCache42gAccessibilityEnhancedUserInterfaceEnabledE
__ZN7WebCore13CharacterData7setDataERKN3WTF6StringERi
__ZN7WebCore13ContainerNode11appendChildEN3WTF10PassRefPtrINS_4NodeEEERib
__ZN7WebCore13ContainerNode11removeChildEPNS_4NodeERi
__ZN7WebCore13ElementShadow31ensureSelectFeatureSetCollectedEv
__ZN7WebCore13HTTPHeaderMapC1Ev
__ZN7WebCore13HTTPHeaderMapD1Ev
__ZN7WebCore13HitTestResultC1ERKS0_
@@ -517,6 +516,7 @@ __ZN7WebCore18DOMWindowExtensionC1EPNS_5FrameEPNS_15DOMWrapperWorldE
__ZN7WebCore18HTMLContentElement6createEPNS_8DocumentE
__ZN7WebCore10Pasteboard17generalPasteboardEv
__ZN7WebCore10Pasteboard14writePlainTextERKN3WTF6StringENS0_18SmartReplaceOptionE
__ZN7WebCore18ContentDistributor22ensureSelectFeatureSetEPNS_13ElementShadowE
__ZN7WebCore18PlatformPasteboard10uniqueNameEv
__ZN7WebCore18PlatformPasteboard13bufferForTypeERKN3WTF6StringE
__ZN7WebCore18PlatformPasteboard13stringForTypeERKN3WTF6StringE
@@ -917,15 +917,15 @@ void Element::classAttributeChanged(const AtomicString& newClassString)
bool Element::shouldInvalidateDistributionWhenAttributeChanged(ElementShadow* elementShadow, const QualifiedName& name, const AtomicString& newValue)
{
ASSERT(elementShadow);
elementShadow->ensureSelectFeatureSetCollected();
const SelectRuleFeatureSet& featureSet = elementShadow->distributor().ensureSelectFeatureSet(elementShadow);

if (isIdAttributeName(name)) {
AtomicString oldId = attributeData()->idForStyleResolution();
AtomicString newId = makeIdForStyleResolution(newValue, document()->inQuirksMode());
if (newId != oldId) {
if (!oldId.isEmpty() && elementShadow->selectRuleFeatureSet().hasSelectorForId(oldId))
if (!oldId.isEmpty() && featureSet.hasSelectorForId(oldId))
return true;
if (!newId.isEmpty() && elementShadow->selectRuleFeatureSet().hasSelectorForId(newId))
if (!newId.isEmpty() && featureSet.hasSelectorForId(newId))
return true;
}
}
@@ -937,16 +937,16 @@ bool Element::shouldInvalidateDistributionWhenAttributeChanged(ElementShadow* el
const bool shouldFoldCase = document()->inQuirksMode();
const SpaceSplitString& oldClasses = attributeData->classNames();
const SpaceSplitString newClasses(newClassString, shouldFoldCase);
if (checkSelectorForClassChange(oldClasses, newClasses, elementShadow->selectRuleFeatureSet()))
if (checkSelectorForClassChange(oldClasses, newClasses, featureSet))
return true;
} else if (const ElementAttributeData* attributeData = this->attributeData()) {
const SpaceSplitString& oldClasses = attributeData->classNames();
if (checkSelectorForClassChange(oldClasses, elementShadow->selectRuleFeatureSet()))
if (checkSelectorForClassChange(oldClasses, featureSet))
return true;
}
}

return elementShadow->selectRuleFeatureSet().hasSelectorForAttribute(name.localName());
return featureSet.hasSelectorForAttribute(name.localName());
}

// Returns true is the given attribute is an event handler.
@@ -42,7 +42,6 @@
namespace WebCore {

ElementShadow::ElementShadow()
: m_shouldCollectSelectFeatureSet(false)
{
}

@@ -83,8 +82,7 @@ void ElementShadow::addShadowRoot(Element* shadowHost, PassRefPtr<ShadowRoot> sh
shadowRoot->setHost(shadowHost);
shadowRoot->setParentTreeScope(shadowHost->treeScope());
m_shadowRoots.push(shadowRoot.get());
setValidityUndetermined();
invalidateDistribution(shadowHost);
m_distributor.didShadowBoundaryChange(shadowHost);
ChildNodeInsertionNotifier(shadowHost).notify(shadowRoot.get());

// Existence of shadow roots requires the host and its children to do traversal using ComposedShadowTreeWalker.
@@ -119,7 +117,7 @@ void ElementShadow::removeAllShadowRoots()
ChildNodeRemovalNotifier(shadowHost).notify(oldRoot.get());
}

invalidateDistribution(shadowHost);
m_distributor.invalidateDistribution(shadowHost);
}

void ElementShadow::attach()
@@ -165,94 +163,6 @@ void ElementShadow::recalcStyle(Node::StyleChange change)
root->recalcStyle(change);
}

void ElementShadow::ensureDistribution()
{
if (!m_distributor.needsDistribution())
return;
m_distributor.distribute(host());
}

void ElementShadow::ensureDistributionFromDocument()
{
Vector<Element*, 8> hosts;
for (Element* current = host(); current; current = current->shadowHost())
hosts.append(current);

for (size_t i = hosts.size(); i > 0; --i)
hosts[i - 1]->shadow()->ensureDistribution();
}

void ElementShadow::setValidityUndetermined()
{
m_distributor.setValidity(ContentDistributor::Undetermined);
}

void ElementShadow::invalidateDistribution()
{
invalidateDistribution(host());
}

void ElementShadow::invalidateDistribution(Element* host)
{
bool needsInvalidation = m_distributor.needsInvalidation();
bool needsReattach = needsInvalidation ? m_distributor.invalidate(host) : false;

if (needsReattach && host->attached()) {
for (Node* n = host->firstChild(); n; n = n->nextSibling())
n->lazyReattach();
host->setNeedsStyleRecalc();
}

if (needsInvalidation)
m_distributor.finishInivalidation();
}

void ElementShadow::setShouldCollectSelectFeatureSet()
{
if (shouldCollectSelectFeatureSet())
return;

m_shouldCollectSelectFeatureSet = true;

if (ShadowRoot* parentShadowRoot = host()->containingShadowRoot()) {
if (ElementShadow* parentElementShadow = parentShadowRoot->owner())
parentElementShadow->setShouldCollectSelectFeatureSet();
}
}

void ElementShadow::ensureSelectFeatureSetCollected()
{
if (!m_shouldCollectSelectFeatureSet)
return;

m_selectFeatures.clear();
for (ShadowRoot* root = oldestShadowRoot(); root; root = root->youngerShadowRoot())
collectSelectFeatureSetFrom(root);
m_shouldCollectSelectFeatureSet = false;
}

void ElementShadow::collectSelectFeatureSetFrom(ShadowRoot* root)
{
if (ScopeContentDistribution::hasElementShadow(root)) {
for (Element* element = ElementTraversal::firstWithin(root); element; element = ElementTraversal::next(element)) {
if (ElementShadow* elementShadow = element->shadow()) {
elementShadow->ensureSelectFeatureSetCollected();
m_selectFeatures.add(elementShadow->m_selectFeatures);
}
}
}

if (ScopeContentDistribution::hasContentElement(root)) {
for (Element* element = ElementTraversal::firstWithin(root); element; element = ElementTraversal::next(element)) {
if (isHTMLContentElement(element)) {
const CSSSelectorList& list = toHTMLContentElement(element)->selectorList();
for (CSSSelector* selector = list.first(); selector; selector = list.next(selector))
m_selectFeatures.collectFeaturesFromSelector(selector);
}
}
}
}

void ElementShadow::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
{
MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::DOM);
@@ -265,11 +175,4 @@ void ElementShadow::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
info.addMember(m_distributor);
}

void ElementShadow::didAffectSelector(AffectedSelectorMask mask)
{
ensureSelectFeatureSetCollected();
if (selectRuleFeatureSet().hasSelectorFor(mask))
invalidateDistribution();
}

} // namespace
@@ -29,7 +29,6 @@

#include "ContentDistributor.h"
#include "ExceptionCode.h"
#include "SelectRuleFeatureSet.h"
#include "ShadowRoot.h"
#include <wtf/DoublyLinkedList.h>
#include <wtf/Noncopyable.h>
@@ -52,6 +51,7 @@ class ElementShadow {
Element* host() const;
ShadowRoot* youngestShadowRoot() const;
ShadowRoot* oldestShadowRoot() const;
ElementShadow* containingShadow() const;

void removeAllShadowRoots();
void addShadowRoot(Element* shadowHost, PassRefPtr<ShadowRoot>, ShadowRoot::ShadowRootType, ExceptionCode&);
@@ -63,31 +63,19 @@ class ElementShadow {
bool needsStyleRecalc();
void recalcStyle(Node::StyleChange);

void setValidityUndetermined();
void invalidateDistribution();
void ensureDistribution();
void ensureDistributionFromDocument();
void invalidateDistribution() { m_distributor.invalidateDistribution(host()); }
void ensureDistribution() { m_distributor.ensureDistribution(host()); }
void didAffectSelector(AffectedSelectorMask mask) { m_distributor.didAffectSelector(host(), mask); }
void willAffectSelector() { m_distributor.willAffectSelector(host()); }

ContentDistributor& distributor();
const ContentDistributor& distributor() const;

void didAffectSelector(AffectedSelectorMask);
bool shouldCollectSelectFeatureSet() const { return m_shouldCollectSelectFeatureSet; }
void setShouldCollectSelectFeatureSet();
void ensureSelectFeatureSetCollected();

const SelectRuleFeatureSet& selectRuleFeatureSet() const;

void reportMemoryUsage(MemoryObjectInfo*) const;
private:
void invalidateDistribution(Element* host);

void collectSelectFeatureSetFrom(ShadowRoot*);

DoublyLinkedList<ShadowRoot> m_shadowRoots;
ContentDistributor m_distributor;
SelectRuleFeatureSet m_selectFeatures;
bool m_shouldCollectSelectFeatureSet : 1;
};

inline ShadowRoot* ElementShadow::youngestShadowRoot() const
@@ -116,12 +104,6 @@ inline Element* ElementShadow::host() const
return youngestShadowRoot()->host();
}

inline const SelectRuleFeatureSet& ElementShadow::selectRuleFeatureSet() const
{
ASSERT(!m_shouldCollectSelectFeatureSet);
return m_selectFeatures;
}

inline ShadowRoot* Node::youngestShadowRoot() const
{
if (!this->isElementNode())
@@ -131,6 +113,14 @@ inline ShadowRoot* Node::youngestShadowRoot() const
return 0;
}

inline ElementShadow* ElementShadow::containingShadow() const
{
ShadowRoot* parentRoot = host()->containingShadowRoot();
if (!parentRoot)
return 0;
return parentRoot->owner();
}

class ShadowRootVector : public Vector<RefPtr<ShadowRoot> > {
public:
explicit ShadowRootVector(ElementShadow* tree)

0 comments on commit ed2ee44

Please sign in to comment.