mirror of
https://github.com/shoelace-style/webawesome.git
synced 2026-01-12 20:19:13 +00:00
Compare commits
2 Commits
select-tag
...
isolate
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
82faf7da36 | ||
|
|
fd0fad361f |
@@ -1,7 +1,7 @@
|
||||
{% set themeId = theme.fileSlug %}
|
||||
|
||||
<div>
|
||||
<template shadowrootmode="open">
|
||||
<wa-isolate>
|
||||
<template>
|
||||
<link rel="stylesheet" href="/dist/styles/utilities.css">
|
||||
<link rel="stylesheet" href="/dist/styles/themes/{{ page.fileSlug or 'default' }}.css">
|
||||
<link rel="stylesheet" href="/dist/styles/themes/{{ themeId }}/color.css">
|
||||
@@ -21,4 +21,4 @@
|
||||
{# <div class="wa-warning wa-outlined wa-filled"><wa-icon slot="icon" name="triangle-exclamation" variant="regular"></wa-icon></div> #}
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</wa-isolate>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{% set themeId = theme.fileSlug %}
|
||||
|
||||
<div>
|
||||
<template shadowrootmode="open">
|
||||
<wa-isolate>
|
||||
<template>
|
||||
<link rel="stylesheet" href="/dist/styles/native/content.css">
|
||||
<link rel="stylesheet" href="/dist/styles/native/blockquote.css">
|
||||
<link rel="stylesheet" href="/dist/styles/themes/{{ page.fileSlug or 'default' }}.css">
|
||||
@@ -13,4 +13,4 @@
|
||||
<p>Body text</p>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</wa-isolate>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { html } from 'lit';
|
||||
import { customElement, property, query } from 'lit/decorators.js';
|
||||
import { classMap } from 'lit/directives/class-map.js';
|
||||
import recursiveQSA from '../../internal/recursive-qsa.js';
|
||||
import { HasSlotController, getInnerHTML } from '../../internal/slot.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import '../icon/icon.js';
|
||||
@@ -325,25 +326,6 @@ function absolutizeURLs(root: Element | DocumentFragment, base = location.href)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get elements that match a selector within an element’s shadow tree
|
||||
* and any parent shadow trees, all the way up to the light DOM
|
||||
* @param selector
|
||||
* @param node - The node to start the search from
|
||||
*/
|
||||
function recursiveQSA(selector: string, node: Node) {
|
||||
const ret: Element[] = [];
|
||||
|
||||
for (let root = node; root.nodeType !== Node.DOCUMENT_NODE; ) {
|
||||
root = root.getRootNode();
|
||||
const elements = (root as ShadowRoot | Document).querySelectorAll(selector);
|
||||
|
||||
ret.push(...elements);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
function dedent(code: string) {
|
||||
// Remove blank lines at the start and end
|
||||
code = code.replace(/^\s*\n|\n\s*$/g, '');
|
||||
|
||||
48
src/components/isolate/isolate.ts
Normal file
48
src/components/isolate/isolate.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import { customElement, property } from 'lit/decorators.js';
|
||||
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
|
||||
import recursiveQSA from '../../internal/recursive-qsa.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
|
||||
/**
|
||||
* @summary Render a piece of code in shadow DOM. An alternative to DSD that plays nicely with DOM operations like cloning etc.
|
||||
* @documentation https://backers.webawesome.com/docs/components/isolate
|
||||
* @status experimental
|
||||
* @since 3.0
|
||||
*
|
||||
*/
|
||||
@customElement('wa-isolate')
|
||||
export default class WaIsolate extends WebAwesomeElement {
|
||||
/** Includes resources and other elements from the surrounding page */
|
||||
@property({ reflect: true }) include?: string;
|
||||
|
||||
render() {
|
||||
return unsafeHTML(this.getShadowHTML());
|
||||
}
|
||||
|
||||
// TODO memoize this and only update if:
|
||||
// - this.include changes
|
||||
// - elements have been added/removed that match the selector
|
||||
// - Element contents have changed
|
||||
private getShadowHTML(): string {
|
||||
let html = '';
|
||||
|
||||
if (this.ownerDocument) {
|
||||
if (this.include) {
|
||||
let includedElements = recursiveQSA(this.include, this);
|
||||
html += includedElements.map(el => el.outerHTML).join('\n');
|
||||
}
|
||||
|
||||
// Get template elements from the light DOM
|
||||
const templates = Array.from(this.querySelectorAll(':scope > template'));
|
||||
html += templates.map(template => template.innerHTML).join('\n');
|
||||
}
|
||||
|
||||
return html;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'wa-isolate': WaIsolate;
|
||||
}
|
||||
}
|
||||
18
src/internal/recursive-qsa.ts
Normal file
18
src/internal/recursive-qsa.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* Get elements that match a selector within an element’s shadow tree
|
||||
* and any parent shadow trees, all the way up to the light DOM
|
||||
* @param selector
|
||||
* @param node - The node to start the search from
|
||||
*/
|
||||
export default function recursiveQSA(selector: string, node: Node) {
|
||||
const ret: Element[] = [];
|
||||
|
||||
for (let root = node; root.nodeType !== Node.DOCUMENT_NODE; ) {
|
||||
root = root.getRootNode();
|
||||
const elements = (root as ShadowRoot | Document).querySelectorAll(selector);
|
||||
|
||||
ret.push(...elements);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
Reference in New Issue
Block a user