lml-main
Version:
This is now a mono repository published into many standalone packages.
316 lines (259 loc) • 9.26 kB
JavaScript
/*! postcss-smart-import v0.7.5 by Sebastian Software <s.werner@sebastian-software.de> */
import _get from 'lodash/get';
import path from 'path';
import assign from 'object-assign';
import postcss from 'postcss';
import _includes from 'lodash/includes';
import resolveId from 'resolve';
import readCache from 'read-cache';
import valueParser from 'postcss-value-parser';
import promiseEach from 'promise-each';
var moduleDirectories = ["web_modules", "node_modules"];
function resolveModule(id, opts) {
return new Promise(function (resolve, reject) {
resolveId(id, opts, function (err, path$$1) {
return err ? reject(err) : resolve(path$$1);
});
});
}
var resolveId$1 = function (id, base, options) {
var paths = options.path;
var resolveOpts = {
basedir: base,
moduleDirectory: moduleDirectories,
paths: paths,
extensions: [".css", ".sss", ".less", ".scss", ".sass"],
packageFilter: function processPackage(pkg) {
if (pkg.style) {
pkg.main = pkg.style;
} else if (pkg.browser) {
pkg.main = pkg.browser;
} else if (!pkg.main || !/\.css$/.test(pkg.main)) {
pkg.main = "index.css";
}
return pkg;
}
};
return resolveModule("./" + id, resolveOpts)["catch"](function () {
return resolveModule(id, resolveOpts);
})["catch"](function () {
if (!_includes(paths, base)) {
paths.unshift(base);
}
throw new Error(["Failed to find '" + id + "'", "in [ ", " " + paths.join(",\n "), "]"].join("\n "));
});
};
function loadContent(fileName) {
return readCache(fileName, "utf-8");
}
var stringify = valueParser.stringify;
function parseStatements(result, styles) {
var statements = [];
var nodes = [];
styles.each(function (node) {
var stmt;
if (node.type === "atrule" && node.name === "import") stmt = parseImport(result, node);
if (stmt) {
if (nodes.length > 0) {
statements.push({
type: "nodes",
nodes: nodes
});
nodes = [];
}
statements.push(stmt);
} else {
nodes.push(node);
}
});
if (nodes.length > 0) {
statements.push({
type: "nodes",
nodes: nodes
});
}
return statements;
}
function parseImport(result, atRule) {
var prev = atRule.prev();
while (prev && prev.type === "comment") {
prev = prev.prev();
}
if (prev) {
if (prev.type !== "atrule" || prev.name !== "import" && prev.name !== "charset") {
return result.warn("@import must precede all other statements (besides @charset)", { node: atRule });
}
}
if (atRule.nodes) {
return result.warn("It looks like you didn't end your @import statement correctly. Child nodes are attached to it.", { node: atRule });
}
var params = valueParser(atRule.params).nodes;
var stmt = {
type: "import",
node: atRule
};
if (params.length === 0 || (params[0].type !== "string" || !params[0].value) && (params[0].type !== "function" || params[0].value !== "url" || params[0].nodes.length === 0 || !params[0].nodes[0].value)) {
return result.warn("Unable to find uri in '" + atRule.toString() + "'", { node: atRule });
}
if (params[0].type === "string") stmt.uri = params[0].value;else stmt.uri = params[0].nodes[0].value;
stmt.fullUri = stringify(params[0]);
return stmt;
}
function SmartImport(options) {
options = assign({
root: process.cwd(),
path: [],
skipDuplicates: true,
resolve: resolveId$1,
load: loadContent,
plugins: []
}, options);
options.root = path.resolve(options.root);
// convert string to an array of a single element
if (typeof options.path === "string") options.path = [options.path];
if (!Array.isArray(options.path)) options.path = [];
options.path = options.path.map(function (possibleRelativePath) {
return path.resolve(options.root, possibleRelativePath);
});
return function (styles, result) {
var state = {
importedFiles: {},
hashFiles: {}
};
var fileName = _get(styles, "source.input.file");
if (fileName) state.importedFiles[fileName] = {};
if (options.plugins && !Array.isArray(options.plugins)) throw new Error("plugins option must be an array");
return parseStyles(result, styles, options, state, []).then(function (bundle) {
applyRaws(bundle);
applyStyles(bundle, styles);
if (typeof options.onImport === "function") options.onImport(Object.keys(state.importedFiles));
});
};
}
function applyRaws(bundle) {
bundle.forEach(function (stmt, index) {
if (index === 0) return;
if (stmt.parent) {
var before = stmt.parent.node.raws.before;
if (stmt.type === "nodes") stmt.nodes[0].raws.before = before;else stmt.node.raws.before = before;
} else if (stmt.type === "nodes") {
stmt.nodes[0].raws.before = stmt.nodes[0].raws.before || "\n";
}
});
}
function applyStyles(bundle, styles) {
styles.nodes = [];
bundle.forEach(function (stmt) {
if (stmt.type === "import") {
stmt.node.parent = undefined;
styles.append(stmt.node);
} else if (stmt.type === "media") {
stmt.node.parent = undefined;
styles.append(stmt.node);
} else if (stmt.type === "nodes") {
stmt.nodes.forEach(function (node) {
node.parent = undefined;
styles.append(node);
});
}
});
}
function parseStyles(result, styles, options, state, media) {
var statements = parseStatements(result, styles);
return Promise.resolve(statements).then(promiseEach(function (stmt) {
// skip protocol base uri (protocol://url) or protocol-relative
if (stmt.type !== "import" || /^(?:[a-z]+:)?\/\//i.test(stmt.uri)) return null;else return resolveImportId(result, stmt, options, state);
})).then(function () {
var imports = [];
var bundle = [];
// squash statements and their children
statements.forEach(function (stmt) {
if (stmt.type === "import") {
if (stmt.children) {
stmt.children.forEach(function (child, index) {
if (child.type === "import") imports.push(child);else bundle.push(child);
// For better output
if (index === 0) child.parent = stmt;
});
} else {
imports.push(stmt);
}
} else if (stmt.type === "media" || stmt.type === "nodes") {
bundle.push(stmt);
}
});
return imports.concat(bundle);
});
}
function resolveImportId(result, stmt, options, state) {
var atRule = stmt.node;
var sourceFile = _get(atRule, "source.input.file");
var base = sourceFile ? path.dirname(sourceFile) : options.root;
return Promise.resolve(options.resolve(stmt.uri, base, options)).then(function (resolved) {
if (!Array.isArray(resolved)) resolved = [resolved];
// Add dependency messages:
resolved.forEach(function (fileName) {
result.messages.push({
type: "dependency",
file: fileName,
parent: sourceFile
});
});
return Promise.all(resolved.map(function (file) {
return loadImportContent(result, stmt, file, options, state);
}));
}).then(function (importedContent) {
// Merge loaded statements
stmt.children = importedContent.reduce(function (currentContent, statements) {
if (statements) {
currentContent = currentContent.concat(statements);
}
return currentContent;
}, []);
})["catch"](function (err) {
result.warn(err.message, { node: atRule });
});
}
function loadImportContent(result, stmt, filename, options, state) {
var atRule = stmt.node;
if (options.skipDuplicates) {
// skip files already imported at the same scope
if (state.importedFiles[filename]) return null;
// save imported files to skip them next time
state.importedFiles[filename] = true;
}
return Promise.resolve(options.load(filename, options)).then(function (content) {
if (typeof options.transform !== "function") {
return content;
}
return Promise.resolve(options.transform(content, filename, options)).then(function (transformed) {
return typeof transformed === "string" ? transformed : content;
});
}).then(function (content) {
if (content.trim() === "") {
result.warn(filename + " is empty", { node: atRule });
return null;
}
// skip previous imported files not containing @import rules
if (state.hashFiles[content]) return null;
return postcss(options.plugins).process(content, {
from: filename,
syntax: result.opts.syntax,
parser: result.opts.parser
}).then(function (importedResult) {
var styles = importedResult.root;
result.messages = result.messages.concat(importedResult.messages);
if (options.skipDuplicates) {
var hasImport = styles.some(function (child) {
return child.type === "atrule" && child.name === "import";
});
if (!hasImport) state.hashFiles[content] = true;
}
// recursion: import @import from imported file
return parseStyles(result, styles, options, state);
});
});
}
var index = postcss.plugin("postcss-smart-import", SmartImport);
export default index;
//# sourceMappingURL=index.classic.esmodule.js.map