2017-05-18 110 views
0

Interactive Fiddle

這裏是行爲的短重複的例子,我想實現:嵌套postcss在規則不被刪除

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規則似乎與它的節點能夠正確地更換本身(然後不執行?)。

我不知道如何去做這件事。有什麼建議麼?

回答

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

規則行者保留當前檢查規則的索引。在索引1找到keepmekeepme.replaceWith(removeme)將插入removemekeepme,然後繼續走AST ...

由於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