-
Notifications
You must be signed in to change notification settings - Fork 8
/
register-styles.html
128 lines (108 loc) · 3.95 KB
/
register-styles.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
<link rel="import" href="../polymer/lib/elements/dom-module.html">
<script>
(function() {
/**
* @namespace Vaadin
*/
window.Vaadin = window.Vaadin || {};
let moduleIdIndex = 0;
// Map of <CSSResult, Polymer.DomModule> pairs.
const styleMap = {};
/**
* Registers CSS styles for a component type. Make sure to register the styles before
* the first instance of a component of the type is attached to DOM.
*
* @param {String} themeFor The local/tag name of the component type to register the styles for
* @param {CSSResult | CSSResult[]} styles The CSS style rules to be registered for the component type
* matching themeFor and included in the local scope of each component instance
* @param {Object=} options Additional options
* @return {void}
*/
Vaadin.registerStyles = (themeFor, styles, options) => {
const themeId = (options && options.moduleId) || `custom-style-module-${moduleIdIndex++}`;
if (!Array.isArray(styles)) {
styles = styles ? [styles] : [];
}
styles.forEach(cssResult => {
if (!(cssResult instanceof CSSResult)) {
throw new Error(
'An item in styles is not of type CSSResult. Use `unsafeCSS` or `css`.');
}
if (!styleMap[cssResult]) {
const styleModuleElement = document.createElement('dom-module');
styleModuleElement.innerHTML = `
<template>
<style>${cssResult.toString()}</style>
</template>
`;
const styleId = `custom-style-module-${moduleIdIndex++}`;
styleModuleElement.register(styleId);
styleMap[cssResult] = styleId;
}
});
const themeModuleElement = document.createElement('dom-module');
if (themeFor) {
const elementClass = window.customElements && window.customElements.get(themeFor);
if (elementClass && elementClass.hasOwnProperty('__finalized')) {
console.warn(`The custom element definition for "${themeFor}"
was finalized before a style module was registered.
Make sure to add component specific style modules before
importing the corresponding custom element.`);
}
themeModuleElement.setAttribute('theme-for', themeFor);
}
const moduleIncludes = (options && options.include) || [];
themeModuleElement.innerHTML = `
<template>
${moduleIncludes.map(include => `<style include=${include}></style>`)}
${styles.map(style => `<style include=${styleMap[style]}></style>`)}
</template>
`;
themeModuleElement.register(themeId);
};
/* MAGI REMOVE START */
/* Template literal tags derived from LitElement */
const constructionToken = {};
class CSSResult {
constructor(cssText, safeToken) {
if (safeToken !== constructionToken) {
throw new Error(
'CSSResult is not constructable. Use `unsafeCSS` or `css` instead.');
}
this.cssText = cssText;
}
toString() {
return this.cssText;
}
}
/**
* Wrap a value for interpolation in a css tagged template literal.
*
* This is unsafe because untrusted CSS text can be used to phone home
* or exfiltrate data to an attacker controlled site. Take care to only use
* this with trusted input.
*/
Vaadin.unsafeCSS = (value) => {
return new CSSResult(String(value), constructionToken);
};
const textFromCSSResult = (value) => {
if (value instanceof CSSResult) {
return value.cssText;
} else if (typeof value === 'number') {
return value;
} else {
throw new Error(
`Value passed to 'css' function must be a 'css' function result: ${
value}. Use 'unsafeCSS' to pass non-literal values, but
take care to ensure page security.`);
}
};
Vaadin.css = (strings, ...values) => {
const cssText = values.reduce(
(acc, v, idx) => acc + textFromCSSResult(v) + strings[idx + 1],
strings[0]);
return new CSSResult(cssText, constructionToken);
};
/* MAGI REMOVE END */
})();
</script>