在标题预填写时聚焦编辑器

我有类似的网址:

https://forum.example.com/new-message?groupname=moderators&title=Help+me+with+some+task+please

我会在我的网站上链接它,将用户带到论坛来提问。我使用各种值来预填标题,以包含他们想知道的任何主题,并且我希望编辑器成为焦点。

我曾试图查看如何修改它,并找到了 composer.js 文件及其 focusTarget 定义,如果能传入 title,修改它以支持此行为会非常容易。

我遇到的问题是,我找不到 focusTarget 的实际调用位置。我已经编程多年,但刚接触 Ember,而且我做的 JavaScript 编程相对较少。

任何关于如何处理此问题的建议都将不胜感激(如果能附带一个合理的说明手册的 rtfm 指针,那就更好了)。

祝好。

我想这正是您要找的:

https://github.com/discourse/discourse/blob/main/app/assets/javascripts/discourse/app/components/composer-editor.js#L159-L164

每次 focusTarget 值更改时,都会调用此 setFocus 函数。

这段代码是实现功能的关键。我不确定需要修改哪段代码才能让该方法获取标题,以便在那里适当地将焦点设置到编辑器……

https://github.com/discourse/discourse/blob/main/app/assets/javascripts/discourse/app/services/composer.js#L218-L243

我认为你可以做类似的事情。这应该会奏效。

import putCursorAtEnd from "discourse/lib/put-cursor-at-end";

api.onAppEvent("composer:open", ({ model }) => {
  if (model.title !== "") {
    scheduleOnce("afterRender", () => {
      putCursorAtEnd(document.querySelector("textarea.d-editor-input"));
    });
  }
});
1 个赞

我几乎快弄好了——代码执行时,我收到一个错误,提示 scheduleOnce 未定义——我试过 api.scheduleOnce,但看起来 scheduleOnce 是 Ember 的东西。我尝试在我的组件中添加这个导入,但得到了一个“只允许在顶层进行导入”的错误。
import { scheduleOnce } from "@ember/runloop";

我猜我遗漏了一些小东西,我会继续摆弄它,但想看看你是否能一眼看出问题所在。

再次感谢 :slight_smile:

是的,导入是正确的。将两个导入都放在文件的顶部,您应该就没问题了。

1 个赞

我应该把它们放在哪个文件里? 我想做的是在 <head> 中使用它——作为一个组件——这是我所做的,结果是日志“scheduling afterRender”出现,然后是关于 scheduleOnce 不存在的错误。我尝试了几种导入方式,但都不起作用。我怀疑我对 JavaScript 模块的不熟悉导致了问题。也许我不能通过组件来做,而需要做一个更完整的插件。我会看看——再次感谢你的帮助 :slight_smile:

<script type="text/discourse-plugin" version="1.8.0">
    api.onAppEvent("composer:open", ({ model }) => {
      console.log("composer open happened, model is: ", model);
      if (model.title !== "") {
        console.log("scheduling afterRender");
        scheduleOnce("afterRender", () => {
          console.log("after render happening");
          api.putCursorAtEnd(document.querySelector("textarea.d-editor-input"));
        });
      }
    });
</script>

哦,我明白了。我以为你在它的文件中使用了 JS its files

那么,从管理员界面,你会写:

<script type="text/discourse-plugin" version="1.8.0">
    const putCursorAtEnd = require("discourse/lib/put-cursor-at-end").default;
    const { scheduleOnce } = require("@ember/runloop");

    api.onAppEvent("composer:open", ({ model }) => {
      if (model.title !== "") {
        scheduleOnce("afterRender", () => {
          putCursorAtEnd(document.querySelector("textarea.d-editor-input"));
        });
      }
    });
</script>

顺便说一句,我强烈建议你使用 Theme CLI。你可以从模板创建一个主题组件,将其与 Discourse 同步并实时刷新,然后使用编辑器更新任何更改。这比使用 UI 容易得多!

2 个赞

非常感谢——我知道我遗漏了什么——我一定会设置它来使用主题 CLI 并以这种方式编辑它们 :slight_smile: :slight_smile:

1 个赞

再次感谢 Arkshine,我使用 discourse_theme 创建了我的第一个组件 :slight_smile:
对于发现此帖子的任何人,我基本上只需要运行几个命令:

gem install discourse_theme
npm install -g yarn
discourse_theme new <component-name>

然后编辑文件:javascripts/discourse/api-initializers/.js
将其上传到 GitHub,然后您就可以安装/共享了。
我的在这里:https://github.com/ihatepasswords-xyz/discourse_focus_editor_component
它似乎有一个功能,您可以在修改文件时自动更新服务器上的版本。听起来不错,而且很有用,因为我将深入研究更复杂的组件。

干杯

1 个赞

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.