UNPKG

12.8 kBJavaScriptView Raw
1define('jsxstyle-utils', ['exports'], function(exports) {
2 'use strict';
3
4 var canUseDOM = !!(
5 typeof window !== 'undefined' &&
6 window.document &&
7 window.document.createElement
8 );
9 var styleElement;
10 if (
11 typeof module !== 'undefined' &&
12 module.hot &&
13 typeof module.hot.addDisposeHandler === 'function'
14 ) {
15 // gross
16 var hot = module.hot;
17 if (typeof hot.data === 'object') {
18 styleElement = hot.data.styleElement;
19 }
20 hot.addDisposeHandler(function(data) {
21 data.styleElement = styleElement;
22 });
23 }
24 if (canUseDOM && !styleElement) {
25 styleElement = document.createElement('style');
26 styleElement.type = 'text/css';
27 styleElement.appendChild(document.createTextNode('/* jsxstyle */'));
28 document.head.appendChild(styleElement);
29 }
30 function addStyleToHead(rule) {
31 if (styleElement) {
32 var sheet = styleElement.sheet;
33 try {
34 sheet.insertRule(rule, sheet.cssRules.length);
35 } catch (insertError) {
36 // insertRule will fail for rules with pseudoelements the browser doesn't support.
37 // see: https://github.com/smyte/jsxstyle/issues/75
38 if (process.env.NODE_ENV !== 'production') {
39 console.error(
40 '[jsxstyle] Could not insert rule at position ' +
41 sheet.cssRules.length +
42 ': `' +
43 rule +
44 '`'
45 );
46 }
47 }
48 }
49 }
50
51 var componentStyles = {
52 Block: { display: 'block' },
53 Box: null,
54 Col: { display: 'flex', flexDirection: 'column' },
55 Grid: { display: 'grid' },
56 Inline: { display: 'inline' },
57 InlineBlock: { display: 'inline-block' },
58 Row: { display: 'flex', flexDirection: 'row' },
59 };
60
61 /**
62 * Copyright 2013-present, Facebook, Inc.
63 * All rights reserved.
64 *
65 * This source code is licensed under the BSD-style license found in the
66 * LICENSE file in the root directory of this source tree. An additional grant
67 * of patent rights can be found in the PATENTS file in the same directory.
68 *
69 */
70 var isUnitlessNumber = {
71 animationIterationCount: true,
72 borderImageOutset: true,
73 borderImageSlice: true,
74 borderImageWidth: true,
75 boxFlex: true,
76 boxFlexGroup: true,
77 boxOrdinalGroup: true,
78 columnCount: true,
79 columns: true,
80 flex: true,
81 flexGrow: true,
82 flexNegative: true,
83 flexOrder: true,
84 flexPositive: true,
85 flexShrink: true,
86 fontWeight: true,
87 gridColumn: true,
88 gridColumnEnd: true,
89 gridColumnSpan: true,
90 gridColumnStart: true,
91 gridRow: true,
92 gridRowEnd: true,
93 gridRowSpan: true,
94 gridRowStart: true,
95 lineClamp: true,
96 lineHeight: true,
97 opacity: true,
98 order: true,
99 orphans: true,
100 tabSize: true,
101 widows: true,
102 zIndex: true,
103 zoom: true,
104 // SVG-related properties
105 fillOpacity: true,
106 floodOpacity: true,
107 stopOpacity: true,
108 strokeDasharray: true,
109 strokeDashoffset: true,
110 strokeMiterlimit: true,
111 strokeOpacity: true,
112 strokeWidth: true,
113 };
114 function prefixKey(prefix, key) {
115 return prefix + key.charAt(0).toUpperCase() + key.substring(1);
116 }
117 var prefixes = ['Webkit', 'ms', 'Moz', 'O'];
118 Object.keys(isUnitlessNumber).forEach(function(prop) {
119 prefixes.forEach(function(prefix) {
120 isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop];
121 });
122 });
123 function dangerousStyleValue(name, value) {
124 var isEmpty = value == null || typeof value === 'boolean' || value === '';
125 if (isEmpty) {
126 return '';
127 }
128 if (
129 typeof value === 'number' &&
130 value !== 0 &&
131 !(isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name])
132 ) {
133 if (value > -1 && value < 1) {
134 return Math.round(value * 1e6) / 1e4 + '%';
135 }
136 return value + 'px';
137 }
138 return ('' + value).trim();
139 }
140
141 var uppercasePattern = /([A-Z])/g;
142 var msPattern = /^ms-/;
143 var hyphenateCache = {};
144 function hyphenateStyleName(styleName) {
145 if (hyphenateCache.hasOwnProperty(styleName)) {
146 return hyphenateCache[styleName];
147 }
148 var hyphenatedString = styleName
149 .replace(uppercasePattern, '-$1')
150 .toLowerCase()
151 .replace(msPattern, '-ms-');
152 hyphenateCache[styleName] = hyphenatedString;
153 return hyphenateCache[styleName];
154 }
155
156 // global flag makes subsequent calls of capRegex.test advance to the next match
157 var capRegex = /[A-Z]/g;
158 var pseudoelements = {
159 after: true,
160 before: true,
161 placeholder: true,
162 selection: true,
163 };
164 var pseudoclasses = {
165 active: true,
166 checked: true,
167 disabled: true,
168 empty: true,
169 enabled: true,
170 focus: true,
171 hover: true,
172 invalid: true,
173 required: true,
174 target: true,
175 valid: true,
176 };
177 var specialCaseProps = {
178 children: true,
179 class: true,
180 className: true,
181 component: true,
182 mediaQueries: true,
183 props: true,
184 style: true,
185 };
186 function getStyleKeysForProps(props, pretty) {
187 if (pretty === void 0) {
188 pretty = false;
189 }
190 if (typeof props !== 'object' || props === null) {
191 return null;
192 }
193 var propKeys = Object.keys(props).sort();
194 var keyCount = propKeys.length;
195 if (keyCount === 0) {
196 return null;
197 }
198 var mediaQueries = props.mediaQueries;
199 var hasMediaQueries = typeof mediaQueries === 'object';
200 var usesMediaQueries = false;
201 var styleKeyObj = {};
202 var classNameKey = '';
203 var seenMQs = {};
204 var mqSortKeys = {};
205 if (hasMediaQueries) {
206 var idx = -1;
207 for (var k in mediaQueries) {
208 mqSortKeys[k] = '@' + (1000 + ++idx);
209 }
210 }
211 for (var idx = -1; ++idx < keyCount; ) {
212 var originalPropName = propKeys[idx];
213 if (
214 specialCaseProps.hasOwnProperty(originalPropName) ||
215 !props.hasOwnProperty(originalPropName)
216 ) {
217 continue;
218 }
219 var propName = originalPropName;
220 var propSansMQ = void 0;
221 var pseudoelement = void 0;
222 var pseudoclass = void 0;
223 var mqKey = void 0;
224 capRegex.lastIndex = 0;
225 var splitIndex = 0;
226 var prefix =
227 capRegex.test(originalPropName) &&
228 capRegex.lastIndex > 1 &&
229 originalPropName.slice(0, capRegex.lastIndex - 1);
230 // check for media query prefix
231 if (prefix && hasMediaQueries && mediaQueries.hasOwnProperty(prefix)) {
232 usesMediaQueries = true;
233 mqKey = prefix;
234 splitIndex = capRegex.lastIndex - 1;
235 propSansMQ =
236 originalPropName[splitIndex].toLowerCase() +
237 originalPropName.slice(splitIndex + 1);
238 prefix =
239 capRegex.test(originalPropName) &&
240 propSansMQ.slice(0, capRegex.lastIndex - splitIndex - 1);
241 }
242 // check for pseudoelement prefix
243 if (prefix && pseudoelements.hasOwnProperty(prefix)) {
244 pseudoelement = prefix;
245 splitIndex = capRegex.lastIndex - 1;
246 prefix =
247 capRegex.test(originalPropName) &&
248 originalPropName[splitIndex].toLowerCase() +
249 originalPropName.slice(splitIndex + 1, capRegex.lastIndex - 1);
250 }
251 // check for pseudoclass prefix
252 if (prefix && pseudoclasses.hasOwnProperty(prefix)) {
253 pseudoclass = prefix;
254 splitIndex = capRegex.lastIndex - 1;
255 }
256 // trim prefixes off propName
257 if (splitIndex > 0) {
258 propName =
259 originalPropName[splitIndex].toLowerCase() +
260 originalPropName.slice(splitIndex + 1);
261 }
262 var styleValue = dangerousStyleValue(propName, props[originalPropName]);
263 if (styleValue === '') {
264 continue;
265 }
266 var mediaQuery = mqKey && mediaQueries[mqKey];
267 var mqSortKey = mqKey && mqSortKeys[mqKey];
268 var key =
269 '.' +
270 (mqSortKey || '') +
271 (pseudoclass ? ':' + pseudoclass : '') +
272 (pseudoelement ? '::' + pseudoelement : '');
273 if (!styleKeyObj.hasOwnProperty(key)) {
274 styleKeyObj[key] = { styles: pretty ? '\n' : '' };
275 if (mediaQuery) {
276 styleKeyObj[key].mediaQuery = mediaQuery;
277 }
278 if (pseudoclass) {
279 styleKeyObj[key].pseudoclass = pseudoclass;
280 }
281 if (pseudoelement) {
282 styleKeyObj[key].pseudoelement = pseudoelement;
283 }
284 }
285 if (mediaQuery) {
286 seenMQs[mediaQuery] = seenMQs[mediaQuery] || '';
287 seenMQs[mediaQuery] += propSansMQ + ':' + styleValue + ';';
288 } else {
289 classNameKey += originalPropName + ':' + styleValue + ';';
290 }
291 styleKeyObj[key].styles +=
292 (pretty ? ' ' : '') +
293 hyphenateStyleName(propName) +
294 (pretty ? ': ' : ':') +
295 styleValue +
296 (pretty ? ';\n' : ';');
297 }
298 // append media query key
299 if (usesMediaQueries) {
300 var mqKeys = Object.keys(seenMQs).sort();
301 for (var idx = -1, len = mqKeys.length; ++idx < len; ) {
302 var mediaQuery = mqKeys[idx];
303 classNameKey += '@' + mediaQuery + '~' + seenMQs[mediaQuery];
304 }
305 }
306 if (classNameKey === '') {
307 return null;
308 }
309 styleKeyObj.classNameKey = classNameKey;
310 return styleKeyObj;
311 }
312
313 /* tslint:disable no-bitwise */
314 // thx darksky: https://git.io/v9kWO
315 function stringHash(str) {
316 var hash = 5381;
317 var i = str.length;
318 while (i) {
319 hash = (hash * 33) ^ str.charCodeAt(--i);
320 }
321 /* JavaScript does bitwise operations (like XOR, above) on 32-bit signed
322 * integers. Since we want the results to be always positive, convert the
323 * signed int to an unsigned by doing an unsigned bitshift. */
324 return hash >>> 0;
325 }
326
327 function cannotInject() {
328 throw new Error(
329 'jsxstyle error: `injectOptions` must be called before any jsxstyle components mount.'
330 );
331 }
332 function alreadyInjected() {
333 throw new Error(
334 'jsxstyle error: `injectOptions` should be called once and only once.'
335 );
336 }
337 function getStringHash(key, props) {
338 return '_' + stringHash(key).toString(36);
339 }
340 function getStyleCache() {
341 var _classNameCache = {};
342 var getClassNameForKey = getStringHash;
343 var onInsertRule;
344 var pretty = false;
345 var styleCache = {
346 reset: function() {
347 _classNameCache = {};
348 },
349 injectOptions: function(options) {
350 if (options) {
351 if (options.getClassName) {
352 getClassNameForKey = options.getClassName;
353 }
354 if (options.onInsertRule) {
355 onInsertRule = options.onInsertRule;
356 }
357 if (options.pretty) {
358 pretty = options.pretty;
359 }
360 }
361 styleCache.injectOptions = alreadyInjected;
362 },
363 getClassName: function(props, classNameProp) {
364 styleCache.injectOptions = cannotInject;
365 var styleObj = getStyleKeysForProps(props, pretty);
366 if (typeof styleObj !== 'object' || styleObj === null) {
367 return classNameProp || null;
368 }
369 var key = styleObj.classNameKey;
370 if (key && !_classNameCache.hasOwnProperty(key)) {
371 _classNameCache[key] = getClassNameForKey(key, props);
372 delete styleObj.classNameKey;
373 Object.keys(styleObj)
374 .sort()
375 .forEach(function(k) {
376 var selector = '.' + _classNameCache[key];
377 // prettier-ignore
378 var _a = styleObj[k], pseudoclass = _a.pseudoclass, pseudoelement = _a.pseudoelement, mediaQuery = _a.mediaQuery, styles = _a.styles;
379 var rule =
380 selector +
381 (pseudoclass ? ':' + pseudoclass : '') +
382 (pseudoelement ? '::' + pseudoelement : '') +
383 (' {' + styles + '}');
384 if (mediaQuery) {
385 rule = '@media ' + mediaQuery + ' { ' + rule + ' }';
386 }
387 if (
388 onInsertRule &&
389 // if the function returns false, bail.
390 onInsertRule(rule, props) === false
391 ) {
392 return;
393 }
394 addStyleToHead(rule);
395 });
396 }
397 return _classNameCache[key] && classNameProp
398 ? classNameProp + ' ' + _classNameCache[key]
399 : _classNameCache[key] || classNameProp || null;
400 },
401 };
402 return styleCache;
403 }
404
405 exports.addStyleToHead = addStyleToHead;
406 exports.componentStyles = componentStyles;
407 exports.dangerousStyleValue = dangerousStyleValue;
408 exports.getStyleCache = getStyleCache;
409 exports.getStyleKeysForProps = getStyleKeysForProps;
410 exports.pseudoelements = pseudoelements;
411 exports.pseudoclasses = pseudoclasses;
412 exports.hyphenateStyleName = hyphenateStyleName;
413 exports.stringHash = stringHash;
414
415 Object.defineProperty(exports, '__esModule', { value: true });
416});