koishijs / koishi

Cross-platform chatbot framework made with love
https://koishi.chat
MIT License
4.53k stars 246 forks source link

Bug: h.transform 不会处理命中元素的嵌套元素 #1396

Closed ilharp closed 6 months ago

ilharp commented 6 months ago

Describe the bug

利用 h.transform() 处理元素时,如果一个元素被命中,则其子元素不会被处理。

对于以下规则:

{
  aa: (attrs, children) => h('aa', { a: attrs.a + '_modified' }, children )
}

<bb>
  <aa a="hello1">
    <aa a="hello2" />
  </aa>
</bb>

输出

<bb>
  <aa a="hello1_modified">
    <aa a="hello2"/>
  </aa>
</bb>

hello1 和 hello2 均为某个元素的子元素。此时仅 hello1 会被处理,hello2 不会被处理。

Steps to reproduce

const h = require('koishi')

console.log(
  h.transform(
    '<bb><aa a="hello1"><aa a="hello2" /></aa></bb>',
    {
      aa: (attrs, children) => h('aa', { a: `${attrs.a}_modified` }, children )
    }
  )
)

输出

<bb>
  <aa a="hello1_modified">
    <aa a="hello2"/>
  </aa>
</bb>
ilharp commented 6 months ago

这是预期行为。如果你需要递归处理子元素,那么你需要写一个递归函数实现。

一个示例:

const h = require('koishi')

function myTransform(e) {
  return h.transform(
    e,
    {
      aa: (attrs, children) => h('aa', { a: `${attrs.a}_modified` }, myTransform(children))
    }
  )
}

console.log(myTransform('<bb><aa a="hello1"><aa a="hello2" /></aa></bb>'))

输出

<bb>
  <aa a="hello1_modified">
    <aa a="hello2_modified"/>
  </aa>
</bb>