Nach viel Kopfzerbrechen und dem Hinzufügen vieler console.log()s zu Discourse habe ich entdeckt, warum es nicht funktionierte und wie es zum Laufen gebracht werden kann.
Das Parsen erfolgt nicht mit dem gerenderten HTML, sondern mit den Markdown-Tokens. Ich hatte state.push(html_raw) in der replace()-Funktion verwendet, um meine [snapblocks] BBCode-Tags zu rendern.
// assets/javascripts/lib/discourse-markdown/snapblocks-discourse.js
export function(helper) {
md.block.bbcode.ruler.push("snapblocks", {
tag: "snapblocks",
replace(state, tagInfo, content) {
let token = state.push('html_raw', '', 0)
token.content = `<pre class="snapblocks-blocks">${content}</pre>`
},
});
}
Das Problem war, dass der Token-Typ html_raw vom Rich-Text-Editor-Konverter ignoriert wird. Das bedeutet, dass Sie dies nicht verwenden können, wenn Sie Unterstützung für den Rich-Text-Editor wünschen.
Ich habe herausgefunden, dass es durch die Verwendung von bbcode_open, text und bbcode_close funktioniert.
// assets/javascripts/lib/discourse-markdown/snapblocks-discourse.js
export function(helper) {
md.block.bbcode.ruler.push("snapblocks", {
tag: "snapblocks",
replace(state, tagInfo, content) {
let token = state.push('bbcode_open', 'pre', 1)
token.attrs = [['class', 'snapblocks-discourse']]
token = state.push('text', '', 0)
token.content = content
token = token.push('bbcode_close', 'pre', -1)
token.attrs = [['class', 'snapblocks-discourse']] // für spätere Prüfungen benötigt
},
});
}
Sobald dies erledigt ist, wird es nicht mehr ignoriert.
Wenn Sie zu rich-text-editor-extension.js wechseln, machen Sie Folgendes.
// assets/javascripts/lib/rich-text-editor-extension.js
import { i18n } from "discourse-i18n";
const SNAPBLOCKS_NODES = ["inline_snapblocks", "snapblocks"];
/** @type {RichEditorExtension} */
const extension = {
snapblocks: {
attrs: { rendered: { default: true } },
code: true,
group: "block",
content: "text*", // Dies ist erforderlich
createGapCursor: true,
parseDOM:[{ tag: "pre.snapblocks-blocks" }],
toDOM: () => ["pre", { class: "snapblocks-blocks" }, 0],
},
},
parse: {
bbcode_open(state, token) {
// Der Token hier ist dasselbe `bbcode_open`-Token-Objekt
// aus dem vorherigen Code
if (token.attrGet('class') === 'snapblocks-blocks') {
state.openNode(state.schema.nodes.snapblocks, {
open: token.attrGet("open") !== null,
});
return true;
}
},
bbcode_close(state, token) {
if (token.attrGet('class') === 'snapblocks-blocks') {
state.closeNode();
return true;
}
},
},
serializeNode: {
snapblocks(state, node) {
// Dies konvertiert es einfach zurück in einfachen Text-Markdown
state.write("[snapblocks]\n");
state.renderContent(node);
state.write("\n[/snapblocks]\n\n");
},
},
}
Die Schlüssel in der parse-Eigenschaft sind Parser für den Token-Typ, der im Markdown-Parser verwendet werden kann.
Es steckt definitiv mehr dahinter, aber zumindest klärt dies die Dinge viel mehr als zuvor.