UNPKG

7.12 kBJavaScriptView Raw
1"use strict";
2
3exports.__esModule = true;
4exports["default"] = void 0;
5
6var _stringHash = _interopRequireDefault(require("string-hash"));
7
8var _stylesheet = _interopRequireDefault(require("./lib/stylesheet"));
9
10function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
11
12var sanitize = function sanitize(rule) {
13 return rule.replace(/\/style/gi, '\\/style');
14};
15
16var StyleSheetRegistry = /*#__PURE__*/function () {
17 function StyleSheetRegistry(_temp) {
18 var _ref = _temp === void 0 ? {} : _temp,
19 _ref$styleSheet = _ref.styleSheet,
20 styleSheet = _ref$styleSheet === void 0 ? null : _ref$styleSheet,
21 _ref$optimizeForSpeed = _ref.optimizeForSpeed,
22 optimizeForSpeed = _ref$optimizeForSpeed === void 0 ? false : _ref$optimizeForSpeed,
23 _ref$isBrowser = _ref.isBrowser,
24 isBrowser = _ref$isBrowser === void 0 ? typeof window !== 'undefined' : _ref$isBrowser;
25
26 this._sheet = styleSheet || new _stylesheet["default"]({
27 name: 'styled-jsx',
28 optimizeForSpeed: optimizeForSpeed
29 });
30
31 this._sheet.inject();
32
33 if (styleSheet && typeof optimizeForSpeed === 'boolean') {
34 this._sheet.setOptimizeForSpeed(optimizeForSpeed);
35
36 this._optimizeForSpeed = this._sheet.isOptimizeForSpeed();
37 }
38
39 this._isBrowser = isBrowser;
40 this._fromServer = undefined;
41 this._indices = {};
42 this._instancesCounts = {};
43 this.computeId = this.createComputeId();
44 this.computeSelector = this.createComputeSelector();
45 }
46
47 var _proto = StyleSheetRegistry.prototype;
48
49 _proto.add = function add(props) {
50 var _this = this;
51
52 if (undefined === this._optimizeForSpeed) {
53 this._optimizeForSpeed = Array.isArray(props.children);
54
55 this._sheet.setOptimizeForSpeed(this._optimizeForSpeed);
56
57 this._optimizeForSpeed = this._sheet.isOptimizeForSpeed();
58 }
59
60 if (this._isBrowser && !this._fromServer) {
61 this._fromServer = this.selectFromServer();
62 this._instancesCounts = Object.keys(this._fromServer).reduce(function (acc, tagName) {
63 acc[tagName] = 0;
64 return acc;
65 }, {});
66 }
67
68 var _this$getIdAndRules = this.getIdAndRules(props),
69 styleId = _this$getIdAndRules.styleId,
70 rules = _this$getIdAndRules.rules; // Deduping: just increase the instances count.
71
72
73 if (styleId in this._instancesCounts) {
74 this._instancesCounts[styleId] += 1;
75 return;
76 }
77
78 var indices = rules.map(function (rule) {
79 return _this._sheet.insertRule(rule);
80 }) // Filter out invalid rules
81 .filter(function (index) {
82 return index !== -1;
83 });
84 this._indices[styleId] = indices;
85 this._instancesCounts[styleId] = 1;
86 };
87
88 _proto.remove = function remove(props) {
89 var _this2 = this;
90
91 var _this$getIdAndRules2 = this.getIdAndRules(props),
92 styleId = _this$getIdAndRules2.styleId;
93
94 invariant(styleId in this._instancesCounts, "styleId: `" + styleId + "` not found");
95 this._instancesCounts[styleId] -= 1;
96
97 if (this._instancesCounts[styleId] < 1) {
98 var tagFromServer = this._fromServer && this._fromServer[styleId];
99
100 if (tagFromServer) {
101 tagFromServer.parentNode.removeChild(tagFromServer);
102 delete this._fromServer[styleId];
103 } else {
104 this._indices[styleId].forEach(function (index) {
105 return _this2._sheet.deleteRule(index);
106 });
107
108 delete this._indices[styleId];
109 }
110
111 delete this._instancesCounts[styleId];
112 }
113 };
114
115 _proto.update = function update(props, nextProps) {
116 this.add(nextProps);
117 this.remove(props);
118 };
119
120 _proto.flush = function flush() {
121 this._sheet.flush();
122
123 this._sheet.inject();
124
125 this._fromServer = undefined;
126 this._indices = {};
127 this._instancesCounts = {};
128 this.computeId = this.createComputeId();
129 this.computeSelector = this.createComputeSelector();
130 };
131
132 _proto.cssRules = function cssRules() {
133 var _this3 = this;
134
135 var fromServer = this._fromServer ? Object.keys(this._fromServer).map(function (styleId) {
136 return [styleId, _this3._fromServer[styleId]];
137 }) : [];
138
139 var cssRules = this._sheet.cssRules();
140
141 return fromServer.concat(Object.keys(this._indices).map(function (styleId) {
142 return [styleId, _this3._indices[styleId].map(function (index) {
143 return cssRules[index].cssText;
144 }).join(_this3._optimizeForSpeed ? '' : '\n')];
145 }) // filter out empty rules
146 .filter(function (rule) {
147 return Boolean(rule[1]);
148 }));
149 }
150 /**
151 * createComputeId
152 *
153 * Creates a function to compute and memoize a jsx id from a basedId and optionally props.
154 */
155 ;
156
157 _proto.createComputeId = function createComputeId() {
158 var cache = {};
159 return function (baseId, props) {
160 if (!props) {
161 return "jsx-" + baseId;
162 }
163
164 var propsToString = String(props);
165 var key = baseId + propsToString; // return `jsx-${hashString(`${baseId}-${propsToString}`)}`
166
167 if (!cache[key]) {
168 cache[key] = "jsx-" + (0, _stringHash["default"])(baseId + "-" + propsToString);
169 }
170
171 return cache[key];
172 };
173 }
174 /**
175 * createComputeSelector
176 *
177 * Creates a function to compute and memoize dynamic selectors.
178 */
179 ;
180
181 _proto.createComputeSelector = function createComputeSelector(selectoPlaceholderRegexp) {
182 if (selectoPlaceholderRegexp === void 0) {
183 selectoPlaceholderRegexp = /__jsx-style-dynamic-selector/g;
184 }
185
186 var cache = {};
187 return function (id, css) {
188 // Sanitize SSR-ed CSS.
189 // Client side code doesn't need to be sanitized since we use
190 // document.createTextNode (dev) and the CSSOM api sheet.insertRule (prod).
191 if (!this._isBrowser) {
192 css = sanitize(css);
193 }
194
195 var idcss = id + css;
196
197 if (!cache[idcss]) {
198 cache[idcss] = css.replace(selectoPlaceholderRegexp, id);
199 }
200
201 return cache[idcss];
202 };
203 };
204
205 _proto.getIdAndRules = function getIdAndRules(props) {
206 var _this4 = this;
207
208 var css = props.children,
209 dynamic = props.dynamic,
210 id = props.id;
211
212 if (dynamic) {
213 var styleId = this.computeId(id, dynamic);
214 return {
215 styleId: styleId,
216 rules: Array.isArray(css) ? css.map(function (rule) {
217 return _this4.computeSelector(styleId, rule);
218 }) : [this.computeSelector(styleId, css)]
219 };
220 }
221
222 return {
223 styleId: this.computeId(id),
224 rules: Array.isArray(css) ? css : [css]
225 };
226 }
227 /**
228 * selectFromServer
229 *
230 * Collects style tags from the document with id __jsx-XXX
231 */
232 ;
233
234 _proto.selectFromServer = function selectFromServer() {
235 var elements = Array.prototype.slice.call(document.querySelectorAll('[id^="__jsx-"]'));
236 return elements.reduce(function (acc, element) {
237 var id = element.id.slice(2);
238 acc[id] = element;
239 return acc;
240 }, {});
241 };
242
243 return StyleSheetRegistry;
244}();
245
246exports["default"] = StyleSheetRegistry;
247
248function invariant(condition, message) {
249 if (!condition) {
250 throw new Error("StyleSheetRegistry: " + message + ".");
251 }
252}
\No newline at end of file