UNPKG

2.86 kBJavaScriptView Raw
1"use strict";
2
3var _cssTree = _interopRequireDefault(require("css-tree"));
4
5var _cssMediaquery = _interopRequireDefault(require("css-mediaquery"));
6
7var _debug = _interopRequireDefault(require("debug"));
8
9function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
10
11const debuglog = (0, _debug.default)('penthouse:preformatting:nonMatchingMediaQueryRemover'); // only filters out:
12// - @print
13// - min-width > width OR min-height > height
14// and the latter only if !keepLargerMediaQueries (which is the default)
15
16function _isMatchingMediaQuery(mediaQuery, matchConfig) {
17 // TODO: use the media query parsing from css-tree instead
18 let mediaAST;
19
20 try {
21 mediaAST = _cssMediaquery.default.parse(mediaQuery);
22 } catch (e) {
23 // cant parse, most likely browser cant either
24 return false;
25 }
26
27 var keep = mediaAST.some(function (mq) {
28 // not sure why css-mediaquery library sometimes flags the inverse as type,
29 // rather than the inverse field, but for our purposes we want to treat
30 // them the same.
31 const isInverse = mq.inverse || mq.type === 'not';
32
33 if (!isInverse && mq.type === 'print' || isInverse && mq.type === 'screen') {
34 return false;
35 } // f.e. @media all {}
36 // go for false positives over false negatives,
37 // i.e. accept @media randomThing {}
38
39
40 if (mq.expressions.length === 0) {
41 return true;
42 }
43
44 return mq.expressions.some(function ({
45 modifier,
46 feature,
47 value
48 }) {
49 if (modifier === 'min') {
50 const constructedQuery = `${isInverse ? 'not ' : ''}(min-${feature}: ${value})`;
51 return _cssMediaquery.default.match(constructedQuery, matchConfig);
52 } else {
53 return true;
54 }
55 });
56 });
57 return keep;
58}
59
60function nonMatchingMediaQueryRemover(ast, width, height, keepLargerMediaQueries) {
61 debuglog('BEFORE');
62 const matchConfig = {
63 type: 'screen',
64 width: (keepLargerMediaQueries ? 9999999999 : width) + 'px',
65 height: (keepLargerMediaQueries ? 9999999999 : height) + 'px'
66 };
67 debuglog('matchConfig: ' + JSON.stringify(matchConfig, null, 2));
68
69 _cssTree.default.walk(ast, {
70 visit: 'Atrule',
71 enter: (atrule, item, list) => {
72 // ignore (keep) all non media query rules
73 if (_cssTree.default.keyword(atrule.name).name !== 'media') {
74 return;
75 } // this can happen - why? (atrule.prelude === null)
76 // and should we remove this rule here, or keep it?
77
78
79 if (!atrule.prelude) {
80 return;
81 }
82
83 const mediaQuery = _cssTree.default.generate(atrule.prelude);
84
85 const isMatching = _isMatchingMediaQuery(mediaQuery, matchConfig);
86
87 if (!isMatching) {
88 debuglog('DROP: ' + `(${mediaQuery}), `);
89 list.remove(item);
90 }
91 }
92 });
93
94 return ast;
95}
96
97module.exports = nonMatchingMediaQueryRemover;
\No newline at end of file