From e227ca163673eba9555c9ac71482f4a03fb89870 Mon Sep 17 00:00:00 2001 From: Steven Walker Date: Thu, 19 Feb 2026 07:47:12 +1100 Subject: [PATCH] [#132] Added Highlight.js syntax highlighter. --- composer.json | 1 + composer.lock | 54 ++++++++++++++++++- config/default/core.extension.yml | 1 + .../editor.editor.civictheme_rich_text.yml | 3 ++ .../filter.format.civictheme_rich_text.yml | 9 +++- config/default/highlight_js.settings.yml | 12 +++++ config/default/seckit.settings.yml | 2 +- tests/behat/features/seckit.feature | 2 +- .../custom/do_base/do_base.libraries.yml | 5 ++ .../do_base/src/Hook/LibraryInfoAlterHook.php | 27 ++++++++++ 10 files changed, 112 insertions(+), 4 deletions(-) create mode 100644 config/default/highlight_js.settings.yml create mode 100644 web/modules/custom/do_base/do_base.libraries.yml create mode 100644 web/modules/custom/do_base/src/Hook/LibraryInfoAlterHook.php diff --git a/composer.json b/composer.json index c55d925d..b00b4d0e 100644 --- a/composer.json +++ b/composer.json @@ -28,6 +28,7 @@ "drupal/gin": "^4.0.6", "drupal/gin_toolbar": "^2", "drupal/google_tag": "^2.0.9", + "drupal/highlight_js": "^1.2", "drupal/lagoon_logs": "^3.0.1", "drupal/metatag": "^2.2", "drupal/pathauto": "^1.14", diff --git a/composer.lock b/composer.lock index 3abe2fad..7a6d0d27 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "ce081e63b3639ce500037147a974b7aa", + "content-hash": "568d8e68ffbeedad71d925da755e5339", "packages": [ { "name": "asm89/stack-cors", @@ -3705,6 +3705,58 @@ "source": "https://git.drupalcode.org/project/google_tag" } }, + { + "name": "drupal/highlight_js", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://git.drupalcode.org/project/highlight_js.git", + "reference": "1.2.0" + }, + "dist": { + "type": "zip", + "url": "https://ftp.drupal.org/files/projects/highlight_js-1.2.0.zip", + "reference": "1.2.0", + "shasum": "ae389f3a03ee09d4dcb83cd3d731e6910bfe1a5c" + }, + "require": { + "drupal/core": "^9 || ^10 || ^11" + }, + "type": "drupal-module", + "extra": { + "drupal": { + "version": "1.2.0", + "datestamp": "1763546332", + "security-coverage": { + "status": "covered", + "message": "Covered by Drupal's security advisory policy" + } + } + }, + "notification-url": "https://packages.drupal.org/8/downloads", + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "a.dmitriiev", + "homepage": "https://www.drupal.org/user/3235287" + }, + { + "name": "norman.lol", + "homepage": "https://www.drupal.org/user/2482808" + }, + { + "name": "sujan shrestha", + "homepage": "https://www.drupal.org/user/3475737" + } + ], + "description": "Adds the HighlightJs plugin to CKEditor 5 with syntax highlighting provided by HighlightJs.", + "homepage": "https://www.drupal.org/project/highlight_js", + "support": { + "source": "https://git.drupalcode.org/project/highlight_js" + } + }, { "name": "drupal/key", "version": "1.22.0", diff --git a/config/default/core.extension.yml b/config/default/core.extension.yml index 8e58d412..ed0b2b45 100644 --- a/config/default/core.extension.yml +++ b/config/default/core.extension.yml @@ -47,6 +47,7 @@ module: gin_toolbar: 0 google_tag: 0 help: 0 + highlight_js: 0 history: 0 image: 0 image_captcha: 0 diff --git a/config/default/editor.editor.civictheme_rich_text.yml b/config/default/editor.editor.civictheme_rich_text.yml index c919942b..434361a5 100644 --- a/config/default/editor.editor.civictheme_rich_text.yml +++ b/config/default/editor.editor.civictheme_rich_text.yml @@ -6,6 +6,7 @@ dependencies: - filter.format.civictheme_rich_text module: - ckeditor5 + - highlight_js _core: default_config_hash: SztHd9Hrw3-1EuKex-O6V-Kc5EpxLGsSam2HEDXSgDM format: civictheme_rich_text @@ -40,6 +41,8 @@ settings: - subscript - '|' - sourceEditing + - '|' + - highlightJs plugins: ckeditor5_alignment: enabled_alignments: diff --git a/config/default/filter.format.civictheme_rich_text.yml b/config/default/filter.format.civictheme_rich_text.yml index 1c920ed0..625d36e5 100644 --- a/config/default/filter.format.civictheme_rich_text.yml +++ b/config/default/filter.format.civictheme_rich_text.yml @@ -6,6 +6,7 @@ dependencies: - core.entity_view_mode.media.embedded module: - editor + - highlight_js - linkit - media _core: @@ -44,7 +45,7 @@ filters: status: true weight: -50 settings: - allowed_html: '

    
' + allowed_html: '

    
' filter_html_help: true filter_html_nofollow: false filter_html_escape: @@ -72,6 +73,12 @@ filters: weight: -44 settings: filter_url_length: 72 + highlight_js: + id: highlight_js + provider: highlight_js + status: true + weight: -40 + settings: { } linkit: id: linkit provider: linkit diff --git a/config/default/highlight_js.settings.yml b/config/default/highlight_js.settings.yml new file mode 100644 index 00000000..89342203 --- /dev/null +++ b/config/default/highlight_js.settings.yml @@ -0,0 +1,12 @@ +copy_enable: true +copy_bg_transparent: false +copy_bg_color: '#4243b1' +copy_txt_color: '#ffffff' +copy_btn_text: '' +copy_success_text: '' +success_txt_color: '#ffffff' +role_copy_access: { } +languages: { } +theme: github +success_bg_transparent: false +success_bg_color: '#4243b1' diff --git a/config/default/seckit.settings.yml b/config/default/seckit.settings.yml index 5c8db19a..029bdb3b 100644 --- a/config/default/seckit.settings.yml +++ b/config/default/seckit.settings.yml @@ -8,7 +8,7 @@ seckit_xss: default-src: "'self'" script-src: "'self' https://www.googletagmanager.com https://www.gstatic.com https://www.recaptcha.net https://www.google.com https://cdnjs.cloudflare.com https://cdn.jsdelivr.net/gh/cferdinandi/tabby@12.0.3/dist/js/tabby.min.js https://unpkg.com/@popperjs/core@2.11.6/dist/umd/popper.js https://unpkg.com/tippy.js@6.3.7/dist/tippy.umd.js" object-src: "'none'" - style-src: "'self' 'unsafe-inline' https://fonts.googleapis.com/ https://cdn.jsdelivr.net/gh/cferdinandi/tabby@12.0.3/dist/css/tabby-ui.min.css https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.12/codemirror.css https://unpkg.com/tippy.js@6.3.7/dist/tippy.css https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/css/select2.min.css" + style-src: "'self' https://cdnjs.cloudflare.com/ajax/libs/highlight.js/ 'unsafe-inline' https://fonts.googleapis.com/ https://cdn.jsdelivr.net/gh/cferdinandi/tabby@12.0.3/dist/css/tabby-ui.min.css https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.12/codemirror.css https://unpkg.com/tippy.js@6.3.7/dist/tippy.css https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/css/select2.min.css" img-src: "'self' data:" media-src: "'self'" frame-src: "'self' https://www.youtube.com https://www.recaptcha.net https://www.google.com" diff --git a/tests/behat/features/seckit.feature b/tests/behat/features/seckit.feature index 5108a8e0..5094c44e 100644 --- a/tests/behat/features/seckit.feature +++ b/tests/behat/features/seckit.feature @@ -17,7 +17,7 @@ Feature: Seckit And the response header "Content-Security-Policy" should contain the value "media-src 'self'" And the response header "Content-Security-Policy" should contain the value "report-uri /report-csp-violation" And the response header "Content-Security-Policy" should contain the value "script-src 'self' https://www.googletagmanager.com https://www.gstatic.com https://www.recaptcha.net https://www.google.com https://cdnjs.cloudflare.com https://cdn.jsdelivr.net/gh/cferdinandi/tabby@12.0.3/dist/js/tabby.min.js https://unpkg.com/@popperjs/core@2.11.6/dist/umd/popper.js https://unpkg.com/tippy.js@6.3.7/dist/tippy.umd.js;" - And the response header "Content-Security-Policy" should contain the value "style-src 'self' 'unsafe-inline' https://fonts.googleapis.com/ https://cdn.jsdelivr.net/gh/cferdinandi/tabby@12.0.3/dist/css/tabby-ui.min.css https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.12/codemirror.css https://unpkg.com/tippy.js@6.3.7/dist/tippy.css https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/css/select2.min.css;" + And the response header "Content-Security-Policy" should contain the value "style-src 'self' https://cdnjs.cloudflare.com/ajax/libs/highlight.js/ 'unsafe-inline' https://fonts.googleapis.com/ https://cdn.jsdelivr.net/gh/cferdinandi/tabby@12.0.3/dist/css/tabby-ui.min.css https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.12/codemirror.css https://unpkg.com/tippy.js@6.3.7/dist/tippy.css https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/css/select2.min.css;" And the response header "Strict-Transport-Security" should contain the value "max-age=31536000" And the response header "Strict-Transport-Security" should contain the value "includeSubDomains" And the response header "Strict-Transport-Security" should contain the value "preload" diff --git a/web/modules/custom/do_base/do_base.libraries.yml b/web/modules/custom/do_base/do_base.libraries.yml new file mode 100644 index 00000000..8fb82d57 --- /dev/null +++ b/web/modules/custom/do_base/do_base.libraries.yml @@ -0,0 +1,5 @@ +highlight_js.gherkin: + js: + https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/gherkin.min.js: { type: external, minified: true } + dependencies: + - highlight_js/highlight_js.js diff --git a/web/modules/custom/do_base/src/Hook/LibraryInfoAlterHook.php b/web/modules/custom/do_base/src/Hook/LibraryInfoAlterHook.php new file mode 100644 index 00000000..98736981 --- /dev/null +++ b/web/modules/custom/do_base/src/Hook/LibraryInfoAlterHook.php @@ -0,0 +1,27 @@ +