diff options
Diffstat (limited to 'node_modules/postcss-modules-extract-imports/lib/index.js')
-rw-r--r-- | node_modules/postcss-modules-extract-imports/lib/index.js | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/node_modules/postcss-modules-extract-imports/lib/index.js b/node_modules/postcss-modules-extract-imports/lib/index.js new file mode 100644 index 0000000..e552655 --- /dev/null +++ b/node_modules/postcss-modules-extract-imports/lib/index.js @@ -0,0 +1,181 @@ +'use strict'; + +var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); + +var postcss = require('postcss'); +var topologicalSort = require('./topologicalSort'); + +var declWhitelist = ['composes']; +var declFilter = new RegExp(`^(${declWhitelist.join('|')})$`); +var matchImports = /^(.+?)\s+from\s+(?:"([^"]+)"|'([^']+)'|(global))$/; +var icssImport = /^:import\((?:"([^"]+)"|'([^']+)')\)/; + +var VISITED_MARKER = 1; + +function createParentName(rule, root) { + return `__${root.index(rule.parent)}_${rule.selector}`; +} + +function serializeImports(imports) { + return imports.map(function (importPath) { + return '`' + importPath + '`'; + }).join(', '); +} + +/** + * :import('G') {} + * + * Rule + * composes: ... from 'A' + * composes: ... from 'B' + + * Rule + * composes: ... from 'A' + * composes: ... from 'A' + * composes: ... from 'C' + * + * Results in: + * + * graph: { + * G: [], + * A: [], + * B: ['A'], + * C: ['A'], + * } + */ +function addImportToGraph(importId, parentId, graph, visited) { + var siblingsId = parentId + '_' + 'siblings'; + var visitedId = parentId + '_' + importId; + + if (visited[visitedId] !== VISITED_MARKER) { + if (!Array.isArray(visited[siblingsId])) visited[siblingsId] = []; + + var siblings = visited[siblingsId]; + + if (Array.isArray(graph[importId])) graph[importId] = graph[importId].concat(siblings);else graph[importId] = siblings.slice(); + + visited[visitedId] = VISITED_MARKER; + siblings.push(importId); + } +} + +module.exports = postcss.plugin('modules-extract-imports', function () { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + var failOnWrongOrder = options.failOnWrongOrder; + + return function (css) { + var graph = {}; + var visited = {}; + + var existingImports = {}; + var importDecls = {}; + var imports = {}; + + var importIndex = 0; + + var createImportedName = typeof options.createImportedName !== 'function' ? function (importName /*, path*/) { + return `i__imported_${importName.replace(/\W/g, '_')}_${importIndex++}`; + } : options.createImportedName; + + // Check the existing imports order and save refs + css.walkRules(function (rule) { + var matches = icssImport.exec(rule.selector); + + if (matches) { + var _matches = _slicedToArray(matches, 3), + /*match*/doubleQuotePath = _matches[1], + singleQuotePath = _matches[2]; + + var importPath = doubleQuotePath || singleQuotePath; + + addImportToGraph(importPath, 'root', graph, visited); + + existingImports[importPath] = rule; + } + }); + + // Find any declaration that supports imports + css.walkDecls(declFilter, function (decl) { + var matches = decl.value.match(matchImports); + var tmpSymbols = void 0; + + if (matches) { + var _matches2 = _slicedToArray(matches, 5), + + /*match*/symbols = _matches2[1], + doubleQuotePath = _matches2[2], + singleQuotePath = _matches2[3], + global = _matches2[4]; + + if (global) { + // Composing globals simply means changing these classes to wrap them in global(name) + tmpSymbols = symbols.split(/\s+/).map(function (s) { + return `global(${s})`; + }); + } else { + var importPath = doubleQuotePath || singleQuotePath; + var parentRule = createParentName(decl.parent, css); + + addImportToGraph(importPath, parentRule, graph, visited); + + importDecls[importPath] = decl; + imports[importPath] = imports[importPath] || {}; + + tmpSymbols = symbols.split(/\s+/).map(function (s) { + if (!imports[importPath][s]) { + imports[importPath][s] = createImportedName(s, importPath); + } + + return imports[importPath][s]; + }); + } + + decl.value = tmpSymbols.join(' '); + } + }); + + var importsOrder = topologicalSort(graph, failOnWrongOrder); + + if (importsOrder instanceof Error) { + var importPath = importsOrder.nodes.find(function (importPath) { + return importDecls.hasOwnProperty(importPath); + }); + var decl = importDecls[importPath]; + + var errMsg = 'Failed to resolve order of composed modules ' + serializeImports(importsOrder.nodes) + '.'; + + throw decl.error(errMsg, { + plugin: 'modules-extract-imports', + word: 'composes' + }); + } + + var lastImportRule = void 0; + importsOrder.forEach(function (path) { + var importedSymbols = imports[path]; + var rule = existingImports[path]; + + if (!rule && importedSymbols) { + rule = postcss.rule({ + selector: `:import("${path}")`, + raws: { after: '\n' } + }); + + if (lastImportRule) css.insertAfter(lastImportRule, rule);else css.prepend(rule); + } + + lastImportRule = rule; + + if (!importedSymbols) return; + + Object.keys(importedSymbols).forEach(function (importedSymbol) { + rule.append(postcss.decl({ + value: importedSymbol, + prop: importedSymbols[importedSymbol], + raws: { before: '\n ' } + })); + }); + }); + }; +});
\ No newline at end of file |