Simplify tree scope tracking in StyleEngine.

ShadowRoot should deal with adding and removing itself from the active
scope list. HTMLStyleElement should just add/remove itself directy from
the StyleSheetCollection on the scope its entering or leaving in
insertedInto/removedFrom.

R=ojan@chromium.org

Review URL: https://codereview.chromium.org/844133002
This commit is contained in:
Elliott Sprehn 2015-01-09 20:12:00 -08:00
parent 2b77bba1d8
commit 04288dc280
6 changed files with 32 additions and 77 deletions

View File

@ -49,6 +49,7 @@ StyleEngine::StyleEngine(Document& document)
, m_fontSelector(CSSFontSelector::create(&document))
{
m_fontSelector->registerForInvalidationCallbacks(this);
m_activeTreeScopes.add(&document);
}
StyleEngine::~StyleEngine()
@ -57,28 +58,14 @@ StyleEngine::~StyleEngine()
m_fontSelector->unregisterForInvalidationCallbacks(this);
}
void StyleEngine::addStyleSheetCandidateNode(Node* node, bool createdByParser)
void StyleEngine::addTreeScope(TreeScope& scope)
{
if (!node->inDocument())
return;
TreeScope& treeScope = isHTMLStyleElement(*node) ? node->treeScope() : *m_document;
ASSERT(isHTMLStyleElement(node) || treeScope == m_document);
StyleSheetCollection& collection = treeScope.styleSheets();
collection.addStyleSheetCandidateNode(node, createdByParser);
if (treeScope != m_document)
m_activeTreeScopes.add(&treeScope);
m_activeTreeScopes.add(&scope);
}
void StyleEngine::removeStyleSheetCandidateNode(Node* node, ContainerNode* scopingNode, TreeScope& treeScope)
void StyleEngine::removeTreeScope(TreeScope& scope)
{
ASSERT(isHTMLStyleElement(node) || treeScope == m_document);
StyleSheetCollection& collection = treeScope.styleSheets();
collection.removeStyleSheetCandidateNode(node, scopingNode);
m_activeTreeScopes.remove(&treeScope);
m_activeTreeScopes.remove(&scope);
}
void StyleEngine::updateActiveStyleSheets()
@ -88,28 +75,12 @@ void StyleEngine::updateActiveStyleSheets()
if (!m_document->isActive())
return;
// TODO(esprehn): Remove special case for document.
m_document->styleSheets().updateActiveStyleSheets(this);
TreeScopeSet treeScopes = m_activeTreeScopes;
HashSet<TreeScope*> treeScopesRemoved;
for (TreeScopeSet::iterator it = treeScopes.begin(); it != treeScopes.end(); ++it) {
TreeScope* treeScope = *it;
ASSERT(treeScope != m_document);
StyleSheetCollection& collection = treeScope->styleSheets();
collection.updateActiveStyleSheets(this);
if (!collection.hasStyleSheetCandidateNodes())
treeScopesRemoved.add(treeScope);
}
m_activeTreeScopes.removeAll(treeScopesRemoved);
for (TreeScope* treeScope : m_activeTreeScopes)
treeScope->styleSheets().updateActiveStyleSheets(this);
}
void StyleEngine::appendActiveAuthorStyleSheets()
{
// TODO(esprehn): Remove special case for document.
m_resolver->appendAuthorStyleSheets(m_document->styleSheets().activeAuthorStyleSheets());
for (TreeScope* treeScope : m_activeTreeScopes)
m_resolver->appendAuthorStyleSheets(treeScope->styleSheets().activeAuthorStyleSheets());

View File

@ -56,8 +56,8 @@ public:
void detachFromDocument();
void addStyleSheetCandidateNode(Node*, bool createdByParser);
void removeStyleSheetCandidateNode(Node*, ContainerNode* scopingNode, TreeScope&);
void addTreeScope(TreeScope&);
void removeTreeScope(TreeScope&);
void updateActiveStyleSheets();

View File

@ -46,31 +46,21 @@ StyleSheetCollection::~StyleSheetCollection()
{
}
void StyleSheetCollection::addStyleSheetCandidateNode(Node* node, bool)
void StyleSheetCollection::addStyleSheetCandidateNode(HTMLStyleElement& element)
{
if (!node->inDocument())
return;
// Until the <body> exists, we have no choice but to compare document positions,
// since styles outside of the body and head continue to be shunted into the head
// (and thus can shift to end up before dynamically added DOM content that is also
// outside the body).
m_styleSheetCandidateNodes.add(node);
ASSERT(element.inActiveDocument());
m_styleSheetCandidateNodes.add(&element);
}
void StyleSheetCollection::removeStyleSheetCandidateNode(Node* node, ContainerNode* scopingNode)
void StyleSheetCollection::removeStyleSheetCandidateNode(HTMLStyleElement& element)
{
m_styleSheetCandidateNodes.remove(node);
m_styleSheetCandidateNodes.remove(&element);
}
void StyleSheetCollection::collectStyleSheets(Vector<RefPtr<CSSStyleSheet>>& sheets)
{
DocumentOrderedList::iterator begin = m_styleSheetCandidateNodes.begin();
DocumentOrderedList::iterator end = m_styleSheetCandidateNodes.end();
for (DocumentOrderedList::iterator it = begin; it != end; ++it) {
Node* node = *it;
if (!isHTMLStyleElement(*node))
continue;
for (Node* node : m_styleSheetCandidateNodes) {
ASSERT(isHTMLStyleElement(*node));
if (CSSStyleSheet* sheet = toHTMLStyleElement(node)->sheet())
sheets.append(sheet);
}

View File

@ -38,6 +38,7 @@ namespace blink {
class CSSStyleSheet;
class ContainerNode;
class HTMLStyleElement;
class StyleEngine;
class TreeScope;
@ -54,9 +55,8 @@ public:
Vector<RefPtr<CSSStyleSheet> >& activeAuthorStyleSheets() { return m_activeAuthorStyleSheets; }
const Vector<RefPtr<CSSStyleSheet> >& activeAuthorStyleSheets() const { return m_activeAuthorStyleSheets; }
void addStyleSheetCandidateNode(Node*, bool createdByParser);
void removeStyleSheetCandidateNode(Node*, ContainerNode* scopingNode);
bool hasStyleSheetCandidateNodes() const { return !m_styleSheetCandidateNodes.isEmpty(); }
void addStyleSheetCandidateNode(HTMLStyleElement&);
void removeStyleSheetCandidateNode(HTMLStyleElement&);
void updateActiveStyleSheets(StyleEngine*);

View File

@ -29,6 +29,7 @@
#include "sky/engine/bindings/core/v8/ExceptionState.h"
#include "sky/engine/core/css/resolver/StyleResolver.h"
#include "sky/engine/core/dom/Document.h"
#include "sky/engine/core/dom/ElementTraversal.h"
#include "sky/engine/core/dom/StyleEngine.h"
#include "sky/engine/core/dom/Text.h"
@ -112,6 +113,9 @@ void ShadowRoot::insertedInto(ContainerNode* insertionPoint)
{
DocumentFragment::insertedInto(insertionPoint);
if (inActiveDocument())
document().styleEngine()->addTreeScope(*this);
if (ShadowRoot* root = host()->containingShadowRoot())
root->addChildShadowRoot();
}
@ -124,6 +128,9 @@ void ShadowRoot::removedFrom(ContainerNode* insertionPoint)
if (root)
root->removeChildShadowRoot();
if (inActiveDocument())
document().styleEngine()->removeTreeScope(*this);
DocumentFragment::removedFrom(insertionPoint);
}

View File

@ -30,6 +30,7 @@
#include "sky/engine/core/dom/Document.h"
#include "sky/engine/core/dom/Element.h"
#include "sky/engine/core/dom/StyleEngine.h"
#include "sky/engine/core/dom/StyleSheetCollection.h"
#include "sky/engine/core/dom/shadow/ShadowRoot.h"
#include "sky/engine/core/frame/LocalFrame.h"
#include "sky/engine/platform/TraceEvent.h"
@ -45,16 +46,6 @@ HTMLStyleElement::~HTMLStyleElement()
{
if (m_sheet)
m_sheet->clearOwnerNode();
// TODO(esprehn): How can we still be in the document when our destructor
// is running?
if (inDocument()) {
ContainerNode* scopingNode = this->scopingNode();
TreeScope& scope = scopingNode ? scopingNode->treeScope() : treeScope();
if (StyleEngine* styleEngine = document().styleEngine())
styleEngine->removeStyleSheetCandidateNode(this, scopingNode, scope);
}
if (m_sheet)
clearSheet();
}
@ -77,10 +68,10 @@ void HTMLStyleElement::parseAttribute(const QualifiedName& name, const AtomicStr
void HTMLStyleElement::insertedInto(ContainerNode* insertionPoint)
{
HTMLElement::insertedInto(insertionPoint);
if (inActiveDocument()) {
document().styleEngine()->addStyleSheetCandidateNode(this, false);
process();
}
if (!inActiveDocument())
return;
treeScope().styleSheets().addStyleSheetCandidateNode(*this);
process();
}
void HTMLStyleElement::removedFrom(ContainerNode* insertionPoint)
@ -90,14 +81,10 @@ void HTMLStyleElement::removedFrom(ContainerNode* insertionPoint)
if (!insertionPoint->inActiveDocument())
return;
ShadowRoot* scopingNode = containingShadowRoot();
if (!scopingNode)
scopingNode = insertionPoint->containingShadowRoot();
TreeScope* containingScope = containingShadowRoot();
TreeScope& scope = containingScope ? *containingScope : insertionPoint->treeScope();
document().styleEngine()->removeStyleSheetCandidateNode(this, scopingNode, scope);
scope.styleSheets().removeStyleSheetCandidateNode(*this);
RefPtr<CSSStyleSheet> removedSheet = m_sheet.get();