1 | 'use strict';
|
---|
2 |
|
---|
3 | function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
|
---|
4 |
|
---|
5 | var postcss = _interopDefault(require('postcss'));
|
---|
6 | var valueParser = _interopDefault(require('postcss-values-parser'));
|
---|
7 |
|
---|
8 | // return whether a node is a valid comma
|
---|
9 | var getComma = (node => Object(node).type === 'comma');
|
---|
10 |
|
---|
11 | const imageSetFunctionMatchRegExp = /^(-webkit-)?image-set$/i; // return a valid image
|
---|
12 |
|
---|
13 | var getImage = (node => // <url> | <image()> | <cross-fade()> | <gradient>
|
---|
14 | // the image-set() function can not be nested inside of itself
|
---|
15 | Object(node).type === 'func' && /^(cross-fade|image|(repeating-)?(conic|linear|radial)-gradient|url)$/i.test(node.value) && !(node.parent.parent && node.parent.parent.type === 'func' && imageSetFunctionMatchRegExp.test(node.parent.parent.value)) ? String(node) : Object(node).type === 'string' ? node.value : false);
|
---|
16 |
|
---|
17 | const dpiRatios = {
|
---|
18 | dpcm: 2.54,
|
---|
19 | dpi: 1,
|
---|
20 | dppx: 96,
|
---|
21 | x: 96
|
---|
22 | }; // return a valid @media rule
|
---|
23 |
|
---|
24 | var getMedia = ((node, mediasByDpr) => {
|
---|
25 | if (Object(node).type === 'number' && node.unit in dpiRatios) {
|
---|
26 | // calculate min-device-pixel-ratio and min-resolution
|
---|
27 | const dpi = Number(node.value) * dpiRatios[node.unit.toLowerCase()];
|
---|
28 | const dpr = Math.floor(dpi / dpiRatios.x * 100) / 100;
|
---|
29 |
|
---|
30 | if (dpi in mediasByDpr) {
|
---|
31 | return false;
|
---|
32 | } else {
|
---|
33 | const media = mediasByDpr[dpi] = postcss.atRule({
|
---|
34 | name: 'media',
|
---|
35 | params: `(-webkit-min-device-pixel-ratio: ${dpr}), (min-resolution: ${dpi}dpi)`
|
---|
36 | });
|
---|
37 | return media;
|
---|
38 | }
|
---|
39 | } else {
|
---|
40 | return false;
|
---|
41 | }
|
---|
42 | });
|
---|
43 |
|
---|
44 | var handleInvalidation = ((opts, message, word) => {
|
---|
45 | if (opts.oninvalid === 'warn') {
|
---|
46 | opts.decl.warn(opts.result, message, {
|
---|
47 | word: String(word)
|
---|
48 | });
|
---|
49 | } else if (opts.oninvalid === 'throw') {
|
---|
50 | throw opts.decl.error(message, {
|
---|
51 | word: String(word)
|
---|
52 | });
|
---|
53 | }
|
---|
54 | });
|
---|
55 |
|
---|
56 | var processImageSet = ((imageSetOptionNodes, decl, opts) => {
|
---|
57 | const parent = decl.parent;
|
---|
58 | const mediasByDpr = {};
|
---|
59 | let length = imageSetOptionNodes.length;
|
---|
60 | let index = -1;
|
---|
61 |
|
---|
62 | while (index < length) {
|
---|
63 | const _ref = [index < 0 ? true : getComma(imageSetOptionNodes[index]), getImage(imageSetOptionNodes[index + 1]), getMedia(imageSetOptionNodes[index + 2], mediasByDpr)],
|
---|
64 | comma = _ref[0],
|
---|
65 | value = _ref[1],
|
---|
66 | media = _ref[2]; // handle invalidations
|
---|
67 |
|
---|
68 | if (!comma) {
|
---|
69 | return handleInvalidation(opts, 'unexpected comma', imageSetOptionNodes[index]);
|
---|
70 | } else if (!value) {
|
---|
71 | return handleInvalidation(opts, 'unexpected image', imageSetOptionNodes[index + 1]);
|
---|
72 | } else if (!media) {
|
---|
73 | return handleInvalidation(opts, 'unexpected resolution', imageSetOptionNodes[index + 2]);
|
---|
74 | } // prepare @media { decl: <image> }
|
---|
75 |
|
---|
76 |
|
---|
77 | const parentClone = parent.clone().removeAll();
|
---|
78 | const declClone = decl.clone({
|
---|
79 | value
|
---|
80 | });
|
---|
81 | parentClone.append(declClone);
|
---|
82 | media.append(parentClone);
|
---|
83 | index += 3;
|
---|
84 | }
|
---|
85 |
|
---|
86 | const medias = Object.keys(mediasByDpr).sort((a, b) => a - b).map(params => mediasByDpr[params]); // conditionally prepend previous siblings
|
---|
87 |
|
---|
88 | if (medias.length) {
|
---|
89 | const firstDecl = medias[0].nodes[0].nodes[0];
|
---|
90 |
|
---|
91 | if (medias.length === 1) {
|
---|
92 | decl.value = firstDecl.value;
|
---|
93 | } else {
|
---|
94 | const siblings = parent.nodes;
|
---|
95 | const previousSiblings = siblings.slice(0, siblings.indexOf(decl)).concat(firstDecl);
|
---|
96 |
|
---|
97 | if (previousSiblings.length) {
|
---|
98 | const parentClone = parent.cloneBefore().removeAll();
|
---|
99 | parentClone.append(previousSiblings);
|
---|
100 | } // prepend any @media { decl: <image> } rules
|
---|
101 |
|
---|
102 |
|
---|
103 | parent.before(medias.slice(1)); // conditionally remove the current rule
|
---|
104 |
|
---|
105 | if (!opts.preserve) {
|
---|
106 | decl.remove(); // and then conditionally remove its parent
|
---|
107 |
|
---|
108 | if (!parent.nodes.length) {
|
---|
109 | parent.remove();
|
---|
110 | }
|
---|
111 | }
|
---|
112 | }
|
---|
113 | }
|
---|
114 | });
|
---|
115 |
|
---|
116 | const imageSetValueMatchRegExp = /(^|[^\w-])(-webkit-)?image-set\(/;
|
---|
117 | const imageSetFunctionMatchRegExp$1 = /^(-webkit-)?image-set$/i;
|
---|
118 | var index = postcss.plugin('postcss-image-set-function', opts => {
|
---|
119 | // prepare options
|
---|
120 | const preserve = 'preserve' in Object(opts) ? Boolean(opts.preserve) : true;
|
---|
121 | const oninvalid = 'oninvalid' in Object(opts) ? opts.oninvalid : 'ignore';
|
---|
122 | return (root, result) => {
|
---|
123 | // for every declaration
|
---|
124 | root.walkDecls(decl => {
|
---|
125 | const value = decl.value; // if a declaration likely uses an image-set() function
|
---|
126 |
|
---|
127 | if (imageSetValueMatchRegExp.test(value)) {
|
---|
128 | const valueAST = valueParser(value).parse(); // process every image-set() function
|
---|
129 |
|
---|
130 | valueAST.walkType('func', node => {
|
---|
131 | if (imageSetFunctionMatchRegExp$1.test(node.value)) {
|
---|
132 | processImageSet(node.nodes.slice(1, -1), decl, {
|
---|
133 | decl,
|
---|
134 | oninvalid,
|
---|
135 | preserve,
|
---|
136 | result
|
---|
137 | });
|
---|
138 | }
|
---|
139 | });
|
---|
140 | }
|
---|
141 | });
|
---|
142 | };
|
---|
143 | });
|
---|
144 |
|
---|
145 | module.exports = index;
|
---|
146 | //# sourceMappingURL=index.cjs.js.map
|
---|