FEATURE: JS API interface for hljs plugins (#18382)

* FEATURE: JS API interface for hljs plugins

Co-authored-by: Penar Musaraj <pmusaraj@gmail.com>
This commit is contained in:
Rafael dos Santos Silva 2022-09-27 13:26:52 -03:00 committed by GitHub
parent 217274f2c1
commit 0f5db0838d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 59 additions and 7 deletions

View File

@ -3,6 +3,8 @@ import mergeHTMLPlugin from "discourse/lib/highlight-syntax-merge-html-plugin";
/*global hljs:true */ /*global hljs:true */
let _moreLanguages = []; let _moreLanguages = [];
let _plugins = [];
let _initialized = false;
export default function highlightSyntax(elem, siteSettings, session) { export default function highlightSyntax(elem, siteSettings, session) {
if (!elem) { if (!elem) {
@ -26,11 +28,7 @@ export default function highlightSyntax(elem, siteSettings, session) {
} }
return loadScript(path).then(() => { return loadScript(path).then(() => {
customHighlightJSLanguages(); initializer();
hljs.addPlugin(mergeHTMLPlugin);
hljs.configure({
ignoreUnescapedHTML: true,
});
codeblocks.forEach((e) => { codeblocks.forEach((e) => {
// Large code blocks can cause crashes or slowdowns // Large code blocks can cause crashes or slowdowns
@ -48,6 +46,10 @@ export function registerHighlightJSLanguage(name, fn) {
_moreLanguages.push({ name, fn }); _moreLanguages.push({ name, fn });
} }
export function registerHighlightJSPlugin(plugin) {
_plugins.push(plugin);
}
function customHighlightJSLanguages() { function customHighlightJSLanguages() {
_moreLanguages.forEach((l) => { _moreLanguages.forEach((l) => {
if (hljs.getLanguage(l.name) === undefined) { 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;
}
}

View File

@ -79,7 +79,10 @@ import { modifySelectKit } from "select-kit/mixins/plugin-api";
import { on } from "@ember/object/evented"; import { on } from "@ember/object/evented";
import { registerCustomAvatarHelper } from "discourse/helpers/user-avatar"; import { registerCustomAvatarHelper } from "discourse/helpers/user-avatar";
import { registerCustomPostMessageCallback as registerCustomPostMessageCallback1 } from "discourse/controllers/topic"; 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 { registerTopicFooterButton } from "discourse/lib/register-topic-footer-button";
import { registerTopicFooterDropdown } from "discourse/lib/register-topic-footer-dropdown"; import { registerTopicFooterDropdown } from "discourse/lib/register-topic-footer-dropdown";
import { registerDesktopNotificationHandler } from "discourse/lib/desktop-notifications"; 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 // based on Semantic Versioning 2.0.0. Please update the changelog at
// docs/CHANGELOG-JAVASCRIPT-PLUGIN-API.md whenever you change the version // docs/CHANGELOG-JAVASCRIPT-PLUGIN-API.md whenever you change the version
// using the format described at https://keepachangelog.com/en/1.0.0/. // 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. // This helper prevents us from applying the same `modifyClass` over and over in test mode.
function canModify(klass, type, resolverName, changes) { function canModify(klass, type, resolverName, changes) {
@ -1372,6 +1375,26 @@ class PluginApi {
registerHighlightJSLanguage(name, fn); 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. * Adds global notices to display.
* *

View File

@ -7,6 +7,14 @@ in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 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). 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 ## [1.3.0] - 2022-05-29
### Added ### Added