1; (function ($, window, document) { 2 const $doc = $(document); 3 4 $doc.ready(function () { 5 toggleReadMore(); 6 copyToClipboard(); 7 shareUrls(); 8 toggleExtraAuthors(); 9 toggleDisclosure(); 10 }); 11 12 const toggleDisclosure = () => { 13 const toggle = ($button) => { 14 const $disclosure = $button.closest('.bw-author-byline__disclosure'); 15 const isExpanded = $disclosure.toggleClass('is-open').hasClass('is-open'); 16 17 $button.attr('aria-expanded', isExpanded); 18 }; 19 20 $('.js-author-byline-disclosure-toggle') 21 .on('click', function () { 22 toggle($(this)); 23 }) 24 .on('keydown', function (event) { 25 if (event.key === 'Enter' || event.key === ' ' || event.key === 'Spacebar') { 26 event.preventDefault(); 27 toggle($(this)); 28 } 29 }); 30 }; 31 32 const toggleReadMore = () => { 33 $('.js-read-more-toggle').on('click', function () { 34 const $button = $(this); 35 const $wrap = $button.closest('.bw-author-byline__read-more'); 36 const isExpanded = $wrap.toggleClass('is-expanded').hasClass('is-expanded'); 37 38 $button.attr('aria-expanded', isExpanded); 39 $button.find('.bw-author-byline__read-more-toggle-label') 40 .text(isExpanded ? $button.attr('data-read-less') : $button.attr('data-read-more')); 41 }); 42 } 43 44 const toggleExtraAuthors = () => { 45 const setExpanded = ($full, isExpanded) => { 46 $full.toggleClass('is-expanded', isExpanded); 47 $full.find('.js-extra-users-open, .js-extra-users-close') 48 .attr('aria-expanded', isExpanded); 49 }; 50 51 $('.js-extra-users-open').on('click', function () { 52 setExpanded($(this).closest('.bw-author-byline__full'), true); 53 }); 54 55 $('.js-extra-users-close').on('click', function () { 56 setExpanded($(this).closest('.bw-author-byline__full'), false); 57 }); 58 }; 59 60 const copyToClipboard = () => { 61 $('.js-copy-link').on('click', function (event) { 62 event.preventDefault(); 63 64 const url = $(this).attr('href'); 65 66 if (navigator.clipboard && window.isSecureContext) { 67 navigator.clipboard.writeText(url) 68 .then(() => { 69 $(this).addClass('is-copied'); 70 71 setTimeout(() => { 72 $(this).removeClass('is-copied'); 73 }, 2000); 74 }) 75 .catch((err) => { 76 console.error('Copy failed:', err); 77 }); 78 } 79 }); 80 }; 81 82 const shareUrls = () => { 83 $('.js-share-toggle').on('click', function (event) { 84 event.preventDefault(); 85 event.stopPropagation(); 86 87 const $shareContainer = $(this).closest('.js-share'); 88 const $dropdown = $shareContainer.find('.js-share-dropdown'); 89 const isActive = $shareContainer.hasClass('is-active'); 90 91 $shareContainer.toggleClass('is-active', !isActive); 92 $(this).attr('aria-expanded', !isActive); 93 94 if (!isActive) { 95 positionShareDropdown($dropdown); 96 } 97 }); 98 99 $doc.on('click', function (event) { 100 if (!$(event.target).closest('.js-share').length) { 101 const $shares = $('.js-share.is-active'); 102 103 $shares.removeClass('is-active'); 104 $shares.find('.js-share-toggle').attr('aria-expanded', 'false'); 105 } 106 }); 107 108 $('.js-share-link').on('click', function (event) { 109 const url = $(this).attr('href'); 110 111 const breakpoint = window.matchMedia('(max-width: 1023px)'); 112 113 if (breakpoint.matches) { 114 return; 115 } 116 117 event.preventDefault(); 118 119 const width = 600; 120 const height = 500; 121 122 const left = window.screenX + (window.outerWidth - width) / 2; 123 const top = window.screenY + (window.outerHeight - height) / 2; 124 125 window.open( 126 url, 127 'share-window', 128 `width=${width},height=${height}
128,left=${left},top=${top},toolbar=no,menubar=no,scrollbars=yes,resizable=yes` 129 ); 130 }); 131 132 $(window).on('resize', function () { 133 $('.js-share.is-active .js-share-dropdown').each(function () { 134 positionShareDropdown($(this)); 135 }); 136 }); 137 138 function positionShareDropdown($dropdown) { 139 const el = $dropdown[0]; 140 141 $dropdown.removeClass('is-flip-right'); 142 143 const rect = el.getBoundingClientRect(); 144 const viewportWidth = $(window).width(); 145 146 if (rect.right > viewportWidth) { 147 $dropdown.addClass('is-flip-right'); 148 } 149 150 if (rect.left < 0) { 151 $dropdown.removeClass('is-flip-right'); 152 } 153 } 154 }; 155 156})(jQuery, window, document);
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.