You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

2295 regels
60 KiB

  1. (function (global, factory) {
  2. typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
  3. typeof define === 'function' && define.amd ? define(['exports'], factory) :
  4. (factory((global.jss = {})));
  5. }(this, (function (exports) { 'use strict';
  6. var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
  7. var isBrowser = (typeof window === "undefined" ? "undefined" : _typeof(window)) === "object" && (typeof document === "undefined" ? "undefined" : _typeof(document)) === 'object' && document.nodeType === 9;
  8. /**
  9. * Link rule with CSSStyleRule and nested rules with corresponding nested cssRules if both exists.
  10. */
  11. function linkRule(rule, cssRule) {
  12. rule.renderable = cssRule;
  13. if (rule.rules && cssRule.cssRules) rule.rules.link(cssRule.cssRules);
  14. }
  15. var global$1 = (typeof global !== "undefined" ? global :
  16. typeof self !== "undefined" ? self :
  17. typeof window !== "undefined" ? window : {});
  18. if (typeof global$1.setTimeout === 'function') ;
  19. if (typeof global$1.clearTimeout === 'function') ;
  20. // from https://github.com/kumavis/browser-process-hrtime/blob/master/index.js
  21. var performance = global$1.performance || {};
  22. var performanceNow =
  23. performance.now ||
  24. performance.mozNow ||
  25. performance.msNow ||
  26. performance.oNow ||
  27. performance.webkitNow ||
  28. function(){ return (new Date()).getTime() };
  29. /**
  30. * Similar to invariant but only logs a warning if the condition is not met.
  31. * This can be used to log issues in development environments in critical
  32. * paths. Removing the logging code for production environments will keep the
  33. * same logic and follow the same code paths.
  34. */
  35. var __DEV__ = "development" !== 'production';
  36. var warning = function() {};
  37. if (__DEV__) {
  38. warning = function(condition, format, args) {
  39. var len = arguments.length;
  40. args = new Array(len > 2 ? len - 2 : 0);
  41. for (var key = 2; key < len; key++) {
  42. args[key - 2] = arguments[key];
  43. }
  44. if (format === undefined) {
  45. throw new Error(
  46. '`warning(condition, format, ...args)` requires a warning ' +
  47. 'message argument'
  48. );
  49. }
  50. if (format.length < 10 || (/^[s\W]*$/).test(format)) {
  51. throw new Error(
  52. 'The warning format should be able to uniquely identify this ' +
  53. 'warning. Please, use a more descriptive format than: ' + format
  54. );
  55. }
  56. if (!condition) {
  57. var argIndex = 0;
  58. var message = 'Warning: ' +
  59. format.replace(/%s/g, function() {
  60. return args[argIndex++];
  61. });
  62. if (typeof console !== 'undefined') {
  63. console.error(message);
  64. }
  65. try {
  66. // This error was thrown as a convenience so that you can use this stack
  67. // to find the callsite that caused this warning to fire.
  68. throw new Error(message);
  69. } catch(x) {}
  70. }
  71. };
  72. }
  73. var warning_1 = warning;
  74. var join = function join(value, by) {
  75. var result = '';
  76. for (var i = 0; i < value.length; i++) {
  77. // Remove !important from the value, it will be readded later.
  78. if (value[i] === '!important') break;
  79. if (result) result += by;
  80. result += value[i];
  81. }
  82. return result;
  83. };
  84. /**
  85. * Converts array values to string.
  86. *
  87. * `margin: [['5px', '10px']]` > `margin: 5px 10px;`
  88. * `border: ['1px', '2px']` > `border: 1px, 2px;`
  89. * `margin: [['5px', '10px'], '!important']` > `margin: 5px 10px !important;`
  90. * `color: ['red', !important]` > `color: red !important;`
  91. */
  92. function toCssValue(value) {
  93. var ignoreImportant = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
  94. if (!Array.isArray(value)) return value;
  95. var cssValue = '';
  96. // Support space separated values via `[['5px', '10px']]`.
  97. if (Array.isArray(value[0])) {
  98. for (var i = 0; i < value.length; i++) {
  99. if (value[i] === '!important') break;
  100. if (cssValue) cssValue += ', ';
  101. cssValue += join(value[i], ' ');
  102. }
  103. } else cssValue = join(value, ', ');
  104. // Add !important, because it was ignored.
  105. if (!ignoreImportant && value[value.length - 1] === '!important') {
  106. cssValue += ' !important';
  107. }
  108. return cssValue;
  109. }
  110. /**
  111. * Indent a string.
  112. * http://jsperf.com/array-join-vs-for
  113. */
  114. function indentStr(str, indent) {
  115. var result = '';
  116. for (var index = 0; index < indent; index++) {
  117. result += ' ';
  118. }return result + str;
  119. }
  120. /**
  121. * Converts a Rule to CSS string.
  122. */
  123. function toCss(selector, style) {
  124. var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  125. var result = '';
  126. if (!style) return result;
  127. var _options$indent = options.indent,
  128. indent = _options$indent === undefined ? 0 : _options$indent;
  129. var fallbacks = style.fallbacks;
  130. indent++;
  131. // Apply fallbacks first.
  132. if (fallbacks) {
  133. // Array syntax {fallbacks: [{prop: value}]}
  134. if (Array.isArray(fallbacks)) {
  135. for (var index = 0; index < fallbacks.length; index++) {
  136. var fallback = fallbacks[index];
  137. for (var prop in fallback) {
  138. var value = fallback[prop];
  139. if (value != null) {
  140. result += '\n' + indentStr(prop + ': ' + toCssValue(value) + ';', indent);
  141. }
  142. }
  143. }
  144. } else {
  145. // Object syntax {fallbacks: {prop: value}}
  146. for (var _prop in fallbacks) {
  147. var _value = fallbacks[_prop];
  148. if (_value != null) {
  149. result += '\n' + indentStr(_prop + ': ' + toCssValue(_value) + ';', indent);
  150. }
  151. }
  152. }
  153. }
  154. for (var _prop2 in style) {
  155. var _value2 = style[_prop2];
  156. if (_value2 != null && _prop2 !== 'fallbacks') {
  157. result += '\n' + indentStr(_prop2 + ': ' + toCssValue(_value2) + ';', indent);
  158. }
  159. }
  160. // Allow empty style in this case, because properties will be added dynamically.
  161. if (!result && !options.allowEmpty) return result;
  162. indent--;
  163. result = indentStr(selector + ' {' + result + '\n', indent) + indentStr('}', indent);
  164. return result;
  165. }
  166. var _typeof$1 = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
  167. return typeof obj;
  168. } : function (obj) {
  169. return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
  170. };
  171. var classCallCheck = function (instance, Constructor) {
  172. if (!(instance instanceof Constructor)) {
  173. throw new TypeError("Cannot call a class as a function");
  174. }
  175. };
  176. var createClass = function () {
  177. function defineProperties(target, props) {
  178. for (var i = 0; i < props.length; i++) {
  179. var descriptor = props[i];
  180. descriptor.enumerable = descriptor.enumerable || false;
  181. descriptor.configurable = true;
  182. if ("value" in descriptor) descriptor.writable = true;
  183. Object.defineProperty(target, descriptor.key, descriptor);
  184. }
  185. }
  186. return function (Constructor, protoProps, staticProps) {
  187. if (protoProps) defineProperties(Constructor.prototype, protoProps);
  188. if (staticProps) defineProperties(Constructor, staticProps);
  189. return Constructor;
  190. };
  191. }();
  192. var _extends = Object.assign || function (target) {
  193. for (var i = 1; i < arguments.length; i++) {
  194. var source = arguments[i];
  195. for (var key in source) {
  196. if (Object.prototype.hasOwnProperty.call(source, key)) {
  197. target[key] = source[key];
  198. }
  199. }
  200. }
  201. return target;
  202. };
  203. var StyleRule = function () {
  204. function StyleRule(key, style, options) {
  205. classCallCheck(this, StyleRule);
  206. this.type = 'style';
  207. this.isProcessed = false;
  208. var sheet = options.sheet,
  209. Renderer = options.Renderer,
  210. selector = options.selector;
  211. this.key = key;
  212. this.options = options;
  213. this.style = style;
  214. if (selector) this.selectorText = selector;
  215. this.renderer = sheet ? sheet.renderer : new Renderer();
  216. }
  217. /**
  218. * Set selector string.
  219. * Attention: use this with caution. Most browsers didn't implement
  220. * selectorText setter, so this may result in rerendering of entire Style Sheet.
  221. */
  222. createClass(StyleRule, [{
  223. key: 'prop',
  224. /**
  225. * Get or set a style property.
  226. */
  227. value: function prop(name, value) {
  228. // It's a getter.
  229. if (value === undefined) return this.style[name];
  230. // Don't do anything if the value has not changed.
  231. if (this.style[name] === value) return this;
  232. value = this.options.jss.plugins.onChangeValue(value, name, this);
  233. var isEmpty = value == null || value === false;
  234. var isDefined = name in this.style;
  235. // Value is empty and wasn't defined before.
  236. if (isEmpty && !isDefined) return this;
  237. // We are going to remove this value.
  238. var remove = isEmpty && isDefined;
  239. if (remove) delete this.style[name];else this.style[name] = value;
  240. // Renderable is defined if StyleSheet option `link` is true.
  241. if (this.renderable) {
  242. if (remove) this.renderer.removeProperty(this.renderable, name);else this.renderer.setProperty(this.renderable, name, value);
  243. return this;
  244. }
  245. var sheet = this.options.sheet;
  246. if (sheet && sheet.attached) {
  247. warning_1(false, 'Rule is not linked. Missing sheet option "link: true".');
  248. }
  249. return this;
  250. }
  251. /**
  252. * Apply rule to an element inline.
  253. */
  254. }, {
  255. key: 'applyTo',
  256. value: function applyTo(renderable) {
  257. var json = this.toJSON();
  258. for (var prop in json) {
  259. this.renderer.setProperty(renderable, prop, json[prop]);
  260. }return this;
  261. }
  262. /**
  263. * Returns JSON representation of the rule.
  264. * Fallbacks are not supported.
  265. * Useful for inline styles.
  266. */
  267. }, {
  268. key: 'toJSON',
  269. value: function toJSON() {
  270. var json = {};
  271. for (var prop in this.style) {
  272. var value = this.style[prop];
  273. if ((typeof value === 'undefined' ? 'undefined' : _typeof$1(value)) !== 'object') json[prop] = value;else if (Array.isArray(value)) json[prop] = toCssValue(value);
  274. }
  275. return json;
  276. }
  277. /**
  278. * Generates a CSS string.
  279. */
  280. }, {
  281. key: 'toString',
  282. value: function toString(options) {
  283. var sheet = this.options.sheet;
  284. var link = sheet ? sheet.options.link : false;
  285. var opts = link ? _extends({}, options, { allowEmpty: true }) : options;
  286. return toCss(this.selector, this.style, opts);
  287. }
  288. }, {
  289. key: 'selector',
  290. set: function set$$1(selector) {
  291. if (selector === this.selectorText) return;
  292. this.selectorText = selector;
  293. if (!this.renderable) return;
  294. var hasChanged = this.renderer.setSelector(this.renderable, selector);
  295. // If selector setter is not implemented, rerender the rule.
  296. if (!hasChanged && this.renderable) {
  297. var renderable = this.renderer.replaceRule(this.renderable, this);
  298. if (renderable) this.renderable = renderable;
  299. }
  300. }
  301. /**
  302. * Get selector string.
  303. */
  304. ,
  305. get: function get$$1() {
  306. return this.selectorText;
  307. }
  308. }]);
  309. return StyleRule;
  310. }();
  311. function unwrapExports (x) {
  312. return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
  313. }
  314. function createCommonjsModule(fn, module) {
  315. return module = { exports: {} }, fn(module, module.exports), module.exports;
  316. }
  317. var ponyfill = createCommonjsModule(function (module, exports) {
  318. Object.defineProperty(exports, "__esModule", {
  319. value: true
  320. });
  321. exports['default'] = symbolObservablePonyfill;
  322. function symbolObservablePonyfill(root) {
  323. var result;
  324. var _Symbol = root.Symbol;
  325. if (typeof _Symbol === 'function') {
  326. if (_Symbol.observable) {
  327. result = _Symbol.observable;
  328. } else {
  329. result = _Symbol('observable');
  330. _Symbol.observable = result;
  331. }
  332. } else {
  333. result = '@@observable';
  334. }
  335. return result;
  336. }});
  337. unwrapExports(ponyfill);
  338. var lib = createCommonjsModule(function (module, exports) {
  339. Object.defineProperty(exports, "__esModule", {
  340. value: true
  341. });
  342. var _ponyfill2 = _interopRequireDefault(ponyfill);
  343. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  344. var root; /* global window */
  345. if (typeof self !== 'undefined') {
  346. root = self;
  347. } else if (typeof window !== 'undefined') {
  348. root = window;
  349. } else if (typeof global$1 !== 'undefined') {
  350. root = global$1;
  351. } else {
  352. root = module;
  353. }
  354. var result = (0, _ponyfill2['default'])(root);
  355. exports['default'] = result;
  356. });
  357. unwrapExports(lib);
  358. var symbolObservable = lib;
  359. var isObservable = (function (value) {
  360. return value && value[symbolObservable] && value === value[symbolObservable]();
  361. });
  362. var isArray = Array.isArray;
  363. function cloneStyle(style) {
  364. // Support empty values in case user ends up with them by accident.
  365. if (style == null) return style;
  366. // Support string value for SimpleRule.
  367. var typeOfStyle = typeof style === 'undefined' ? 'undefined' : _typeof$1(style);
  368. if (typeOfStyle === 'string' || typeOfStyle === 'number' || typeOfStyle === 'function') {
  369. return style;
  370. }
  371. // Support array for FontFaceRule.
  372. if (isArray(style)) return style.map(cloneStyle);
  373. // Support Observable styles. Observables are immutable, so we don't need to
  374. // copy them.
  375. if (isObservable(style)) return style;
  376. var newStyle = {};
  377. for (var name in style) {
  378. var value = style[name];
  379. if ((typeof value === 'undefined' ? 'undefined' : _typeof$1(value)) === 'object') {
  380. newStyle[name] = cloneStyle(value);
  381. continue;
  382. }
  383. newStyle[name] = value;
  384. }
  385. return newStyle;
  386. }
  387. /**
  388. * Create a rule instance.
  389. */
  390. function createRule() {
  391. var name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'unnamed';
  392. var decl = arguments[1];
  393. var options = arguments[2];
  394. var jss = options.jss;
  395. var declCopy = cloneStyle(decl);
  396. var rule = jss.plugins.onCreateRule(name, declCopy, options);
  397. if (rule) return rule;
  398. // It is an at-rule and it has no instance.
  399. if (name[0] === '@') {
  400. warning_1(false, '[JSS] Unknown at-rule %s', name);
  401. }
  402. return new StyleRule(name, declCopy, options);
  403. }
  404. var CSS = global$1.CSS;
  405. var env$1 = "development";
  406. var escapeRegex = /([[\].#*$><+~=|^:(),"'`])/g;
  407. var escape = (function (str) {
  408. // We don't need to escape it in production, because we are not using user's
  409. // input for selectors, we are generating a valid selector.
  410. if (env$1 === 'production') return str;
  411. if (!CSS || !CSS.escape) {
  412. return str.replace(escapeRegex, '\\$1');
  413. }
  414. return CSS.escape(str);
  415. });
  416. /**
  417. * Contains rules objects and allows adding/removing etc.
  418. * Is used for e.g. by `StyleSheet` or `ConditionalRule`.
  419. */
  420. var RuleList = function () {
  421. // Original styles object.
  422. function RuleList(options) {
  423. var _this = this;
  424. classCallCheck(this, RuleList);
  425. this.map = {};
  426. this.raw = {};
  427. this.index = [];
  428. this.update = function (name, data) {
  429. var _options = _this.options,
  430. plugins = _options.jss.plugins,
  431. sheet = _options.sheet;
  432. if (typeof name === 'string') {
  433. plugins.onUpdate(data, _this.get(name), sheet);
  434. } else {
  435. for (var index = 0; index < _this.index.length; index++) {
  436. plugins.onUpdate(name, _this.index[index], sheet);
  437. }
  438. }
  439. };
  440. this.options = options;
  441. this.classes = options.classes;
  442. }
  443. /**
  444. * Create and register rule.
  445. *
  446. * Will not render after Style Sheet was rendered the first time.
  447. */
  448. // Used to ensure correct rules order.
  449. // Rules registry for access by .get() method.
  450. // It contains the same rule registered by name and by selector.
  451. createClass(RuleList, [{
  452. key: 'add',
  453. value: function add(name, decl, options) {
  454. var _options2 = this.options,
  455. parent = _options2.parent,
  456. sheet = _options2.sheet,
  457. jss = _options2.jss,
  458. Renderer = _options2.Renderer,
  459. generateClassName = _options2.generateClassName;
  460. options = _extends({
  461. classes: this.classes,
  462. parent: parent,
  463. sheet: sheet,
  464. jss: jss,
  465. Renderer: Renderer,
  466. generateClassName: generateClassName
  467. }, options);
  468. if (!options.selector && this.classes[name]) {
  469. options.selector = '.' + escape(this.classes[name]);
  470. }
  471. this.raw[name] = decl;
  472. var rule = createRule(name, decl, options);
  473. var className = void 0;
  474. if (!options.selector && rule instanceof StyleRule) {
  475. className = generateClassName(rule, sheet);
  476. rule.selector = '.' + escape(className);
  477. }
  478. this.register(rule, className);
  479. var index = options.index === undefined ? this.index.length : options.index;
  480. this.index.splice(index, 0, rule);
  481. return rule;
  482. }
  483. /**
  484. * Get a rule.
  485. */
  486. }, {
  487. key: 'get',
  488. value: function get$$1(name) {
  489. return this.map[name];
  490. }
  491. /**
  492. * Delete a rule.
  493. */
  494. }, {
  495. key: 'remove',
  496. value: function remove(rule) {
  497. this.unregister(rule);
  498. this.index.splice(this.indexOf(rule), 1);
  499. }
  500. /**
  501. * Get index of a rule.
  502. */
  503. }, {
  504. key: 'indexOf',
  505. value: function indexOf(rule) {
  506. return this.index.indexOf(rule);
  507. }
  508. /**
  509. * Run `onProcessRule()` plugins on every rule.
  510. */
  511. }, {
  512. key: 'process',
  513. value: function process() {
  514. var plugins = this.options.jss.plugins;
  515. // We need to clone array because if we modify the index somewhere else during a loop
  516. // we end up with very hard-to-track-down side effects.
  517. this.index.slice(0).forEach(plugins.onProcessRule, plugins);
  518. }
  519. /**
  520. * Register a rule in `.map` and `.classes` maps.
  521. */
  522. }, {
  523. key: 'register',
  524. value: function register(rule, className) {
  525. this.map[rule.key] = rule;
  526. if (rule instanceof StyleRule) {
  527. this.map[rule.selector] = rule;
  528. if (className) this.classes[rule.key] = className;
  529. }
  530. }
  531. /**
  532. * Unregister a rule.
  533. */
  534. }, {
  535. key: 'unregister',
  536. value: function unregister(rule) {
  537. delete this.map[rule.key];
  538. if (rule instanceof StyleRule) {
  539. delete this.map[rule.selector];
  540. delete this.classes[rule.key];
  541. }
  542. }
  543. /**
  544. * Update the function values with a new data.
  545. */
  546. }, {
  547. key: 'link',
  548. /**
  549. * Link renderable rules with CSSRuleList.
  550. */
  551. value: function link(cssRules) {
  552. var map = this.options.sheet.renderer.getUnescapedKeysMap(this.index);
  553. for (var i = 0; i < cssRules.length; i++) {
  554. var cssRule = cssRules[i];
  555. var _key = this.options.sheet.renderer.getKey(cssRule);
  556. if (map[_key]) _key = map[_key];
  557. var rule = this.map[_key];
  558. if (rule) linkRule(rule, cssRule);
  559. }
  560. }
  561. /**
  562. * Convert rules to a CSS string.
  563. */
  564. }, {
  565. key: 'toString',
  566. value: function toString(options) {
  567. var str = '';
  568. var sheet = this.options.sheet;
  569. var link = sheet ? sheet.options.link : false;
  570. for (var index = 0; index < this.index.length; index++) {
  571. var rule = this.index[index];
  572. var css = rule.toString(options);
  573. // No need to render an empty rule.
  574. if (!css && !link) continue;
  575. if (str) str += '\n';
  576. str += css;
  577. }
  578. return str;
  579. }
  580. }]);
  581. return RuleList;
  582. }();
  583. /* eslint-disable-next-line no-use-before-define */
  584. var StyleSheet = function () {
  585. function StyleSheet(styles, options) {
  586. var _this = this;
  587. classCallCheck(this, StyleSheet);
  588. this.update = function (name, data) {
  589. if (typeof name === 'string') {
  590. _this.rules.update(name, data);
  591. } else {
  592. _this.rules.update(name);
  593. }
  594. return _this;
  595. };
  596. this.attached = false;
  597. this.deployed = false;
  598. this.linked = false;
  599. this.classes = {};
  600. this.options = _extends({}, options, {
  601. sheet: this,
  602. parent: this,
  603. classes: this.classes
  604. });
  605. this.renderer = new options.Renderer(this);
  606. this.rules = new RuleList(this.options);
  607. for (var _name in styles) {
  608. this.rules.add(_name, styles[_name]);
  609. }
  610. this.rules.process();
  611. }
  612. /**
  613. * Attach renderable to the render tree.
  614. */
  615. createClass(StyleSheet, [{
  616. key: 'attach',
  617. value: function attach() {
  618. if (this.attached) return this;
  619. if (!this.deployed) this.deploy();
  620. this.renderer.attach();
  621. if (!this.linked && this.options.link) this.link();
  622. this.attached = true;
  623. return this;
  624. }
  625. /**
  626. * Remove renderable from render tree.
  627. */
  628. }, {
  629. key: 'detach',
  630. value: function detach() {
  631. if (!this.attached) return this;
  632. this.renderer.detach();
  633. this.attached = false;
  634. return this;
  635. }
  636. /**
  637. * Add a rule to the current stylesheet.
  638. * Will insert a rule also after the stylesheet has been rendered first time.
  639. */
  640. }, {
  641. key: 'addRule',
  642. value: function addRule(name, decl, options) {
  643. var queue = this.queue;
  644. // Plugins can create rules.
  645. // In order to preserve the right order, we need to queue all `.addRule` calls,
  646. // which happen after the first `rules.add()` call.
  647. if (this.attached && !queue) this.queue = [];
  648. var rule = this.rules.add(name, decl, options);
  649. this.options.jss.plugins.onProcessRule(rule);
  650. if (this.attached) {
  651. if (!this.deployed) return rule;
  652. // Don't insert rule directly if there is no stringified version yet.
  653. // It will be inserted all together when .attach is called.
  654. if (queue) queue.push(rule);else {
  655. this.insertRule(rule);
  656. if (this.queue) {
  657. this.queue.forEach(this.insertRule, this);
  658. this.queue = undefined;
  659. }
  660. }
  661. return rule;
  662. }
  663. // We can't add rules to a detached style node.
  664. // We will redeploy the sheet once user will attach it.
  665. this.deployed = false;
  666. return rule;
  667. }
  668. /**
  669. * Insert rule into the StyleSheet
  670. */
  671. }, {
  672. key: 'insertRule',
  673. value: function insertRule(rule) {
  674. var renderable = this.renderer.insertRule(rule);
  675. if (renderable && this.options.link) linkRule(rule, renderable);
  676. }
  677. /**
  678. * Create and add rules.
  679. * Will render also after Style Sheet was rendered the first time.
  680. */
  681. }, {
  682. key: 'addRules',
  683. value: function addRules(styles, options) {
  684. var added = [];
  685. for (var _name2 in styles) {
  686. added.push(this.addRule(_name2, styles[_name2], options));
  687. }
  688. return added;
  689. }
  690. /**
  691. * Get a rule by name.
  692. */
  693. }, {
  694. key: 'getRule',
  695. value: function getRule(name) {
  696. return this.rules.get(name);
  697. }
  698. /**
  699. * Delete a rule by name.
  700. * Returns `true`: if rule has been deleted from the DOM.
  701. */
  702. }, {
  703. key: 'deleteRule',
  704. value: function deleteRule(name) {
  705. var rule = this.rules.get(name);
  706. if (!rule) return false;
  707. this.rules.remove(rule);
  708. if (this.attached && rule.renderable) {
  709. return this.renderer.deleteRule(rule.renderable);
  710. }
  711. return true;
  712. }
  713. /**
  714. * Get index of a rule.
  715. */
  716. }, {
  717. key: 'indexOf',
  718. value: function indexOf(rule) {
  719. return this.rules.indexOf(rule);
  720. }
  721. /**
  722. * Deploy pure CSS string to a renderable.
  723. */
  724. }, {
  725. key: 'deploy',
  726. value: function deploy() {
  727. this.renderer.deploy();
  728. this.deployed = true;
  729. return this;
  730. }
  731. /**
  732. * Link renderable CSS rules from sheet with their corresponding models.
  733. */
  734. }, {
  735. key: 'link',
  736. value: function link() {
  737. var cssRules = this.renderer.getRules();
  738. // Is undefined when VirtualRenderer is used.
  739. if (cssRules) this.rules.link(cssRules);
  740. this.linked = true;
  741. return this;
  742. }
  743. /**
  744. * Update the function values with a new data.
  745. */
  746. }, {
  747. key: 'toString',
  748. /**
  749. * Convert rules to a CSS string.
  750. */
  751. value: function toString(options) {
  752. return this.rules.toString(options);
  753. }
  754. }]);
  755. return StyleSheet;
  756. }();
  757. var PluginsRegistry = function () {
  758. function PluginsRegistry() {
  759. classCallCheck(this, PluginsRegistry);
  760. this.hooks = {
  761. onCreateRule: [],
  762. onProcessRule: [],
  763. onProcessStyle: [],
  764. onProcessSheet: [],
  765. onChangeValue: [],
  766. onUpdate: []
  767. /**
  768. * Call `onCreateRule` hooks and return an object if returned by a hook.
  769. */
  770. };
  771. }
  772. createClass(PluginsRegistry, [{
  773. key: 'onCreateRule',
  774. value: function onCreateRule(name, decl, options) {
  775. for (var i = 0; i < this.hooks.onCreateRule.length; i++) {
  776. var rule = this.hooks.onCreateRule[i](name, decl, options);
  777. if (rule) return rule;
  778. }
  779. return null;
  780. }
  781. /**
  782. * Call `onProcessRule` hooks.
  783. */
  784. }, {
  785. key: 'onProcessRule',
  786. value: function onProcessRule(rule) {
  787. if (rule.isProcessed) return;
  788. var sheet = rule.options.sheet;
  789. for (var i = 0; i < this.hooks.onProcessRule.length; i++) {
  790. this.hooks.onProcessRule[i](rule, sheet);
  791. }
  792. // $FlowFixMe
  793. if (rule.style) this.onProcessStyle(rule.style, rule, sheet);
  794. rule.isProcessed = true;
  795. }
  796. /**
  797. * Call `onProcessStyle` hooks.
  798. */
  799. }, {
  800. key: 'onProcessStyle',
  801. value: function onProcessStyle(style, rule, sheet) {
  802. var nextStyle = style;
  803. for (var i = 0; i < this.hooks.onProcessStyle.length; i++) {
  804. nextStyle = this.hooks.onProcessStyle[i](nextStyle, rule, sheet);
  805. // $FlowFixMe
  806. rule.style = nextStyle;
  807. }
  808. }
  809. /**
  810. * Call `onProcessSheet` hooks.
  811. */
  812. }, {
  813. key: 'onProcessSheet',
  814. value: function onProcessSheet(sheet) {
  815. for (var i = 0; i < this.hooks.onProcessSheet.length; i++) {
  816. this.hooks.onProcessSheet[i](sheet);
  817. }
  818. }
  819. /**
  820. * Call `onUpdate` hooks.
  821. */
  822. }, {
  823. key: 'onUpdate',
  824. value: function onUpdate(data, rule, sheet) {
  825. for (var i = 0; i < this.hooks.onUpdate.length; i++) {
  826. this.hooks.onUpdate[i](data, rule, sheet);
  827. }
  828. }
  829. /**
  830. * Call `onChangeValue` hooks.
  831. */
  832. }, {
  833. key: 'onChangeValue',
  834. value: function onChangeValue(value, prop, rule) {
  835. var processedValue = value;
  836. for (var i = 0; i < this.hooks.onChangeValue.length; i++) {
  837. processedValue = this.hooks.onChangeValue[i](processedValue, prop, rule);
  838. }
  839. return processedValue;
  840. }
  841. /**
  842. * Register a plugin.
  843. * If function is passed, it is a shortcut for `{onProcessRule}`.
  844. */
  845. }, {
  846. key: 'use',
  847. value: function use(plugin) {
  848. for (var name in plugin) {
  849. if (this.hooks[name]) this.hooks[name].push(plugin[name]);else warning_1(false, '[JSS] Unknown hook "%s".', name);
  850. }
  851. }
  852. }]);
  853. return PluginsRegistry;
  854. }();
  855. var SimpleRule = function () {
  856. function SimpleRule(key, value, options) {
  857. classCallCheck(this, SimpleRule);
  858. this.type = 'simple';
  859. this.isProcessed = false;
  860. this.key = key;
  861. this.value = value;
  862. this.options = options;
  863. }
  864. /**
  865. * Generates a CSS string.
  866. */
  867. // eslint-disable-next-line no-unused-vars
  868. createClass(SimpleRule, [{
  869. key: 'toString',
  870. value: function toString(options) {
  871. if (Array.isArray(this.value)) {
  872. var str = '';
  873. for (var index = 0; index < this.value.length; index++) {
  874. str += this.key + ' ' + this.value[index] + ';';
  875. if (this.value[index + 1]) str += '\n';
  876. }
  877. return str;
  878. }
  879. return this.key + ' ' + this.value + ';';
  880. }
  881. }]);
  882. return SimpleRule;
  883. }();
  884. /**
  885. * Rule for @keyframes
  886. */
  887. var KeyframesRule = function () {
  888. function KeyframesRule(key, frames, options) {
  889. classCallCheck(this, KeyframesRule);
  890. this.type = 'keyframes';
  891. this.isProcessed = false;
  892. this.key = key;
  893. this.options = options;
  894. this.rules = new RuleList(_extends({}, options, { parent: this }));
  895. for (var name in frames) {
  896. this.rules.add(name, frames[name], _extends({}, this.options, {
  897. parent: this,
  898. selector: name
  899. }));
  900. }
  901. this.rules.process();
  902. }
  903. /**
  904. * Generates a CSS string.
  905. */
  906. createClass(KeyframesRule, [{
  907. key: 'toString',
  908. value: function toString() {
  909. var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { indent: 1 };
  910. var inner = this.rules.toString(options);
  911. if (inner) inner += '\n';
  912. return this.key + ' {\n' + inner + '}';
  913. }
  914. }]);
  915. return KeyframesRule;
  916. }();
  917. /**
  918. * Conditional rule for @media, @supports
  919. */
  920. var ConditionalRule = function () {
  921. function ConditionalRule(key, styles, options) {
  922. classCallCheck(this, ConditionalRule);
  923. this.type = 'conditional';
  924. this.isProcessed = false;
  925. this.key = key;
  926. this.options = options;
  927. this.rules = new RuleList(_extends({}, options, { parent: this }));
  928. for (var name in styles) {
  929. this.rules.add(name, styles[name]);
  930. }
  931. this.rules.process();
  932. }
  933. /**
  934. * Get a rule.
  935. */
  936. createClass(ConditionalRule, [{
  937. key: 'getRule',
  938. value: function getRule(name) {
  939. return this.rules.get(name);
  940. }
  941. /**
  942. * Get index of a rule.
  943. */
  944. }, {
  945. key: 'indexOf',
  946. value: function indexOf(rule) {
  947. return this.rules.indexOf(rule);
  948. }
  949. /**
  950. * Create and register rule, run plugins.
  951. */
  952. }, {
  953. key: 'addRule',
  954. value: function addRule(name, style, options) {
  955. var rule = this.rules.add(name, style, options);
  956. this.options.jss.plugins.onProcessRule(rule);
  957. return rule;
  958. }
  959. /**
  960. * Generates a CSS string.
  961. */
  962. }, {
  963. key: 'toString',
  964. value: function toString() {
  965. var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { indent: 1 };
  966. var inner = this.rules.toString(options);
  967. return inner ? this.key + ' {\n' + inner + '\n}' : '';
  968. }
  969. }]);
  970. return ConditionalRule;
  971. }();
  972. var FontFaceRule = function () {
  973. function FontFaceRule(key, style, options) {
  974. classCallCheck(this, FontFaceRule);
  975. this.type = 'font-face';
  976. this.isProcessed = false;
  977. this.key = key;
  978. this.style = style;
  979. this.options = options;
  980. }
  981. /**
  982. * Generates a CSS string.
  983. */
  984. createClass(FontFaceRule, [{
  985. key: 'toString',
  986. value: function toString(options) {
  987. if (Array.isArray(this.style)) {
  988. var str = '';
  989. for (var index = 0; index < this.style.length; index++) {
  990. str += toCss(this.key, this.style[index]);
  991. if (this.style[index + 1]) str += '\n';
  992. }
  993. return str;
  994. }
  995. return toCss(this.key, this.style, options);
  996. }
  997. }]);
  998. return FontFaceRule;
  999. }();
  1000. var ViewportRule = function () {
  1001. function ViewportRule(key, style, options) {
  1002. classCallCheck(this, ViewportRule);
  1003. this.type = 'viewport';
  1004. this.isProcessed = false;
  1005. this.key = key;
  1006. this.style = style;
  1007. this.options = options;
  1008. }
  1009. /**
  1010. * Generates a CSS string.
  1011. */
  1012. createClass(ViewportRule, [{
  1013. key: 'toString',
  1014. value: function toString(options) {
  1015. return toCss(this.key, this.style, options);
  1016. }
  1017. }]);
  1018. return ViewportRule;
  1019. }();
  1020. var classes = {
  1021. '@charset': SimpleRule,
  1022. '@import': SimpleRule,
  1023. '@namespace': SimpleRule,
  1024. '@keyframes': KeyframesRule,
  1025. '@media': ConditionalRule,
  1026. '@supports': ConditionalRule,
  1027. '@font-face': FontFaceRule,
  1028. '@viewport': ViewportRule,
  1029. '@-ms-viewport': ViewportRule
  1030. /**
  1031. * Generate plugins which will register all rules.
  1032. */
  1033. };var plugins = Object.keys(classes).map(function (key) {
  1034. // https://jsperf.com/indexof-vs-substr-vs-regex-at-the-beginning-3
  1035. var re = new RegExp('^' + key);
  1036. var RuleClass = classes[key];
  1037. var onCreateRule = function onCreateRule(name, decl, options) {
  1038. return re.test(name) ? new RuleClass(name, decl, options) : null;
  1039. };
  1040. return { onCreateRule: onCreateRule };
  1041. });
  1042. var observablesPlugin = {
  1043. onCreateRule: function onCreateRule(name, decl, options) {
  1044. if (!isObservable(decl)) return null;
  1045. // Cast `decl` to `Observable`, since it passed the type guard.
  1046. var style$ = decl;
  1047. var rule = createRule(name, {}, options);
  1048. // TODO
  1049. // Call `stream.subscribe()` returns a subscription, which should be explicitly
  1050. // unsubscribed from when we know this sheet is no longer needed.
  1051. style$.subscribe(function (style) {
  1052. for (var prop in style) {
  1053. rule.prop(prop, style[prop]);
  1054. }
  1055. });
  1056. return rule;
  1057. },
  1058. onProcessRule: function onProcessRule(rule) {
  1059. if (!(rule instanceof StyleRule)) return;
  1060. var styleRule = rule;
  1061. var style = styleRule.style;
  1062. var _loop = function _loop(prop) {
  1063. var value = style[prop];
  1064. if (!isObservable(value)) return 'continue';
  1065. delete style[prop];
  1066. value.subscribe({
  1067. next: function next(nextValue) {
  1068. styleRule.prop(prop, nextValue);
  1069. }
  1070. });
  1071. };
  1072. for (var prop in style) {
  1073. var _ret = _loop(prop);
  1074. if (_ret === 'continue') continue;
  1075. }
  1076. }
  1077. };
  1078. // A symbol replacement.
  1079. var now = Date.now();
  1080. var fnValuesNs = 'fnValues' + now;
  1081. var fnStyleNs = 'fnStyle' + ++now;
  1082. var functionsPlugin = {
  1083. onCreateRule: function onCreateRule(name, decl, options) {
  1084. if (typeof decl !== 'function') return null;
  1085. var rule = createRule(name, {}, options);
  1086. rule[fnStyleNs] = decl;
  1087. return rule;
  1088. },
  1089. onProcessStyle: function onProcessStyle(style, rule) {
  1090. var fn = {};
  1091. for (var prop in style) {
  1092. var value = style[prop];
  1093. if (typeof value !== 'function') continue;
  1094. delete style[prop];
  1095. fn[prop] = value;
  1096. }
  1097. rule = rule;
  1098. rule[fnValuesNs] = fn;
  1099. return style;
  1100. },
  1101. onUpdate: function onUpdate(data, rule) {
  1102. // It is a rules container like for e.g. ConditionalRule.
  1103. if (rule.rules instanceof RuleList) {
  1104. rule.rules.update(data);
  1105. return;
  1106. }
  1107. if (!(rule instanceof StyleRule)) return;
  1108. rule = rule;
  1109. // If we have a fn values map, it is a rule with function values.
  1110. if (rule[fnValuesNs]) {
  1111. for (var prop in rule[fnValuesNs]) {
  1112. rule.prop(prop, rule[fnValuesNs][prop](data));
  1113. }
  1114. }
  1115. rule = rule;
  1116. var fnStyle = rule[fnStyleNs];
  1117. // If we have a style function, the entire rule is dynamic and style object
  1118. // will be returned from that function.
  1119. if (fnStyle) {
  1120. var style = fnStyle(data);
  1121. for (var _prop in style) {
  1122. rule.prop(_prop, style[_prop]);
  1123. }
  1124. }
  1125. }
  1126. };
  1127. /**
  1128. * Sheets registry to access them all at one place.
  1129. */
  1130. var SheetsRegistry = function () {
  1131. function SheetsRegistry() {
  1132. classCallCheck(this, SheetsRegistry);
  1133. this.registry = [];
  1134. }
  1135. createClass(SheetsRegistry, [{
  1136. key: 'add',
  1137. /**
  1138. * Register a Style Sheet.
  1139. */
  1140. value: function add(sheet) {
  1141. var registry = this.registry;
  1142. var index = sheet.options.index;
  1143. if (registry.indexOf(sheet) !== -1) return;
  1144. if (registry.length === 0 || index >= this.index) {
  1145. registry.push(sheet);
  1146. return;
  1147. }
  1148. // Find a position.
  1149. for (var i = 0; i < registry.length; i++) {
  1150. if (registry[i].options.index > index) {
  1151. registry.splice(i, 0, sheet);
  1152. return;
  1153. }
  1154. }
  1155. }
  1156. /**
  1157. * Reset the registry.
  1158. */
  1159. }, {
  1160. key: 'reset',
  1161. value: function reset() {
  1162. this.registry = [];
  1163. }
  1164. /**
  1165. * Remove a Style Sheet.
  1166. */
  1167. }, {
  1168. key: 'remove',
  1169. value: function remove(sheet) {
  1170. var index = this.registry.indexOf(sheet);
  1171. this.registry.splice(index, 1);
  1172. }
  1173. /**
  1174. * Convert all attached sheets to a CSS string.
  1175. */
  1176. }, {
  1177. key: 'toString',
  1178. value: function toString(options) {
  1179. return this.registry.filter(function (sheet) {
  1180. return sheet.attached;
  1181. }).map(function (sheet) {
  1182. return sheet.toString(options);
  1183. }).join('\n');
  1184. }
  1185. }, {
  1186. key: 'index',
  1187. /**
  1188. * Current highest index number.
  1189. */
  1190. get: function get$$1() {
  1191. return this.registry.length === 0 ? 0 : this.registry[this.registry.length - 1].options.index;
  1192. }
  1193. }]);
  1194. return SheetsRegistry;
  1195. }();
  1196. /**
  1197. * This is a global sheets registry. Only DomRenderer will add sheets to it.
  1198. * On the server one should use an own SheetsRegistry instance and add the
  1199. * sheets to it, because you need to make sure to create a new registry for
  1200. * each request in order to not leak sheets across requests.
  1201. */
  1202. var sheets = new SheetsRegistry();
  1203. var ns = '2f1acc6c3a606b082e5eef5e54414ffb';
  1204. if (global$1[ns] == null) global$1[ns] = 0;
  1205. // Bundle may contain multiple JSS versions at the same time. In order to identify
  1206. // the current version with just one short number and use it for classes generation
  1207. // we use a counter. Also it is more accurate, because user can manually reevaluate
  1208. // the module.
  1209. var moduleId = global$1[ns]++;
  1210. var maxRules = 1e10;
  1211. var env$2 = "development";
  1212. /**
  1213. * Returns a function which generates unique class names based on counters.
  1214. * When new generator function is created, rule counter is reseted.
  1215. * We need to reset the rule counter for SSR for each request.
  1216. */
  1217. var createGenerateClassNameDefault = (function () {
  1218. var ruleCounter = 0;
  1219. var defaultPrefix = env$2 === 'production' ? 'c' : '';
  1220. return function (rule, sheet) {
  1221. ruleCounter += 1;
  1222. if (ruleCounter > maxRules) {
  1223. warning_1(false, '[JSS] You might have a memory leak. Rule counter is at %s.', ruleCounter);
  1224. }
  1225. var prefix = defaultPrefix;
  1226. var jssId = '';
  1227. if (sheet) {
  1228. prefix = sheet.options.classNamePrefix || defaultPrefix;
  1229. if (sheet.options.jss.id != null) jssId += sheet.options.jss.id;
  1230. }
  1231. if (env$2 === 'production') {
  1232. return '' + prefix + moduleId + jssId + ruleCounter;
  1233. }
  1234. return prefix + rule.key + '-' + moduleId + (jssId && '-' + jssId) + '-' + ruleCounter;
  1235. };
  1236. });
  1237. /**
  1238. * Cache the value from the first time a function is called.
  1239. */
  1240. var memoize = function memoize(fn) {
  1241. var value = void 0;
  1242. return function () {
  1243. if (!value) value = fn();
  1244. return value;
  1245. };
  1246. };
  1247. /**
  1248. * Get a style property value.
  1249. */
  1250. function getPropertyValue(cssRule, prop) {
  1251. try {
  1252. return cssRule.style.getPropertyValue(prop);
  1253. } catch (err) {
  1254. // IE may throw if property is unknown.
  1255. return '';
  1256. }
  1257. }
  1258. /**
  1259. * Set a style property.
  1260. */
  1261. function setProperty(cssRule, prop, value) {
  1262. try {
  1263. var cssValue = value;
  1264. if (Array.isArray(value)) {
  1265. cssValue = toCssValue(value, true);
  1266. if (value[value.length - 1] === '!important') {
  1267. cssRule.style.setProperty(prop, cssValue, 'important');
  1268. return true;
  1269. }
  1270. }
  1271. cssRule.style.setProperty(prop, cssValue);
  1272. } catch (err) {
  1273. // IE may throw if property is unknown.
  1274. return false;
  1275. }
  1276. return true;
  1277. }
  1278. /**
  1279. * Remove a style property.
  1280. */
  1281. function removeProperty(cssRule, prop) {
  1282. try {
  1283. cssRule.style.removeProperty(prop);
  1284. } catch (err) {
  1285. warning_1(false, '[JSS] DOMException "%s" was thrown. Tried to remove property "%s".', err.message, prop);
  1286. }
  1287. }
  1288. var CSSRuleTypes = {
  1289. STYLE_RULE: 1,
  1290. KEYFRAMES_RULE: 7
  1291. /**
  1292. * Get the CSS Rule key.
  1293. */
  1294. };var getKey = function () {
  1295. var extractKey = function extractKey(cssText) {
  1296. var from = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
  1297. return cssText.substr(from, cssText.indexOf('{') - 1);
  1298. };
  1299. return function (cssRule) {
  1300. if (cssRule.type === CSSRuleTypes.STYLE_RULE) return cssRule.selectorText;
  1301. if (cssRule.type === CSSRuleTypes.KEYFRAMES_RULE) {
  1302. var name = cssRule.name;
  1303. if (name) return '@keyframes ' + name;
  1304. // There is no rule.name in the following browsers:
  1305. // - IE 9
  1306. // - Safari 7.1.8
  1307. // - Mobile Safari 9.0.0
  1308. var cssText = cssRule.cssText;
  1309. return '@' + extractKey(cssText, cssText.indexOf('keyframes'));
  1310. }
  1311. // Conditionals.
  1312. return extractKey(cssRule.cssText);
  1313. };
  1314. }();
  1315. /**
  1316. * Set the selector.
  1317. */
  1318. function setSelector(cssRule, selectorText) {
  1319. cssRule.selectorText = selectorText;
  1320. // Return false if setter was not successful.
  1321. // Currently works in chrome only.
  1322. return cssRule.selectorText === selectorText;
  1323. }
  1324. /**
  1325. * Gets the `head` element upon the first call and caches it.
  1326. */
  1327. var getHead = memoize(function () {
  1328. return document.head || document.getElementsByTagName('head')[0];
  1329. });
  1330. /**
  1331. * Gets a map of rule keys, where the property is an unescaped key and value
  1332. * is a potentially escaped one.
  1333. * It is used to identify CSS rules and the corresponding JSS rules. As an identifier
  1334. * for CSSStyleRule we normally use `selectorText`. Though if original selector text
  1335. * contains escaped code points e.g. `:not(#\\20)`, CSSOM will compile it to `:not(# )`
  1336. * and so CSS rule's `selectorText` won't match JSS rule selector.
  1337. *
  1338. * https://www.w3.org/International/questions/qa-escapes#cssescapes
  1339. */
  1340. var getUnescapedKeysMap = function () {
  1341. var style = void 0;
  1342. var isAttached = false;
  1343. return function (rules) {
  1344. var map = {};
  1345. // https://github.com/facebook/flow/issues/2696
  1346. if (!style) style = document.createElement('style');
  1347. for (var i = 0; i < rules.length; i++) {
  1348. var rule = rules[i];
  1349. if (!(rule instanceof StyleRule)) continue;
  1350. var selector = rule.selector;
  1351. // Only unescape selector over CSSOM if it contains a back slash.
  1352. if (selector && selector.indexOf('\\') !== -1) {
  1353. // Lazilly attach when needed.
  1354. if (!isAttached) {
  1355. getHead().appendChild(style);
  1356. isAttached = true;
  1357. }
  1358. style.textContent = selector + ' {}';
  1359. var _style = style,
  1360. sheet = _style.sheet;
  1361. if (sheet) {
  1362. var cssRules = sheet.cssRules;
  1363. if (cssRules) map[cssRules[0].selectorText] = rule.key;
  1364. }
  1365. }
  1366. }
  1367. if (isAttached) {
  1368. getHead().removeChild(style);
  1369. isAttached = false;
  1370. }
  1371. return map;
  1372. };
  1373. }();
  1374. /**
  1375. * Find attached sheet with an index higher than the passed one.
  1376. */
  1377. function findHigherSheet(registry, options) {
  1378. for (var i = 0; i < registry.length; i++) {
  1379. var sheet = registry[i];
  1380. if (sheet.attached && sheet.options.index > options.index && sheet.options.insertionPoint === options.insertionPoint) {
  1381. return sheet;
  1382. }
  1383. }
  1384. return null;
  1385. }
  1386. /**
  1387. * Find attached sheet with the highest index.
  1388. */
  1389. function findHighestSheet(registry, options) {
  1390. for (var i = registry.length - 1; i >= 0; i--) {
  1391. var sheet = registry[i];
  1392. if (sheet.attached && sheet.options.insertionPoint === options.insertionPoint) {
  1393. return sheet;
  1394. }
  1395. }
  1396. return null;
  1397. }
  1398. /**
  1399. * Find a comment with "jss" inside.
  1400. */
  1401. function findCommentNode(text) {
  1402. var head = getHead();
  1403. for (var i = 0; i < head.childNodes.length; i++) {
  1404. var node = head.childNodes[i];
  1405. if (node.nodeType === 8 && node.nodeValue.trim() === text) {
  1406. return node;
  1407. }
  1408. }
  1409. return null;
  1410. }
  1411. /**
  1412. * Find a node before which we can insert the sheet.
  1413. */
  1414. function findPrevNode(options) {
  1415. var registry = sheets.registry;
  1416. if (registry.length > 0) {
  1417. // Try to insert before the next higher sheet.
  1418. var sheet = findHigherSheet(registry, options);
  1419. if (sheet) return sheet.renderer.element;
  1420. // Otherwise insert after the last attached.
  1421. sheet = findHighestSheet(registry, options);
  1422. if (sheet) return sheet.renderer.element.nextElementSibling;
  1423. }
  1424. // Try to find a comment placeholder if registry is empty.
  1425. var insertionPoint = options.insertionPoint;
  1426. if (insertionPoint && typeof insertionPoint === 'string') {
  1427. var comment = findCommentNode(insertionPoint);
  1428. if (comment) return comment.nextSibling;
  1429. // If user specifies an insertion point and it can't be found in the document -
  1430. // bad specificity issues may appear.
  1431. warning_1(insertionPoint === 'jss', '[JSS] Insertion point "%s" not found.', insertionPoint);
  1432. }
  1433. return null;
  1434. }
  1435. /**
  1436. * Insert style element into the DOM.
  1437. */
  1438. function insertStyle(style, options) {
  1439. var insertionPoint = options.insertionPoint;
  1440. var prevNode = findPrevNode(options);
  1441. if (prevNode) {
  1442. var parentNode = prevNode.parentNode;
  1443. if (parentNode) parentNode.insertBefore(style, prevNode);
  1444. return;
  1445. }
  1446. // Works with iframes and any node types.
  1447. if (insertionPoint && typeof insertionPoint.nodeType === 'number') {
  1448. // https://stackoverflow.com/questions/41328728/force-casting-in-flow
  1449. var insertionPointElement = insertionPoint;
  1450. var _parentNode = insertionPointElement.parentNode;
  1451. if (_parentNode) _parentNode.insertBefore(style, insertionPointElement.nextSibling);else warning_1(false, '[JSS] Insertion point is not in the DOM.');
  1452. return;
  1453. }
  1454. getHead().insertBefore(style, prevNode);
  1455. }
  1456. /**
  1457. * Read jss nonce setting from the page if the user has set it.
  1458. */
  1459. var getNonce = memoize(function () {
  1460. var node = document.querySelector('meta[property="csp-nonce"]');
  1461. return node ? node.getAttribute('content') : null;
  1462. });
  1463. var DomRenderer = function () {
  1464. function DomRenderer(sheet) {
  1465. classCallCheck(this, DomRenderer);
  1466. this.getPropertyValue = getPropertyValue;
  1467. this.setProperty = setProperty;
  1468. this.removeProperty = removeProperty;
  1469. this.setSelector = setSelector;
  1470. this.getKey = getKey;
  1471. this.getUnescapedKeysMap = getUnescapedKeysMap;
  1472. this.hasInsertedRules = false;
  1473. // There is no sheet when the renderer is used from a standalone StyleRule.
  1474. if (sheet) sheets.add(sheet);
  1475. this.sheet = sheet;
  1476. var _ref = this.sheet ? this.sheet.options : {},
  1477. media = _ref.media,
  1478. meta = _ref.meta,
  1479. element = _ref.element;
  1480. this.element = element || document.createElement('style');
  1481. this.element.setAttribute('data-jss', '');
  1482. if (media) this.element.setAttribute('media', media);
  1483. if (meta) this.element.setAttribute('data-meta', meta);
  1484. var nonce = getNonce();
  1485. if (nonce) this.element.setAttribute('nonce', nonce);
  1486. }
  1487. /**
  1488. * Insert style element into render tree.
  1489. */
  1490. // HTMLStyleElement needs fixing https://github.com/facebook/flow/issues/2696
  1491. createClass(DomRenderer, [{
  1492. key: 'attach',
  1493. value: function attach() {
  1494. // In the case the element node is external and it is already in the DOM.
  1495. if (this.element.parentNode || !this.sheet) return;
  1496. // When rules are inserted using `insertRule` API, after `sheet.detach().attach()`
  1497. // browsers remove those rules.
  1498. // TODO figure out if its a bug and if it is known.
  1499. // Workaround is to redeploy the sheet before attaching as a string.
  1500. if (this.hasInsertedRules) {
  1501. this.deploy();
  1502. this.hasInsertedRules = false;
  1503. }
  1504. insertStyle(this.element, this.sheet.options);
  1505. }
  1506. /**
  1507. * Remove style element from render tree.
  1508. */
  1509. }, {
  1510. key: 'detach',
  1511. value: function detach() {
  1512. this.element.parentNode.removeChild(this.element);
  1513. }
  1514. /**
  1515. * Inject CSS string into element.
  1516. */
  1517. }, {
  1518. key: 'deploy',
  1519. value: function deploy() {
  1520. if (!this.sheet) return;
  1521. this.element.textContent = '\n' + this.sheet.toString() + '\n';
  1522. }
  1523. /**
  1524. * Insert a rule into element.
  1525. */
  1526. }, {
  1527. key: 'insertRule',
  1528. value: function insertRule(rule, index) {
  1529. var sheet = this.element.sheet;
  1530. var cssRules = sheet.cssRules;
  1531. var str = rule.toString();
  1532. if (!index) index = cssRules.length;
  1533. if (!str) return false;
  1534. try {
  1535. sheet.insertRule(str, index);
  1536. } catch (err) {
  1537. warning_1(false, '[JSS] Can not insert an unsupported rule \n\r%s', rule);
  1538. return false;
  1539. }
  1540. this.hasInsertedRules = true;
  1541. return cssRules[index];
  1542. }
  1543. /**
  1544. * Delete a rule.
  1545. */
  1546. }, {
  1547. key: 'deleteRule',
  1548. value: function deleteRule(cssRule) {
  1549. var sheet = this.element.sheet;
  1550. var index = this.indexOf(cssRule);
  1551. if (index === -1) return false;
  1552. sheet.deleteRule(index);
  1553. return true;
  1554. }
  1555. /**
  1556. * Get index of a CSS Rule.
  1557. */
  1558. }, {
  1559. key: 'indexOf',
  1560. value: function indexOf(cssRule) {
  1561. var cssRules = this.element.sheet.cssRules;
  1562. for (var _index = 0; _index < cssRules.length; _index++) {
  1563. if (cssRule === cssRules[_index]) return _index;
  1564. }
  1565. return -1;
  1566. }
  1567. /**
  1568. * Generate a new CSS rule and replace the existing one.
  1569. */
  1570. }, {
  1571. key: 'replaceRule',
  1572. value: function replaceRule(cssRule, rule) {
  1573. var index = this.indexOf(cssRule);
  1574. var newCssRule = this.insertRule(rule, index);
  1575. this.element.sheet.deleteRule(index);
  1576. return newCssRule;
  1577. }
  1578. /**
  1579. * Get all rules elements.
  1580. */
  1581. }, {
  1582. key: 'getRules',
  1583. value: function getRules() {
  1584. return this.element.sheet.cssRules;
  1585. }
  1586. }]);
  1587. return DomRenderer;
  1588. }();
  1589. /* eslint-disable class-methods-use-this */
  1590. /**
  1591. * Rendering backend to do nothing in nodejs.
  1592. */
  1593. var VirtualRenderer = function () {
  1594. function VirtualRenderer() {
  1595. classCallCheck(this, VirtualRenderer);
  1596. }
  1597. createClass(VirtualRenderer, [{
  1598. key: 'setProperty',
  1599. value: function setProperty() {
  1600. return true;
  1601. }
  1602. }, {
  1603. key: 'getPropertyValue',
  1604. value: function getPropertyValue() {
  1605. return '';
  1606. }
  1607. }, {
  1608. key: 'removeProperty',
  1609. value: function removeProperty() {}
  1610. }, {
  1611. key: 'setSelector',
  1612. value: function setSelector() {
  1613. return true;
  1614. }
  1615. }, {
  1616. key: 'getKey',
  1617. value: function getKey() {
  1618. return '';
  1619. }
  1620. }, {
  1621. key: 'attach',
  1622. value: function attach() {}
  1623. }, {
  1624. key: 'detach',
  1625. value: function detach() {}
  1626. }, {
  1627. key: 'deploy',
  1628. value: function deploy() {}
  1629. }, {
  1630. key: 'insertRule',
  1631. value: function insertRule() {
  1632. return false;
  1633. }
  1634. }, {
  1635. key: 'deleteRule',
  1636. value: function deleteRule() {
  1637. return true;
  1638. }
  1639. }, {
  1640. key: 'replaceRule',
  1641. value: function replaceRule() {
  1642. return false;
  1643. }
  1644. }, {
  1645. key: 'getRules',
  1646. value: function getRules() {}
  1647. }, {
  1648. key: 'indexOf',
  1649. value: function indexOf() {
  1650. return -1;
  1651. }
  1652. }]);
  1653. return VirtualRenderer;
  1654. }();
  1655. var defaultPlugins = plugins.concat([observablesPlugin, functionsPlugin]);
  1656. var instanceCounter = 0;
  1657. var Jss = function () {
  1658. function Jss(options) {
  1659. classCallCheck(this, Jss);
  1660. this.id = instanceCounter++;
  1661. this.version = "9.8.7";
  1662. this.plugins = new PluginsRegistry();
  1663. this.options = {
  1664. createGenerateClassName: createGenerateClassNameDefault,
  1665. Renderer: isBrowser ? DomRenderer : VirtualRenderer,
  1666. plugins: []
  1667. };
  1668. this.generateClassName = createGenerateClassNameDefault();
  1669. // eslint-disable-next-line prefer-spread
  1670. this.use.apply(this, defaultPlugins);
  1671. this.setup(options);
  1672. }
  1673. createClass(Jss, [{
  1674. key: 'setup',
  1675. value: function setup() {
  1676. var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  1677. if (options.createGenerateClassName) {
  1678. this.options.createGenerateClassName = options.createGenerateClassName;
  1679. // $FlowFixMe
  1680. this.generateClassName = options.createGenerateClassName();
  1681. }
  1682. if (options.insertionPoint != null) this.options.insertionPoint = options.insertionPoint;
  1683. if (options.virtual || options.Renderer) {
  1684. this.options.Renderer = options.Renderer || (options.virtual ? VirtualRenderer : DomRenderer);
  1685. }
  1686. // eslint-disable-next-line prefer-spread
  1687. if (options.plugins) this.use.apply(this, options.plugins);
  1688. return this;
  1689. }
  1690. /**
  1691. * Create a Style Sheet.
  1692. */
  1693. }, {
  1694. key: 'createStyleSheet',
  1695. value: function createStyleSheet(styles) {
  1696. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  1697. var index = options.index;
  1698. if (typeof index !== 'number') {
  1699. index = sheets.index === 0 ? 0 : sheets.index + 1;
  1700. }
  1701. var sheet = new StyleSheet(styles, _extends({}, options, {
  1702. jss: this,
  1703. generateClassName: options.generateClassName || this.generateClassName,
  1704. insertionPoint: this.options.insertionPoint,
  1705. Renderer: this.options.Renderer,
  1706. index: index
  1707. }));
  1708. this.plugins.onProcessSheet(sheet);
  1709. return sheet;
  1710. }
  1711. /**
  1712. * Detach the Style Sheet and remove it from the registry.
  1713. */
  1714. }, {
  1715. key: 'removeStyleSheet',
  1716. value: function removeStyleSheet(sheet) {
  1717. sheet.detach();
  1718. sheets.remove(sheet);
  1719. return this;
  1720. }
  1721. /**
  1722. * Create a rule without a Style Sheet.
  1723. */
  1724. }, {
  1725. key: 'createRule',
  1726. value: function createRule$$1(name) {
  1727. var style = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  1728. var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  1729. // Enable rule without name for inline styles.
  1730. if ((typeof name === 'undefined' ? 'undefined' : _typeof$1(name)) === 'object') {
  1731. options = style;
  1732. style = name;
  1733. name = undefined;
  1734. }
  1735. // Cast from RuleFactoryOptions to RuleOptions
  1736. // https://stackoverflow.com/questions/41328728/force-casting-in-flow
  1737. var ruleOptions = options;
  1738. ruleOptions.jss = this;
  1739. ruleOptions.Renderer = this.options.Renderer;
  1740. if (!ruleOptions.generateClassName) ruleOptions.generateClassName = this.generateClassName;
  1741. if (!ruleOptions.classes) ruleOptions.classes = {};
  1742. var rule = createRule(name, style, ruleOptions);
  1743. if (!ruleOptions.selector && rule instanceof StyleRule) {
  1744. rule.selector = '.' + ruleOptions.generateClassName(rule);
  1745. }
  1746. this.plugins.onProcessRule(rule);
  1747. return rule;
  1748. }
  1749. /**
  1750. * Register plugin. Passed function will be invoked with a rule instance.
  1751. */
  1752. }, {
  1753. key: 'use',
  1754. value: function use() {
  1755. var _this = this;
  1756. for (var _len = arguments.length, plugins$$1 = Array(_len), _key = 0; _key < _len; _key++) {
  1757. plugins$$1[_key] = arguments[_key];
  1758. }
  1759. plugins$$1.forEach(function (plugin) {
  1760. // Avoids applying same plugin twice, at least based on ref.
  1761. if (_this.options.plugins.indexOf(plugin) === -1) {
  1762. _this.options.plugins.push(plugin);
  1763. _this.plugins.use(plugin);
  1764. }
  1765. });
  1766. return this;
  1767. }
  1768. }]);
  1769. return Jss;
  1770. }();
  1771. /**
  1772. * Extracts a styles object with only props that contain function values.
  1773. */
  1774. function getDynamicStyles(styles) {
  1775. var to = null;
  1776. for (var key in styles) {
  1777. var value = styles[key];
  1778. var type = typeof value === 'undefined' ? 'undefined' : _typeof$1(value);
  1779. if (type === 'function') {
  1780. if (!to) to = {};
  1781. to[key] = value;
  1782. } else if (type === 'object' && value !== null && !Array.isArray(value)) {
  1783. var extracted = getDynamicStyles(value);
  1784. if (extracted) {
  1785. if (!to) to = {};
  1786. to[key] = extracted;
  1787. }
  1788. }
  1789. }
  1790. return to;
  1791. }
  1792. /**
  1793. * SheetsManager is like a WeakMap which is designed to count StyleSheet
  1794. * instances and attach/detach automatically.
  1795. */
  1796. var SheetsManager = function () {
  1797. function SheetsManager() {
  1798. classCallCheck(this, SheetsManager);
  1799. this.sheets = [];
  1800. this.refs = [];
  1801. this.keys = [];
  1802. }
  1803. createClass(SheetsManager, [{
  1804. key: 'get',
  1805. value: function get$$1(key) {
  1806. var index = this.keys.indexOf(key);
  1807. return this.sheets[index];
  1808. }
  1809. }, {
  1810. key: 'add',
  1811. value: function add(key, sheet) {
  1812. var sheets = this.sheets,
  1813. refs = this.refs,
  1814. keys = this.keys;
  1815. var index = sheets.indexOf(sheet);
  1816. if (index !== -1) return index;
  1817. sheets.push(sheet);
  1818. refs.push(0);
  1819. keys.push(key);
  1820. return sheets.length - 1;
  1821. }
  1822. }, {
  1823. key: 'manage',
  1824. value: function manage(key) {
  1825. var index = this.keys.indexOf(key);
  1826. var sheet = this.sheets[index];
  1827. if (this.refs[index] === 0) sheet.attach();
  1828. this.refs[index]++;
  1829. if (!this.keys[index]) this.keys.splice(index, 0, key);
  1830. return sheet;
  1831. }
  1832. }, {
  1833. key: 'unmanage',
  1834. value: function unmanage(key) {
  1835. var index = this.keys.indexOf(key);
  1836. if (index === -1) {
  1837. // eslint-ignore-next-line no-console
  1838. warning_1(false, "SheetsManager: can't find sheet to unmanage");
  1839. return;
  1840. }
  1841. if (this.refs[index] > 0) {
  1842. this.refs[index]--;
  1843. if (this.refs[index] === 0) this.sheets[index].detach();
  1844. }
  1845. }
  1846. }, {
  1847. key: 'size',
  1848. get: function get$$1() {
  1849. return this.keys.length;
  1850. }
  1851. }]);
  1852. return SheetsManager;
  1853. }();
  1854. /**
  1855. * Creates a new instance of Jss.
  1856. */
  1857. var create = function create(options) {
  1858. return new Jss(options);
  1859. };
  1860. /**
  1861. * A global Jss instance.
  1862. */
  1863. var index$1 = create();
  1864. exports.create = create;
  1865. exports.default = index$1;
  1866. exports.getDynamicStyles = getDynamicStyles;
  1867. exports.toCssValue = toCssValue;
  1868. exports.SheetsRegistry = SheetsRegistry;
  1869. exports.SheetsManager = SheetsManager;
  1870. exports.RuleList = RuleList;
  1871. exports.sheets = sheets;
  1872. exports.createGenerateClassName = createGenerateClassNameDefault;
  1873. Object.defineProperty(exports, '__esModule', { value: true });
  1874. })));
  1875. //# sourceMappingURL=jss.js.map