我尝试向编辑器添加一个小组件,已经进展到可以从工具栏插入代码的阶段,但我不确定如何使其中的 JavaScript 正常运行。我假设需要以插件或主题组件的形式将 JavaScript 内部嵌入,而不是从外部网站调用,但我不确定具体如何实现。这在编辑器中是否可行?
您能更具体地说明您想要实现什么吗?您是想添加一个新的工具栏按钮,向编辑器文本区域添加内容,还是有其他需求?
我试图实现的是让用户在编辑器中插入他们特定的小部件,他们只需输入一个数字,工具栏就会自动将其包裹起来。例如,如果输入 112756,则会自动包裹以下代码:
<div id='PurpleAirWidget_112756_module_AQI_conversion_C0_average_10_layer_detailed'>正在加载 PurpleAir 小部件...</div>
<script src='https://www.purpleair.com/pa.widget.js?key=N6HB6JJ0BP1Z05SE&module=AQI&conversion=C0&average=10&layer=detailed&container=PurpleAirWidget_112756_module_AQI_conversion_C0_average_10_layer_detailed'></script>
效果大概会像这样:
好的,听起来你已经知道如何向编辑器添加内容了?(如果还没有,参考这个示例可能会有所帮助:https://github.com/discourse/discourse-gifs。该主题组件在从工具栏点击按钮时会打开一个模态框,然后根据在模态框中点击的内容将内容插入到编辑器中)。
如果你正尝试让脚本加载并对帖子内容执行某些操作,我认为这篇帖子可能会为你指明正确的方向……使用 loadScript 和 decorateCooked:Difficulties in correctly adding external JavaScript - #4 by StevenTammen
您可能可以以某种方式使用此内容(无论是直接使用还是分叉定制):Mentionables composer 按钮。
感谢您指明方向,我似乎遇到了另一个问题,打开使用该脚本的主题页面时,它没有加载/渲染。只有在我刷新页面后,它才能正常加载,但并非每次都如此。这是因为 Discourse 是一个单页应用程序吗?我只是想弄清楚是我对 Discourse 的了解不足,还是我需要自己编程某些东西。
这是我目前使用的代码。任何指导都将不胜感激
let loadScript = require('discourse/lib/load-script').default;
api.decorateCooked($elem => { $elem.children('div[data-PAWidget]').ready(function() {
$elem.children('div[data-PAWidget]').append(" <div id='PurpleAirWidget_11726_module_AQI_conversion_C0_average_0_layer_standard'>Loading PurpleAir Widget...</div>");
loadScript("https://www.purpleair.com/pa.widget.js?key=21R72LUN79CXRZ50&module=AQI&conversion=C0&average=0&layer=standard&container=PurpleAirWidget_11726_module_AQI_conversion_C0_average_0_layer_standard").then(()=>{
})
})
});
我尝试了一下,结果与您类似。我尝试使用 decorateCookedElement,因为我们最终将弃用 decorateCooked。
api.decorateCookedElement(
(element) => {
element.childNodes.forEach((node) => {
if (node.dataset && node.dataset.pawidget) {
node.insertAdjacentHTML(
"beforeend",
"<div id='PurpleAirWidget_11726_module_AQI_conversion_C0_average_0_layer_standard'>Loading PurpleAir Widget...</div>"
);
loadScript(
`https://www.purpleair.com/pa.widget.js?key=${node.dataset.pawidget}&module=AQI&conversion=C0&average=0&layer=standard&container=PurpleAirWidget_11726_module_AQI_conversion_C0_average_0_layer_standard`
);
}
});
},
{ id: "widget-append", onlyStream: true, afterAdopt: true }
);
这里的一个细微差别是我将密钥与数据属性一起传递:
<div data-PAWidget="21R72LUN79CXRZ50"></div>
这对我来说效果很好,如果这是脚本第一次加载。如果我查看一个带有脚本的帖子,然后返回到主题列表并重新进入该主题,它就无效了(直到我刷新)。我可以看到 decorateCookedElement 在每次加载相关帖子时都会触发,但有些东西阻止了脚本再次运行。
我不确定这是否相关,但我也在控制台中看到了来自 pa.widget.js 的 Uncaught TypeError: i is null 错误:


