UNPKG

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