mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
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:
parent
2b77bba1d8
commit
04288dc280
@ -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());
|
||||
|
||||
|
||||
@ -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();
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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*);
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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();
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user