Commit 56974e50 authored by tasak@google.com's avatar tasak@google.com

Added addXSLStyleSheet and removeXSLStyleSheet to StyleEngine.

To apply XSLStyleSheet, we only need the first one. We don't need
to have all XSL stylesheets if the XML document has more than two
XSL stylesheets. So modified not to add XSLStyleSheet to
StyleSheetCandidateNodes. Instead, modified to make StyleEngine have
the first XSLStyleSheet.

BUG=367689
TEST=No new test, because this patch is just for refactoring.

Review URL: https://codereview.chromium.org/257363002

git-svn-id: svn://svn.chromium.org/blink/trunk@175775 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 62f6c5db
......@@ -51,21 +51,7 @@ void DocumentStyleSheetCollection::collectStyleSheetsFromCandidates(StyleEngine*
Node* n = *it;
StyleSheetCandidate candidate(*n);
if (candidate.isXSL()) {
// Processing instruction (XML documents only).
// We don't support linking to embedded CSS stylesheets, see <https://bugs.webkit.org/show_bug.cgi?id=49281> for discussion.
// Don't apply XSL transforms to already transformed documents -- <rdar://problem/4132806>
if (RuntimeEnabledFeatures::xsltEnabled() && !document().transformSourceDocument()) {
ProcessingInstruction* pi = toProcessingInstruction(n);
// Don't apply XSL transforms until loading is finished.
if (!document().parsing() && !pi->isLoading())
document().applyXSLTransform(pi);
return;
}
continue;
}
ASSERT(!candidate.isXSL());
if (candidate.isImport()) {
Document* document = candidate.importedDocument();
if (!document)
......
......@@ -59,8 +59,15 @@ ProcessingInstruction::~ProcessingInstruction()
if (m_sheet)
m_sheet->clearOwnerNode();
if (inDocument())
document().styleEngine()->removeStyleSheetCandidateNode(this);
// FIXME: ProcessingInstruction should not be in document here.
// However, if we add ASSERT(!inDocument()), fast/xsl/xslt-entity.xml
// crashes. We need to investigate ProcessingInstruction lifetime.
if (inDocument()) {
if (m_isCSS)
document().styleEngine()->removeStyleSheetCandidateNode(this);
else if (m_isXSL)
document().styleEngine()->removeXSLStyleSheet(this);
}
#endif
}
......@@ -242,11 +249,11 @@ Node::InsertionNotificationRequest ProcessingInstruction::insertedInto(Container
String href;
String charset;
// To make it possible for us to see isXSL in
// StyleEngine::addStyleSheetCandidateNode, split checkStyleSheet
// into two methods, checkStyleSheet and process.
bool isValid = checkStyleSheet(href, charset);
document().styleEngine()->addStyleSheetCandidateNode(this, m_createdByParser);
if (m_isCSS)
document().styleEngine()->addStyleSheetCandidateNode(this, m_createdByParser);
else if (m_isXSL)
document().styleEngine()->addXSLStyleSheet(this, m_createdByParser);
if (isValid)
process(href, charset);
return InsertionDone;
......@@ -258,7 +265,10 @@ void ProcessingInstruction::removedFrom(ContainerNode* insertionPoint)
if (!insertionPoint->inDocument())
return;
document().styleEngine()->removeStyleSheetCandidateNode(this);
if (m_isCSS)
document().styleEngine()->removeStyleSheetCandidateNode(this);
else if (m_isXSL)
document().styleEngine()->removeXSLStyleSheet(this);
RefPtrWillBeRawPtr<StyleSheet> removedSheet = m_sheet;
......
......@@ -86,6 +86,11 @@ private:
DEFINE_NODE_TYPE_CASTS(ProcessingInstruction, nodeType() == Node::PROCESSING_INSTRUCTION_NODE);
inline bool isXSLStyleSheet(const Node& node)
{
return node.nodeType() == Node::PROCESSING_INSTRUCTION_NODE && toProcessingInstruction(node).isXSL();
}
} // namespace WebCore
#endif
......@@ -75,6 +75,7 @@ StyleEngine::StyleEngine(Document& document)
// We don't need to create CSSFontSelector for imported document or
// HTMLTemplateElement's document, because those documents have no frame.
, m_fontSelector(document.frame() ? CSSFontSelector::create(&document) : nullptr)
, m_xslStyleSheet(nullptr)
{
if (m_fontSelector)
m_fontSelector->registerForInvalidationCallbacks(this);
......@@ -286,7 +287,7 @@ void StyleEngine::addStyleSheetCandidateNode(Node* node, bool createdByParser)
TreeScope& treeScope = isHTMLStyleElement(*node) ? node->treeScope() : *m_document;
ASSERT(isHTMLStyleElement(node) || treeScope == m_document);
ASSERT(!isXSLStyleSheet(*node));
TreeScopeStyleSheetCollection* collection = ensureStyleSheetCollectionFor(treeScope);
ASSERT(collection);
collection->addStyleSheetCandidateNode(node, createdByParser);
......@@ -304,6 +305,7 @@ void StyleEngine::removeStyleSheetCandidateNode(Node* node)
void StyleEngine::removeStyleSheetCandidateNode(Node* node, ContainerNode* scopingNode, TreeScope& treeScope)
{
ASSERT(isHTMLStyleElement(node) || treeScope == m_document);
ASSERT(!isXSLStyleSheet(*node));
TreeScopeStyleSheetCollection* collection = styleSheetCollectionFor(treeScope);
ASSERT(collection);
......@@ -313,6 +315,37 @@ void StyleEngine::removeStyleSheetCandidateNode(Node* node, ContainerNode* scopi
m_activeTreeScopes.remove(&treeScope);
}
void StyleEngine::addXSLStyleSheet(ProcessingInstruction* node, bool createdByParser)
{
if (!node->inDocument())
return;
ASSERT(isXSLStyleSheet(*node));
bool needToUpdate = false;
if (createdByParser || !m_xslStyleSheet) {
needToUpdate = !m_xslStyleSheet;
} else {
unsigned position = m_xslStyleSheet->compareDocumentPositionInternal(node, Node::TreatShadowTreesAsDisconnected);
needToUpdate = position & Node::DOCUMENT_POSITION_FOLLOWING;
}
if (!needToUpdate)
return;
markTreeScopeDirty(*m_document);
m_xslStyleSheet = node;
}
void StyleEngine::removeXSLStyleSheet(ProcessingInstruction* node)
{
ASSERT(isXSLStyleSheet(*node));
if (m_xslStyleSheet != node)
return;
markTreeScopeDirty(*m_document);
m_xslStyleSheet = nullptr;
}
void StyleEngine::modifiedStyleSheetCandidateNode(Node* node)
{
if (!node->inDocument())
......@@ -487,6 +520,13 @@ bool StyleEngine::shouldClearResolver() const
return !m_didCalculateResolver && !haveStylesheetsLoaded();
}
bool StyleEngine::shouldApplyXSLTransform() const
{
if (!RuntimeEnabledFeatures::xsltEnabled())
return false;
return m_xslStyleSheet && !m_document->transformSourceDocument();
}
StyleResolverChange StyleEngine::resolverChanged(StyleResolverUpdateMode mode)
{
StyleResolverChange change;
......@@ -504,6 +544,15 @@ StyleResolverChange StyleEngine::resolverChanged(StyleResolverUpdateMode mode)
return change;
}
if (shouldApplyXSLTransform()) {
// Processing instruction (XML documents only).
// We don't support linking to embedded CSS stylesheets, see <https://bugs.webkit.org/show_bug.cgi?id=49281> for discussion.
// Don't apply XSL transforms to already transformed documents -- <rdar://problem/4132806>
if (!m_document->parsing() && !m_xslStyleSheet->isLoading())
m_document->applyXSLTransform(m_xslStyleSheet.get());
return change;
}
m_didCalculateResolver = true;
if (document().didLayoutWithPendingStylesheets() && !hasPendingSheets())
change.setNeedsRepaint();
......
......@@ -109,6 +109,8 @@ public:
void removeStyleSheetCandidateNode(Node*, ContainerNode* scopingNode, TreeScope&);
void modifiedStyleSheetCandidateNode(Node*);
void enableExitTransitionStylesheets();
void addXSLStyleSheet(ProcessingInstruction*, bool createdByParser);
void removeXSLStyleSheet(ProcessingInstruction*);
void invalidateInjectedStyleSheetCache();
void updateInjectedStyleSheetCache() const;
......@@ -200,6 +202,7 @@ private:
TreeScopeStyleSheetCollection* ensureStyleSheetCollectionFor(TreeScope&);
TreeScopeStyleSheetCollection* styleSheetCollectionFor(TreeScope&);
bool shouldUpdateShadowTreeStyleSheetCollection(StyleResolverUpdateMode);
bool shouldApplyXSLTransform() const;
void markTreeScopeDirty(TreeScope&);
......@@ -278,6 +281,8 @@ private:
WillBeHeapHashMap<AtomicString, RawPtrWillBeMember<StyleSheetContents> > m_textToSheetCache;
WillBeHeapHashMap<RawPtrWillBeMember<StyleSheetContents>, AtomicString> m_sheetToTextCache;
RefPtr<ProcessingInstruction> m_xslStyleSheet;
};
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment