123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- var List = require('css-tree').List;
- var resolveKeyword = require('css-tree').keyword;
- var hasOwnProperty = Object.prototype.hasOwnProperty;
- var walk = require('css-tree').walk;
- function addRuleToMap(map, item, list, single) {
- var node = item.data;
- var name = resolveKeyword(node.name).basename;
- var 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) {
- var collected = Object.create(null);
- var topInjectPoint = null;
- ast.children.each(function(node, item, list) {
- if (node.type === 'Atrule') {
- var 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 (var atrule in collected) {
- for (var 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;
- }
- var 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
- // };
- }
- }
- module.exports = function rejoinAtrule(ast, options) {
- relocateAtrules(ast, options);
- walk(ast, {
- visit: 'Atrule',
- reverse: true,
- enter: processAtrule
- });
- };
|