WIP - add extractor, generate snippet_data
This commit is contained in:
181
node_modules/postcss-modules-extract-imports/lib/index.js
generated
vendored
Normal file
181
node_modules/postcss-modules-extract-imports/lib/index.js
generated
vendored
Normal file
@ -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 ' }
|
||||
}));
|
||||
});
|
||||
});
|
||||
};
|
||||
});
|
||||
56
node_modules/postcss-modules-extract-imports/lib/topologicalSort.js
generated
vendored
Normal file
56
node_modules/postcss-modules-extract-imports/lib/topologicalSort.js
generated
vendored
Normal file
@ -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;
|
||||
Reference in New Issue
Block a user