Skip to content

Commit 346eaf7

Browse files
First stab at detecting the Safari adopted style sheet bug (#121)
* Don't throw if the browser doesn't support the modern `adoptedStyleSheets` API * Partially addresses #120
1 parent 869431e commit 346eaf7

File tree

2 files changed

+66
-1
lines changed

2 files changed

+66
-1
lines changed

src/util/detect-bugs.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import TRANSITIONRUN_EVENT_LOOP from "./detect-bugs/transitionrun-loop.js";
22
import UNREGISTERED_TRANSITION from "./detect-bugs/unregistered-transition.js";
3+
import ADOPTED_STYLE_SHEET from "./detect-bugs/adopted-style-sheet.js";
34

4-
export const detectors = { TRANSITIONRUN_EVENT_LOOP, UNREGISTERED_TRANSITION };
5+
export const detectors = { TRANSITIONRUN_EVENT_LOOP, UNREGISTERED_TRANSITION, ADOPTED_STYLE_SHEET };
56

67
/**
78
* Data structure for all detected bugs.
@@ -17,6 +18,13 @@ for (let bug in detectors) {
1718
let detector = detectors[bug];
1819
Object.defineProperty(bugs, bug, {
1920
get () {
21+
if (detector.value !== undefined) {
22+
delete detector.valuePending;
23+
delete this[bug];
24+
25+
return (this[bug] = detector.value);
26+
}
27+
2028
detector.valuePending.then(value => {
2129
delete this[bug];
2230
this[bug] = value;
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import gentleRegisterProperty from "../gentle-register-property.js";
2+
3+
/**
4+
* Detect if the browser is affected by the Safari adopted style sheet bug:
5+
* removing a CSS custom property from an adopted stylesheet in a ShadowRoot
6+
* does not update the computed value as expected and doesn't trigger a transition.
7+
* @returns {{value: boolean, valuePending: boolean}}
8+
*/
9+
export default {
10+
get value () {
11+
let dummy = document.createElement("div");
12+
document.body.append(dummy);
13+
dummy.attachShadow({ mode: "open" });
14+
15+
if (Object.isFrozen(dummy.shadowRoot.adoptedStyleSheets)) {
16+
// The browser doesn't support the modern adoptedStyleSheets API, i.e., it is not affected by the bug
17+
dummy.remove();
18+
delete this.value;
19+
20+
return (this.value = false);
21+
}
22+
23+
gentleRegisterProperty("--style-observer-adopted-style-sheet-bug", {
24+
syntax: "<number>",
25+
inherits: true,
26+
initialValue: 0,
27+
});
28+
29+
let sheet = new CSSStyleSheet();
30+
sheet.insertRule(`
31+
:host {
32+
/* This declaration shouldn't be empty for the bug to trigger */
33+
color: transparent;
34+
}
35+
`);
36+
37+
dummy.shadowRoot.adoptedStyleSheets.push(sheet);
38+
let style = sheet.cssRules[0].style;
39+
40+
style.setProperty("--style-observer-adopted-style-sheet-bug", "1");
41+
let cs = getComputedStyle(dummy);
42+
let oldValue = cs.getPropertyValue("--style-observer-adopted-style-sheet-bug");
43+
44+
style.removeProperty("--style-observer-adopted-style-sheet-bug");
45+
cs = getComputedStyle(dummy);
46+
let newValue = cs.getPropertyValue("--style-observer-adopted-style-sheet-bug");
47+
48+
dummy.remove();
49+
delete this.value;
50+
51+
return (this.value = oldValue === newValue);
52+
},
53+
get valuePending () {
54+
delete this.valuePending;
55+
return this.value;
56+
},
57+
};

0 commit comments

Comments
 (0)