Skip to content

Commit 94737e5

Browse files
committed
feat: shadowMode
1 parent 18d0ae4 commit 94737e5

File tree

2 files changed

+94
-1
lines changed

2 files changed

+94
-1
lines changed

Diff for: index.js

+12-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ module.exports.pitch = function (remainingRequest) {
1616
var isProduction = this.minimize || process.env.NODE_ENV === 'production'
1717
var addStylesClientPath = loaderUtils.stringifyRequest(this, '!' + path.join(__dirname, 'lib/addStylesClient.js'))
1818
var addStylesServerPath = loaderUtils.stringifyRequest(this, '!' + path.join(__dirname, 'lib/addStylesServer.js'))
19+
var addStylesShadowPath = loaderUtils.stringifyRequest(this, '!' + path.join(__dirname, 'lib/addStylesShadow.js'))
1920

2021
var request = loaderUtils.stringifyRequest(this, '!!' + remainingRequest)
2122
var id = JSON.stringify(hash(request + path.relative(__dirname, this.resourcePath)))
@@ -36,7 +37,17 @@ module.exports.pitch = function (remainingRequest) {
3637
'if(content.locals) module.exports = content.locals;'
3738
]
3839

39-
if (!isServer) {
40+
// shadowMode is enabled in vue-cli with vue build --target web-component.
41+
// exposes the same __inject__ method like SSR
42+
if (options.shadowMode) {
43+
return shared.concat([
44+
'// add CSS to Shadow Root',
45+
'var add = require(' + addStylesShadowPath + ').default',
46+
'module.exports.__inject__ = function (shadowRoot) {',
47+
' add(' + id + ', content, shadowRoot)',
48+
'};'
49+
]).join('\n')
50+
} else if (!isServer) {
4051
// on the client: dynamic inject + hot-reload
4152
var code = [
4253
'// add the styles to the DOM',

Diff for: lib/addStylesShadow.js

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import listToStyles from './listToStyles'
2+
3+
export default function addStylesToShadowDOM (parentId, list, shadowRoot) {
4+
var styles = listToStyles(parentId, list)
5+
addStyles(styles, shadowRoot)
6+
}
7+
8+
/*
9+
type StyleObject = {
10+
id: number;
11+
parts: Array<StyleObjectPart>
12+
}
13+
14+
type StyleObjectPart = {
15+
css: string;
16+
media: string;
17+
sourceMap: ?string
18+
}
19+
*/
20+
21+
function addStyles (styles /* Array<StyleObject> */, shadowRoot) {
22+
const injectedStyles =
23+
shadowRoot._injectedStyles ||
24+
(shadowRoot._injectedStyles = {})
25+
for (var i = 0; i < styles.length; i++) {
26+
var item = styles[i]
27+
var style = injectedStyles[item.id]
28+
if (style) {
29+
style.refs++
30+
for (var j = 0; j < style.parts.length; j++) {
31+
style.parts[j](item.parts[j])
32+
}
33+
for (; j < item.parts.length; j++) {
34+
style.parts.push(addStyle(item.parts[j], shadowRoot))
35+
}
36+
if (style.parts.length > item.parts.length) {
37+
style.parts.length = item.parts.length
38+
}
39+
} else {
40+
var parts = []
41+
for (var j = 0; j < item.parts.length; j++) {
42+
parts.push(addStyle(item.parts[j], shadowRoot))
43+
}
44+
injectedStyles[item.id] = { id: item.id, refs: 1, parts: parts }
45+
}
46+
}
47+
}
48+
49+
function createStyleElement (shadowRoot) {
50+
var styleElement = document.createElement('style')
51+
styleElement.type = 'text/css'
52+
shadowRoot.appendChild(styleElement)
53+
return styleElement
54+
}
55+
56+
function addStyle (obj /* StyleObjectPart */, shadowRoot) {
57+
var styleElement = createStyleElement(shadowRoot)
58+
var css = obj.css
59+
var media = obj.media
60+
var sourceMap = obj.sourceMap
61+
62+
if (media) {
63+
styleElement.setAttribute('media', media)
64+
}
65+
66+
if (sourceMap) {
67+
// https://developer.chrome.com/devtools/docs/javascript-debugging
68+
// this makes source maps inside style tags work properly in Chrome
69+
css += '\n/*# sourceURL=' + sourceMap.sources[0] + ' */'
70+
// http://stackoverflow.com/a/26603875
71+
css += '\n/*# sourceMappingURL=data:application/json;base64,' + btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))) + ' */'
72+
}
73+
74+
if (styleElement.styleSheet) {
75+
styleElement.styleSheet.cssText = css
76+
} else {
77+
while (styleElement.firstChild) {
78+
styleElement.removeChild(styleElement.firstChild)
79+
}
80+
styleElement.appendChild(document.createTextNode(css))
81+
}
82+
}

0 commit comments

Comments
 (0)