Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
Size: Mime:
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _react = require("react");

var _constants = require("../constants");

var _StyleTags = require("./StyleTags");

var _extractCompsFromCSS = _interopRequireDefault(require("../utils/extractCompsFromCSS"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

/* determine the maximum number of components before tags are sharded */
let MAX_SIZE;

if (_constants.IS_BROWSER) {
  /* in speedy mode we can keep a lot more rules in a sheet before a slowdown can be expected */
  MAX_SIZE = _constants.DISABLE_SPEEDY ? 40 : 1000;
} else {
  /* for servers we do not need to shard at all */
  MAX_SIZE = -1;
}

const toHTML = tag => tag.toHTML();

let sheetRunningId = 0;
let master;
let StyleSheet = class StyleSheet {
  /* a map from ids to tags */

  /* deferred rules for a given id */

  /* this is used for not reinjecting rules via hasNameForId() */

  /* when rules for an id are removed using remove() we have to ignore rehydratedNames for it */

  /* a list of tags belonging to this StyleSheet */

  /* current capacity until a new tag must be created */

  /* children (aka clones) of this StyleSheet inheriting all and future injections */
  constructor(target, forceServer = false) {
    this.id = void 0;
    this.sealed = void 0;
    this.forceServer = void 0;
    this.target = void 0;
    this.tagMap = void 0;
    this.deferred = void 0;
    this.rehydratedNames = void 0;
    this.ignoreRehydratedNames = void 0;
    this.tags = void 0;
    this.capacity = void 0;
    this.clones = void 0;
    this.id = sheetRunningId += 1;
    this.sealed = false;
    this.forceServer = forceServer;
    this.target = forceServer ? null : _constants.IS_BROWSER ? document.head : null;
    this.tagMap = {};
    this.deferred = {};
    this.rehydratedNames = {};
    this.ignoreRehydratedNames = {};
    this.tags = [];
    this.capacity = 1;
    this.clones = [];
  }
  /* rehydrate all SSR'd style tags */


  rehydrate() {
    if (!_constants.IS_BROWSER || this.forceServer) {
      return this;
    }

    const els = [];
    const names = [];
    let extracted = [];
    let isStreamed = false;
    /* retrieve all of our SSR style elements from the DOM */

    const nodes = document.querySelectorAll(`style[${_constants.SC_ATTR}]`);
    const nodesSize = nodes.length;
    /* abort rehydration if no previous style tags were found */

    if (nodesSize === 0) {
      return this;
    }

    for (let i = 0; i < nodesSize; i += 1) {
      // $FlowFixMe: We can trust that all elements in this query are style elements
      // HTMLStyleElement
      const el = nodes[i];
      /* check if style tag is a streamed tag */

      isStreamed = !!el.getAttribute(_constants.SC_STREAM_ATTR) || isStreamed;
      /* retrieve all component names */

      const elNames = (el.getAttribute(_constants.SC_ATTR) || '').trim().split(/\s+/);
      const elNamesSize = elNames.length;

      for (let j = 0; j < elNamesSize; j += 1) {
        const name = elNames[j];
        /* add rehydrated name to sheet to avoid readding styles */

        this.rehydratedNames[name] = true;
        names.push(name);
      }
      /* extract all components and their CSS */


      extracted = extracted.concat((0, _extractCompsFromCSS.default)(el.textContent));
      /* store original HTMLStyleElement */

      els.push(el);
    }
    /* abort rehydration if nothing was extracted */


    const extractedSize = extracted.length;

    if (extractedSize === 0) {
      return this;
    }
    /* create a tag to be used for rehydration */


    const tag = (0, _StyleTags.makeTag)(this.target, null, this.forceServer);
    const rehydrationTag = (0, _StyleTags.makeRehydrationTag)(tag, els, extracted, names, isStreamed);
    /* reset capacity and adjust MAX_SIZE by the initial size of the rehydration */

    this.capacity = Math.max(1, MAX_SIZE - extractedSize);
    this.tags.push(rehydrationTag);
    /* retrieve all component ids */

    for (let j = 0; j < extractedSize; j += 1) {
      this.tagMap[extracted[j].componentId] = rehydrationTag;
    }

    return this;
  }
  /* retrieve a "master" instance of StyleSheet which is typically used when no other is available
   * The master StyleSheet is targeted by injectGlobal, keyframes, and components outside of any
    * StyleSheetManager's context */


  static get master() {
    return master || (master = new StyleSheet().rehydrate());
  }
  /* NOTE: This is just for backwards-compatibility with jest-styled-components */


  static get instance() {
    return StyleSheet.master;
  }
  /* reset the internal "master" instance */


  static reset(forceServer = false) {
    master = new StyleSheet(undefined, forceServer).rehydrate();
  }
  /* adds "children" to the StyleSheet that inherit all of the parents' rules
   * while their own rules do not affect the parent */


  clone() {
    const sheet = new StyleSheet(this.target, this.forceServer);
    /* add to clone array */

    this.clones.push(sheet);
    /* clone all tags */

    sheet.tags = this.tags.map(tag => {
      const ids = tag.getIds();
      const newTag = tag.clone();
      /* reconstruct tagMap */

      for (let i = 0; i < ids.length; i += 1) {
        sheet.tagMap[ids[i]] = newTag;
      }

      return newTag;
    });
    /* clone other maps */

    sheet.rehydratedNames = _objectSpread({}, this.rehydratedNames);
    sheet.deferred = _objectSpread({}, this.deferred);
    return sheet;
  }
  /* force StyleSheet to create a new tag on the next injection */


  sealAllTags() {
    this.capacity = 1;
    this.sealed = true;
  }
  /* get a tag for a given componentId, assign the componentId to one, or shard */


  getTagForId(id) {
    /* simply return a tag, when the componentId was already assigned one */
    const prev = this.tagMap[id];

    if (prev !== undefined && !this.sealed) {
      return prev;
    }

    let tag = this.tags[this.tags.length - 1];
    /* shard (create a new tag) if the tag is exhausted (See MAX_SIZE) */

    this.capacity -= 1;

    if (this.capacity === 0) {
      this.capacity = MAX_SIZE;
      this.sealed = false;
      tag = (0, _StyleTags.makeTag)(this.target, tag ? tag.styleTag : null, this.forceServer);
      this.tags.push(tag);
    }

    return this.tagMap[id] = tag;
  }
  /* mainly for injectGlobal to check for its id */


  hasId(id) {
    return this.tagMap[id] !== undefined;
  }
  /* caching layer checking id+name to already have a corresponding tag and injected rules */


  hasNameForId(id, name) {
    /* exception for rehydrated names which are checked separately */
    if (this.ignoreRehydratedNames[id] === undefined && this.rehydratedNames[name]) {
      return true;
    }

    const tag = this.tagMap[id];
    return tag !== undefined && tag.hasNameForId(id, name);
  }
  /* registers a componentId and registers it on its tag */


  deferredInject(id, cssRules) {
    /* don't inject when the id is already registered */
    if (this.tagMap[id] !== undefined) {
      return;
    }

    const clones = this.clones;

    for (let i = 0; i < clones.length; i += 1) {
      clones[i].deferredInject(id, cssRules);
    }

    this.getTagForId(id).insertMarker(id);
    this.deferred[id] = cssRules;
  }
  /* injects rules for a given id with a name that will need to be cached */


  inject(id, cssRules, name) {
    const clones = this.clones;

    for (let i = 0; i < clones.length; i += 1) {
      clones[i].inject(id, cssRules, name);
    }
    /* add deferred rules for component */


    let injectRules = cssRules;
    const deferredRules = this.deferred[id];

    if (deferredRules !== undefined) {
      injectRules = deferredRules.concat(injectRules);
      delete this.deferred[id];
    }

    const tag = this.getTagForId(id);
    tag.insertRules(id, injectRules, name);
  }
  /* removes all rules for a given id, which doesn't remove its marker but resets it */


  remove(id) {
    const tag = this.tagMap[id];

    if (tag === undefined) {
      return;
    }

    const clones = this.clones;

    for (let i = 0; i < clones.length; i += 1) {
      clones[i].remove(id);
    }
    /* remove all rules from the tag */


    tag.removeRules(id);
    /* ignore possible rehydrated names */

    this.ignoreRehydratedNames[id] = true;
    /* delete possible deferred rules */

    delete this.deferred[id];
  }

  toHTML() {
    return this.tags.map(tag => tag.toHTML()).join(''); // @todo
    // return this.tags.map(toHTML).join('')
  }

  toReactElements() {
    const id = this.id;
    return this.tags.map((tag, i) => {
      const key = `sc-${id}-${i}`;
      return (0, _react.cloneElement)(tag.toElement(), {
        key
      });
    });
  }

};
var _default = StyleSheet;
exports.default = _default;