Diff
Modified: trunk/LayoutTests/ChangeLog (190255 => 190256)
--- trunk/LayoutTests/ChangeLog 2015-09-25 22:04:32 UTC (rev 190255)
+++ trunk/LayoutTests/ChangeLog 2015-09-25 22:06:09 UTC (rev 190256)
@@ -1,3 +1,19 @@
+2015-09-25 Antti Koivisto <[email protected]>
+
+ Implement scoped styling for shadow DOM
+ https://bugs.webkit.org/show_bug.cgi?id=149230
+
+ Reviewed by Ryosuke Niwa.
+
+ * fast/shadow-dom/css-scoping-shadow-with-rules-no-style-leak-expected.html: Added.
+ * fast/shadow-dom/css-scoping-shadow-with-rules-no-style-leak.html: Added.
+
+ Add a test that verifies that shadow DOM style doesn't affect normal DOM.
+
+ * platform/mac/TestExpectations:
+
+ Enable fast/shadow-dom/css-scoping-shadow-with-rules.html
+
2015-09-25 Tim Horton <[email protected]>
Scrolling a overflow: scroll region makes find overlay holes stick to the edge of the region
Added: trunk/LayoutTests/fast/shadow-dom/css-scoping-shadow-with-rules-no-style-leak-expected.html (0 => 190256)
--- trunk/LayoutTests/fast/shadow-dom/css-scoping-shadow-with-rules-no-style-leak-expected.html (rev 0)
+++ trunk/LayoutTests/fast/shadow-dom/css-scoping-shadow-with-rules-no-style-leak-expected.html 2015-09-25 22:06:09 UTC (rev 190256)
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<html>
+<body>
+ <p>Test passes if you see a single 100px by 100px green box below.</p>
+ <div style="width: 100px; height: 100px; background: green;"></div>
+</body>
+</html>
Added: trunk/LayoutTests/fast/shadow-dom/css-scoping-shadow-with-rules-no-style-leak.html (0 => 190256)
--- trunk/LayoutTests/fast/shadow-dom/css-scoping-shadow-with-rules-no-style-leak.html (rev 0)
+++ trunk/LayoutTests/fast/shadow-dom/css-scoping-shadow-with-rules-no-style-leak.html 2015-09-25 22:06:09 UTC (rev 190256)
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>CSS Scoping - a style rule inside a shadow tree doesn't affect the normal dom</title>
+ <link rel="author" title="Ryosuke Niwa" href=""
+ <link rel="help" href=""
+ <link rel="match" href=""
+</head>
+<body>
+ <style>
+ my-host {
+ display: block;
+ }
+ div {
+ width: 100px;
+ height: 100px;
+ background: green;
+ color:green;
+ }
+ </style>
+ <p>Test passes if you see a single 100px by 100px green box below.</p>
+ <my-host>
+ </my-host>
+ <div>FAIL</div>
+ <script>
+
+ try {
+ var shadowHost = document.querySelector('my-host');
+ shadowRoot = shadowHost.attachShadow({mode: 'open'});
+ shadowRoot.innerHTML = '<style> div { background: red; } </style>';
+ } catch (exception) {
+ document.body.appendChild(document.createTextNode(exception));
+ }
+
+ </script>
+</body>
+</html>
Modified: trunk/LayoutTests/platform/mac/TestExpectations (190255 => 190256)
--- trunk/LayoutTests/platform/mac/TestExpectations 2015-09-25 22:04:32 UTC (rev 190255)
+++ trunk/LayoutTests/platform/mac/TestExpectations 2015-09-25 22:06:09 UTC (rev 190256)
@@ -1308,8 +1308,6 @@
webkit.org/b/149128 fast/text/control-characters [ ImageOnlyFailure ]
webkit.org/b/148695 fast/shadow-dom [ Pass ]
-
-webkit.org/b/149328 fast/shadow-dom/css-scoping-shadow-with-rules.html [ ImageOnlyFailure ]
webkit.org/b/149328 fast/shadow-dom/css-scoping-shadow-host-rule.html [ ImageOnlyFailure ]
webkit.org/b/149328 fast/shadow-dom/css-scoping-shadow-host-functional-rule.html [ ImageOnlyFailure ]
webkit.org/b/149328 fast/shadow-dom/css-scoping-shadow-slotted-rule.html [ ImageOnlyFailure ]
Modified: trunk/Source/WebCore/ChangeLog (190255 => 190256)
--- trunk/Source/WebCore/ChangeLog 2015-09-25 22:04:32 UTC (rev 190255)
+++ trunk/Source/WebCore/ChangeLog 2015-09-25 22:06:09 UTC (rev 190256)
@@ -1,3 +1,62 @@
+2015-09-25 Antti Koivisto <[email protected]>
+
+ Implement scoped styling for shadow DOM
+ https://bugs.webkit.org/show_bug.cgi?id=149230
+
+ Reviewed by Ryosuke Niwa.
+
+ Test: fast/shadow-dom/css-scoping-shadow-with-rules-no-style-leak.html
+
+ * css/ElementRuleCollector.cpp:
+ (WebCore::ElementRuleCollector::collectMatchingRules):
+
+ Only use special path here for user agent shadow trees.
+
+ * dom/AuthorStyleSheets.cpp:
+ (WebCore::AuthorStyleSheets::AuthorStyleSheets):
+ (WebCore::AuthorStyleSheets::removePendingSheet):
+ (WebCore::AuthorStyleSheets::updateActiveStyleSheets):
+
+ Basic support for ShadowRoot scoped stylesheets.
+
+ * dom/AuthorStyleSheets.h:
+ (WebCore::AuthorStyleSheets::activeStyleSheets):
+ * dom/InlineStyleSheetOwner.cpp:
+ (WebCore::InlineStyleSheetOwner::~InlineStyleSheetOwner):
+ (WebCore::authorStyleSheetsForElement):
+ (WebCore::InlineStyleSheetOwner::insertedIntoDocument):
+ (WebCore::InlineStyleSheetOwner::removedFromDocument):
+ (WebCore::InlineStyleSheetOwner::clearDocumentData):
+ (WebCore::InlineStyleSheetOwner::childrenChanged):
+ (WebCore::InlineStyleSheetOwner::createSheet):
+ (WebCore::InlineStyleSheetOwner::isLoading):
+ (WebCore::InlineStyleSheetOwner::sheetLoaded):
+ (WebCore::InlineStyleSheetOwner::startLoadingDynamicSheet):
+
+ Basic support for ShadowRoot scoped inline stylesheets.
+
+ * dom/InlineStyleSheetOwner.h:
+ (WebCore::InlineStyleSheetOwner::sheet):
+ * dom/ShadowRoot.cpp:
+ (WebCore::ShadowRoot::styleResolver):
+
+ Create and initialize ShadowRoot scoped style resolver.
+
+ (WebCore::ShadowRoot::resetStyleResolver):
+ (WebCore::ShadowRoot::authorStyleSheets):
+
+ Collection of author stylesheets in the shadow tree.
+
+ (WebCore::ShadowRoot::updateStyle):
+
+ Trigger style recalc when stylesheets change.
+
+ (WebCore::ShadowRoot::cloneNode):
+ * dom/ShadowRoot.h:
+ (WebCore::ShadowRoot::resetStyleInheritance):
+ * html/HTMLStyleElement.h:
+ * svg/SVGStyleElement.h:
+
2015-09-25 Alex Christensen <[email protected]>
Clean up CMake build on Mac
Modified: trunk/Source/WebCore/css/ElementRuleCollector.cpp (190255 => 190256)
--- trunk/Source/WebCore/css/ElementRuleCollector.cpp 2015-09-25 22:04:32 UTC (rev 190255)
+++ trunk/Source/WebCore/css/ElementRuleCollector.cpp 2015-09-25 22:06:09 UTC (rev 190256)
@@ -40,6 +40,7 @@
#include "RenderRegion.h"
#include "SVGElement.h"
#include "SelectorCompiler.h"
+#include "ShadowRoot.h"
#include "StyleProperties.h"
#include "StyledElement.h"
@@ -152,7 +153,8 @@
collectMatchingRulesForList(matchRequest.ruleSet->cuePseudoRules(), matchRequest, ruleRange);
#endif
- if (m_element.isInShadowTree()) {
+ auto* shadowRoot = m_element.containingShadowRoot();
+ if (shadowRoot && shadowRoot->type() == ShadowRoot::Type::UserAgent) {
const AtomicString& pseudoId = m_element.shadowPseudoId();
if (!pseudoId.isEmpty())
collectMatchingRulesForList(matchRequest.ruleSet->shadowPseudoElementRules(pseudoId.impl()), matchRequest, ruleRange);
Modified: trunk/Source/WebCore/dom/AuthorStyleSheets.cpp (190255 => 190256)
--- trunk/Source/WebCore/dom/AuthorStyleSheets.cpp 2015-09-25 22:04:32 UTC (rev 190255)
+++ trunk/Source/WebCore/dom/AuthorStyleSheets.cpp 2015-09-25 22:06:09 UTC (rev 190256)
@@ -41,6 +41,7 @@
#include "SVGNames.h"
#include "SVGStyleElement.h"
#include "Settings.h"
+#include "ShadowRoot.h"
#include "StyleInvalidationAnalysis.h"
#include "StyleResolver.h"
#include "StyleSheetContents.h"
@@ -54,11 +55,17 @@
using namespace ContentExtensions;
using namespace HTMLNames;
-AuthorStyleSheets::AuthorStyleSheets(TreeScope& treeScope)
- : m_document(treeScope.documentScope())
+AuthorStyleSheets::AuthorStyleSheets(Document& document)
+ : m_document(document)
{
}
+AuthorStyleSheets::AuthorStyleSheets(ShadowRoot& shadowRoot)
+ : m_document(shadowRoot.documentScope())
+ , m_shadowRoot(&shadowRoot)
+{
+}
+
// This method is called whenever a top-level stylesheet has finished loading.
void AuthorStyleSheets::removePendingSheet(RemovePendingSheetNotificationType notification)
{
@@ -79,7 +86,12 @@
m_document.setNeedsNotifyRemoveAllPendingStylesheet();
return;
}
-
+
+ if (m_shadowRoot) {
+ m_shadowRoot->updateStyle();
+ return;
+ }
+
m_document.didRemoveAllPendingStylesheet();
}
@@ -299,9 +311,12 @@
bool requiresFullStyleRecalc;
analyzeStyleSheetChange(updateFlag, activeCSSStyleSheets, styleResolverUpdateType, requiresFullStyleRecalc);
- if (styleResolverUpdateType == Reconstruct)
- m_document.clearStyleResolver();
- else {
+ if (styleResolverUpdateType == Reconstruct) {
+ if (m_shadowRoot)
+ m_shadowRoot->resetStyleResolver();
+ else
+ m_document.clearStyleResolver();
+ } else {
StyleResolver& styleResolver = m_document.ensureStyleResolver();
if (styleResolverUpdateType == Reset) {
styleResolver.ruleSets().resetAuthorStyle();
Modified: trunk/Source/WebCore/dom/AuthorStyleSheets.h (190255 => 190256)
--- trunk/Source/WebCore/dom/AuthorStyleSheets.h 2015-09-25 22:04:32 UTC (rev 190255)
+++ trunk/Source/WebCore/dom/AuthorStyleSheets.h 2015-09-25 22:06:09 UTC (rev 190256)
@@ -45,12 +45,14 @@
class StyleSheet;
class StyleSheetContents;
class StyleSheetList;
+class ShadowRoot;
class TreeScope;
class AuthorStyleSheets {
WTF_MAKE_FAST_ALLOCATED;
public:
- explicit AuthorStyleSheets(TreeScope&);
+ explicit AuthorStyleSheets(Document&);
+ explicit AuthorStyleSheets(ShadowRoot&);
const Vector<RefPtr<CSSStyleSheet>>& activeStyleSheets() const { return m_activeStyleSheets; }
@@ -107,6 +109,7 @@
void analyzeStyleSheetChange(UpdateFlag, const Vector<RefPtr<CSSStyleSheet>>& newStylesheets, StyleResolverUpdateType&, bool& requiresFullStyleRecalc);
Document& m_document;
+ ShadowRoot* m_shadowRoot { nullptr };
Vector<RefPtr<StyleSheet>> m_styleSheetsForStyleSheetList;
Vector<RefPtr<CSSStyleSheet>> m_activeStyleSheets;
Modified: trunk/Source/WebCore/dom/InlineStyleSheetOwner.cpp (190255 => 190256)
--- trunk/Source/WebCore/dom/InlineStyleSheetOwner.cpp 2015-09-25 22:04:32 UTC (rev 190255)
+++ trunk/Source/WebCore/dom/InlineStyleSheetOwner.cpp 2015-09-25 22:06:09 UTC (rev 190256)
@@ -27,6 +27,7 @@
#include "MediaList.h"
#include "MediaQueryEvaluator.h"
#include "ScriptableDocumentParser.h"
+#include "ShadowRoot.h"
#include "StyleSheetContents.h"
#include "TextNodeTraversal.h"
#include <wtf/text/StringBuilder.h>
@@ -46,10 +47,16 @@
{
}
-void InlineStyleSheetOwner::insertedIntoDocument(Document& document, Element& element)
+static AuthorStyleSheets& authorStyleSheetsForElement(Element& element)
{
- document.authorStyleSheets().addStyleSheetCandidateNode(element, m_isParsingChildren);
+ auto* shadowRoot = element.containingShadowRoot();
+ return shadowRoot ? shadowRoot->authorStyleSheets() : element.document().authorStyleSheets();
+}
+void InlineStyleSheetOwner::insertedIntoDocument(Document&, Element& element)
+{
+ authorStyleSheetsForElement(element).addStyleSheetCandidateNode(element, m_isParsingChildren);
+
if (m_isParsingChildren)
return;
createSheetFromTextContents(element);
@@ -57,7 +64,7 @@
void InlineStyleSheetOwner::removedFromDocument(Document& document, Element& element)
{
- document.authorStyleSheets().removeStyleSheetCandidateNode(element);
+ authorStyleSheetsForElement(element).removeStyleSheetCandidateNode(element);
if (m_sheet)
clearSheet();
@@ -67,14 +74,14 @@
document.styleResolverChanged(DeferRecalcStyle);
}
-void InlineStyleSheetOwner::clearDocumentData(Document& document, Element& element)
+void InlineStyleSheetOwner::clearDocumentData(Document&, Element& element)
{
if (m_sheet)
m_sheet->clearOwnerNode();
if (!element.inDocument())
return;
- document.authorStyleSheets().removeStyleSheetCandidateNode(element);
+ authorStyleSheetsForElement(element).removeStyleSheetCandidateNode(element);
}
void InlineStyleSheetOwner::childrenChanged(Element& element)
@@ -138,7 +145,7 @@
if (!screenEval.eval(mediaQueries.get()) && !printEval.eval(mediaQueries.get()))
return;
- document.authorStyleSheets().addPendingSheet();
+ authorStyleSheetsForElement(element).addPendingSheet();
m_loading = true;
@@ -160,18 +167,18 @@
return m_sheet && m_sheet->isLoading();
}
-bool InlineStyleSheetOwner::sheetLoaded(Document& document)
+bool InlineStyleSheetOwner::sheetLoaded(Element& element)
{
if (isLoading())
return false;
- document.authorStyleSheets().removePendingSheet();
+ authorStyleSheetsForElement(element).removePendingSheet();
return true;
}
-void InlineStyleSheetOwner::startLoadingDynamicSheet(Document& document)
+void InlineStyleSheetOwner::startLoadingDynamicSheet(Element& element)
{
- document.authorStyleSheets().addPendingSheet();
+ authorStyleSheetsForElement(element).addPendingSheet();
}
}
Modified: trunk/Source/WebCore/dom/InlineStyleSheetOwner.h (190255 => 190256)
--- trunk/Source/WebCore/dom/InlineStyleSheetOwner.h 2015-09-25 22:04:32 UTC (rev 190255)
+++ trunk/Source/WebCore/dom/InlineStyleSheetOwner.h 2015-09-25 22:06:09 UTC (rev 190256)
@@ -41,8 +41,8 @@
CSSStyleSheet* sheet() const { return m_sheet.get(); }
bool isLoading() const;
- bool sheetLoaded(Document&);
- void startLoadingDynamicSheet(Document&);
+ bool sheetLoaded(Element&);
+ void startLoadingDynamicSheet(Element&);
void insertedIntoDocument(Document&, Element&);
void removedFromDocument(Document&, Element&);
Modified: trunk/Source/WebCore/dom/ShadowRoot.cpp (190255 => 190256)
--- trunk/Source/WebCore/dom/ShadowRoot.cpp 2015-09-25 22:04:32 UTC (rev 190255)
+++ trunk/Source/WebCore/dom/ShadowRoot.cpp 2015-09-25 22:06:09 UTC (rev 190256)
@@ -27,6 +27,8 @@
#include "config.h"
#include "ShadowRoot.h"
+#include "AuthorStyleSheets.h"
+#include "CSSStyleSheet.h"
#include "ElementTraversal.h"
#include "InsertionPoint.h"
#include "RenderElement.h"
@@ -40,6 +42,7 @@
struct SameSizeAsShadowRoot : public DocumentFragment, public TreeScope {
unsigned countersAndFlags[1];
void* styleResolver;
+ void* authorStyleSheets;
void* host;
#if ENABLE(SHADOW_DOM)
void* slotAssignment;
@@ -73,12 +76,44 @@
StyleResolver& ShadowRoot::styleResolver()
{
- if (m_styleResolver)
- return *m_styleResolver;
+ // FIXME: Use isolated style resolver for user agent shadow roots.
+ if (m_type == Type::UserAgent)
+ return document().ensureStyleResolver();
- return document().ensureStyleResolver();
+ if (!m_styleResolver) {
+ // FIXME: We could share style resolver with shadow roots that have identical style.
+ m_styleResolver = std::make_unique<StyleResolver>(document(), true);
+ if (m_authorStyleSheets)
+ m_styleResolver->appendAuthorStyleSheets(0, m_authorStyleSheets->activeStyleSheets());
+ }
+ return *m_styleResolver;
}
+void ShadowRoot::resetStyleResolver()
+{
+ m_styleResolver = nullptr;
+}
+
+AuthorStyleSheets& ShadowRoot::authorStyleSheets()
+{
+ if (!m_authorStyleSheets)
+ m_authorStyleSheets = std::make_unique<AuthorStyleSheets>(*this);
+ return *m_authorStyleSheets;
+}
+
+void ShadowRoot::updateStyle()
+{
+ bool shouldRecalcStyle = false;
+
+ if (m_authorStyleSheets) {
+ // FIXME: Make optimized updated work.
+ shouldRecalcStyle = m_authorStyleSheets->updateActiveStyleSheets(AuthorStyleSheets::FullUpdate);
+ }
+
+ if (shouldRecalcStyle)
+ setNeedsStyleRecalc();
+}
+
PassRefPtr<Node> ShadowRoot::cloneNode(bool, ExceptionCode& ec)
{
ec = DATA_CLONE_ERR;
Modified: trunk/Source/WebCore/dom/ShadowRoot.h (190255 => 190256)
--- trunk/Source/WebCore/dom/ShadowRoot.h 2015-09-25 22:04:32 UTC (rev 190255)
+++ trunk/Source/WebCore/dom/ShadowRoot.h 2015-09-25 22:06:09 UTC (rev 190256)
@@ -36,6 +36,7 @@
namespace WebCore {
+class AuthorStyleSheets;
class ContentDistributor;
class HTMLSlotElement;
class SlotAssignment;
@@ -56,6 +57,10 @@
virtual ~ShadowRoot();
StyleResolver& styleResolver();
+ AuthorStyleSheets& authorStyleSheets();
+
+ void updateStyle();
+ void resetStyleResolver();
bool resetStyleInheritance() const { return m_resetStyleInheritance; }
void setResetStyleInheritance(bool);
@@ -102,10 +107,11 @@
bool m_resetStyleInheritance;
Type m_type;
+ Element* m_host;
+
std::unique_ptr<StyleResolver> m_styleResolver;
+ std::unique_ptr<AuthorStyleSheets> m_authorStyleSheets;
- Element* m_host;
-
#if ENABLE(SHADOW_DOM)
std::unique_ptr<SlotAssignment> m_slotAssignments;
#endif
Modified: trunk/Source/WebCore/html/HTMLStyleElement.h (190255 => 190256)
--- trunk/Source/WebCore/html/HTMLStyleElement.h 2015-09-25 22:04:32 UTC (rev 190255)
+++ trunk/Source/WebCore/html/HTMLStyleElement.h 2015-09-25 22:06:09 UTC (rev 190256)
@@ -59,9 +59,9 @@
virtual void finishParsingChildren() override;
bool isLoading() const { return m_styleSheetOwner.isLoading(); }
- virtual bool sheetLoaded() override { return m_styleSheetOwner.sheetLoaded(document()); }
+ virtual bool sheetLoaded() override { return m_styleSheetOwner.sheetLoaded(*this); }
virtual void notifyLoadedSheetAndAllCriticalSubresources(bool errorOccurred) override;
- virtual void startLoadingDynamicSheet() override { m_styleSheetOwner.startLoadingDynamicSheet(document()); }
+ virtual void startLoadingDynamicSheet() override { m_styleSheetOwner.startLoadingDynamicSheet(*this); }
virtual void addSubresourceAttributeURLs(ListHashSet<URL>&) const override;
Modified: trunk/Source/WebCore/svg/SVGStyleElement.h (190255 => 190256)
--- trunk/Source/WebCore/svg/SVGStyleElement.h 2015-09-25 22:04:32 UTC (rev 190255)
+++ trunk/Source/WebCore/svg/SVGStyleElement.h 2015-09-25 22:06:09 UTC (rev 190256)
@@ -59,8 +59,8 @@
virtual void finishParsingChildren() override;
virtual bool isLoading() const { return m_styleSheetOwner.isLoading(); }
- virtual bool sheetLoaded() override { return m_styleSheetOwner.sheetLoaded(document()); }
- virtual void startLoadingDynamicSheet() override { m_styleSheetOwner.startLoadingDynamicSheet(document()); }
+ virtual bool sheetLoaded() override { return m_styleSheetOwner.sheetLoaded(*this); }
+ virtual void startLoadingDynamicSheet() override { m_styleSheetOwner.startLoadingDynamicSheet(*this); }
virtual Timer* svgLoadEventTimer() override { return &m_svgLoadEventTimer; }
InlineStyleSheetOwner m_styleSheetOwner;