1/** 2 * @file 3 * Custom AnchorJS JS. 4 * 5 */ 6/* jshint esversion: 6 */ 7 8(function ($, Drupal, drupalSettings, anchors, window) { 9 'use strict'; 10 // Per https://www.bryanbraun.com/anchorjs/#dont-run-it-too-late, adding 11 // anchors outside behaviors so that they are added early. 12 13 // Setting anchor default options. 14 anchors.options.visible = 'always'; 15 anchors.options.ariaLabel = Drupal.t('Copy link to clipboard'); 16 anchors.options.titleText = Drupal.t('Copy link to clipboard'); 17 18 /** 19 * Adds anchors and configures custom attributes. 20 */ 21 function handleAnchors() { 22 // Custom selector variable checks for `settings` and falls back 23 // on drupalSettings so function can run in and out of Drupal behaviors. 24 const custom_selector = typeof (settings) !== 'undefined' ? settings.anchorjs.selector : drupalSettings.anchorjs.selector; 25 // Add anchors 26 if (custom_selector) { 27 // If selector was set with custom value, apply anchors to that selector. 28 anchors.add(custom_selector); 29 } 30 else { 31 // Use default selector ('h2, h3, h4, h5, h6'). 32 anchors.add(); 33 } 34 // Set custom title and aria label for each anchor from the element's text. 35 // Use setTimeout to ensure anchor links are fully rendered in the DOM. 36 setTimeout(() => { 37 anchors.elements.forEach(element => { 38 const element_text = element.innerText.trim(); 39 if (element_text.length) { 40 const element_anchor = element.querySelector('.anchorjs-link'); 41 if (element_anchor) { 42 const descriptive_text = Drupal.t('Copy link to section: ') + element_text; 43 element_anchor.setAttribute('aria-label', descriptive_text); 44 element_anchor.setAttribute('title', descriptive_text); 45 } 46 } 47 }); 48 }, 0); 49 } 50 handleAnchors(); 51 52 Drupal.behaviors.anchorJS = { 53 attach: function (context, settings) { 54 // Run handleAnchors() again to account for any new DOM elements in context 55 // that are missing anchor links every time the behavior runs. 56 handleAnchors(); 57 58 $(once('anchorJS', 'a.anchorjs-link', context)).each(() => { 59 $(this).click(function () { 60 // Copy anchorjs location to clipboard. Clipboard JS is loaded async, 61 // so need to check that it exists the time of the click event. 62 const ClipboardJS = window.ClipboardJS || null; 63 if (ClipboardJS && ClipboardJS.isSupported()) { 64 new ClipboardJS('a.anchorjs-link', { 65 text: function (trigger) { 66 return trigger.href; 67 } 68 }); 69 } 70 }); 71 }); 72 } 73 }; 74 75})(jQuery, Drupal, drupalSettings, anchors, window);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.