|
|
- 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
- });
- };
|