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, opts);
|
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 | return importPromise.then(
|
30 |
|
31 | ({ file, contents }) => processor.process(contents, { from: file }).then(
|
32 | ({ root }) => {
|
33 |
|
34 | opts.result.messages.push({ type: 'dependency', file: file, parent: cwf });
|
35 |
|
36 |
|
37 | const nodes = root.nodes.slice(0);
|
38 |
|
39 |
|
40 | if (media) {
|
41 |
|
42 | const mediaRule = postcss.atRule({
|
43 | name: 'media',
|
44 | params: media,
|
45 | source: rule.source
|
46 | });
|
47 |
|
48 |
|
49 | mediaRule.append(nodes);
|
50 |
|
51 |
|
52 | rule.replaceWith(mediaRule);
|
53 | } else {
|
54 |
|
55 | rule.replaceWith(nodes);
|
56 | }
|
57 |
|
58 |
|
59 | return transformNode({ nodes }, opts);
|
60 | }
|
61 | ),
|
62 | () => {
|
63 |
|
64 | manageUnresolved(rule, opts, '@import', `Could not resolve the @import for "${id}"`);
|
65 | }
|
66 | )
|
67 | }
|
68 | }
|
69 | }
|
70 |
|
71 | const processor = postcss();
|
72 |
|
73 |
|
74 | const getImportOpts = (node, opts) => {
|
75 | const [ rawid, ...medias ] = list.space(node.params);
|
76 | const id = getReplacedString(trimWrappingURL(rawid), node, opts);
|
77 | const media = medias.join(' ');
|
78 |
|
79 |
|
80 | const cwf = node.source && node.source.input && node.source.input.file || opts.result.from;
|
81 | const cwd = cwf ? path.dirname(cwf) : opts.importRoot;
|
82 |
|
83 | return { id, media, cwf, cwd };
|
84 | };
|
85 |
|
86 |
|
87 | const trimWrappingURL = string => trimWrappingQuotes(string.replace(/^url\(([\W\w]*)\)$/, '$1'));
|
88 |
|
89 |
|
90 | const trimWrappingQuotes = string => string.replace(/^("|')([\W\w]*)\1$/, '$2');
|