Implement automatic updating of styles
This commit is contained in:
parent
f6b0d6d004
commit
25fbfeebfd
3 changed files with 48 additions and 3 deletions
|
@ -1,3 +1,35 @@
|
||||||
|
class StylesEvent extends Event {
|
||||||
|
constructor() {
|
||||||
|
super("styles", { bubbles: true })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const styleSelector = `style, link[rel="stylesheet"]`
|
||||||
|
|
||||||
|
/** @param {Element} node */
|
||||||
|
const isStyleNode = node => node.matches(styleSelector) || node.querySelector(styleSelector)
|
||||||
|
|
||||||
|
/** @param {MutationRecord} mutation */
|
||||||
|
const isStyleMutation = mutation =>
|
||||||
|
(mutation.target instanceof Element) && isStyleNode(mutation.target)
|
||||||
|
|| (mutation.target instanceof Text) && isStyleNode(mutation.target.parentElement)
|
||||||
|
|| [...mutation.removedNodes].find(isStyleNode)
|
||||||
|
|
||||||
|
const StylesObserver = new MutationObserver(mutations => {
|
||||||
|
[...mutations].forEach(console.log)
|
||||||
|
for (const {target} of [...mutations].filter(isStyleMutation)) {
|
||||||
|
target.dispatchEvent(new StylesEvent())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
StylesObserver.observe(document.head, {
|
||||||
|
subtree: true,
|
||||||
|
characterData: true,
|
||||||
|
childList: true,
|
||||||
|
attributes: true,
|
||||||
|
attributeFilter: ["rel", "href"],
|
||||||
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} href
|
* @param {string} href
|
||||||
* @param {string} layer
|
* @param {string} layer
|
||||||
|
@ -58,18 +90,18 @@ function collectStyles(sheet, target) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class PullStyles extends HTMLElement {
|
export default class AdoptStyles extends HTMLElement {
|
||||||
static observedAttributes = ["adopt", "layer"]
|
static observedAttributes = ["adopt", "layer"]
|
||||||
|
|
||||||
attributeChangedCallback() {
|
attributeChangedCallback() {
|
||||||
this.pullStyles()
|
this.adoptStyles()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} adopt What to adopt
|
* @param {string} adopt What to adopt
|
||||||
* @param {string|undefined} layer What CSS layer to wrap the external styles in
|
* @param {string|undefined} layer What CSS layer to wrap the external styles in
|
||||||
*/
|
*/
|
||||||
pullStyles(adopt=this.adopt, layer=this.layer) {
|
adoptStyles(adopt=this.adopt, layer=this.layer) {
|
||||||
if (adopt == "all") {
|
if (adopt == "all") {
|
||||||
this.replaceChildren(document.createElement("style"))
|
this.replaceChildren(document.createElement("style"))
|
||||||
const rules = new RuleCollection(layer)
|
const rules = new RuleCollection(layer)
|
||||||
|
@ -86,4 +118,15 @@ export default class PullStyles extends HTMLElement {
|
||||||
get sheet() { return this.querySelector("style") }
|
get sheet() { return this.querySelector("style") }
|
||||||
get adopt() { return this.getAttribute("adopt") }
|
get adopt() { return this.getAttribute("adopt") }
|
||||||
get layer() { return this.getAttribute("layer") }
|
get layer() { return this.getAttribute("layer") }
|
||||||
|
|
||||||
|
connectedCallback() {
|
||||||
|
this.abortController = new AbortController()
|
||||||
|
document.addEventListener("styles", () => {
|
||||||
|
this.adoptStyles()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
disconnectedCallback() {
|
||||||
|
this.abortController.abort()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
<template shadowrootmode="open">
|
<template shadowrootmode="open">
|
||||||
<adopt-styles adopt="all"></adopt-styles>
|
<adopt-styles adopt="all"></adopt-styles>
|
||||||
<p class="inline">Inline</p>
|
<p class="inline">Inline</p>
|
||||||
|
<p class="layer">Layer</p>
|
||||||
<p class="linked">Linked</p>
|
<p class="linked">Linked</p>
|
||||||
</template>
|
</template>
|
||||||
</my-component>
|
</my-component>
|
||||||
|
|
|
@ -9,3 +9,4 @@ into a Shadow-DOM.
|
||||||
- [x] Import `<style>` tags
|
- [x] Import `<style>` tags
|
||||||
- [x] Import into layer
|
- [x] Import into layer
|
||||||
- [ ] Import from layer
|
- [ ] Import from layer
|
||||||
|
- [x] Automatic updating
|
||||||
|
|
Loading…
Reference in a new issue