From 51ad90431bd6ff3d73dcbc2e7b9cdaa750902d59 Mon Sep 17 00:00:00 2001 From: "Peter Droogmans (attiks)" Date: Wed, 27 Nov 2024 12:41:37 +0100 Subject: [PATCH 1/3] feat: Add links to H2 tags Refs: #UNO-865 --- config/filter.format.ckeditor.yml | 65 +++++++++++++-- config/filter.format.text_editor_simple.yml | 10 ++- config/user.role.editor.yml | 1 + .../components/h2-id-link/h2-id-link.css | 12 +++ .../components/h2-id-link/h2-id-link.js | 0 .../src/Plugin/Filter/H2IdFilter.php | 83 +++++++++++++++++++ .../unocha_utility.libraries.yml | 6 ++ 7 files changed, 170 insertions(+), 7 deletions(-) create mode 100644 html/modules/custom/unocha_utility/components/h2-id-link/h2-id-link.css create mode 100644 html/modules/custom/unocha_utility/components/h2-id-link/h2-id-link.js create mode 100644 html/modules/custom/unocha_utility/src/Plugin/Filter/H2IdFilter.php create mode 100644 html/modules/custom/unocha_utility/unocha_utility.libraries.yml diff --git a/config/filter.format.ckeditor.yml b/config/filter.format.ckeditor.yml index c6b9ee7f..34c7170a 100644 --- a/config/filter.format.ckeditor.yml +++ b/config/filter.format.ckeditor.yml @@ -3,50 +3,103 @@ langcode: en status: true dependencies: module: + - editor - linkit + - media - unocha_utility name: CKEditor format: ckeditor weight: 0 filters: + editor_file_reference: + id: editor_file_reference + provider: editor + status: false + weight: -42 + settings: { } + filter_align: + id: filter_align + provider: filter + status: false + weight: -41 + settings: { } filter_autop: id: filter_autop provider: filter status: true - weight: 0 + weight: -49 + settings: { } + filter_caption: + id: filter_caption + provider: filter + status: false + weight: -40 settings: { } filter_html: id: filter_html provider: filter status: true - weight: -10 + weight: -50 settings: allowed_html: '

    1. ' filter_html_help: true filter_html_nofollow: false + filter_html_escape: + id: filter_html_escape + provider: filter + status: false + weight: -43 + settings: { } + filter_html_image_secure: + id: filter_html_image_secure + provider: filter + status: false + weight: -39 + settings: { } filter_htmlcorrector: id: filter_htmlcorrector provider: filter status: true - weight: 10 + weight: -45 + settings: { } + filter_image_lazy_load: + id: filter_image_lazy_load + provider: filter + status: false + weight: -38 settings: { } filter_url: id: filter_url provider: filter status: true - weight: 0 + weight: -48 settings: filter_url_length: 72 linkit: id: linkit provider: linkit status: true - weight: 0 + weight: -47 settings: title: true + media_embed: + id: media_embed + provider: media + status: false + weight: -37 + settings: + default_view_mode: default + allowed_view_modes: { } + allowed_media_types: { } unocha_external_link_filter: id: unocha_external_link_filter provider: unocha_utility status: true - weight: 0 + weight: -46 + settings: { } + unocha_h2_id_filter: + id: unocha_h2_id_filter + provider: unocha_utility + status: true + weight: -44 settings: { } diff --git a/config/filter.format.text_editor_simple.yml b/config/filter.format.text_editor_simple.yml index 22c25193..4e8400b9 100644 --- a/config/filter.format.text_editor_simple.yml +++ b/config/filter.format.text_editor_simple.yml @@ -1,7 +1,9 @@ uuid: 6ac6625f-9f29-4bbf-9fa2-e8176a27c2a8 langcode: en status: true -dependencies: { } +dependencies: + module: + - unocha_utility name: 'Text Editor - Simple' format: text_editor_simple weight: 0 @@ -13,3 +15,9 @@ filters: weight: 0 settings: filter_url_length: 72 + unocha_h2_id_filter: + id: unocha_h2_id_filter + provider: unocha_utility + status: true + weight: 0 + settings: { } diff --git a/config/user.role.editor.yml b/config/user.role.editor.yml index e288ba21..4b035de1 100644 --- a/config/user.role.editor.yml +++ b/config/user.role.editor.yml @@ -3,6 +3,7 @@ langcode: en status: true dependencies: config: + - entity_browser.browser.stories - filter.format.ckeditor - filter.format.text_editor_simple - media.type.image diff --git a/html/modules/custom/unocha_utility/components/h2-id-link/h2-id-link.css b/html/modules/custom/unocha_utility/components/h2-id-link/h2-id-link.css new file mode 100644 index 00000000..feb1d401 --- /dev/null +++ b/html/modules/custom/unocha_utility/components/h2-id-link/h2-id-link.css @@ -0,0 +1,12 @@ +h2[data-ocha-h2-link] a[data-ocha-h2-link-tag] { + float: left; + margin-left: -24px; + padding-right: 5px; + text-decoration: none; + outline: none; + visibility: hidden; +} + +h2[data-ocha-h2-link]:hover > a[data-ocha-h2-link-tag] { + visibility: visible; +} diff --git a/html/modules/custom/unocha_utility/components/h2-id-link/h2-id-link.js b/html/modules/custom/unocha_utility/components/h2-id-link/h2-id-link.js new file mode 100644 index 00000000..e69de29b diff --git a/html/modules/custom/unocha_utility/src/Plugin/Filter/H2IdFilter.php b/html/modules/custom/unocha_utility/src/Plugin/Filter/H2IdFilter.php new file mode 100644 index 00000000..2a65dfb5 --- /dev/null +++ b/html/modules/custom/unocha_utility/src/Plugin/Filter/H2IdFilter.php @@ -0,0 +1,83 @@ +'; + $prefix = '' . $meta . ''; + $suffix = ''; + $dom = new \DOMDocument(); + $dom->loadHTML($prefix . $text . $suffix, $flags); + + // Process the links. + $h2s = $dom->getElementsByTagName('h2'); + foreach ($h2s as $h2) { + $lib_needed = TRUE; + + /** @var \DOMElement $h2 */ + $id = $h2->getAttribute('id'); + if (empty($id)) { + $id = Html::cleanCssIdentifier(strtolower($h2->textContent)); + $h2->setAttribute('id', $id); + } + + $h2->setAttribute('data-ocha-h2-link', $id); + $a = $dom->createElement('a', '#'); + $a->setAttribute('data-ocha-h2-link-tag', $id); + $a->setAttribute('href', '#' . $id); + $h2->prepend($a); + } + + // Get the modified html. + $html = $dom->saveHTML(); + + // Search for the body tag and return its content. + $start = mb_strpos($html, ''); + $end = mb_strrpos($html, ''); + if ($start !== FALSE && $end !== FALSE) { + $start += 6; + $text = trim(mb_substr($html, $start, $end - $start)); + } + } + } + + $result = new FilterProcessResult($text); + if ($lib_needed) { + $result->setAttachments([ + 'library' => [ + 'unocha_utility/h2-id-link', + ], + ]); + } + + return $result; + } + +} diff --git a/html/modules/custom/unocha_utility/unocha_utility.libraries.yml b/html/modules/custom/unocha_utility/unocha_utility.libraries.yml new file mode 100644 index 00000000..8e7fc6ba --- /dev/null +++ b/html/modules/custom/unocha_utility/unocha_utility.libraries.yml @@ -0,0 +1,6 @@ +h2-id-link: + css: + theme: + components/h2-id-link/h2-id-link.css: {} + js: + components/h2-id-link/h2-id-link.js: {} From 27b8e3576c5955e909dfabb522b3340e1fc8a8ff Mon Sep 17 00:00:00 2001 From: "Peter Droogmans (attiks)" Date: Wed, 27 Nov 2024 13:00:01 +0100 Subject: [PATCH 2/3] chore: Adjust style for mobile --- .../unocha_utility/components/h2-id-link/h2-id-link.css | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/html/modules/custom/unocha_utility/components/h2-id-link/h2-id-link.css b/html/modules/custom/unocha_utility/components/h2-id-link/h2-id-link.css index feb1d401..51fc62c0 100644 --- a/html/modules/custom/unocha_utility/components/h2-id-link/h2-id-link.css +++ b/html/modules/custom/unocha_utility/components/h2-id-link/h2-id-link.css @@ -10,3 +10,9 @@ h2[data-ocha-h2-link] a[data-ocha-h2-link-tag] { h2[data-ocha-h2-link]:hover > a[data-ocha-h2-link-tag] { visibility: visible; } + +@media (max-width: 1024px) { + h2[data-ocha-h2-link]:hover a[data-ocha-h2-link-tag] { + margin-left: 0; + } +} From ad69521528088e875f4a91c0f0761779223b90da Mon Sep 17 00:00:00 2001 From: "Peter Droogmans (attiks)" Date: Thu, 28 Nov 2024 11:19:54 +0100 Subject: [PATCH 3/3] feat: Add Web share to H2 tags Refs: #UNO-865 --- .../components/h2-id-link/h2-id-link.css | 41 ++++++++++ .../components/h2-id-link/h2-id-link.js | 77 +++++++++++++++++++ .../components/h2-id-link/share.svg | 4 + 3 files changed, 122 insertions(+) create mode 100644 html/modules/custom/unocha_utility/components/h2-id-link/share.svg diff --git a/html/modules/custom/unocha_utility/components/h2-id-link/h2-id-link.css b/html/modules/custom/unocha_utility/components/h2-id-link/h2-id-link.css index 51fc62c0..a81c543c 100644 --- a/html/modules/custom/unocha_utility/components/h2-id-link/h2-id-link.css +++ b/html/modules/custom/unocha_utility/components/h2-id-link/h2-id-link.css @@ -16,3 +16,44 @@ h2[data-ocha-h2-link]:hover > a[data-ocha-h2-link-tag] { margin-left: 0; } } + +/** + * Web Share API + * + * Modifications for when the browser can natively share images or text. + */ +.data-ocha-h2-share-button--can-share { + position: relative; +} + +.data-ocha-h2-share-button--can-share a[data-ocha-h2-link-tag] { + display: none; +} + +.data-ocha-h2-share-button { + width: 24px; + height: 24px; + border: none; + background: none; + padding: 0; + margin-inline-start: .5rem; +} + +.data-ocha-h2-share-button img { + display: block; +} + +/** + * While the figure is being rasterized for sharing, we make the following + * modifications. + */ + +/* hide share button */ +.is--capturing .data-ocha-h2-share-button { + display: none; +} + +/* remove underline from hyperlinked sources */ +.is--capturing .data-ocha-h2-share-button__source a { + text-decoration: none; +} diff --git a/html/modules/custom/unocha_utility/components/h2-id-link/h2-id-link.js b/html/modules/custom/unocha_utility/components/h2-id-link/h2-id-link.js index e69de29b..ab5b1227 100644 --- a/html/modules/custom/unocha_utility/components/h2-id-link/h2-id-link.js +++ b/html/modules/custom/unocha_utility/components/h2-id-link/h2-id-link.js @@ -0,0 +1,77 @@ +/** + * @file + * Use the Web Share API on H2. + */ + +(function () { + if (!!navigator.canShare) { + var h2Titles = document.querySelectorAll('h2[data-ocha-h2-link]'); + + h2Titles.forEach((h2Title) => { + // Create share button. + let shareButton = document.createElement('button'); + // @TODO: fix non-translatable text + shareButton.innerHTML = 'Share'; + shareButton.classList.add( + 'data-ocha-h2-share-button', + ); + + // Using this as an error, as opposed to success as it appears in the + // default cd-social-links component. + shareButton.dataset.message = 'Failed to share'; + + // Set up Web Share API when button is clicked. + shareButton.addEventListener('click', (ev) => { + let h2Title = ev.target.closest('h2[data-ocha-h2-link]'); + + let shareData = { + title: window.title, + url: window.location.href + '#' + h2Title.id, + text: h2Title.nextElementSibling.textContent + }; + + // Hide share button while capturing an image of the figure. + h2Title.classList.add('is--capturing'); + + try { + // Share. + if (navigator.canShare(shareData)) { + navigator.share(shareData); + } + else { + // Share without text. + delete shareData.text; + if (navigator.canShare(shareData)) { + navigator.share(shareData); + } + else { + // Share without title. + delete shareData.title; + if (navigator.canShare(shareData)) { + navigator.share(shareData); + } + } + } + } catch (err) { + // Show user feedback and remove after some time. + shareButton.classList.add('is--showing-message'); + setTimeout(function () { + shareButton.classList.remove('is--showing-message'); + }, 2500); + + // Log error to console. + console.error('Sharing failed:', err); + } + + // Show share button now that image capture was attempted. + h2Title.classList.remove('is--capturing'); + }); + + // Insert button into DOM. + h2Title.append(shareButton); + // Mark this figure as shareable. + h2Title.classList.add('data-ocha-h2-share-button--can-share'); + }); + } +}()); + diff --git a/html/modules/custom/unocha_utility/components/h2-id-link/share.svg b/html/modules/custom/unocha_utility/components/h2-id-link/share.svg new file mode 100644 index 00000000..41ff8bfa --- /dev/null +++ b/html/modules/custom/unocha_utility/components/h2-id-link/share.svg @@ -0,0 +1,4 @@ + + + +