|
|
- 'use strict';
-
- Object.defineProperty(exports, '__esModule', {
- value: true
- });
-
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
-
- var _postcss = require('postcss');
-
- var _postcss2 = _interopRequireDefault(_postcss);
-
- var _cssSelectorTokenizer = require('css-selector-tokenizer');
-
- var _cssSelectorTokenizer2 = _interopRequireDefault(_cssSelectorTokenizer);
-
- var hasOwnProperty = Object.prototype.hasOwnProperty;
-
- function getSingleLocalNamesForComposes(selectors) {
- return selectors.nodes.map(function (node) {
- if (node.type !== 'selector' || node.nodes.length !== 1) {
- throw new Error('composition is only allowed when selector is single :local class name not in "' + _cssSelectorTokenizer2['default'].stringify(selectors) + '"');
- }
- node = node.nodes[0];
- if (node.type !== 'nested-pseudo-class' || node.name !== 'local' || node.nodes.length !== 1) {
- throw new Error('composition is only allowed when selector is single :local class name not in "' + _cssSelectorTokenizer2['default'].stringify(selectors) + '", "' + _cssSelectorTokenizer2['default'].stringify(node) + '" is weird');
- }
- node = node.nodes[0];
- if (node.type !== 'selector' || node.nodes.length !== 1) {
- throw new Error('composition is only allowed when selector is single :local class name not in "' + _cssSelectorTokenizer2['default'].stringify(selectors) + '", "' + _cssSelectorTokenizer2['default'].stringify(node) + '" is weird');
- }
- node = node.nodes[0];
- if (node.type !== 'class') {
- // 'id' is not possible, because you can't compose ids
- throw new Error('composition is only allowed when selector is single :local class name not in "' + _cssSelectorTokenizer2['default'].stringify(selectors) + '", "' + _cssSelectorTokenizer2['default'].stringify(node) + '" is weird');
- }
- return node.name;
- });
- }
-
- var processor = _postcss2['default'].plugin('postcss-modules-scope', function (options) {
- return function (css) {
- var generateScopedName = options && options.generateScopedName || processor.generateScopedName;
-
- var exports = {};
-
- function exportScopedName(name) {
- var scopedName = generateScopedName(name, css.source.input.from, css.source.input.css);
- exports[name] = exports[name] || [];
- if (exports[name].indexOf(scopedName) < 0) {
- exports[name].push(scopedName);
- }
- return scopedName;
- }
-
- function localizeNode(node) {
- var newNode = Object.create(node);
- switch (node.type) {
- case 'selector':
- newNode.nodes = node.nodes.map(localizeNode);
- return newNode;
- case 'class':
- case 'id':
- var scopedName = exportScopedName(node.name);
- newNode.name = scopedName;
- return newNode;
- }
- throw new Error(node.type + ' ("' + _cssSelectorTokenizer2['default'].stringify(node) + '") is not allowed in a :local block');
- }
-
- function traverseNode(node) {
- switch (node.type) {
- case 'nested-pseudo-class':
- if (node.name === 'local') {
- if (node.nodes.length !== 1) {
- throw new Error('Unexpected comma (",") in :local block');
- }
- return localizeNode(node.nodes[0]);
- }
- /* falls through */
- case 'selectors':
- case 'selector':
- var newNode = Object.create(node);
- newNode.nodes = node.nodes.map(traverseNode);
- return newNode;
- }
- return node;
- }
-
- // Find any :import and remember imported names
- var importedNames = {};
- css.walkRules(function (rule) {
- if (/^:import\(.+\)$/.test(rule.selector)) {
- rule.walkDecls(function (decl) {
- importedNames[decl.prop] = true;
- });
- }
- });
-
- // Find any :local classes
- css.walkRules(function (rule) {
- var selector = _cssSelectorTokenizer2['default'].parse(rule.selector);
- var newSelector = traverseNode(selector);
- rule.selector = _cssSelectorTokenizer2['default'].stringify(newSelector);
- rule.walkDecls(/composes|compose-with/, function (decl) {
- var localNames = getSingleLocalNamesForComposes(selector);
- var classes = decl.value.split(/\s+/);
- classes.forEach(function (className) {
- var global = /^global\(([^\)]+)\)$/.exec(className);
- if (global) {
- localNames.forEach(function (exportedName) {
- exports[exportedName].push(global[1]);
- });
- } else if (hasOwnProperty.call(importedNames, className)) {
- localNames.forEach(function (exportedName) {
- exports[exportedName].push(className);
- });
- } else if (hasOwnProperty.call(exports, className)) {
- localNames.forEach(function (exportedName) {
- exports[className].forEach(function (item) {
- exports[exportedName].push(item);
- });
- });
- } else {
- throw decl.error('referenced class name "' + className + '" in ' + decl.prop + ' not found');
- }
- });
- decl.remove();
- });
-
- rule.walkDecls(function (decl) {
- var tokens = decl.value.split(/(,|'[^']*'|"[^"]*")/);
- tokens = tokens.map(function (token, idx) {
- if (idx === 0 || tokens[idx - 1] === ',') {
- var localMatch = /^(\s*):local\s*\((.+?)\)/.exec(token);
- if (localMatch) {
- return localMatch[1] + exportScopedName(localMatch[2]) + token.substr(localMatch[0].length);
- } else {
- return token;
- }
- } else {
- return token;
- }
- });
- decl.value = tokens.join('');
- });
- });
-
- // Find any :local keyframes
- css.walkAtRules(function (atrule) {
- if (/keyframes$/.test(atrule.name)) {
- var localMatch = /^\s*:local\s*\((.+?)\)\s*$/.exec(atrule.params);
- if (localMatch) {
- atrule.params = exportScopedName(localMatch[1]);
- }
- }
- });
-
- // If we found any :locals, insert an :export rule
- var exportedNames = Object.keys(exports);
- if (exportedNames.length > 0) {
- (function () {
- var exportRule = _postcss2['default'].rule({ selector: ':export' });
- exportedNames.forEach(function (exportedName) {
- return exportRule.append({
- prop: exportedName,
- value: exports[exportedName].join(' '),
- raws: { before: '\n ' }
- });
- });
- css.append(exportRule);
- })();
- }
- };
- });
-
- processor.generateScopedName = function (exportedName, path) {
- var sanitisedPath = path.replace(/\.[^\.\/\\]+$/, '').replace(/[\W_]+/g, '_').replace(/^_|_$/g, '');
- return '_' + sanitisedPath + '__' + exportedName;
- };
-
- exports['default'] = processor;
- module.exports = exports['default'];
|