嵌套的postcss at-rule不会被删除

时间:2017-05-18 23:59:03

标签: postcss

Interactive Fiddle

以下是我想要实现的行为的简短可重现示例:

var postcss = require('postcss');
var plugin = postcss.plugin('keepme', () => (root) => {
  root.walkAtRules(/keepme|removeme/, (atRule) => {
    if (atRule.name === 'keepme') {
      atRule.replaceWith(atRule.nodes);
    } else {
      atRule.remove();
    }
  });
});
postcss([plugin]).process(`
  @keepme {
    @removeme {
      .selector { color: red; }
    }
  }
`).then(result => console.log(result.css));

给出输入

  @keepme {
    @removeme {
      .selector { color: red; }
    }
  }

我希望这会返回一个空字符串。

相反,我收到输出

@removeme {
  .selector { color: red; }
}

@keepme规则似乎正确地将其自身替换为其节点(然后不执行?)。

我不知道该如何解决这个问题。有什么建议吗?

1 个答案:

答案 0 :(得分:0)

replaceWith的实现方式如下:

/**
 * Inserts node(s) before the current node and removes the current node.
 *
 * @param {...Node} nodes - node(s) to replace current one
 *
 * @example
 * if ( atrule.name == 'mixin' ) {
 *   atrule.replaceWith(mixinRules[atrule.params]);
 * }
 *
 * @return {Node} current node to methods chain
 */
replaceWith(...nodes) {
    if (this.parent) {
        for (let node of nodes) {
            this.parent.insertBefore(this, node);
        }
        this.remove();
    }
    return this;
}

给出要遍历的规则列表:

  1. @keepme
  2. @removeme
  3. rule-walker保留当前检查规则的索引。在索引1处,它找到keepmekeepme.replaceWith(removeme)会在 removeme之前插入keepme ,然后继续走向...

    由于removeme向前移动,助行器已经移过它,并且不会执行该规则。

    修复方法是修改replaceWith,以便在 检查规则后移动子节点

      root.walkAtRules(/keepme|removeme/, (atRule) => {
        if (atRule.name === 'keepme') {
          if (atRule.parent) {
            for (let node of atRule.nodes.reverse()) {
              atRule.parent.insertAfter(atRule, node);
            }
          }
        }
        atRule.remove();
      });
    

    符合预期:Interactive fiddle