'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var _extends = require('@babel/runtime/helpers/extends'); var warning = require('tiny-warning'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } var _extends__default = /*#__PURE__*/_interopDefaultLegacy(_extends); var warning__default = /*#__PURE__*/_interopDefaultLegacy(warning); var separatorRegExp = /\s*,\s*/g; var parentRegExp = /&/g; var refRegExp = /\$([\w-]+)/g; /** * Convert nested rules to separate, remove them from original styles. * * @param {Rule} rule * @api public */ function jssNested() { // Get a function to be used for $ref replacement. function getReplaceRef(container, sheet) { return function (match, key) { var rule = container.getRule(key) || sheet && sheet.getRule(key); if (rule) { rule = rule; return rule.selector; } process.env.NODE_ENV !== "production" ? warning__default['default'](false, "[JSS] Could not find the referenced rule \"" + key + "\" in \"" + (container.options.meta || container.toString()) + "\".") : void 0; return key; }; } function replaceParentRefs(nestedProp, parentProp) { var parentSelectors = parentProp.split(separatorRegExp); var nestedSelectors = nestedProp.split(separatorRegExp); var result = ''; for (var i = 0; i < parentSelectors.length; i++) { var parent = parentSelectors[i]; for (var j = 0; j < nestedSelectors.length; j++) { var nested = nestedSelectors[j]; if (result) result += ', '; // Replace all & by the parent or prefix & with the parent. result += nested.indexOf('&') !== -1 ? nested.replace(parentRegExp, parent) : parent + " " + nested; } } return result; } function getOptions(rule, container, prevOptions) { // Options has been already created, now we only increase index. if (prevOptions) return _extends__default['default']({}, prevOptions, { index: prevOptions.index + 1 // $FlowFixMe[prop-missing] }); var nestingLevel = rule.options.nestingLevel; nestingLevel = nestingLevel === undefined ? 1 : nestingLevel + 1; var options = _extends__default['default']({}, rule.options, { nestingLevel: nestingLevel, index: container.indexOf(rule) + 1 // We don't need the parent name to be set options for chlid. }); delete options.name; return options; } function onProcessStyle(style, rule, sheet) { if (rule.type !== 'style') return style; var styleRule = rule; var container = styleRule.options.parent; var options; var replaceRef; for (var prop in style) { var isNested = prop.indexOf('&') !== -1; var isNestedConditional = prop[0] === '@'; if (!isNested && !isNestedConditional) continue; options = getOptions(styleRule, container, options); if (isNested) { var selector = replaceParentRefs(prop, styleRule.selector); // Lazily create the ref replacer function just once for // all nested rules within the sheet. if (!replaceRef) replaceRef = getReplaceRef(container, sheet); // Replace all $refs. selector = selector.replace(refRegExp, replaceRef); container.addRule(selector, style[prop], _extends__default['default']({}, options, { selector: selector })); } else if (isNestedConditional) { // Place conditional right after the parent rule to ensure right ordering. container.addRule(prop, {}, options) // Flow expects more options but they aren't required // And flow doesn't know this will always be a StyleRule which has the addRule method // $FlowFixMe[incompatible-use] // $FlowFixMe[prop-missing] .addRule(styleRule.key, style[prop], { selector: styleRule.selector }); } delete style[prop]; } return style; } return { onProcessStyle: onProcessStyle }; } exports.default = jssNested;