vue-shadow-dom
Version:
Shadow dom support for Vue
1 lines • 9.2 kB
Source Map (JSON)
{"version":3,"file":"shadow.cjs.prod.cjs","sources":["../src/shadow.tsx"],"sourcesContent":["import { defineComponent, h, ref, Teleport, onBeforeMount, onMounted, computed, reactive, PropType, watch } from 'vue'\r\nimport type { App, VNode } from 'vue'\r\n\r\ntype GShadowRoot = typeof global.ShadowRoot.prototype\r\n\r\nexport interface ShadowOption {\r\n mode?: 'open' | 'closed'\r\n delegatesFocus?: boolean\r\n}\r\n\r\nexport function makeShadow(el: Element, option?: ShadowOption) {\r\n return makeShadowRaw(el, el.childNodes, option)\r\n}\r\nexport function makeShadowRaw(rootEl: Element, childNodes?: Iterable<Node>, option?: ShadowOption): ShadowRoot | undefined\r\nexport function makeShadowRaw(rootEl: Element, childNodes?: Iterable<Node>, { mode = 'open', delegatesFocus = false }: ShadowOption = { mode: 'open' }) {\r\n try {\r\n const oldroot = rootEl.shadowRoot\r\n if (oldroot != null) {\r\n console.error('[shadow] Attach shadow multiple times', rootEl, childNodes, oldroot)\r\n return\r\n } else {\r\n const shadow_root = rootEl.attachShadow({ mode, delegatesFocus })\r\n if (childNodes) putDomIntoShadow(shadow_root, childNodes)\r\n return shadow_root\r\n }\r\n } catch (e) {\r\n console.error('[shadow] make shadow-root failed', rootEl, childNodes)\r\n console.error(e)\r\n }\r\n}\r\n\r\n// function removeShadow(rootEl: Element): Element {\r\n// const newroot = rootEl.cloneNode() as Element\r\n// while (rootEl.hasChildNodes()) {\r\n// newroot.appendChild(rootEl.firstChild!)\r\n// }\r\n// rootEl.parentElement!.replaceChild(newroot, rootEl)\r\n// console.log('removeShadow', newroot)\r\n// return newroot\r\n// }\r\n\r\nfunction putDomIntoShadow(shadow_root: GShadowRoot, childNodes: Iterable<Node>) {\r\n const fragment = document.createDocumentFragment()\r\n for (const node of childNodes) {\r\n fragment.appendChild(node)\r\n }\r\n shadow_root.appendChild(fragment)\r\n}\r\n\r\nconst virtual_root = document.createDocumentFragment()\r\n\r\nexport const ShadowStyle = defineComponent({\r\n props: {\r\n media: String,\r\n nonce: String,\r\n },\r\n setup(props, { slots }) {\r\n return (): VNode => (\r\n <style media={props.media} nonce={props.nonce}>\r\n {slots.default?.()}\r\n </style>\r\n )\r\n },\r\n})\r\n\r\nexport interface ShadowRootExpose {\r\n shadow_root?: GShadowRoot\r\n}\r\n\r\nexport const ShadowRoot = withType<{\r\n install: typeof install\r\n Style: typeof ShadowStyle\r\n}>()(\r\n defineComponent({\r\n props: {\r\n mode: {\r\n type: String as PropType<'open' | 'closed'>,\r\n default: 'open',\r\n },\r\n delegatesFocus: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n abstract: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n tag: {\r\n type: String,\r\n default: 'div',\r\n },\r\n adoptedStyleSheets: {\r\n type: Array as PropType<CSSStyleSheet[]>,\r\n },\r\n },\r\n emits: ['error'],\r\n setup(props, { slots, expose, emit }) {\r\n const abstract = ref(false)\r\n\r\n const el = ref<HTMLElement>()\r\n const teleport_el = ref<HTMLElement>()\r\n const shadow_root = ref<GShadowRoot>()\r\n\r\n const teleport_target = computed(() => shadow_root.value ?? virtual_root)\r\n\r\n const ex: ShadowRootExpose = reactive({\r\n shadow_root,\r\n })\r\n expose(ex)\r\n\r\n onBeforeMount(() => {\r\n abstract.value = props.abstract\r\n })\r\n\r\n onMounted(() => {\r\n try {\r\n if (abstract.value) {\r\n if (teleport_el.value!.parentElement!.shadowRoot) {\r\n shadow_root.value = teleport_el.value!.parentElement!.shadowRoot\r\n } else {\r\n shadow_root.value = makeShadowRaw(teleport_el.value!.parentElement!, void 0, {\r\n mode: props.mode,\r\n delegatesFocus: props.delegatesFocus,\r\n })\r\n }\r\n } else {\r\n shadow_root.value = makeShadowRaw(el.value!, void 0, { mode: props.mode, delegatesFocus: props.delegatesFocus })\r\n }\r\n shadow_root.value?.styleSheets\r\n } catch (e) {\r\n console.error(e)\r\n emit('error', e)\r\n }\r\n })\r\n\r\n watch([shadow_root, () => props.adoptedStyleSheets], ([shadow_root, adoptedStyleSheets]) => {\r\n if (!shadow_root || !adoptedStyleSheets) return\r\n try {\r\n ;(shadow_root as any).adoptedStyleSheets = adoptedStyleSheets\r\n } catch (e) {\r\n console.error(e)\r\n emit('error', e)\r\n }\r\n })\r\n\r\n return (): VNode => {\r\n const child_part = (\r\n <Teleport ref={teleport_el} to={teleport_target.value}>\r\n {[slots.default?.()]}\r\n </Teleport>\r\n )\r\n if (abstract.value) return child_part\r\n return <props.tag ref={el}>{child_part}</props.tag>\r\n }\r\n },\r\n install,\r\n Style: ShadowStyle,\r\n })\r\n)\r\n\r\nfunction withType<W>(): <T>(obj: T) => T & W {\r\n return obj => obj as any\r\n}\r\n\r\nexport function install(app: App) {\r\n app.component('shadow-root', ShadowRoot)\r\n\r\n app.directive('shadow', {\r\n beforeMount(el: HTMLElement) {\r\n console.warn('[VueShadowDom] Deprecated v-shadow directive, use <shadow-root> component')\r\n makeShadow(el)\r\n },\r\n })\r\n}\r\n\r\nexport { ShadowRoot as shadow_root, ShadowStyle as shadow_style }\r\nexport default { ShadowRoot, ShadowStyle, shadow_root: ShadowRoot, shadow_style: ShadowStyle, install }\r\n"],"names":["makeShadow","el","option","makeShadowRaw","childNodes","rootEl","mode","delegatesFocus","oldroot","shadowRoot","console","error","shadow_root","attachShadow","fragment","document","createDocumentFragment","node","appendChild","putDomIntoShadow","e","virtual_root","ShadowStyle","defineComponent","props","media","String","nonce","setup","slots","h","default","ShadowRoot","type","Boolean","abstract","tag","adoptedStyleSheets","Array","emits","[object Object]","expose","emit","ref","teleport_el","teleport_target","computed","value","reactive","onBeforeMount","onMounted","parentElement","styleSheets","watch","child_part","Teleport","to","install","Style","app","component","directive","warn","shadow_style"],"mappings":"kGAUgBA,EAAWC,EAAaC,GACpC,OAAOC,EAAcF,EAAIA,EAAGG,WAAYF,YAG5BC,EAAcE,EAAiBD,GAA6BE,KAAEA,EAAO,OAAMC,eAAEA,GAAiB,GAAwB,CAAED,KAAM,SAC1I,IACI,MAAME,EAAUH,EAAOI,WACvB,GAAe,MAAXD,EAEA,YADAE,QAAQC,MAAM,wCAAyCN,EAAQD,EAAYI,GAExE,CACH,MAAMI,EAAcP,EAAOQ,aAAa,CAAEP,KAAAA,EAAMC,eAAAA,IAEhD,OADIH,GAmBhB,SAA0BQ,EAA0BR,GAChD,MAAMU,EAAWC,SAASC,yBAC1B,IAAK,MAAMC,KAAQb,EACfU,EAASI,YAAYD,GAEzBL,EAAYM,YAAYJ,GAxBAK,CAAiBP,EAAaR,GACvCQ,GAEb,MAAOQ,GACLV,QAAQC,MAAM,mCAAoCN,EAAQD,GAC1DM,QAAQC,MAAMS,IAsBtB,MAAMC,EAAeN,SAASC,yBAEjBM,EAAcC,kBAAgB,CACvCC,MAAO,CACHC,MAAOC,OACPC,MAAOD,QAEXE,MAAK,CAACJ,GAAOK,MAAEA,KACJ,IACHC,aAAOL,MAAOD,EAAMC,MAAOE,MAAOH,EAAMG,OACnCE,EAAME,eAUVC,EAITT,kBAAgB,CACZC,MAAO,CACHlB,KAAM,CACF2B,KAAMP,OACNK,QAAS,QAEbxB,eAAgB,CACZ0B,KAAMC,QACNH,SAAS,GAEbI,SAAU,CACNF,KAAMC,QACNH,SAAS,GAEbK,IAAK,CACDH,KAAMP,OACNK,QAAS,OAEbM,mBAAoB,CAChBJ,KAAMK,QAGdC,MAAO,CAAC,SACRC,MAAMhB,GAAOK,MAAEA,EAAKY,OAAEA,EAAMC,KAAEA,IAC1B,MAAMP,EAAWQ,OAAI,GAEf1C,EAAK0C,QACLC,EAAcD,QACd/B,EAAc+B,QAEdE,EAAkBC,YAAS,IAAMlC,EAAYmC,OAAS1B,IA0C5D,OArCAoB,EAH6BO,WAAS,CAClCpC,YAAAA,KAIJqC,iBAAc,KACVd,EAASY,MAAQvB,EAAMW,YAG3Be,aAAU,KACN,IACQf,EAASY,MACLH,EAAYG,MAAOI,cAAe1C,WAClCG,EAAYmC,MAAQH,EAAYG,MAAOI,cAAe1C,WAEtDG,EAAYmC,MAAQ5C,EAAcyC,EAAYG,MAAOI,mBAAgB,EAAQ,CACzE7C,KAAMkB,EAAMlB,KACZC,eAAgBiB,EAAMjB,iBAI9BK,EAAYmC,MAAQ5C,EAAcF,EAAG8C,WAAQ,EAAQ,CAAEzC,KAAMkB,EAAMlB,KAAMC,eAAgBiB,EAAMjB,iBAEnGK,EAAYmC,OAAOK,YACrB,MAAOhC,GACLV,QAAQC,MAAMS,GACdsB,EAAK,QAAStB,OAItBiC,QAAM,CAACzC,EAAa,IAAMY,EAAMa,qBAAqB,EAAEzB,EAAayB,MAChE,GAAKzB,GAAgByB,EACrB,IACMzB,EAAoByB,mBAAqBA,EAC7C,MAAOjB,GACLV,QAAQC,MAAMS,GACdsB,EAAK,QAAStB,OAIf,KACH,MAAMkC,EACFxB,IAACyB,YAASZ,IAAKC,EAAaY,GAAIX,EAAgBE,OAC3C,CAAClB,EAAME,cAGhB,OAAII,EAASY,MAAcO,EACpBxB,IAACN,EAAMY,KAAIO,IAAK1C,GAAKqD,KAGpCG,QAAAA,EACAC,MAAOpC,aAQCmC,EAAQE,GACpBA,EAAIC,UAAU,cAAe5B,GAE7B2B,EAAIE,UAAU,SAAU,CACpBrB,YAAYvC,GACRS,QAAQoD,KAAK,6EACb9D,EAAWC,MAMvB,MAAe,CAAE+B,WAAAA,EAAYV,YAAAA,EAAaV,YAAaoB,EAAY+B,aAAczC,EAAamC,QAAAA"}