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)