cache.cjs.js 3.83 KB
'use strict';

function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }

var sheet = require('@emotion/sheet');
var utils = require('@emotion/utils');
var Stylis = _interopDefault(require('@emotion/stylis'));

// https://github.com/thysultan/stylis.js/tree/master/plugins/rule-sheet
// inlined to avoid umd wrapper and peerDep warnings/installing stylis
// since we use stylis after closure compiler
var delimiter = '/*|*/';
var needle = delimiter + '}';

function toSheet(block) {
  if (block) {
    current.push(block + '}');
  }
}

var ruleSheet = function ruleSheet(context, content, selectors, parents, line, column, length, at, depth) {
  switch (context) {
    case -1:
      {
        current = [];
        break;
      }

    case 2:
      if (at === 0) return content + delimiter;
      break;
    // at-rule

    case 3:
      switch (at) {
        // @font-face, @page
        case 102:
        case 112:
          {
            current.push(selectors[0] + content);
            return '';
          }

        default:
          {
            return content + delimiter;
          }
      }

    case -2:
      {
        content.split(needle).forEach(toSheet);
        return current;
      }
  }
};

var current;

var createCache = function createCache(options) {
  if (options === undefined) options = {};
  var key = options.key || 'css';
  var stylisOptions;

  if (options.prefix !== undefined) {
    stylisOptions = {
      prefix: options.prefix
    };
  }

  var stylis = new Stylis(stylisOptions);
  stylis.use(options.stylisPlugins)(ruleSheet);

  if (process.env.NODE_ENV !== 'production') {
    // $FlowFixMe
    if (/[^a-z-]/.test(key)) {
      throw new Error("Emotion key must only contain lower case alphabetical characters and - but \"" + key + "\" was passed");
    }

    var sourceMapRegEx = /\/\*#\ssourceMappingURL=data:application\/json;\S+\s+\*\//;
    var currentSourceMap;
    stylis.use(function (context, content, selectors) {
      switch (context) {
        case -1:
          {
            var result = sourceMapRegEx.exec(content);

            if (result) {
              currentSourceMap = result[0];
            }

            break;
          }

        case 2:
          {
            for (var i = 0, len = selectors.length; len > i; i++) {
              // :last-child isn't included here since it's safe
              // because a style element will never be the last element
              var match = selectors[i].match(/:(first|nth|nth-last)-child/);

              if (match !== null) {
                console.error("The pseudo class \"" + match[1] + "\" is potentially unsafe when doing server-side rendering. Try changing it to \"" + match[1] + "-of-type\"");
              }
            }

            break;
          }

        case -2:
          {
            if (currentSourceMap) {
              content.forEach(function (rule, i) {
                content[i] = rule + currentSourceMap;
              });
              currentSourceMap = '';
            }
          }
      }
    });
  }

  var inserted = {}; // $FlowFixMe

  var container;

  if (utils.isBrowser) {
    container = options.container || document.head;
    var nodes = document.querySelectorAll("style[data-emotion-" + key + "]");
    Array.prototype.forEach.call(nodes, function (node) {
      var attrib = node.getAttribute("data-emotion-" + key); // $FlowFixMe

      attrib.split(' ').forEach(function (id) {
        inserted[id] = true;
      });

      if (node.parentNode !== container) {
        container.appendChild(node);
      }
    });
  }

  var context = {
    stylis: stylis,
    key: key,
    sheet: new sheet.StyleSheet({
      key: key,
      container: container,
      nonce: options.nonce
    }),
    inserted: inserted,
    registered: {},
    theme: {}
  };
  return context;
};

module.exports = createCache;