summaryrefslogtreecommitdiffstats
path: root/node_modules/postcss-modules-extract-imports/lib
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/postcss-modules-extract-imports/lib')
-rw-r--r--node_modules/postcss-modules-extract-imports/lib/index.js181
-rw-r--r--node_modules/postcss-modules-extract-imports/lib/topologicalSort.js56
2 files changed, 237 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
diff --git a/node_modules/postcss-modules-extract-imports/lib/topologicalSort.js b/node_modules/postcss-modules-extract-imports/lib/topologicalSort.js
new file mode 100644
index 0000000..04151f7
--- /dev/null
+++ b/node_modules/postcss-modules-extract-imports/lib/topologicalSort.js
@@ -0,0 +1,56 @@
+"use strict";
+
+var PERMANENT_MARKER = 2;
+var TEMPORARY_MARKER = 1;
+
+function createError(node, graph) {
+ var er = new Error("Nondeterministic import's order");
+
+ var related = graph[node];
+ var relatedNode = related.find(function (relatedNode) {
+ return graph[relatedNode].indexOf(node) > -1;
+ });
+
+ er.nodes = [node, relatedNode];
+
+ return er;
+}
+
+function walkGraph(node, graph, state, result, strict) {
+ if (state[node] === PERMANENT_MARKER) return;
+ if (state[node] === TEMPORARY_MARKER) {
+ if (strict) return createError(node, graph);
+ return;
+ }
+
+ state[node] = TEMPORARY_MARKER;
+
+ var children = graph[node];
+ var length = children.length;
+
+ for (var i = 0; i < length; ++i) {
+ var er = walkGraph(children[i], graph, state, result, strict);
+ if (er instanceof Error) return er;
+ }
+
+ state[node] = PERMANENT_MARKER;
+
+ result.push(node);
+}
+
+function topologicalSort(graph, strict) {
+ var result = [];
+ var state = {};
+
+ var nodes = Object.keys(graph);
+ var length = nodes.length;
+
+ for (var i = 0; i < length; ++i) {
+ var er = walkGraph(nodes[i], graph, state, result, strict);
+ if (er instanceof Error) return er;
+ }
+
+ return result;
+}
+
+module.exports = topologicalSort; \ No newline at end of file