Skip to content

Commit f1bbeff

Browse files
mfreed7moz-wptsync-bot
authored andcommitted
Bug 1624068 [wpt PR 22374] - Disable @import in replace() and replaceSync(), a=testonly
Automatic update from web-platform-tests Disable @import in replace() and replaceSync() The CSSWG resolved [1] that "@import doesn't parse in constructable stylesheets and as a result throw syntax errors". We have a comment [2] requesting clarification, but the working assumption is: - calling replace() with text that includes @import will ignore the @import, and issue a console warning. - calling replaceSync() with text that includes @import will ignore the @import, and issue a console warning. - calling insertRule() on a constructed stylesheet with an @import rule will throw a SyntaxError. (no change here) *Prior* to this CL, the behavior of Chromium was: - calling replace() with text that includes @import would work. The returned Promise would resolve once all @imports were loaded. Any invalid @import rules would cause a NetworkError to be thrown. - calling replaceSync() with text that includes @import would throw a "NotAllowed" exception. - calling insertRule() on a constructed stylesheet with an @import rule will throw a SyntaxError. The Intent to Remove for this change is at [3]. [1] WICG/construct-stylesheets#119 (comment) [2] WICG/construct-stylesheets#119 (comment) [3] https://groups.google.com/a/chromium.org/g/blink-dev/c/RKG8oxp22RY/m/fdFnG1rGCgAJ Bug: 1055943 Change-Id: I0a8444289b137b4c2880be5231696bb526331107 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2106996 Reviewed-by: Mason Freed <[email protected]> Reviewed-by: Rune Lillesveen <[email protected]> Reviewed-by: Rakina Zata Amni <[email protected]> Commit-Queue: Mason Freed <[email protected]> Cr-Commit-Position: refs/heads/master@{#756894} -- wpt-commits: e797def7c972c5a7e7f6d37d909931d1f34bb6dc wpt-pr: 22374
1 parent b3df1ff commit f1bbeff

File tree

2 files changed

+68
-41
lines changed

2 files changed

+68
-41
lines changed

testing/web-platform/tests/css/cssom/CSSStyleSheet-constructable.html

+66-39
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848

4949
test(() => {
5050
const sheet = new CSSStyleSheet({disabled: true, media: "screen, print"});
51-
assert_equals(sheet.title, null);
51+
assert_equals(sheet.title, null, "The title attribute must return the title or null if title is the empty string");
5252
assert_equals(sheet.ownerNode, null);
5353
assert_equals(sheet.ownerRule, null);
5454
assert_equals(sheet.media.length, 2);
@@ -66,7 +66,7 @@
6666
assert_equals(sheet.cssRules[0].cssText, redStyleTexts[1]);
6767

6868
const sheet2 = new CSSStyleSheet({});
69-
assert_equals(sheet2.title, null);
69+
assert_equals(sheet2.title, null, "The title attribute must return the title or null if title is the empty string");
7070
assert_equals(sheet2.ownerNode, null);
7171
assert_equals(sheet2.ownerRule, null);
7272
assert_equals(sheet2.media.length, 0);
@@ -81,7 +81,7 @@
8181
assert_equals(sheet2.cssRules.length, 0);
8282

8383
const sheet3 = new CSSStyleSheet();
84-
assert_equals(sheet3.title, null);
84+
assert_equals(sheet3.title, null, "The title attribute must return the title or null if title is the empty string");
8585
assert_equals(sheet3.ownerNode, null);
8686
assert_equals(sheet3.ownerRule, null);
8787
assert_equals(sheet3.media.length, 0);
@@ -98,14 +98,14 @@
9898

9999
test(() => {
100100
const sheet = new CSSStyleSheet({title: "something"});
101-
assert_equals(sheet.title, null);
102-
}, "title cannot be set in the CSSStyleSheet constructor");
101+
assert_equals(sheet.title, null, "title and alternate are not supported by the constructor. https://github.com/WICG/construct-stylesheets/issues/105");
102+
}, "title can be set in the CSSStyleSheet constructor");
103103

104104
promise_test(() => {
105105
const sheet = new CSSStyleSheet({disabled: true, media: "screen, print"});
106106
const promise_sheet = sheet.replace(redStyleTexts[0]);
107107
return promise_sheet.then(function(sheet) {
108-
assert_equals(sheet.title, null);
108+
assert_equals(sheet.title, null, "The title attribute must return the title or null if title is the empty string");
109109
assert_equals(sheet.ownerNode, null);
110110
assert_equals(sheet.ownerRule, null);
111111
assert_equals(sheet.media.length, 2);
@@ -535,24 +535,19 @@
535535
const style = document.createElement("style");
536536
style.textContent = ".target { color: white; }";
537537
span.shadowRoot.appendChild(style)
538-
// non-adopted styles should be ordered before adopted styles
539-
assert_equals(getComputedStyle(shadowDiv).color, "rgb(255, 0, 0)");
538+
assert_equals(getComputedStyle(shadowDiv).color, "rgb(255, 0, 0)", "non-adopted styles should be ordered before adopted styles");
540539

541540
span.shadowRoot.adoptedStyleSheets = [];
542-
// with no adopted styles in conflict, the non-adopted style should take effect
543-
assert_equals(getComputedStyle(shadowDiv).color, "rgb(255, 255, 255)");
541+
assert_equals(getComputedStyle(shadowDiv).color, "rgb(255, 255, 255)", "with no adopted styles in conflict, the non-adopted style should take effect");
544542

545543
span.shadowRoot.adoptedStyleSheets = [sheet];
546-
// the adopted style should be ordered after the non-adopted style
547-
assert_equals(getComputedStyle(shadowDiv).color, "rgb(255, 0, 0)");
544+
assert_equals(getComputedStyle(shadowDiv).color, "rgb(255, 0, 0)", "the adopted style should be ordered after the non-adopted style");
548545

549546
sheet.disabled = true;
550-
// with the adopted sheet disabled, the non-adopted style should take effect
551-
assert_equals(getComputedStyle(shadowDiv).color, "rgb(255, 255, 255)");
547+
assert_equals(getComputedStyle(shadowDiv).color, "rgb(255, 255, 255)", "with the adopted sheet disabled, the non-adopted style should take effect");
552548

553549
sheet.disabled = false;
554-
// the adopted sheet re-enabled, it should take effect again.
555-
assert_equals(getComputedStyle(shadowDiv).color, "rgb(255, 0, 0)");
550+
assert_equals(getComputedStyle(shadowDiv).color, "rgb(255, 0, 0)", "the adopted sheet re-enabled, it should take effect again");
556551
}, 'Adopted sheets are ordered after non-adopted sheets in the shadow root')
557552

558553
test(() => {
@@ -574,41 +569,32 @@
574569
const style = document.createElement("style");
575570
style.textContent = ".target { color: white; }";
576571
span.appendChild(style)
577-
// non-adopted styles should be ordered before adopted styles
578-
assert_equals(getComputedStyle(span).color, "rgb(255, 0, 0)");
572+
assert_equals(getComputedStyle(span).color, "rgb(255, 0, 0)", "non-adopted styles should be ordered before adopted styles");
579573

580574
document.adoptedStyleSheets = [];
581-
// with no adopted styles in conflict, the non-adopted style should take effect
582-
assert_equals(getComputedStyle(span).color, "rgb(255, 255, 255)");
575+
assert_equals(getComputedStyle(span).color, "rgb(255, 255, 255)", "with no adopted styles in conflict, the non-adopted style should take effect");
583576

584577
document.adoptedStyleSheets = [sheet];
585-
// the adopted style should be ordered after the non-adopted style
586-
assert_equals(getComputedStyle(span).color, "rgb(255, 0, 0)");
578+
assert_equals(getComputedStyle(span).color, "rgb(255, 0, 0)", "the adopted style should be ordered after the non-adopted style");
587579

588580
sheet.disabled = true;
589-
// with the adopted sheet disabled, the non-adopted style should take effect
590-
assert_equals(getComputedStyle(span).color, "rgb(255, 255, 255)");
581+
assert_equals(getComputedStyle(span).color, "rgb(255, 255, 255)", "with the adopted sheet disabled, the non-adopted style should take effect");
591582

592583
sheet.disabled = false;
593-
// the adopted sheet re-enabled, it should take effect again.
594-
assert_equals(getComputedStyle(span).color, "rgb(255, 0, 0)")
584+
assert_equals(getComputedStyle(span).color, "rgb(255, 0, 0)", "the adopted sheet re-enabled, it should take effect again")
595585
}, 'Adopted sheets are ordered after non-adopted sheets in the document')
596586

597587
const import_text = '@import url("support/constructable-import.css");';
598588

599589
test(() => {
600-
assert_throws_dom("NotAllowedError", () => { (new CSSStyleSheet).replaceSync(import_text) });
601-
}, 'CSSStyleSheet.replaceSync throws exception when there is import rule inside');
602-
603-
test(() => {
604-
assert_throws_dom("NotAllowedError", () => { (new CSSStyleSheet).insertRule(import_text) });
590+
assert_throws_dom("SyntaxError", () => { (new CSSStyleSheet).insertRule(import_text) });
605591
}, 'Inserting an @import rule through insertRule on a constructed stylesheet throws an exception');
606592

607593
async_test(t => {
608594
const importUrl = "support/constructable-import.css";
609595
const sheet = new CSSStyleSheet();
610596

611-
assert_throws_dom("NotAllowedError", () => { sheet.replaceSync(`@import url("${importUrl}");`) });
597+
sheet.replaceSync(`@import url("${importUrl}");`);
612598

613599
const timeAfterReplaceSync = performance.now();
614600
let link = document.createElement("link");
@@ -632,27 +618,68 @@
632618
const sheet = new CSSStyleSheet();
633619
span.shadowRoot.adoptedStyleSheets = [sheet];
634620
assert_equals(getComputedStyle(shadowDiv).color, "rgb(0, 0, 0)");
635-
// Replace and assert that the imported rule is applied.
621+
// Replace and assert that the imported rule is NOT applied.
636622
const sheet_promise = sheet.replace(import_text);
623+
return sheet_promise.then((sheet) => {
624+
// replace() ignores @import rules:
625+
assert_equals(sheet.cssRules.length, 0);
626+
assert_equals(getComputedStyle(shadowDiv).color, "rgb(0, 0, 0)");
627+
}).catch((reason) => {
628+
assert_unreached(`Promise was rejected (${reason}) when it should have been resolved`);
629+
});
630+
}, 'CSSStyleSheet.replace allows, but ignores, import rule inside');
631+
632+
promise_test(() => {
633+
const span = document.createElement("span");
634+
thirdSection.appendChild(span);
635+
const shadowDiv = attachShadowDiv(span);
636+
const targetSpan = document.createElement("span");
637+
targetSpan.classList.add("target");
638+
shadowDiv.appendChild(targetSpan);
639+
const sheet = new CSSStyleSheet();
640+
span.shadowRoot.adoptedStyleSheets = [sheet];
641+
assert_equals(getComputedStyle(shadowDiv).color, "rgb(0, 0, 0)");
642+
// Replace and assert that the imported rule is NOT applied, but regular rule does apply.
643+
const sheet_promise = sheet.replace(import_text + ".target { color: blue; }");
637644
return sheet_promise.then((sheet) => {
638645
assert_equals(sheet.cssRules.length, 1);
639-
assert_equals(sheet.cssRules[0].cssText, import_text);
640-
assert_equals(getComputedStyle(shadowDiv).color, "rgb(255, 0, 0)");
646+
// @import not applied:
647+
assert_equals(getComputedStyle(shadowDiv).color, "rgb(0, 0, 0)");
648+
// regular rule applied:
649+
assert_equals(getComputedStyle(targetSpan).color, "rgb(0, 0, 255)");
641650
}).catch((reason) => {
642651
assert_unreached(`Promise was rejected (${reason}) when it should have been resolved`);
643652
});
644-
}, 'CSSStyleSheet.replace allows import rule inside');
653+
}, 'CSSStyleSheet.replace ignores @import rule but still loads other rules');
654+
655+
test(() => {
656+
const span = document.createElement("span");
657+
thirdSection.appendChild(span);
658+
const shadowDiv = attachShadowDiv(span);
659+
const sheet = new CSSStyleSheet();
660+
span.shadowRoot.adoptedStyleSheets = [sheet];
661+
assert_equals(getComputedStyle(shadowDiv).color, "rgb(0, 0, 0)");
662+
// Replace and assert that the imported rule is NOT applied.
663+
try {
664+
sheet.replaceSync(import_text);
665+
// replaceSync() ignores @import rules:
666+
assert_equals(sheet.cssRules.length, 0);
667+
assert_equals(getComputedStyle(shadowDiv).color, "rgb(0, 0, 0)");
668+
} catch(reason) {
669+
assert_unreached(`replaceSync threw an exception (${reason}) when it shouldn't have`);
670+
}
671+
}, 'CSSStyleSheet.replaceSync allows, but ignores, import rule inside');
645672

646673
promise_test(() => {
647674
const sheet = new CSSStyleSheet();
648675
const sheet_promise = sheet.replace("@import url('not-there.css');");
649676

650677
return sheet_promise.then((sheet) => {
651-
assert_unreached("Promise was resolved when it should have been rejected");
678+
// No exception here
652679
}).catch((reason) => {
653-
assert_equals(reason.name, "NetworkError");
680+
assert_unreached("Promise was rejected");
654681
});
655-
}, 'CSSStyleSheet.replace returns rejected promise on failed imports');
682+
}, 'CSSStyleSheet.replace does not reject on failed imports');
656683

657684
test(() => {
658685
const span = document.createElement("span");

testing/web-platform/tests/html/semantics/scripting-1/the-script-element/css-module/import-css-module-basic.html

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,13 @@
2222
const iframe = document.createElement("iframe");
2323
iframe.src = "resources/css-module-at-import-iframe.html";
2424
iframe.onload = test.step_func_done(function () {
25-
assert_equals(iframe.contentDocument.load_error, "NotAllowedError");
25+
assert_equals(iframe.contentDocument.load_error, undefined);
2626
assert_not_equals(getComputedStyle(iframe.contentDocument.querySelector('#test'))
2727
.backgroundColor, "rgb(255, 0, 0)",
2828
"CSS module @import should not succeed");
2929
});
3030
document.body.appendChild(iframe);
31-
}, "An @import CSS Module should not load");
31+
}, "An @import CSS Module should not load, but should not throw an exception");
3232

3333
async_test(function (test) {
3434
const iframe = document.createElement("iframe");

0 commit comments

Comments
 (0)