UNPKG

pretty-lights

Version:
237 lines (181 loc) 7.58 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.isReactElement = isReactElement; exports.isDOMElement = isDOMElement; exports.getClassNamesFromNodes = getClassNamesFromNodes; exports.getStylesFromClassNames = getStylesFromClassNames; exports.getStyleElements = getStyleElements; exports.getKeys = getKeys; exports.hasClassNames = hasClassNames; exports.getMediaRules = getMediaRules; exports.RULE_TYPES = void 0; function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); } function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } function flatMap(arr, iteratee) { var _ref; return (_ref = []).concat.apply(_ref, _toConsumableArray(arr.map(iteratee))); } var RULE_TYPES = { media: 'media', rule: 'rule' }; exports.RULE_TYPES = RULE_TYPES; function getClassNames(selectors, classes) { return classes ? selectors.concat(classes.split(' ')) : selectors; } function getClassNamesFromTestRenderer(selectors, _ref2) { var _ref2$props = _ref2.props, props = _ref2$props === void 0 ? {} : _ref2$props; return getClassNames(selectors, props.className || props["class"]); } function shouldDive(node) { return typeof node.dive === 'function' && typeof node.type() !== 'string'; } function isTagWithClassName(node) { return node.prop('className') && typeof node.type() === 'string'; } function getClassNamesFromEnzyme(selectors, node) { // We need to dive if we have selected a styled child from a shallow render var actualComponent = shouldDive(node) ? node.dive() : node; // Find the first node with a className prop var components = actualComponent.findWhere(isTagWithClassName); var classes = components.length && components.first().prop('className'); return getClassNames(selectors, classes); } function getClassNamesFromCheerio(selectors, node) { var classes = node.attr('class'); return getClassNames(selectors, classes); } function getClassNamesFromDOMElement(selectors, node) { return getClassNames(selectors, node.getAttribute('class')); } function isReactElement(val) { return val.$$typeof === Symbol["for"]('react.test.json'); } // $FORK$ remove css prop checks var domElementPattern = /^((HTML|SVG)\w*)?Element$/; function isDOMElement(val) { return val.nodeType === 1 && val.constructor && val.constructor.name && domElementPattern.test(val.constructor.name); } function isEnzymeElement(val) { return typeof val.findWhere === 'function'; } function isCheerioElement(val) { return val.cheerio === '[cheerio object]'; } function getClassNamesFromNodes(nodes) { return nodes.reduce(function (selectors, node) { if (isReactElement(node)) { return getClassNamesFromTestRenderer(selectors, node); } if (isEnzymeElement(node)) { return getClassNamesFromEnzyme(selectors, node); } if (isCheerioElement(node)) { return getClassNamesFromCheerio(selectors, node); } return getClassNamesFromDOMElement(selectors, node); }, []); } var keyframesPattern = /^@keyframes\s+(animation-[^{\s]+)+/; var removeCommentPattern = /\/\*[\s\S]*?\*\//g; var getElementRules = function getElementRules(element) { var nonSpeedyRule = element.textContent; if (nonSpeedyRule) { return [nonSpeedyRule]; } if (!element.sheet) { return []; } // $FlowFixMe - flow doesn't know about `cssRules` property return [].slice.call(element.sheet.cssRules).map(function (cssRule) { return cssRule.cssText; }); }; function getStylesFromClassNames(classNames, elements) { if (!classNames.length) { return ''; } // eslint-disable-next-line no-use-before-define var keys = getKeys(elements); if (!keys.length) { return ''; } var keyPatten = new RegExp("^(".concat(keys.join('|'), ")-")); var filteredClassNames = classNames.filter(function (className) { return keyPatten.test(className); }); if (!filteredClassNames.length) { return ''; } var selectorPattern = new RegExp("\\.(".concat(filteredClassNames.join('|'), ")")); var keyframes = {}; var styles = ''; flatMap(elements, getElementRules).forEach(function (rule) { if (selectorPattern.test(rule)) { styles += rule; } var match = rule.match(keyframesPattern); if (match !== null) { var name = match[1]; if (keyframes[name] === undefined) { keyframes[name] = ''; } keyframes[name] += rule; } }); var keyframeNameKeys = Object.keys(keyframes); var keyframesStyles = ''; if (keyframeNameKeys.length) { var keyframesNamePattern = new RegExp(keyframeNameKeys.join('|'), 'g'); var keyframesNameCache = {}; var index = 0; styles = styles.replace(keyframesNamePattern, function (name) { if (keyframesNameCache[name] === undefined) { keyframesNameCache[name] = "animation-".concat(index); index += 1; keyframesStyles += keyframes[name]; } return keyframesNameCache[name]; }); keyframesStyles = keyframesStyles.replace(keyframesNamePattern, function (value) { return keyframesNameCache[value]; }); } return (keyframesStyles + styles).replace(removeCommentPattern, ''); } function getStyleElements() { var elements = Array.from(document.querySelectorAll('style[data-lights]')); // $FlowFixMe return elements; } var unique = function unique(arr) { return Array.from(new Set(arr)); }; function getKeys(elements) { var keys = unique(elements.map(function (element) { return element.getAttribute('data-lights'); })).filter(Boolean); return keys; } function hasClassNames(classNames, selectors, target) { // selectors is the classNames of specific css rule return selectors.some(function (selector) { // if no target, use className of the specific css rule and try to find it // in the list of received node classNames to make sure this css rule // applied for root element if (!target) { return classNames.includes(selector.slice(1)); } // check if selector (className) of specific css rule match target return target instanceof RegExp ? target.test(selector) : selector.includes(target); }); } function getMediaRules(rules, media) { return rules.filter(function (rule) { var isMediaMatch = rule.media ? rule.media.replace(/\s/g, '').includes(media.replace(/\s/g, '')) : false; return rule.type === RULE_TYPES.media && isMediaMatch; }).reduce(function (mediaRules, mediaRule) { return mediaRules.concat(mediaRule.rules); }, []); }