diff --git a/engine/core/dom/StyleEngine.cpp b/engine/core/dom/StyleEngine.cpp index d82012de585..3c75e5bb591 100644 --- a/engine/core/dom/StyleEngine.cpp +++ b/engine/core/dom/StyleEngine.cpp @@ -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 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()); diff --git a/engine/core/dom/StyleEngine.h b/engine/core/dom/StyleEngine.h index 685d51b87c3..307f7a75e89 100644 --- a/engine/core/dom/StyleEngine.h +++ b/engine/core/dom/StyleEngine.h @@ -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(); diff --git a/engine/core/dom/StyleSheetCollection.cpp b/engine/core/dom/StyleSheetCollection.cpp index 3c220fc2548..91470b462ba 100644 --- a/engine/core/dom/StyleSheetCollection.cpp +++ b/engine/core/dom/StyleSheetCollection.cpp @@ -46,31 +46,21 @@ StyleSheetCollection::~StyleSheetCollection() { } -void StyleSheetCollection::addStyleSheetCandidateNode(Node* node, bool) +void StyleSheetCollection::addStyleSheetCandidateNode(HTMLStyleElement& element) { - if (!node->inDocument()) - return; - - // Until the 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>& 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); } diff --git a/engine/core/dom/StyleSheetCollection.h b/engine/core/dom/StyleSheetCollection.h index 48d2377db20..bdd208f286c 100644 --- a/engine/core/dom/StyleSheetCollection.h +++ b/engine/core/dom/StyleSheetCollection.h @@ -38,6 +38,7 @@ namespace blink { class CSSStyleSheet; class ContainerNode; +class HTMLStyleElement; class StyleEngine; class TreeScope; @@ -54,9 +55,8 @@ public: Vector >& activeAuthorStyleSheets() { return m_activeAuthorStyleSheets; } const Vector >& 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*); diff --git a/engine/core/dom/shadow/ShadowRoot.cpp b/engine/core/dom/shadow/ShadowRoot.cpp index 0faf6614c56..f2084717f26 100644 --- a/engine/core/dom/shadow/ShadowRoot.cpp +++ b/engine/core/dom/shadow/ShadowRoot.cpp @@ -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); } diff --git a/engine/core/html/HTMLStyleElement.cpp b/engine/core/html/HTMLStyleElement.cpp index 265fd750e53..13501168ff7 100644 --- a/engine/core/html/HTMLStyleElement.cpp +++ b/engine/core/html/HTMLStyleElement.cpp @@ -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 removedSheet = m_sheet.get();