1 |
|
2 | import postcss, { list } from 'postcss';
|
3 | import getReplacedString from './get-replaced-string';
|
4 | import path from 'path';
|
5 | import transformNode from './transform-node';
|
6 | import manageUnresolved from './manage-unresolved';
|
7 |
|
8 |
|
9 | export default function transformImportAtrule(rule, opts) {
|
10 |
|
11 | if (opts.transform.includes('@import')) {
|
12 |
|
13 | const { id, media, cwf, cwd } = getImportOpts(rule);
|
14 |
|
15 | if (
|
16 | (opts.importFilter instanceof Function && opts.importFilter(id, media)) ||
|
17 | (opts.importFilter instanceof RegExp && opts.importFilter.test(id))
|
18 | ) {
|
19 | const cwds = [cwd].concat(opts.importPaths);
|
20 |
|
21 |
|
22 | const importPromise = cwds.reduce(
|
23 | (promise, thiscwd) => promise.catch(
|
24 | () => opts.importResolve(id, thiscwd, opts)
|
25 | ),
|
26 | Promise.reject()
|
27 | );
|
28 |
|
29 | opts.importPromise.push(
|
30 | importPromise.then(
|
31 |
|
32 | ({ file, contents }) => processor.process(contents, { from: file }).then(
|
33 | ({ root }) => {
|
34 |
|
35 | opts.result.messages.push({ type: 'dependency', file: file, parent: cwf });
|
36 |
|
37 |
|
38 | const nodes = root.nodes.slice(0);
|
39 |
|
40 |
|
41 | if (media) {
|
42 |
|
43 | const mediaRule = postcss.atRule({
|
44 | name: 'media',
|
45 | params: media,
|
46 | source: rule.source
|
47 | });
|
48 |
|
49 |
|
50 | mediaRule.append(nodes);
|
51 |
|
52 |
|
53 | rule.replaceWith(mediaRule);
|
54 | } else {
|
55 |
|
56 | rule.replaceWith(nodes);
|
57 | }
|
58 |
|
59 |
|
60 | transformNode({ nodes }, opts);
|
61 | }
|
62 | ),
|
63 | () => {
|
64 |
|
65 | manageUnresolved(rule, opts, '@import', `Could not resolve the @import for "${id}"`);
|
66 | }
|
67 | )
|
68 | );
|
69 | }
|
70 | }
|
71 | }
|
72 |
|
73 | const processor = postcss();
|
74 |
|
75 |
|
76 | const getImportOpts = (node, opts) => {
|
77 | const [ rawid, ...medias ] = list.space(node.params);
|
78 | const id = getReplacedString(trimWrappingURL(rawid), node, opts);
|
79 | const media = medias.join(' ');
|
80 |
|
81 |
|
82 | const cwf = node.source && node.source.input && node.source.input.file || opts.result.from;
|
83 | const cwd = cwf ? path.dirname(cwf) : opts.importRoot;
|
84 |
|
85 | return { id, media, cwf, cwd };
|
86 | };
|
87 |
|
88 |
|
89 | const trimWrappingURL = string => trimWrappingQuotes(string.replace(/^url\(([\W\w]*)\)$/, '$1'));
|
90 |
|
91 |
|
92 | const trimWrappingQuotes = string => string.replace(/^("|')([\W\w]*)\1$/, '$2');
|