diff --git a/app/assets/javascripts/discourse/app/lib/highlight-syntax.js b/app/assets/javascripts/discourse/app/lib/highlight-syntax.js index 0a37a4d813b..e9f16a45919 100644 --- a/app/assets/javascripts/discourse/app/lib/highlight-syntax.js +++ b/app/assets/javascripts/discourse/app/lib/highlight-syntax.js @@ -3,6 +3,8 @@ import mergeHTMLPlugin from "discourse/lib/highlight-syntax-merge-html-plugin"; /*global hljs:true */ let _moreLanguages = []; +let _plugins = []; +let _initialized = false; export default function highlightSyntax(elem, siteSettings, session) { if (!elem) { @@ -26,11 +28,7 @@ export default function highlightSyntax(elem, siteSettings, session) { } return loadScript(path).then(() => { - customHighlightJSLanguages(); - hljs.addPlugin(mergeHTMLPlugin); - hljs.configure({ - ignoreUnescapedHTML: true, - }); + initializer(); codeblocks.forEach((e) => { // Large code blocks can cause crashes or slowdowns @@ -48,6 +46,10 @@ export function registerHighlightJSLanguage(name, fn) { _moreLanguages.push({ name, fn }); } +export function registerHighlightJSPlugin(plugin) { + _plugins.push(plugin); +} + function customHighlightJSLanguages() { _moreLanguages.forEach((l) => { if (hljs.getLanguage(l.name) === undefined) { @@ -55,3 +57,22 @@ function customHighlightJSLanguages() { } }); } + +function customHighlightJSPlugins() { + _plugins.forEach((p) => { + hljs.addPlugin(p); + }); +} + +function initializer() { + if (!_initialized) { + customHighlightJSLanguages(); + customHighlightJSPlugins(); + hljs.addPlugin(mergeHTMLPlugin); + hljs.configure({ + ignoreUnescapedHTML: true, + }); + + _initialized = true; + } +} diff --git a/app/assets/javascripts/discourse/app/lib/plugin-api.js b/app/assets/javascripts/discourse/app/lib/plugin-api.js index 8a72a19b5ea..7074c83d137 100644 --- a/app/assets/javascripts/discourse/app/lib/plugin-api.js +++ b/app/assets/javascripts/discourse/app/lib/plugin-api.js @@ -79,7 +79,10 @@ import { modifySelectKit } from "select-kit/mixins/plugin-api"; import { on } from "@ember/object/evented"; import { registerCustomAvatarHelper } from "discourse/helpers/user-avatar"; import { registerCustomPostMessageCallback as registerCustomPostMessageCallback1 } from "discourse/controllers/topic"; -import { registerHighlightJSLanguage } from "discourse/lib/highlight-syntax"; +import { + registerHighlightJSLanguage, + registerHighlightJSPlugin, +} from "discourse/lib/highlight-syntax"; import { registerTopicFooterButton } from "discourse/lib/register-topic-footer-button"; import { registerTopicFooterDropdown } from "discourse/lib/register-topic-footer-dropdown"; import { registerDesktopNotificationHandler } from "discourse/lib/desktop-notifications"; @@ -106,7 +109,7 @@ import { registerModelTransformer } from "discourse/lib/model-transformers"; // based on Semantic Versioning 2.0.0. Please update the changelog at // docs/CHANGELOG-JAVASCRIPT-PLUGIN-API.md whenever you change the version // using the format described at https://keepachangelog.com/en/1.0.0/. -const PLUGIN_API_VERSION = "1.3.0"; +const PLUGIN_API_VERSION = "1.4.0"; // This helper prevents us from applying the same `modifyClass` over and over in test mode. function canModify(klass, type, resolverName, changes) { @@ -1372,6 +1375,26 @@ class PluginApi { registerHighlightJSLanguage(name, fn); } + /** + * Registers custom HighlightJS plugins. + * + * See https://highlightjs.readthedocs.io/en/latest/plugin-api.html + * for instructions on how to define a new plugin for HighlightJS. + * This API exposes the Function Based Plugins interface + * + * Example: + * + * let aPlugin = { + 'after:highlightElement': ({ el, result, text }) => { + console.log(el); + } + } + * api.registerHighlightJSPlugin(aPlugin); + **/ + registerHighlightJSPlugin(plugin) { + registerHighlightJSPlugin(plugin); + } + /** * Adds global notices to display. * diff --git a/docs/CHANGELOG-JAVASCRIPT-PLUGIN-API.md b/docs/CHANGELOG-JAVASCRIPT-PLUGIN-API.md index 76c23fb12d9..e4f56275683 100644 --- a/docs/CHANGELOG-JAVASCRIPT-PLUGIN-API.md +++ b/docs/CHANGELOG-JAVASCRIPT-PLUGIN-API.md @@ -7,6 +7,14 @@ in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.4.0] - 2022-09-27 + +### Added + +- Adds `registerHighlightJSPlugin`, which allows users to register custom + HighlightJS plugins. See https://highlightjs.readthedocs.io/en/latest/plugin-api.html + for documentation. + ## [1.3.0] - 2022-05-29 ### Added