# decorateCooked 主题与 HighlightJS 对比

**URL:** https://meta.discourse.org/t/decoratecooked-in-theme-vs-highlighjs/126208
**Category:** Support
**Created:** [2019年八月19日 18:21 UTC](https://meta.discourse.org/t/decoratecooked-in-theme-vs-highlighjs/126208 "2019-08-19T18:21:14Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![alldritt](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/alldritt/32/119516_2.png) [@alldritt](https://meta.discourse.org/u/alldritt)
#### Post date: [2019年八月19日 18:21 UTC](https://meta.discourse.org/t/decoratecooked-in-theme-vs-highlighjs/126208/1 "2019-08-19T18:21:14Z")

</div>

我在网站主题中使用 `decorateCooked` 对 HighlightJS 代码块进行特定语言的后期处理。当使用 ``` 标记代码时，它能正常工作；但当使用缩进方式包含代码时，它会失败。

在成功的情况下，HighlightJS 的类在我调用 `decorateCooked` 代码之前就已经存在，我可以使用 jQuery 找到带有目标语言类（‘applescript’）的代码块。而在失败的情况下，似乎 HighlightJS 是在我的插件代码运行之后才应用其功能的，因为 HighlightJS 的类（`hljs applescript`）缺失。不过，当我稍后检查已加载的页面时，这些类又出现了。

以下是我的代码，它定义在主题的 `</HEAD>` 部分：

```plaintext
<script type="text/discourse-plugin" version="0.1">
    if (navigator.appVersion.indexOf('Mac') >= 0) { // 仅在 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; // 不要在编辑器预览中执行此操作
            	}).each(function(index) {
   		            var src = encodeURIComponent(this.innerText);

        		    $( '<a class="widget-button btn btn-default" href="sdapplescript://com.apple.scripteditor?action=new&script=' + src + '">在 Script Debugger 中打开</a>' ).insertAfter($(this).parent());
        	    });
            },
            { id: 'applescript-decorator' }
        );
    }
</script>

```

查看控制台日志，我发现我找到了帖子中的 `<code>` 块，但 `class` 属性被报告为 `undefined`。

有没有办法让我的 `decorateCooked` 代码在 HighlightJS 完成其工作之后运行？

---

<div class="post-metadata">

### Author: ![alldritt](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/alldritt/32/119516_2.png) [@alldritt](https://meta.discourse.org/u/alldritt)
#### Post date: [2019年八月19日 19:14 UTC](https://meta.discourse.org/t/decoratecooked-in-theme-vs-highlighjs/126208/2 "2019-08-19T19:14:23Z")

</div>

我找到了一个使用 `MutationObserver` 的变通方案来解决这个问题，但我不确定这是否是最佳方法：

````plaintext
<script type="text/discourse-plugin" version="0.1">
    if (navigator.appVersion.indexOf('Mac') >= 0) { // 仅在 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 + '">在 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; // 不要在编辑器预览中执行此操作
                }).each(function(index) {
                    var src = encodeURIComponent(this.innerText);

                    $('<a class="widget-button btn btn-default" href="sdapplescript://com.apple.scripteditor?action=new&script=' + src + '">在 Script Debugger 中打开</a>').insertAfter($(this).parent());
                });
                
                // 处理 HighlightJS 在 decorateCooked 调用之后才应用的情况。这通常发生在
                // 通过缩进而非 ``` 引入的代码块中。
                $elem.find('code:not(.applescript,.lang-applescript)').filter(function () {
                    return $(this).parents('.d-editor-preview').length < 1; // 不要在编辑器预览中执行此操作
                }).each(function () {
                    myObserver.observe(this, obsConfig);
                });
            },
            { id: 'applescript-decorator', onlyStream: true }
        );
    }
</script>

````

---

<div class="post-metadata">

### Author: ![Falco](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/falco/32/179432_2.png) [@Falco](https://meta.discourse.org/u/Falco)
#### Post date: [2022年九月27日 16:26 UTC](https://meta.discourse.org/t/decoratecooked-in-theme-vs-highlighjs/126208/3 "2022-09-27T16:26:11Z")

</div>

> [@alldritt](#):
>
> 有没有办法让我的 `decorateCooked` 代码在 HighlightJS 完成后运行？

我遇到了同样的挑战，所以我添加了一个新的 API 功能来处理这种情况：`api.registerHighlightJSPlugin`。

您可以将基于函数的 highlightjs 插件传递给它，相关文档位于 [Plugin API — highlight.js 11.9.0 documentation](https://highlightjs.readthedocs.io/en/latest/plugin-api.html#function-based-plugins)

---

<div class="post-metadata">

### Author: ![system](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/system/32/443519_2.png) [@system](https://meta.discourse.org/u/system)
#### Post date: [2022年十月27日 16:26 UTC](https://meta.discourse.org/t/decoratecooked-in-theme-vs-highlighjs/126208/4 "2022-10-27T16:26:41Z")

</div>

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
