'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; exports.default = jssNested; var _warning = require('warning'); var _warning2 = _interopRequireDefault(_warning); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 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) { return function (match, key) { var rule = container.getRule(key); if (rule) return rule.selector; (0, _warning2.default)(false, '[JSS] Could not find the referenced rule %s in %s.', key, container.options.meta || container); return key; }; } var hasAnd = function hasAnd(str) { return str.indexOf('&') !== -1; }; 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 += hasAnd(nested) ? nested.replace(parentRegExp, parent) : parent + ' ' + nested; } } return result; } function getOptions(rule, container, options) { // Options has been already created, now we only increase index. if (options) return _extends({}, options, { index: options.index + 1 }); var nestingLevel = rule.options.nestingLevel; nestingLevel = nestingLevel === undefined ? 1 : nestingLevel + 1; return _extends({}, rule.options, { nestingLevel: nestingLevel, index: container.indexOf(rule) + 1 }); } function onProcessStyle(style, rule) { if (rule.type !== 'style') return style; var container = rule.options.parent; var options = void 0; var replaceRef = void 0; for (var prop in style) { var isNested = hasAnd(prop); var isNestedConditional = prop[0] === '@'; if (!isNested && !isNestedConditional) continue; options = getOptions(rule, container, options); if (isNested) { var selector = replaceParentRefs(prop, rule.selector // Lazily create the ref replacer function just once for // all nested rules within the sheet. );if (!replaceRef) replaceRef = getReplaceRef(container // Replace all $refs. );selector = selector.replace(refRegExp, replaceRef); container.addRule(selector, style[prop], _extends({}, options, { selector: selector })); } else if (isNestedConditional) { container // Place conditional right after the parent rule to ensure right ordering. .addRule(prop, null, options).addRule(rule.key, style[prop], { selector: rule.selector }); } delete style[prop]; } return style; } return { onProcessStyle: onProcessStyle }; }