在编辑器底部添加投票按钮

这实际上比看起来要棘手(挪动一个按钮能有多难,对吧?:))

我简单尝试了一下,发现最整洁的方法是:将编辑器工具栏分配给一个控制器属性,这样你就可以在 outlet 中访问它。

如果你试图重新实现工具栏的行为,就会遇到 @spirobel 提到的那些直接问题,而且随着文本解析逻辑的调整,未来很可能还会遇到其他问题。

基本原则是尽量在最高抽象层级上使用功能,也就是说,我们需要的是实际编辑器(composer editor)的工具栏……那就直接获取它。

例如:

api.modifyClass("component:d-editor", {
  @on('didInsertElement')
  makeToolbarAccessible() {
    if (this.outletArgs && this.outletArgs.editorType === 'composer') {
      const controller = getOwner(this).lookup('controller:composer');
      controller.set('editorToolbar', this.toolbar);
    }
  }
});

然后在 outlet 中,我们从 composer 控制器获取工具栏,并向其中添加一个新按钮。也许有一种方法可以利用现有的投票按钮(那将是最理想的),但它被封装在 popupMenu 逻辑中,我没能找到将其分离出来的方法。

setupComponent(attrs, ctx) {
  const controller = getOwner(this).lookup('controller:composer');
  
  controller.addObserver('editorToolbar', function() {
    if (this._state === 'destroying') return;

    const toolbar = controller.editorToolbar;
          
    toolbar.addButton({
      group: "extras",
      icon: "chart-bar",
      title: "poll.ui_builder.title",
      sendAction: e => {
        controller.send('storeToolbarState', e);
        this.send("showPollBuilder");
      }
    });
    
    const extras = toolbar.groups.find(g => g.group == 'extras');
    const pollButton = extras.buttons.find(b => b.icon == "chart-bar");
        
    ctx.set('pb', pollButton);
  });
}

然后在模板中:

{{d-button
  type="button"
  action=pb.action
  actionParam=pb
  translatedTitle=pb.title
  icon=pb.icon
  class=pb.className}}

@nexo 试试这个主题组件:discourse-poll-button-bottom.zip (2.5 KB)

附:我刚在 thepavilion.io 上加载了它,看起来能正常工作(仅限移动端)。