title attribute on style & link elements should be ignored inside a shadow tree
authorrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 3 Dec 2018 20:33:23 +0000 (20:33 +0000)
committerrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 3 Dec 2018 20:33:23 +0000 (20:33 +0000)
https://bugs.webkit.org/show_bug.cgi?id=191297

Reviewed by Antti Koivisto.

LayoutTests/imported/w3c:

Rebaseline the test case that's now passing.

* web-platform-tests/css/css-scoping/stylesheet-title-002-expected.txt:

Source/WebCore:

Fixed the by not setting the stylesheet's title even when the title content attribute is present
or set on SVG/HTML style and link elements inside a shadow tree.

Test: fast/shadow-dom/stylesheet-title-in-shadow-tree.html

* dom/InlineStyleSheetOwner.cpp:
(WebCore::InlineStyleSheetOwner::createSheet):
* html/HTMLLinkElement.cpp:
(WebCore::HTMLLinkElement::parseAttribute):
(WebCore::HTMLLinkElement::initializeStyleSheet):
* html/HTMLStyleElement.cpp:
(WebCore::HTMLStyleElement::parseAttribute):
* style/StyleScope.cpp:
(WebCore::Style::Scope::collectActiveStyleSheets):
* svg/SVGStyleElement.cpp:
(WebCore::SVGStyleElement::parseAttribute):

LayoutTests:

Adde a W3C-style testharness.js test for a more comprehensive testing of the title content attribute
on HTML link and style elements and SVG style element inside a shadow tree.

* TestExpectations:
* fast/shadow-dom/resources/green-div.css: Added.
* fast/shadow-dom/resources/red-div.css: Added.
* fast/shadow-dom/stylesheet-title-in-shadow-tree-expected.txt: Added.
* fast/shadow-dom/stylesheet-title-in-shadow-tree.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@238812 268f45cc-cd09-0410-ab3c-d52691b4dbfc

14 files changed:
LayoutTests/ChangeLog
LayoutTests/TestExpectations
LayoutTests/fast/shadow-dom/resources/green-div.css [new file with mode: 0644]
LayoutTests/fast/shadow-dom/resources/red-div.css [new file with mode: 0644]
LayoutTests/fast/shadow-dom/stylesheet-title-in-shadow-tree-expected.txt [new file with mode: 0644]
LayoutTests/fast/shadow-dom/stylesheet-title-in-shadow-tree.html [new file with mode: 0644]
LayoutTests/imported/w3c/ChangeLog
LayoutTests/imported/w3c/web-platform-tests/css/css-scoping/stylesheet-title-002-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/dom/InlineStyleSheetOwner.cpp
Source/WebCore/html/HTMLLinkElement.cpp
Source/WebCore/html/HTMLStyleElement.cpp
Source/WebCore/style/StyleScope.cpp
Source/WebCore/svg/SVGStyleElement.cpp

index 90af4ba..41d2523 100644 (file)
@@ -1,3 +1,19 @@
+2018-12-03  Ryosuke Niwa  <rniwa@webkit.org>
+
+        title attribute on style & link elements should be ignored inside a shadow tree
+        https://bugs.webkit.org/show_bug.cgi?id=191297
+
+        Reviewed by Antti Koivisto.
+
+        Adde a W3C-style testharness.js test for a more comprehensive testing of the title content attribute
+        on HTML link and style elements and SVG style element inside a shadow tree.
+
+        * TestExpectations:
+        * fast/shadow-dom/resources/green-div.css: Added.
+        * fast/shadow-dom/resources/red-div.css: Added.
+        * fast/shadow-dom/stylesheet-title-in-shadow-tree-expected.txt: Added.
+        * fast/shadow-dom/stylesheet-title-in-shadow-tree.html: Added.
+
 2018-12-03  Truitt Savell  <tsavell@apple.com>
 
         Modify unexpected new line in test after https://trac.webkit.org/changeset/238765/webkit
index 504b080..bb2ddc7 100644 (file)
@@ -2817,7 +2817,6 @@ imported/w3c/web-platform-tests/css/css-display/run-in/run-in-run-in-between-004
 imported/w3c/web-platform-tests/css/css-text-decor/text-emphasis-position-above-left-001.xht [ ImageOnlyFailure ]
 imported/w3c/web-platform-tests/css/css-display/run-in/run-in-listitem-between-003.xht [ ImageOnlyFailure ]
 imported/w3c/web-platform-tests/css/css-display/run-in/run-in-basic-010.xht [ ImageOnlyFailure ]
-imported/w3c/web-platform-tests/css/css-scoping/shadow-disabled-sheet-001.html [ ImageOnlyFailure ]
 imported/w3c/web-platform-tests/css/css-display/run-in/run-in-run-in-between-003.xht [ ImageOnlyFailure ]
 imported/w3c/web-platform-tests/css/css-multicol/multicol-breaking-003.html [ ImageOnlyFailure ]
 imported/w3c/web-platform-tests/css/css-display/run-in/run-in-contains-table-caption-001.xht [ ImageOnlyFailure ]
diff --git a/LayoutTests/fast/shadow-dom/resources/green-div.css b/LayoutTests/fast/shadow-dom/resources/green-div.css
new file mode 100644 (file)
index 0000000..821febf
--- /dev/null
@@ -0,0 +1 @@
+div { background-color: green; }
diff --git a/LayoutTests/fast/shadow-dom/resources/red-div.css b/LayoutTests/fast/shadow-dom/resources/red-div.css
new file mode 100644 (file)
index 0000000..0748ddf
--- /dev/null
@@ -0,0 +1 @@
+div { background-color: red; }
diff --git a/LayoutTests/fast/shadow-dom/stylesheet-title-in-shadow-tree-expected.txt b/LayoutTests/fast/shadow-dom/stylesheet-title-in-shadow-tree-expected.txt
new file mode 100644 (file)
index 0000000..bb69d93
--- /dev/null
@@ -0,0 +1,14 @@
+
+PASS title content attribute on a HTML style element should not set the title of a stylesheet inside a shadow tree of open mode 
+PASS title content attribute on a HTML style element should not set the title of a stylesheet inside a shadow tree of closed mode 
+PASS Setting title content attribute on a HTML style element should not set the title of a stylesheet inside a shadow tree of open mode 
+PASS Setting title content attribute on a HTML style element should not set the title of a stylesheet inside a shadow tree of closed mode 
+PASS title content attribute on a SVG style element should not set the title of a stylesheet inside a shadow tree of open mode 
+PASS title content attribute on a SVG style element should not set the title of a stylesheet inside a shadow tree of closed mode 
+PASS Setting title content attribute on a HTML style element should not set the title of a stylesheet inside a shadow tree of open mode 
+PASS Setting title content attribute on a HTML style element should not set the title of a stylesheet inside a shadow tree of closed mode 
+PASS title content attribute on a HTML style element should not set the title of a stylesheet inside a shadow tree of open mode 
+PASS title content attribute on a HTML style element should not set the title of a stylesheet inside a shadow tree of closed mode 
+PASS Setting title content attribute on a HTML style element should not set the title of a stylesheet inside a shadow tree of open mode 
+PASS Setting title content attribute on a HTML style element should not set the title of a stylesheet inside a shadow tree of closed mode 
+
diff --git a/LayoutTests/fast/shadow-dom/stylesheet-title-in-shadow-tree.html b/LayoutTests/fast/shadow-dom/stylesheet-title-in-shadow-tree.html
new file mode 100644 (file)
index 0000000..86c8f37
--- /dev/null
@@ -0,0 +1,136 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org">
+<meta name="assert" content="title content attribute should not affect the stylesheet's title inside a shadow tree">
+<link rel="help" href="https://html.spec.whatwg.org/#attr-style-title">
+<link rel="help" href="https://html.spec.whatwg.org/#attr-link-title">
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+</head>
+<body>
+<div id="log"></div>
+<script>
+
+function testStyleElementWithTitleInShadowTree(mode) {
+    test(function () {
+        const host = document.createElement('div');
+        document.body.appendChild(host);
+        const shadowRoot = host.attachShadow({'mode': mode});
+        shadowRoot.innerHTML = '<style title="foo">div {width: 10px}</style><style title="bar">div {width: 20px}</style><div></div>';
+        assert_equals(shadowRoot.styleSheets.length, 2);
+        assert_equals(shadowRoot.styleSheets[0].title, null);
+        assert_equals(shadowRoot.styleSheets[1].title, null);
+        assert_equals(getComputedStyle(shadowRoot.querySelector('div')).width, '20px');
+    }, `title content attribute on a HTML style element should not set the title of a stylesheet inside a shadow tree of ${mode} mode`);
+}
+
+testStyleElementWithTitleInShadowTree('open');
+testStyleElementWithTitleInShadowTree('closed');
+
+function testUpdatingTitleOnStyleElemenInShadowTree(mode) {
+    test(function () {
+        const host = document.createElement('div');
+        document.body.appendChild(host);
+        const shadowRoot = host.attachShadow({mode});
+        shadowRoot.innerHTML = '<style>div {height: 10px}</style><style>div {height: 20px}</style><div></div>';
+        assert_equals(shadowRoot.styleSheets.length, 2);
+        assert_equals(shadowRoot.styleSheets[0].title, null);
+        assert_equals(shadowRoot.styleSheets[1].title, null);
+        shadowRoot.children[0].setAttribute('title', 'foo');
+        shadowRoot.children[1].setAttribute('title', 'bar');
+        assert_equals(shadowRoot.styleSheets.length, 2);
+        assert_equals(shadowRoot.styleSheets[0].title, null);
+        assert_equals(shadowRoot.styleSheets[1].title, null);
+        assert_equals(getComputedStyle(shadowRoot.querySelector('div')).height, '20px');
+    }, `Setting title content attribute on a HTML style element should not set the title of a stylesheet inside a shadow tree of ${mode} mode`);
+}
+
+testUpdatingTitleOnStyleElemenInShadowTree('open');
+testUpdatingTitleOnStyleElemenInShadowTree('closed');
+
+function testSVGStyleElementWithTitleInShadowTree(mode) {
+    test(function () {
+        const host = document.createElement('div');
+        document.body.appendChild(host);
+        const shadowRoot = host.attachShadow({'mode': mode});
+        shadowRoot.innerHTML = '<svg><style title="foo">div {width: 10px}</style><style title="bar">div {width: 20px}</style></svg><div></div>';
+        assert_equals(shadowRoot.styleSheets.length, 2);
+        assert_equals(shadowRoot.styleSheets[0].title, null);
+        assert_equals(shadowRoot.styleSheets[1].title, null);
+        assert_equals(getComputedStyle(shadowRoot.querySelector('div')).width, '20px');
+    }, `title content attribute on a SVG style element should not set the title of a stylesheet inside a shadow tree of ${mode} mode`);
+}
+
+testSVGStyleElementWithTitleInShadowTree('open');
+testSVGStyleElementWithTitleInShadowTree('closed');
+
+function testUpdatingTitleOnSVGStyleElemenInShadowTree(mode) {
+    test(function () {
+        const host = document.createElement('div');
+        document.body.appendChild(host);
+        const shadowRoot = host.attachShadow({mode});
+        shadowRoot.innerHTML = '<svg><style>div {height: 10px}</style><style>div {height: 20px}</style></svg><div></div>';
+        assert_equals(shadowRoot.styleSheets.length, 2);
+        assert_equals(shadowRoot.styleSheets[0].title, null);
+        assert_equals(shadowRoot.styleSheets[1].title, null);
+        shadowRoot.firstChild.children[0].setAttribute('title', 'foo');
+        shadowRoot.firstChild.children[1].setAttribute('title', 'bar');
+        assert_equals(shadowRoot.styleSheets.length, 2);
+        assert_equals(shadowRoot.styleSheets[0].title, null);
+        assert_equals(shadowRoot.styleSheets[1].title, null);
+        assert_equals(getComputedStyle(shadowRoot.querySelector('div')).height, '20px');
+    }, `Setting title content attribute on a HTML style element should not set the title of a stylesheet inside a shadow tree of ${mode} mode`);
+}
+
+testUpdatingTitleOnSVGStyleElemenInShadowTree('open');
+testUpdatingTitleOnSVGStyleElemenInShadowTree('closed');
+
+function testLinkElementWithTitleInShadowTree(mode) {
+    promise_test(async function () {
+        const host = document.createElement('div');
+        const shadowRoot = host.attachShadow({'mode': mode});
+        shadowRoot.innerHTML = '<link rel="stylesheet" href="resources/green-div.css" title="foo"><link rel="stylesheet" href="resources/green-div.css" title="bar"><div></div>';
+        const promises = Promise.all(Array.from(shadowRoot.querySelectorAll('link')).map((link) => {
+            return new Promise((resolve) => link.addEventListener('load', resolve));
+        }));
+        document.body.appendChild(host);
+        await promises;
+        assert_equals(shadowRoot.styleSheets.length, 2);
+        assert_equals(shadowRoot.styleSheets[0].title, null);
+        assert_equals(shadowRoot.styleSheets[1].title, null);
+        assert_equals(getComputedStyle(shadowRoot.querySelector('div')).backgroundColor, 'rgb(0, 128, 0)');
+    }, `title content attribute on a HTML style element should not set the title of a stylesheet inside a shadow tree of ${mode} mode`);
+}
+
+testLinkElementWithTitleInShadowTree('open');
+testLinkElementWithTitleInShadowTree('closed');
+
+function testUpdatingTitleOnLinkElementInShadowTree(mode) {
+    promise_test(async function () {
+        const host = document.createElement('div');
+        const shadowRoot = host.attachShadow({'mode': mode});
+        shadowRoot.innerHTML = '<link rel="stylesheet" href="resources/green-div.css" title="foo"><link rel="stylesheet" href="resources/green-div.css" title="bar"><div></div>';
+        const promises = Promise.all(Array.from(shadowRoot.querySelectorAll('link')).map((link) => {
+            return new Promise((resolve) => link.addEventListener('load', resolve));
+        }));
+        document.body.appendChild(host);
+        await promises;
+        assert_equals(shadowRoot.styleSheets.length, 2);
+        assert_equals(shadowRoot.styleSheets[0].title, null);
+        assert_equals(shadowRoot.styleSheets[1].title, null);
+        shadowRoot.children[0].setAttribute('title', 'foo');
+        shadowRoot.children[1].setAttribute('title', 'bar');
+        assert_equals(shadowRoot.styleSheets.length, 2);
+        assert_equals(shadowRoot.styleSheets[0].title, null);
+        assert_equals(shadowRoot.styleSheets[1].title, null);
+        assert_equals(getComputedStyle(shadowRoot.querySelector('div')).backgroundColor, 'rgb(0, 128, 0)');
+    }, `Setting title content attribute on a HTML style element should not set the title of a stylesheet inside a shadow tree of ${mode} mode`);
+}
+
+testUpdatingTitleOnLinkElementInShadowTree('open');
+testUpdatingTitleOnLinkElementInShadowTree('closed');
+
+</script>
+</body>
+</html>
index af0905f..f61b31a 100644 (file)
@@ -1,5 +1,16 @@
 2018-11-30  Ryosuke Niwa  <rniwa@webkit.org>
 
+        title attribute on style & link elements should be ignored inside a shadow tree
+        https://bugs.webkit.org/show_bug.cgi?id=191297
+
+        Reviewed by Antti Koivisto.
+
+        Rebaseline the test case that's now passing.
+
+        * web-platform-tests/css/css-scoping/stylesheet-title-002-expected.txt:
+
+2018-11-30  Ryosuke Niwa  <rniwa@webkit.org>
+
         ShadowRoot should have styleSheets property
         https://bugs.webkit.org/show_bug.cgi?id=191311
 
index a18762e..b3f961e 100644 (file)
@@ -1,3 +1,3 @@
 
-FAIL Title attribute in stylesheets not in the document tree is ignored assert_equals: expected 3 but got 2
+PASS Title attribute in stylesheets not in the document tree is ignored 
 
index 734882a..74cce33 100644 (file)
@@ -1,3 +1,27 @@
+2018-12-03  Ryosuke Niwa  <rniwa@webkit.org>
+
+        title attribute on style & link elements should be ignored inside a shadow tree
+        https://bugs.webkit.org/show_bug.cgi?id=191297
+
+        Reviewed by Antti Koivisto.
+
+        Fixed the by not setting the stylesheet's title even when the title content attribute is present
+        or set on SVG/HTML style and link elements inside a shadow tree.
+
+        Test: fast/shadow-dom/stylesheet-title-in-shadow-tree.html
+
+        * dom/InlineStyleSheetOwner.cpp:
+        (WebCore::InlineStyleSheetOwner::createSheet):
+        * html/HTMLLinkElement.cpp:
+        (WebCore::HTMLLinkElement::parseAttribute):
+        (WebCore::HTMLLinkElement::initializeStyleSheet):
+        * html/HTMLStyleElement.cpp:
+        (WebCore::HTMLStyleElement::parseAttribute):
+        * style/StyleScope.cpp:
+        (WebCore::Style::Scope::collectActiveStyleSheets):
+        * svg/SVGStyleElement.cpp:
+        (WebCore::SVGStyleElement::parseAttribute):
+
 2018-12-03  Zalan Bujtas  <zalan@apple.com>
 
         [iOS] Add logging channel for hover related content observation
index 922233d..109f724 100644 (file)
@@ -189,7 +189,8 @@ void InlineStyleSheetOwner::createSheet(Element& element, const String& text)
             ASSERT(cachedSheet->isCacheable());
             m_sheet = CSSStyleSheet::createInline(*cachedSheet, element, m_startTextPosition);
             m_sheet->setMediaQueries(mediaQueries.releaseNonNull());
-            m_sheet->setTitle(element.title());
+            if (!element.isInShadowTree())
+                m_sheet->setTitle(element.title());
 
             sheetLoaded(element);
             element.notifyLoadedSheetAndAllCriticalSubresources(false);
@@ -203,7 +204,8 @@ void InlineStyleSheetOwner::createSheet(Element& element, const String& text)
 
     m_sheet = CSSStyleSheet::createInline(contents.get(), element, m_startTextPosition);
     m_sheet->setMediaQueries(mediaQueries.releaseNonNull());
-    m_sheet->setTitle(element.title());
+    if (!element.isInShadowTree())
+        m_sheet->setTitle(element.title());
 
     contents->parseString(text);
 
index 68e7868..02ca3c5 100644 (file)
@@ -198,7 +198,7 @@ void HTMLLinkElement::parseAttribute(const QualifiedName& name, const AtomicStri
         return;
     }
     if (name == titleAttr) {
-        if (m_sheet)
+        if (m_sheet && !isInShadowTree())
             m_sheet->setTitle(value);
         return;
     }
@@ -401,7 +401,8 @@ void HTMLLinkElement::initializeStyleSheet(Ref<StyleSheetContents>&& styleSheet,
 
     m_sheet = CSSStyleSheet::create(WTFMove(styleSheet), *this, originClean);
     m_sheet->setMediaQueries(MediaQuerySet::create(m_media, context));
-    m_sheet->setTitle(title());
+    if (!isInShadowTree())
+        m_sheet->setTitle(title());
 
     if (!m_sheet->canAccessRules())
         m_sheet->contents().setAsOpaque();
index a233ace..e528c59 100644 (file)
@@ -78,7 +78,7 @@ Ref<HTMLStyleElement> HTMLStyleElement::create(Document& document)
 
 void HTMLStyleElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
 {
-    if (name == titleAttr && sheet())
+    if (name == titleAttr && sheet() && !isInShadowTree())
         sheet()->setTitle(value);
     else if (name == mediaAttr) {
         m_styleSheetOwner.setMedia(value);
index a5e6d73..f0c159b 100644 (file)
@@ -329,7 +329,7 @@ void Scope::collectActiveStyleSheets(Vector<RefPtr<StyleSheet>>& sheets)
             sheet = downcast<ProcessingInstruction>(*node).sheet();
         } else if (is<HTMLLinkElement>(*node) || is<HTMLStyleElement>(*node) || is<SVGStyleElement>(*node)) {
             Element& element = downcast<Element>(*node);
-            AtomicString title = element.attributeWithoutSynchronization(titleAttr);
+            AtomicString title = element.isInShadowTree() ? nullAtom() : element.attributeWithoutSynchronization(titleAttr);
             bool enabledViaScript = false;
             if (is<HTMLLinkElement>(element)) {
                 // <LINK> element
index 9267d12..d0ca399 100644 (file)
@@ -94,7 +94,7 @@ String SVGStyleElement::title() const
 void SVGStyleElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
 {
     if (name == SVGNames::titleAttr) {
-        if (sheet())
+        if (sheet() && !isInShadowTree())
             sheet()->setTitle(value);
         return;
     }