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

feat: add styles to shadow DOM #89

Merged
merged 1 commit into from
Oct 26, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 61 additions & 6 deletions src/assembler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@ export interface AssembleResults {
}

export interface AssembleOptions {
isWebComponent?: boolean
normalizer?: string
styleInjector?: string
styleInjectorSSR?: string
styleInjectorShadow?: string
}

export function assemble(
Expand Down Expand Up @@ -214,11 +216,52 @@ export function assembleFromSource(
? createImport('__vue_create_injector_ssr__', options.styleInjectorSSR)
: inlineCreateInjectorSSR

const inlineCreateInjectorShadow = `function __vue_create_injector_shadow__(__, shadowRoot) {
function createStyleElement(shadowRoot) {
var styleElement = document.createElement('style')
styleElement.type = 'text/css'
shadowRoot.appendChild(styleElement)

return styleElement
}

return function addStyle(id, css) {
const styleElement = createStyleElement(shadowRoot)
if (css.media) styleElement.setAttribute('media', css.media)

let code = css.source

if (${e(compiler.template.isProduction)} && css.map) {
// https://developer.chrome.com/devtools/docs/javascript-debugging
// this makes source maps inside style tags work properly in Chrome
code += '\\n/*# sourceURL=' + css.map.sources[0] + ' */'
// http://stackoverflow.com/a/26603875
code +=
'\\n/*# sourceMappingURL=data:application/json;base64,' +
btoa(unescape(encodeURIComponent(JSON.stringify(css.map)))) +
' */'
}

if ('styleSheet' in styleElement) {
styleElement.styleSheet.cssText = code
} else {
while (styleElement.firstChild) {
styleElement.removeChild(styleElement.firstChild)
}
styleElement.appendChild(document.createTextNode(code))
}
}
}`

const createInjectorShadow = options.styleInjectorShadow
? createImport('__vue_create_injector_shadow__', options.styleInjectorShadow)
: inlineCreateInjectorShadow

// language=JavaScript
const inlineNormalizeComponent = `function __vue_normalize__(
template, style, script,
scope, functional, moduleIdentifier,
createInjector, createInjectorSSR
scope, functional, moduleIdentifier, shadowMode,
createInjector, createInjectorSSR, createInjectorShadow
) {
const component = (typeof script === 'function' ? script.options : script) || {}

Expand Down Expand Up @@ -263,9 +306,13 @@ export function assembleFromSource(
component._ssrRegister = hook
}
else if (style) {
hook = function(context) {
style.call(this, createInjector(context))
}
hook = shadowMode
? function(context) {
style.call(this, createInjectorShadow(context, this.$root.$options.shadowRoot))
}
: function(context) {
style.call(this, createInjector(context))
}
}

if (hook !== undefined) {
Expand Down Expand Up @@ -345,9 +392,11 @@ export function assembleFromSource(
/* component normalizer */
${normalizeComponent}
/* style inject */
${hasStyle && !compiler.template.optimizeSSR ? createInjector : ''}
${hasStyle && !compiler.template.optimizeSSR && !options.isWebComponent ? createInjector : ''}
/* style inject SSR */
${hasStyle && compiler.template.optimizeSSR ? createInjectorSSR : ''}
/* style inject shadow dom */
${hasStyle && options.isWebComponent ? createInjectorShadow : ''}

`

Expand Down Expand Up @@ -403,6 +452,7 @@ export function assembleFromSource(
__vue_scope_id__,
__vue_is_functional_template__,
__vue_module_identifier__,
${options.isWebComponent ? 'true' : 'false'},
${
code.indexOf('__vue_create_injector__') > -1
? '__vue_create_injector__'
Expand All @@ -412,6 +462,11 @@ export function assembleFromSource(
code.indexOf('__vue_create_injector_ssr__') > -1
? '__vue_create_injector_ssr__'
: 'undefined'
},
${
code.indexOf('__vue_create_injector_shadow__') > -1
? '__vue_create_injector_shadow__'
: 'undefined'
}
)`

Expand Down