Estou desenvolvendo uma extensão para o Discourse para exibir snapblocks. Consegui adicionar tags bbcode que são substituídas pelos blocos, infelizmente, se você optar por citar os blocos, você obtém o texto no bloco em um bloco de código em vez da tag bbcode original.
Tentei procurar no código-fonte do plugin de spoiler, mas não consigo descobrir o que ele está fazendo para permitir a citação de spoilers.
Existe uma maneira de corrigir isso e adicionar o texto original do código do bloco dentro das tags bbcode personalizadas?
Aqui está o código-fonte do meu plugin que estou desenvolvendo.
Algo que realmente me incomoda é que não há documentação padrão que seja fácil de consultar, o que tornou o desenvolvimento do meu plugin muito mais difícil.
Testei isso e, de fato, permitiu-me adicionar [sb] ao redor do texto, infelizmente foi apenas o texto que está no elemento. Eu gostaria que ele citasse o texto original em vez disso, pois ele contém tudo para recriar o bloco.
Atualmente, estou tentando ver se consigo fazer com que o SVG real não seja selecionável e apenas tenha um elemento selecionável oculto com a fonte original por baixo do SVG.
Estou conseguindo isso criando um contêiner que contém 2 elementos, o SVG e a fonte. Estou tentando fazer com que o SVG tenha position: relative para que ele possa sair do fluxo e ficar sobre o texto da fonte, além de ter o contêiner do mesmo tamanho que o SVG para fazer parecer que o SVG ainda está dentro do texto. Além disso, o texto da fonte teria opacity: 0 e um tamanho muito pequeno para que fique invisível caso transborde o SVG.
Estou me perguntando se há uma maneira mais fácil de fazer isso, porque a maneira como estou tentando fazer exigiria refazer todas as postagens e também parece uma solução improvisada para algo que sinto que não deveria exigir isso.
Editar: depois de olhar o código da função addTagDecorateCallback(), parece que posso retornar texto no callback para substituir qualquer texto que ele teria usado. Isso realmente ajudará muito mais, pois espero não ter que lidar com meu sistema improvisado no qual estava trabalhando e que funciona terrivelmente.
Consegui fazer funcionar mantendo o texto original em um atributo no HTML e, na função de callback addTagDecorateCallback(), apenas o retorno para obter o texto original.
Aqui está um trecho de código para quem quiser saber o que fiz.
Em assets/javascripts/lib/discourse-markdown/snapblocks-discourse.js, onde ele inicializa as tags bbcode, fiz com que ele armazene o texto original dentro de um atributo snapblocks-source para que eu possa recuperá-lo mais tarde.
No arquivo assets\\javascripts\\discourse\\initializers\\snapblocks-discourse.js, adiciono o código para lidar com as citações.
// 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 não é um elemento HTML
// mas inclui todos os atributos HTML
const { attributes } = this.element;
// Normalmente você verificaria se a "classe" é a sua classe
// mas tudo que preciso aqui é "snapblocks-source"
if (attributes["snapblocks-source"]) {
let prefix = "[sb";
// Adicionando atributos à tag bbcode (que também são armazenados
// no elemento como atributos).
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]";
// se você retornar texto, ele será usado em vez do texto selecionado
return attributes["snapblocks-source"];
}
});
}
Isso é o mesmo para as tags bbcode de bloco, você só precisa usar addBlockDecorateCallback() em vez disso.
Agora, infelizmente, terei que refazer as postagens se quiser que trechos antigos de snapblocks sejam citáveis. Isso também não lida com a seleção de texto no SVG, funciona apenas se você selecionar algum texto antes e/ou depois, bem como pelo menos parte do texto do SVG.