Skip to content
This repository was archived by the owner on Aug 16, 2022. It is now read-only.

Commit 714f08d

Browse files
authored
feat: inject styles to shadow DOM (#89)
1 parent 4faf89a commit 714f08d

File tree

1 file changed

+61
-6
lines changed

1 file changed

+61
-6
lines changed

src/assembler.ts

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,11 @@ export interface AssembleResults {
2626
}
2727

2828
export interface AssembleOptions {
29+
isWebComponent?: boolean
2930
normalizer?: string
3031
styleInjector?: string
3132
styleInjectorSSR?: string
33+
styleInjectorShadow?: string
3234
}
3335

3436
export function assemble(
@@ -214,11 +216,52 @@ export function assembleFromSource(
214216
? createImport('__vue_create_injector_ssr__', options.styleInjectorSSR)
215217
: inlineCreateInjectorSSR
216218

219+
const inlineCreateInjectorShadow = `function __vue_create_injector_shadow__(__, shadowRoot) {
220+
function createStyleElement(shadowRoot) {
221+
var styleElement = document.createElement('style')
222+
styleElement.type = 'text/css'
223+
shadowRoot.appendChild(styleElement)
224+
225+
return styleElement
226+
}
227+
228+
return function addStyle(id, css) {
229+
const styleElement = createStyleElement(shadowRoot)
230+
if (css.media) styleElement.setAttribute('media', css.media)
231+
232+
let code = css.source
233+
234+
if (${e(compiler.template.isProduction)} && css.map) {
235+
// https://developer.chrome.com/devtools/docs/javascript-debugging
236+
// this makes source maps inside style tags work properly in Chrome
237+
code += '\\n/*# sourceURL=' + css.map.sources[0] + ' */'
238+
// http://stackoverflow.com/a/26603875
239+
code +=
240+
'\\n/*# sourceMappingURL=data:application/json;base64,' +
241+
btoa(unescape(encodeURIComponent(JSON.stringify(css.map)))) +
242+
' */'
243+
}
244+
245+
if ('styleSheet' in styleElement) {
246+
styleElement.styleSheet.cssText = code
247+
} else {
248+
while (styleElement.firstChild) {
249+
styleElement.removeChild(styleElement.firstChild)
250+
}
251+
styleElement.appendChild(document.createTextNode(code))
252+
}
253+
}
254+
}`
255+
256+
const createInjectorShadow = options.styleInjectorShadow
257+
? createImport('__vue_create_injector_shadow__', options.styleInjectorShadow)
258+
: inlineCreateInjectorShadow
259+
217260
// language=JavaScript
218261
const inlineNormalizeComponent = `function __vue_normalize__(
219262
template, style, script,
220-
scope, functional, moduleIdentifier,
221-
createInjector, createInjectorSSR
263+
scope, functional, moduleIdentifier, shadowMode,
264+
createInjector, createInjectorSSR, createInjectorShadow
222265
) {
223266
const component = (typeof script === 'function' ? script.options : script) || {}
224267
@@ -263,9 +306,13 @@ export function assembleFromSource(
263306
component._ssrRegister = hook
264307
}
265308
else if (style) {
266-
hook = function(context) {
267-
style.call(this, createInjector(context))
268-
}
309+
hook = shadowMode
310+
? function(context) {
311+
style.call(this, createInjectorShadow(context, this.$root.$options.shadowRoot))
312+
}
313+
: function(context) {
314+
style.call(this, createInjector(context))
315+
}
269316
}
270317
271318
if (hook !== undefined) {
@@ -345,9 +392,11 @@ export function assembleFromSource(
345392
/* component normalizer */
346393
${normalizeComponent}
347394
/* style inject */
348-
${hasStyle && !compiler.template.optimizeSSR ? createInjector : ''}
395+
${hasStyle && !compiler.template.optimizeSSR && !options.isWebComponent ? createInjector : ''}
349396
/* style inject SSR */
350397
${hasStyle && compiler.template.optimizeSSR ? createInjectorSSR : ''}
398+
/* style inject shadow dom */
399+
${hasStyle && options.isWebComponent ? createInjectorShadow : ''}
351400
352401
`
353402

@@ -403,6 +452,7 @@ export function assembleFromSource(
403452
__vue_scope_id__,
404453
__vue_is_functional_template__,
405454
__vue_module_identifier__,
455+
${options.isWebComponent ? 'true' : 'false'},
406456
${
407457
code.indexOf('__vue_create_injector__') > -1
408458
? '__vue_create_injector__'
@@ -412,6 +462,11 @@ export function assembleFromSource(
412462
code.indexOf('__vue_create_injector_ssr__') > -1
413463
? '__vue_create_injector_ssr__'
414464
: 'undefined'
465+
},
466+
${
467+
code.indexOf('__vue_create_injector_shadow__') > -1
468+
? '__vue_create_injector_shadow__'
469+
: 'undefined'
415470
}
416471
)`
417472

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy