1(function (Drupal) { 2 // Helpers Functions 3 const APB = window.APB; 4 const { one, all, text } = APB.DOM; 5 6 // Drupal Behavior 7 Drupal.behaviors.apbImageGallery = { 8 attach: function (context, settings) { 9 // Search in context or document 10 const root = context instanceof HTMLElement ? context : document; 11 const paragraphs = all('.paragraph--type--apb-pb-image-gallery', root); 12 13 if (!paragraphs.length) return; 14 15 paragraphs.forEach(apb_mainParent => { 16 // Skip if already processed 17 if (apb_mainParent.dataset.apbImageGallery === 'initialized') { 18 return; 19 } 20 apb_mainParent.dataset.apbImageGallery = 'initialized'; 21 22 const galleryIdx = Date.now() + Math.random().toString(36).slice(2, 6); 23 24 // GENERAL VARIABLES 25 const apb_sectionTitle = text( 26 one('.field--name-field-apb-section-title', apb_mainParent) 27 ); 28 29 const apb_showSectionTitle = text( 30 one('.field--name-field-apb-show-section-title', apb_mainParent) 31 ); 32 const apb_customClassGroup = text( 33 one('.field--name-field-apb-custom-class', apb_mainParent) 34 ); 35 const apb_igDisplayLayout = text( 36 one( 37 '.field--name-field-apb-display-layout-tx .term-machine-name', 38 apb_mainParent 39 ) 40 ); 41 const apb_igColumns = text( 42 one( 43 '.field--name-field-apb-columns-tx .term-machine-name', 44 apb_mainParent 45 ) 46 ).slice(0, 1); 47 const apb_igColumnGap = text( 48 one( 49 '.field--name-field-apb-column-gap-tx .term-machine-name', 50 apb_mainParent 51 ) 52 ); 53 const apb_igColorStyle = text( 54 one( 55 '.field--name-field-apb-color-style-01 .apb-tax-cs-main-color', 56 apb_mainParent 57 ) 58 ); 59 const apb_contentWidth = text( 60 one( 61 '.field--name-field-apb-width-tx .term-machine-name', 62 apb_mainParent 63 ) 64 ).replace('_', ''); 65 66 // SHOW SECTION TITLE 67 if ( 68 apb_sectionTitle !== '' && 69 apb_showSectionTitle.toLowerCase() === 'yes' 70 ) { 71 const titleEl = one( 72 '.field--name-field-apb-section-title', 73 apb_mainParent 74 ); 75 if (titleEl) titleEl.classList.remove('apb-setup'); 76 } 77 78 // CONTENT WIDTH 79 if (apb_contentWidth && apb_contentWidth !== '100') { 80 apb_mainParent.style.cssText = 81 'max-width:' + 82 apb_contentWidth + 83 '%; margin-left:auto !important; margin-right:auto !important;'; 84 } 85 86 // CUSTOM CLASS GROUP 87 if (apb_customClassGroup) { 88 apb_mainParent.classList.add(apb_customClassGroup); 89 } 90 91 // Columns + layout classes + gap 92 const itemsWrap = one( 93 '.view-apb-pi-image-gallery-items', 94 apb_mainParent 95 ); 96 if (itemsWrap) { 97 itemsWrap.classList.add( 98 `apb-columns-${apb_igColumns}`, 99 `apb-display-layout-${apb_igDisplayLayout}` 100 ); 101 if (apb_igColumnGap) 102 itemsWrap.style.setProperty('grid-gap', apb_igColumnGap); 103 } 104 105 // Single image layout: optional first thumb swap 106 if (apb_igDisplayLayout === 'single_image') { 107 const firstThumbUrl = text( 108 one('.views-row.first a .apb-ig-first-thumb', apb_mainParent) 109 ); 110 if (firstThumbUrl) { 111 const firstImg = one( 112 '.views-row.first a img', 113 apb_mainParent 114 ); 115 if (firstImg) { 116 firstImg.setAttribute('src', firstThumbUrl); 117 firstImg.removeAttribute('width'); 118 firstImg.removeAttribute('height'); 119 } 120 } 121 } 122 123 // ------------------------------------------------------------ 124 // GLightbox hookup 125 // ------------------------------------------------------------ 126 const group = `apb-gallery-${galleryIdx}`; 127 128 const links = all( 129 '.view-apb-pi-image-gallery-items a.apb-image-gallery-link', 130 apb_mainParent 131 ); 132 133 links.forEach(a => { 134 const row = a.closest('.views-row') || apb_mainParent; 135 136 // Title / Description sources (adjust selectors to your actual view fields if needed) 137 const explicitTitle = text( 138 one('.views-field-field-apb-pi-title', row) 139 ); 140 const explicitDesc = 141 text( 142 one('.views-field-field-apb-pi-image-description', row) 143 ) || 144 text( 145 one('.views-field-field-apb-pi-video-description', row) 146 ) || 147 text(one('.views-field-body', row)) || 148 text(one('.field--name-field-caption', row)); 149 150 const img = one('img', a); 151 const imgAlt = (img && img.getAttribute('alt')) || ''; 152 const caption = explicitTitle || imgAlt; 153 154 a.removeAttribute('title'); 155 a.classList.add('glightbox'); 156 a.setAttribute('data-gallery', group); 157 a.setAttribute('data-type', 'image'); // explicit: image items 158 // if (caption) a.setAttribute("data-title", caption); 159 // if (explicitDesc) a.setAttribute("data-description", explicitDesc); 160 161 // keep your tile background color (not used by GLightbox UI itself) 162 if (apb_igColorStyle) a.style.backgroundColor = apb_igColorStyle; 163 }); 164 165 // Initialize a GLightbox instance for this paragraphâs group 166 if (typeof GLightbox === 'function') { 167 GLightbox({ 168 selector: `.glightbox[data-gallery="${group}"]`, 169 touchNavigation: true, 170 loop: true, 171 openEffect: 'fade', 172 closeEffect: 'fade', 173 slideEffect: 'slide', 174 zoomable: true, 175 draggable: true, 176 plyr: { css: false, js: false }, 177 moreText: 'See more', 178 // "bottom" | "right" | "left" 179 descPosition: 'bottom', 180 }); 181 } else { 182 // eslint-disable-next-line no-console 183 console.warn( 184 'GLightbox is not loaded. Include glightbox.min.js and glightbox.min.css.' 185 ); 186 } 187 }); 188 }, 189 }; 190})(Drupal);
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.