Estoy usando decorateCooked en el tema de mi sitio para procesar posteriormente los bloques de código de HighlightJS para un lenguaje en particular. Funciona cuando se usan ``` para indicar código en una publicación, pero falla cuando se usa la indentación para incluir código.
En el caso exitoso, las clases de HighlightJS están presentes antes de que se ejecute mi código decorateCooked, y puedo usar JQuery para encontrar bloques de código que tengan mi clase de lenguaje (‘applescript’). En el caso fallido, parece que HighlightJS aplica su magia después de que se ejecuta mi código del plugin, ya que las clases de HighlightJS (hljs applescript) no están presentes. Sin embargo, estas clases sí aparecen cuando inspecciono más tarde la página cargada.
Aquí está mi código, definido en la parte </HEAD> de mi tema:
<script type="text/discourse-plugin" version="0.1">
if (navigator.appVersion.indexOf('Mac') >= 0) { // Solo hacer esto en Mac
api.decorateCooked(
$elem => {
console.log($elem.find('code'));
console.log($elem.find('code').attr('class'));
$elem.find('.lang-applescript, .applescript').filter(function () {
return $(this).parents('.d-editor-preview').length < 1; // No hacer esto en las vistas previas del editor
}).each(function(index) {
var src = encodeURIComponent(this.innerText);
$( '<a class="widget-button btn btn-default" href="sdapplescript://com.apple.scripteditor?action=new&script=' + src + '">Open in Script Debugger</a>' ).insertAfter($(this).parent());
});
},
{ id: 'applescript-decorator' }
);
}
</script>
Al revisar el registro de la consola, veo que estoy encontrando los bloques <code> en mis publicaciones, pero el atributo class se reporta como undefined.
¿Existe alguna forma de hacer que mi código decorateCooked se ejecute después de que HighlightJS haya hecho su trabajo?
He encontrado una solución alternativa para este problema utilizando MutationObserver, pero no estoy seguro de que sea el mejor enfoque:
<script type="text/discourse-plugin" version="0.1">
if (navigator.appVersion.indexOf('Mac') >= 0) { // Solo hacer esto en Mac
if (typeof myObserver == 'undefined') {
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
var myObserver = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
var target = $(mutation.target);
if (target.hasClass('applescript')) {
var src = encodeURIComponent(mutation.target.innerText);
$('<a class="widget-button btn btn-default" href="sdapplescript://com.apple.scripteditor?action=new&script=' + src + '">Open in Script Debugger</a>').insertAfter(target.parent());
}
});
});
var obsConfig = { childList: false, characterData: false, attributes: true, subtree: false };
}
api.decorateCooked(
$elem => {
$elem.find('.lang-applescript, .applescript').filter(function () {
return $(this).parents('.d-editor-preview').length < 1; // No hacer esto en las vistas previas del editor
}).each(function(index) {
var src = encodeURIComponent(this.innerText);
$('<a class="widget-button btn btn-default" href="sdapplescript://com.apple.scripteditor?action=new&script=' + src + '">Open in Script Debugger</a>').insertAfter($(this).parent());
});
// Manejar el caso en que HighlightJS se aplica *después* de que se llama a decorateCooked. Esto ocurre para
// bloques de código introducidos mediante sangría en lugar de ```.
$elem.find('code:not(.applescript,.lang-applescript)').filter(function () {
return $(this).parents('.d-editor-preview').length < 1; // No hacer esto en las vistas previas del editor
}).each(function () {
myObserver.observe(this, obsConfig);
});
},
{ id: 'applescript-decorator', onlyStream: true }
);
}
</script>