UNPKG

4.68 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6
7var _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"); } }; }();
8
9var _path = require('path');
10
11var _path2 = _interopRequireDefault(_path);
12
13var _postcss = require('postcss');
14
15var _postcss2 = _interopRequireDefault(_postcss);
16
17require('string.prototype.includes');
18
19function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
20
21var defaultResolutions = ['(min--moz-device-pixel-ratio: 1.5)', '(-o-min-device-pixel-ratio: 3/2)', '(-webkit-min-device-pixel-ratio: 1.5)', '(min-device-pixel-ratio: 1.5)', '(min-resolution: 144dpi)', '(min-resolution: 1.5dppx)'];
22
23exports.default = _postcss2.default.plugin('postcss-at2x', at2x);
24
25
26function at2x() {
27 var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
28 _ref$identifier = _ref.identifier,
29 identifier = _ref$identifier === undefined ? '@2x' : _ref$identifier;
30
31 return function (root) {
32 // Create an empty rule so that all the new rules can be appended to this
33 // and then append it at the end.
34 var ruleContainer = _postcss2.default.root();
35
36 root.walkRules(function (rule) {
37 var mediaParent = rule.parent;
38
39 // Check for any `background-size` declarations and keep a reference to it
40 // These need to be added again to prevent it being overridden by usage of
41 // the `background` shorthand
42 var backgroundSize = void 0;
43 rule.walkDecls('background-size', function (decl) {
44 backgroundSize = decl;
45 });
46
47 rule.walkDecls(/^background/, function (decl) {
48 if (!backgroundWithHiResURL(decl.value)) {
49 return;
50 }
51
52 // Construct a duplicate rule but with the image urls
53 // replaced with retina versions
54 var retinaRule = _postcss2.default.rule({ selector: decl.parent.selector });
55 retinaRule.append(decl.clone({
56 value: createRetinaUrl(decl.value, identifier)
57 }));
58
59 // Remove keyword from original declaration here as createRetinaUrl
60 // needs it for regex search
61 decl.value = removeKeyword(decl.value);
62
63 if (backgroundSize) {
64 retinaRule.append(_postcss2.default.decl(backgroundSize));
65 }
66
67 // Create the rules and append them to the container
68 var params = mediaParent.name === 'media' ? combineMediaQuery(mediaParent.params.split(/,\s*/), defaultResolutions) : defaultResolutions.join(', ');
69 var mediaAtRule = _postcss2.default.atRule({ name: 'media', params: params });
70
71 mediaAtRule.append(retinaRule);
72 ruleContainer.append(mediaAtRule);
73 });
74 });
75
76 root.append(ruleContainer);
77 };
78}
79
80/**
81 * Add all the resolutions to each media query to scope them
82 */
83function combineMediaQuery(queries, resolutions) {
84 return queries.reduce(function (finalQuery, query) {
85 resolutions.forEach(function (resolution) {
86 return finalQuery.push(query + ' and ' + resolution);
87 });
88 return finalQuery;
89 }, []).join(', ');
90}
91
92// Matches `url()` content as long as it is followed by `at-2x`
93var urlPathRegex = /url\(([^\r\n]+)\)(?:[^\r\n]+)?at-2x/gm;
94
95function createRetinaUrl(bgValue, identifier) {
96 var match = void 0;
97 // Loop over all occurances of `url()` and match the path
98 while ((match = urlPathRegex.exec(bgValue)) !== null) {
99 var _match = match,
100 _match2 = _slicedToArray(_match, 2),
101 imgUrl = _match2[1];
102
103 var extension = _path2.default.extname(imgUrl);
104
105 if (extension === '.svg') {
106 break;
107 }
108
109 // File name without extension
110 var filename = _path2.default.basename(_path2.default.basename(imgUrl), extension);
111
112 // Replace with retina filename
113 bgValue = bgValue.replace(filename + extension, filename + identifier + extension);
114 }
115
116 return removeKeyword(bgValue);
117}
118
119function removeKeyword(str) {
120 return str.replace(/\sat-2x/g, '');
121}
122
123function backgroundWithHiResURL(bgValue) {
124 return bgValue.includes('url(') && bgValue.includes('at-2x');
125}
126module.exports = exports['default'];
\No newline at end of file