I am developing a discourse extension to display snapblocks. I was able to add bbcode tags that get replaced with the blocks, unfortunately if you select to quote the blocks, you get the text in the block in a code block instead of the original bbcode tag.
I have tried looking through the source code for the spoiler plugin, but I can’t figure out what it’s doing to allow quoting spoilers.
Is there a way to fix this and add the original block code text inside the custom bbcode tags?
Here’s the source code for my plugin I’m developing.
Something that really annoys me, is that there is no standard documentation that is easy to go through, which has made developing my plugin a lot harder.
I tested that out, and it did indeed allow me to add [sb] around the text, unfortunately it was just the text that is on the element. I would like it to quote the original text instead, as that contains everything to recreate block.
I’m currently trying to see if I can have the actual svg not be selectable, and just have a hidden selectable element with the original source underneath the svg.
I’m achieving this by creating a container that contains 2 elements, the svg, and the source. I’m trying to have the svg have position: relative so it can be out of the flow and on top of the source text, as well as having the container the same size as the svg to make it look like the svg is still inside the text. Also, the source text would have opacity: 0 and be a very small size so that it’s invisible in case it may overflow the svg.
I’m wondering if there’s an easier way to do this, because the way I’m trying to do it would require rebaking all the posts, and it also feels like a hacky solution to something I feel shouldn’t require doing this.
Edit: after looking at the code for the addTagDecorateCallback() function, it looks like I can return text in the callback to replace whatever text it would’ve used. That’s actually going to help so much more, since I hopefully won’t have to deal with my hacky system that I was working on that works terribly.
I was able to get it working by keeping the source text in an attribute on the html, and then in the addTagDecorateCallback() callback function, I just return that in order to get the original text.
Here’s a bit of code for anyone wanting to know what I did.
In assets/javascripts/lib/discourse-markdown/snapblocks-discourse.js where it initializes the bbcode tags, I made it store the original text inside a snapblocks-source attribute so I can grab it later.
In the assets\javascripts\discourse\initializers\snapblocks-discourse.js file, I add the code to handle the quoting.
// assets\javascripts\discourse\initializers\snapblocks-discourse.js
import {
addBlockDecorateCallback, // block bbcode tags
addTagDecorateCallback, // inline bbcode tags
} from "discourse/lib/to-markdown";
function initializeSnapblocks(api, siteSettings) {
addTagDecorateCallback(function () {
// this.element is not an HTML element
// but it does include all the html attributes
const { attributes } = this.element;
// Normally you would check if the "class" is your class
// but all I need here is "snapblocks-source"
if (attributes["snapblocks-source"]) {
let prefix = "[sb";
// Adding attributes to the bbcode tag (which are also stored
// on the element as attributes).
const attrs = [
"blockstyle",
"wrap",
"wrapsize",
"zebra",
"showspaces",
"santa",
];
for (const attr of attrs) {
if (attributes[attr]) {
prefix += ` ${attr}=${attributes[attr]}`;
}
}
prefix += "]";
this.prefix = prefix;
this.suffix = "[/sb]";
// if you return text, this will be used instead of the selected text
return attributes["snapblocks-source"];
}
});
}
This is the same for the block bbcode tags, you just have to use addBlockDecorateCallback() instead.
Now unfortunately I will have to rebake posts if I want old snapblocks snippets to be quotable. This also doesn’t handle if you select the text on the svg, it only works if you select some text before and/or after as well as at least part of the svg text.