UNPKG

glam

Version:

inline css for your jsx

164 lines (138 loc) 5.45 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _createClass = function () { function 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function last(arr) { return arr[arr.length - 1]; } // import assign from 'object-assign' /* high performance StyleSheet for css-in-js systems - uses multiple style tags behind the scenes for millions of rules - uses `insertRule` for appending in production for *much* faster performance - 'polyfills' on server side // usage import StyleSheet from 'glamor/lib/sheet' let styleSheet = new StyleSheet() styleSheet.inject() - 'injects' the stylesheet into the page (or into memory if on server) styleSheet.insert('#box { border: 1px solid red; }') - appends a css rule into the stylesheet */ // const doc = global.document; var isBrowser = typeof window !== 'undefined'; var oldIE = function () { if (isBrowser) { var div = document.createElement('div'); div.innerHTML = '<!--[if lt IE 10]><i></i><![endif]-->'; return div.getElementsByTagName('i').length === 1; } return false; }(); var StyleSheet = function () { function StyleSheet() { var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, document = _ref.document, _ref$speedy = _ref.speedy, speedy = _ref$speedy === undefined ? !(process.env.NODE_ENV !== 'production') && !(process.env.NODE_ENV === 'test') : _ref$speedy, _ref$maxLength = _ref.maxLength, maxLength = _ref$maxLength === undefined ? oldIE ? 4000 : 65000 : _ref$maxLength; _classCallCheck(this, StyleSheet); this.document = document; this.isSpeedy = speedy; // the big drawback here is that the css won't be editable in devtools // this.sheet = undefined; this.tags = []; this.maxLength = maxLength; this.ctr = 0; this.inject(); } _createClass(StyleSheet, [{ key: 'makeStyleTag', value: function makeStyleTag() { var tag = this.document.createElement('style'); tag.type = 'text/css'; tag.setAttribute('data-glamor', ''); tag.appendChild(this.document.createTextNode('')); // todo - use a reference node (this.document.head || this.document.getElementsByTagName('head')[0]).appendChild(tag); return tag; } }, { key: 'sheetForTag', value: function sheetForTag(tag) { if (tag.sheet) { return tag.sheet; } // this weirdness brought to you by firefox for (var i = 0; i < this.document.styleSheets.length; i++) { if (this.document.styleSheets[i].ownerNode === tag) { return this.document.styleSheets[i]; } } } }, { key: 'getSheet', value: function getSheet() { return this.sheetForTag(last(this.tags)); } }, { key: 'inject', value: function inject() { if (this.injected) { throw new Error('already injected'); } this.tags[0] = this.makeStyleTag(); this.injected = true; } }, { key: '_insert', value: function _insert(rule) { // this weirdness for perf, and chrome's weird bug // https://stackoverflow.com/questions/20007992/chrome-suddenly-stopped-accepting-insertrule try { var sheet = this.getSheet(); sheet && sheet.insertRule(rule, rule.indexOf('@import') !== -1 ? 0 : sheet.cssRules.length); } catch (e) { if (process.env.NODE_ENV !== 'production') { // might need beter dx for this console.warn('whoops, illegal rule inserted', rule); //eslint-disable-line no-console } } } }, { key: 'insert', value: function insert(rule) { var sheet = this.getSheet(); // this is the ultrafast version, works across browsers if (this.isSpeedy && sheet && sheet.insertRule) { this._insert(rule); } else { if (rule.indexOf('@import') !== -1) { var tag = last(this.tags); tag.insertBefore(this.document.createTextNode(rule), tag.firstChild); } else { last(this.tags).appendChild(this.document.createTextNode(rule)); } } this.ctr++; if (this.ctr % this.maxLength === 0) { this.tags.push(this.makeStyleTag()); } } }, { key: 'rules', value: function rules() { var _this = this; var arr = []; this.tags.forEach(function (tag) { return arr.splice.apply(arr, [arr.length, 0].concat(_toConsumableArray(Array.from(_this.sheetForTag(tag).cssRules)))); }); return arr; } }]); return StyleSheet; }(); exports.default = StyleSheet;