UNPKG

14.5 kBJavaScriptView Raw
1(function (global, factory) {
2 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
3 typeof define === 'function' && define.amd ? define(factory) :
4 (global.b = factory());
5}(this, (function () { 'use strict';
6
7 var pseudos = [
8 ':active',
9 ':any',
10 ':checked',
11 ':default',
12 ':disabled',
13 ':empty',
14 ':enabled',
15 ':first',
16 ':first-child',
17 ':first-of-type',
18 ':fullscreen',
19 ':focus',
20 ':hover',
21 ':indeterminate',
22 ':in-range',
23 ':invalid',
24 ':last-child',
25 ':last-of-type',
26 ':left',
27 ':link',
28 ':only-child',
29 ':only-of-type',
30 ':optional',
31 ':out-of-range',
32 ':read-only',
33 ':read-write',
34 ':required',
35 ':right',
36 ':root',
37 ':scope',
38 ':target',
39 ':valid',
40 ':visited',
41
42 // With value
43 ':dir',
44 ':lang',
45 ':not',
46 ':nth-child',
47 ':nth-last-child',
48 ':nth-last-of-type',
49 ':nth-of-type',
50
51 // Elements
52 '::after',
53 '::before',
54 '::first-letter',
55 '::first-line',
56 '::selection',
57 '::backdrop',
58 '::placeholder',
59 '::marker',
60 '::spelling-error',
61 '::grammar-error'
62 ];
63
64 var popular = {
65 ai : 'alignItems',
66 b : 'bottom',
67 bc : 'backgroundColor',
68 br : 'borderRadius',
69 bs : 'boxShadow',
70 c : 'color',
71 d : 'display',
72 f : 'float',
73 fd : 'flexDirection',
74 ff : 'fontFamily',
75 fs : 'fontSize',
76 h : 'height',
77 jc : 'justifyContent',
78 l : 'left',
79 lh : 'lineHeight',
80 ls : 'letterSpacing',
81 m : 'margin',
82 mb : 'marginBottom',
83 ml : 'marginLeft',
84 mr : 'marginRight',
85 mt : 'marginTop',
86 o : 'opacity',
87 p : 'padding',
88 pb : 'paddingBottom',
89 pl : 'paddingLeft',
90 pr : 'paddingRight',
91 pt : 'paddingTop',
92 r : 'right',
93 t : 'top',
94 ta : 'textAlign',
95 td : 'textDecoration',
96 tt : 'textTransform',
97 w : 'width'
98 };
99
100 var cssProperties = ['float'].concat(Object.keys(
101 findWidth(document.documentElement.style)
102 ).filter(function (p) { return p.indexOf('-') === -1 && p !== 'length'; }));
103
104 function findWidth(obj) {
105 return obj.hasOwnProperty('width')
106 ? obj
107 : findWidth(Object.getPrototypeOf(obj))
108 }
109
110 var memoize = function (fn, cache) {
111 if ( cache === void 0 ) cache = {};
112
113 return function (item) { return item in cache
114 ? cache[item]
115 : cache[item] = fn(item); };
116 };
117
118 function add(style, prop, value) {
119 if (prop in style)
120 { add(style, '!' + prop, value); }
121 else
122 { style[prop] = value; }
123 }
124
125 var vendorMap = Object.create(null, {});
126 var vendorValuePrefix = Object.create(null, {});
127
128 var vendorRegex = /^(o|O|ms|MS|Ms|moz|Moz|webkit|Webkit|WebKit)([A-Z])/;
129
130 var appendPx = memoize(function (prop) {
131 var el = document.createElement('div');
132
133 try {
134 el.style[prop] = '1px';
135 el.style.setProperty(prop, '1px');
136 return el.style[prop].slice(-3) === '1px' ? 'px' : ''
137 } catch (err) {
138 return ''
139 }
140 }, {
141 flex: '',
142 boxShadow: 'px',
143 border: 'px'
144 });
145
146 function lowercaseFirst(string) {
147 return string.charAt(0).toLowerCase() + string.slice(1)
148 }
149
150 function sanitize(styles) {
151 return Object.keys(styles).reduce(function (acc, key) {
152 var value = styles[key];
153
154 if (!value && value !== 0 && value !== '')
155 { return acc }
156
157 if (key === 'content' && value.charAt(0) !== '"')
158 { acc[key] = '"' + value + '"'; }
159 else
160 { acc[key in vendorMap ? vendorMap[key] : key] = formatValue(key, value); }
161
162 return acc
163 }, {})
164 }
165
166 function assign(obj, obj2) {
167 for (var key in obj2) {
168 if (obj2.hasOwnProperty(key))
169 { obj[key] = obj2[key]; }
170 }
171 }
172
173 function hyphenToCamelCase(hyphen) {
174 return hyphen.slice(hyphen.charAt(0) === '-' ? 1 : 0).replace(/-([a-z])/g, function(match) {
175 return match[1].toUpperCase()
176 })
177 }
178
179 function camelCaseToHyphen(camelCase) {
180 return camelCase.replace(/([A-Z])/g, '-$1').toLowerCase()
181 }
182
183 function initials(camelCase) {
184 return camelCase.charAt(0) + (camelCase.match(/([A-Z])/g) || []).join('').toLowerCase()
185 }
186
187 function objectToRules(style, selector, suffix, single) {
188 if ( suffix === void 0 ) suffix = '';
189
190 var base = {};
191
192 var rules = [];
193
194 Object.keys(style).forEach(function (prop) {
195 if (prop.charAt(0) === '@')
196 { rules.push(prop + '{' + objectToRules(style[prop], selector, suffix, single) + '}'); }
197 else if (typeof style[prop] === 'object')
198 { rules = rules.concat(objectToRules(style[prop], selector, suffix + prop, single)); }
199 else
200 { base[prop] = style[prop]; }
201 });
202
203 if (Object.keys(base).length) {
204 rules.unshift(
205 ((single || (suffix.charAt(0) === ' ') ? '' : '&') + '&' + suffix).replace(/&/g, selector) +
206 '{' + stylesToCss(base) + '}'
207 );
208 }
209
210 return rules
211 }
212
213 var selectorSplit = /,(?=(?:(?:[^"]*"){2})*[^"]*$)/;
214
215 function stylesToCss(style) {
216 return Object.keys(style).reduce(function (acc, prop) { return acc + propToString(prop.replace(/!/g, ''), style[prop]); }
217 , '')
218 }
219
220 function propToString(prop, value) {
221 return (vendorRegex.test(prop) ? '-' : '')
222 + (prop.charAt(0) === '-' && prop.charAt(1) === '-'
223 ? prop
224 : camelCaseToHyphen(prop)
225 )
226 + ':'
227 + value
228 + ';'
229 }
230
231 function formatValue(key, value) {
232 return value in vendorValuePrefix
233 ? vendorValuePrefix[value]
234 : addPx(key, value)
235 }
236
237 function addPx(key, value) {
238 return value + (isNaN(value) ? '' : appendPx(key))
239 }
240
241 var document$1 = window.document;
242 var styleSheet = document$1 && document$1.createElement('style');
243 styleSheet && document$1.head.appendChild(styleSheet);
244 var sheet = styleSheet && styleSheet.sheet;
245
246 var debug = false;
247 var classes = Object.create(null, {});
248 var rules = [];
249 var count = 0;
250
251 var classPrefix = 'b' + ('000' + ((Math.random() * 46656) | 0).toString(36)).slice(-3) +
252 ('000' + ((Math.random() * 46656) | 0).toString(36)).slice(-3);
253
254 function setDebug(d) {
255 debug = d;
256 }
257
258 function getSheet() {
259 var content = rules.join('');
260 rules = [];
261 classes = Object.create(null, {});
262 count = 0;
263 return content
264 }
265
266 function insert(rule, index) {
267 rules.push(rule);
268
269 if (debug)
270 { return styleSheet.textContent = rules.join('\n') }
271
272 sheet && sheet.insertRule(rule, arguments.length > 1
273 ? index
274 : sheet.cssRules.length
275 );
276 }
277
278 function createClass(style) {
279 var json = JSON.stringify(style);
280
281 if (json in classes)
282 { return classes[json] }
283
284 var className = classPrefix + (++count)
285 , rules = objectToRules(style, '.' + className);
286
287 for (var i = 0; i < rules.length; i++)
288 { insert(rules[i]); }
289
290 classes[json] = className;
291
292 return className
293 }
294
295 /* eslint no-invalid-this: 0 */
296
297 var shorts = Object.create(null);
298
299 function bss(input, value) {
300 var b = chain(bss);
301 assign(b.__style, parse.apply(null, arguments));
302 return b
303 }
304
305 function setProp(prop, value) {
306 Object.defineProperty(bss, prop, {
307 configurable: true,
308 value: value
309 });
310 }
311
312 Object.defineProperties(bss, {
313 __style: {
314 configurable: true,
315 writable: true,
316 value: {}
317 },
318 valueOf: {
319 configurable: true,
320 writable: true,
321 value: function ValueOf() {
322 return '.' + this.class
323 }
324 }
325 });
326
327 setProp('setDebug', setDebug);
328
329 setProp('$keyframes', keyframes);
330 setProp('$media', $media);
331 setProp('$import', $import);
332 setProp('$nest', $nest);
333 setProp('getSheet', getSheet);
334 setProp('helper', helper);
335 setProp('css', css);
336 setProp('classPrefix', classPrefix);
337
338 function chain(instance) {
339 var newInstance = Object.create(bss, {
340 __style: {
341 value: instance.__style
342 },
343 style: {
344 enumerable: true,
345 get: function() {
346 var this$1 = this;
347
348 return Object.keys(this.__style).reduce(function (acc, key) {
349 if (typeof this$1.__style[key] === 'number' || typeof this$1.__style[key] === 'string')
350 { acc[key.replace(/^!/, '')] = this$1.__style[key]; }
351 return acc
352 }, {})
353 }
354 }
355 });
356
357 if (instance === bss)
358 { bss.__style = {}; }
359
360 return newInstance
361 }
362
363 cssProperties.forEach(function (prop) {
364 var vendor = prop.match(vendorRegex);
365 if (vendor) {
366 var unprefixed = lowercaseFirst(prop.replace(vendorRegex, '$2'));
367 if (cssProperties.indexOf(unprefixed) === -1) {
368 if (unprefixed === 'flexDirection')
369 { vendorValuePrefix.flex = '-' + vendor[1].toLowerCase() + '-flex'; }
370
371 vendorMap[unprefixed] = prop;
372 setProp(unprefixed, setter(prop));
373 setProp(short(unprefixed), bss[unprefixed]);
374 return
375 }
376 }
377
378 setProp(prop, setter(prop));
379 setProp(short(prop), bss[prop]);
380 });
381
382 setProp('content', function Content(arg) {
383 this.__style.content = '"' + arg + '"';
384 return chain(this)
385 });
386
387 Object.defineProperty(bss, 'class', {
388 set: function(value) {
389 this.__class = value;
390 },
391 get: function() {
392 return this.__class || createClass(this.__style)
393 }
394 });
395
396 function $media(value, style) {
397 if (value)
398 { add(this.__style, '@media ' + value, parse(style)); }
399
400 return chain(this)
401 }
402
403 function $import(value) {
404 if (value)
405 { insert('@import ' + value + ';', 0); }
406
407 return chain(this)
408 }
409
410 function $nest(selector, properties) {
411 var this$1 = this;
412
413 if (arguments.length === 1)
414 { Object.keys(selector).forEach(function (x) { return addNest(this$1.__style, x, selector[x]); }); }
415 else if (selector)
416 { addNest(this.__style, selector, properties); }
417
418 return chain(this)
419 }
420
421 function addNest(style, selector, properties) {
422 add(
423 style,
424 selector.split(selectorSplit).map(function (x) {
425 x = x.trim();
426 return (x.charAt(0) === ':' || x.charAt(0) === '[' ? '' : ' ') + x
427 }).join(',&'),
428 parse(properties)
429 );
430 }
431
432 pseudos.forEach(function (name) { return setProp('$' + hyphenToCamelCase(name.replace(/:/g, '')), function Pseudo(value, b) {
433 if (value || b)
434 { add(this.__style, name + (b ? '(' + value + ')' : ''), parse(b || value)); }
435 return chain(this)
436 }); }
437 );
438
439 function setter(prop) {
440 return function CssProperty(value) {
441 if (!value && value !== 0) {
442 delete this.__style[prop];
443 } else if (arguments.length > 0) {
444 add(this.__style, prop, arguments.length === 1
445 ? formatValue(prop, value)
446 : Array.prototype.slice.call(arguments).map(function (v) { return addPx(prop, v); }).join(' ')
447 );
448 }
449
450 return chain(this)
451 }
452 }
453
454 function css(selector, style) {
455 if (arguments.length === 1)
456 { Object.keys(selector).forEach(function (key) { return addCss(key, selector[key]); }); }
457 else
458 { addCss(selector, style); }
459
460 return chain(this)
461 }
462
463 function addCss(selector, style) {
464 objectToRules(parse(style), selector, '', true).forEach(insert);
465 }
466
467 function helper(name, styling) {
468 if (arguments.length === 1)
469 { return Object.keys(name).forEach(function (key) { return helper(key, name[key]); }) }
470
471 delete bss[name]; // Needed to avoid weird get calls in chrome
472
473 if (typeof styling === 'function') {
474 helper[name] = styling;
475 Object.defineProperty(bss, name, {
476 configurable: true,
477 value: function Helper() {
478 var result = styling.apply(null, arguments);
479 assign(this.__style, result.__style);
480 return chain(this)
481 }
482 });
483 } else {
484 helper[name] = parse(styling);
485 Object.defineProperty(bss, name, {
486 configurable: true,
487 get: function() {
488 assign(this.__style, parse(styling));
489 return chain(this)
490 }
491 });
492 }
493 }
494
495 bss.helper('$animate', function (value, props) { return bss.animation(bss.$keyframes(props) + ' ' + value); }
496 );
497
498 function short(prop) {
499 var acronym = initials(prop)
500 , short = popular[acronym] && popular[acronym] !== prop ? prop : acronym;
501
502 shorts[short] = prop;
503 return short
504 }
505
506 var stringToObject = memoize(function (string) {
507 var last = ''
508 , prev;
509
510 return string.trim().split(/;|\n/).reduce(function (acc, line) {
511 line = last + line.trim();
512 last = line.charAt(line.length - 1) === ',' ? line : '';
513 if (last)
514 { return acc }
515
516 if (line.charAt(0) === ',') {
517 acc[prev] += line;
518 return acc
519 }
520
521 var ref = line.replace(/[ :]+/, ' ').split(' ');
522 var key = ref[0];
523 var tokens = ref.slice(1);
524
525 if (!key)
526 { return acc }
527
528 var cssVar = key.charAt(0) === '-' && key.charAt(1) === '-'
529 , prop = cssVar
530 ? key
531 : hyphenToCamelCase(key);
532
533 prev = shorts[prop] || prop;
534
535 if (prop in helper) {
536 typeof helper[prop] === 'function'
537 ? assign(acc, helper[prop].apply(helper, tokens).__style)
538 : assign(acc, helper[prop]);
539 } else if (tokens.length > 0) {
540 add(acc, prev, tokens.map(function (t) { return cssVar ? t : addPx(prev, t); }).join(' '));
541 }
542
543 return acc
544 }, {})
545 });
546
547 var count$1 = 0;
548 var keyframeCache = {};
549
550 function keyframes(props) {
551 var content = Object.keys(props).reduce(function (acc, key) { return acc + key + '{' + stylesToCss(parse(props[key])) + '}'; }
552 , '');
553
554 if (content in keyframeCache)
555 { return keyframeCache[content] }
556
557 var name = classPrefix + count$1++;
558 keyframeCache[content] = name;
559 insert('@keyframes ' + name + '{' + content + '}');
560
561 return name
562 }
563
564 function parse(input, value) {
565 var arguments$1 = arguments;
566 var obj;
567
568 if (typeof input === 'string') {
569 if (typeof value === 'string' || typeof value === 'number')
570 { return (( obj = {}, obj[input] = value, obj )) }
571
572 return stringToObject(input)
573 } else if (Array.isArray(input) && typeof input[0] === 'string') {
574 var str = '';
575 for (var i = 0; i < input.length; i++)
576 { str += input[i] + (arguments$1[i + 1] || ''); }
577 return stringToObject(str)
578 }
579
580 return input.__style || sanitize(input)
581 }
582
583 return bss;
584
585})));
586//# sourceMappingURL=bss.js.map