Spaces:
Configuration error
Configuration error
File size: 2,735 Bytes
a053984 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
import { List, walk, keyword as resolveKeyword } from 'css-tree';
const { hasOwnProperty } = Object.prototype;
function addRuleToMap(map, item, list, single) {
const node = item.data;
const name = resolveKeyword(node.name).basename;
const id = node.name.toLowerCase() + '/' + (node.prelude ? node.prelude.id : null);
if (!hasOwnProperty.call(map, name)) {
map[name] = Object.create(null);
}
if (single) {
delete map[name][id];
}
if (!hasOwnProperty.call(map[name], id)) {
map[name][id] = new List();
}
map[name][id].append(list.remove(item));
}
function relocateAtrules(ast, options) {
const collected = Object.create(null);
let topInjectPoint = null;
ast.children.forEach(function(node, item, list) {
if (node.type === 'Atrule') {
const name = resolveKeyword(node.name).basename;
switch (name) {
case 'keyframes':
addRuleToMap(collected, item, list, true);
return;
case 'media':
if (options.forceMediaMerge) {
addRuleToMap(collected, item, list, false);
return;
}
break;
}
if (topInjectPoint === null &&
name !== 'charset' &&
name !== 'import') {
topInjectPoint = item;
}
} else {
if (topInjectPoint === null) {
topInjectPoint = item;
}
}
});
for (const atrule in collected) {
for (const id in collected[atrule]) {
ast.children.insertList(
collected[atrule][id],
atrule === 'media' ? null : topInjectPoint
);
}
}
};
function isMediaRule(node) {
return node.type === 'Atrule' && node.name === 'media';
}
function processAtrule(node, item, list) {
if (!isMediaRule(node)) {
return;
}
const prev = item.prev && item.prev.data;
if (!prev || !isMediaRule(prev)) {
return;
}
// merge @media with same query
if (node.prelude &&
prev.prelude &&
node.prelude.id === prev.prelude.id) {
prev.block.children.appendList(node.block.children);
list.remove(item);
// TODO: use it when we can refer to several points in source
// prev.loc = {
// primary: prev.loc,
// merged: node.loc
// };
}
}
export default function rejoinAtrule(ast, options) {
relocateAtrules(ast, options);
walk(ast, {
visit: 'Atrule',
reverse: true,
enter: processAtrule
});
};
|