-
Notifications
You must be signed in to change notification settings - Fork 87
/
Copy pathcss-injection-mixin.js
81 lines (68 loc) · 2.17 KB
/
css-injection-mixin.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
/**
* @license
* Copyright (c) 2021 - 2025 Vaadin Ltd.
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
*/
import { CSSInjector } from './src/css-injector.js';
/**
* @type {string[]}
*/
const registeredProperties = new Set();
/**
* Find enclosing root for given element to gather style rules from.
*
* @param {HTMLElement} element
* @return {DocumentOrShadowRoot}
*/
function findRoot(element) {
const root = element.getRootNode();
if (root.host && root.host.constructor.cssInjectPropName) {
return findRoot(root.host);
}
return root;
}
/**
* Mixin for internal use only. Do not use it in custom components.
*
* @polymerMixin
*/
export const CSSInjectionMixin = (superClass) =>
class CSSInjectionMixinClass extends superClass {
static finalize() {
super.finalize();
const propName = this.cssInjectPropName;
// Prevent registering same property twice when a class extends
// another class using this mixin, since `finalize()` is called
// by LitElement for all superclasses in the prototype chain.
if (this.is && !registeredProperties.has(propName)) {
registeredProperties.add(propName);
// Initialize custom property for this class with 0 as default
// so that changing it to 1 would inject styles to instances
// Use `inherits: true` so that property defined on `<html>`
// would apply to components instances within shadow roots
CSS.registerProperty({
name: propName,
syntax: '<number>',
inherits: true,
initialValue: '0',
});
}
}
static get cssInjectPropName() {
return `--${this.is}-css-inject`;
}
/** @protected */
connectedCallback() {
super.connectedCallback();
const root = findRoot(this);
root.__cssInjector ||= new CSSInjector(root);
this.__cssInjector = root.__cssInjector;
this.__cssInjector.componentConnected(this);
}
/** @protected */
disconnectedCallback() {
super.disconnectedCallback();
this.__cssInjector.componentDisconnected(this);
this.__cssInjector = undefined;
}
};