1(function() { 2 'use strict'; 3 4 // Get thumb effect from localized script data 5 const nggDribbbleThumbEffect = (typeof nggDribbbleLinks !== 'undefined' && nggDribbbleLinks.thumbEffect) 6 ? nggDribbbleLinks.thumbEffect 7 : ''; 8 9 function updateDribbbleLinks() { 10 // Target all links with dribbble data attributes across different gallery display types. 11 const selectors = [ 12 'a[data-dribbble-link]', 13 '.ngg-gallery-thumbnail a[data-dribbble-link]', 14 '.ngg-gallery a[data-dribbble-link]', 15 '.nextgen-gallery a[data-dribbble-link]' 16 ]; 17 18 const links = document.querySelectorAll(selectors.join(', ')); 19 20 links.forEach((link) => { 21 const dribbbleLink = link.getAttribute('data-dribbble-link'); 22 const dribbbleTarget = link.getAttribute('data-dribbble-target'); 23 24 if (dribbbleLink) { 25 link.href = dribbbleLink; 26 27 if (dribbbleTarget === '_blank') { 28 link.target = '_blank'; 29 link.rel = 'noopener noreferrer'; 30 } else { 31 link.removeAttribute('target'); 32 link.removeAttribute('rel'); 33 } 34 35 // IMPORTANT: Disable lightbox behavior for this link 36 // Remove lightbox-related classes and attributes 37 link.classList.remove('ngg-fancybox', 'ngg-simplelightbox', 'nextgen_pro_lightbox', 'shutter', 'shutterset'); 38 link.removeAttribute('data-fancybox'); 39 link.removeAttribute('data-lightbox'); 40 link.removeAttribute('data-nplmodal'); 41 link.removeAttribute('rel'); 42 43 link.setAttribute('data-dribbble-direct', 'true'); 44 45 // Add click handler to ensure navigation happens 46 if (!link.hasAttribute('data-dribbble-click-bound')) { 47 link.setAttribute('data-dribbble-click-bound', 'true'); 48 link.addEventListener('click', (e) => { 49 50 e.stopPropagation(); 51 52 // Allow default navigation behavior 53 // If target is _blank, browser will open new tab 54 // Otherwise, navigate in same window 55 if (link.target !== '_blank') { 56 e.preventDefault(); 57 window.location.href = link.href; 58 } 59 }, true); 60 } 61 } 62 }); 63 64 const noTitleLinks = document.querySelectorAll('a[data-ngg-dribbble="1"][data-dribbble-no-title="1"]'); 65 noTitleLinks.forEach((a) => { 66 a.removeAttribute('title'); 67 68 // Remove title from any nested images (including <picture><img ...>). 69 const imgs = a.querySelectorAll('img'); 70 imgs.forEach((img) => { 71 img.removeAttribute('title'); 72 }); 73 }); 74 75 // Fallback: ensure Dribbble images remain clickable even when lightbox is disabled 76 const lightboxIsNone = (nggDribbbleThumbEffect === 'none' || nggDribbbleThumbEffect === ''); 77 const dribbbleAnchors = document.querySelectorAll('a[data-ngg-dribbble="1"]'); 78 dribbbleAnchors.forEach((a) => { 79 if (lightboxIsNone && a.hasAttribute('data-dribbble-no-link')) { 80 a.removeAttribute('href'); 81 a.style.cursor = 'default'; 82 if (!a.hasAttribute('data-dribbble-nolink-bound')) { 83 a.setAttribute('data-dribbble-nolink-bound', 'true'); 84 a.addEventListener('click', (e) => { 85 e.preventDefault(); 86 e.stopPropagation(); 87 }, true); 88 } 89 return; 90 } 91 92 const href = a.getAttribute('href'); 93 if (href && href !== '#' && href !== '') { 94 return; 95 } 96 97 if (lightboxIsNone && !a.classList.contains('use_imagebrowser_effect')) { 98 return; 99 } 100 101 // If NextGen's imagebrowser/attach behavior is used, build a real URL from the stub. 102 if (a.classList.contains('use_imagebrowser_effect')) { 103 const stubUrl = a.getAttribute('data-imagebrowser-url'); 104 if (stubUrl) { 105 const stubId = a.getAttribute('data-image-slug') || a.getAttribute('data-image-id'); 106 if (stubId) { 107 a.setAttribute('href', stubUrl.replace('%STUB%', stubId)); 108 return; 109 } 110 } 111 } 112 113 // Otherwise fall back to the full-size URL provided in data-src. 114 const dataSrc = a.getAttribute('data-src'); 115 if (dataSrc) { 116 a.setAttribute('href', dataSrc); 117 } 118 }); 119 } 120 121 if (typeof jQuery !== 'undefined') { 122 jQuery(document).ready(($) => { 123 updateDribbbleLinks(); 124 jQuery(document).on('refreshed', updateDribbbleLinks); 125 jQuery(document).on('ngg_lightbox_ready', updateDribbbleLinks); 126 jQuery(window).on('ngg.mosaic.complete', updateDribbbleLinks); 127 }); 128 document.addEventListener('nextgen_page_refreshed', updateDribbbleLinks); 129 } else { 130 if (document.readyState === 'loading') { 131 document.addEventListener('DOMContentLoaded', updateDribbbleLinks); 132 } else { 133 updateDribbbleLinks(); 134 } 135 document.addEventListener('nextgen_page_refreshed', updateDribbbleLinks); 136 } 137})(); 138
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.