1const zoloGenerateUniqueName = (uniqueId, customNameAttribute, defaultName = 'field_name') => { 2 const lastPart = uniqueId && typeof uniqueId === 'string' ? uniqueId.split('-').pop() : 'unknown'; 3 const sanitizedCustomName = customNameAttribute 4 ? customNameAttribute 5 .trim() 6 .replace(/[^a-zA-Z0-9]/g, '_') 7 .replace(/\s+/g, '_') 8 : null; 9 10 return sanitizedCustomName ? sanitizedCustomName : `${defaultName}_${lastPart}`; 11}; 12 13// Make the function available on the window object 14window.zoloGenerateUniqueName = zoloGenerateUniqueName; 15 16 17function decodeEntities(str) { 18 const txt = document.createElement('textarea'); 19 txt.innerHTML = str; 20 return txt.value; 21} 22 23function sanitizeHtml(input) { 24 // Decode any HTML entities (e.g., <img> â <img>) 25 const decoded = decodeEntities(input); 26 27 // Parse into a DOM 28 const parser = new DOMParser(); 29 const doc = parser.parseFromString(decoded, 'text/html'); 30 31 // Allowed tags & attributes 32 const allowedTags = ['b', 'i', 'em', 'strong', 'u', 'span', 'div', 'h3', 'p']; 33 const allowedAttrs = ['class', 'style']; 34 35 // Walk all elements 36 doc.body.querySelectorAll('*').forEach(el => { 37 const tag = el.nodeName.toLowerCase(); 38 39 // Remove disallowed tags 40 if (!allowedTags.includes(tag)) { 41 el.remove(); 42 return ''; 43 } 44 45 // Clean attributes 46 [...el.attributes].forEach(attr => { 47 const name = attr.name.toLowerCase(); 48 const value = attr.value.trim().toLowerCase(); 49 50 if ( 51 !allowedAttrs.includes(name) || 52 name.startsWith('on') || // onerror, onclick, etc. 53 value.startsWith('javascript:') 54 ) { 55 el.removeAttribute(attr.name); 56 } 57 }); 58 }); 59 60 return doc.body.innerHTML; 61} 62 63document.addEventListener('DOMContentLoaded', function () { 64 const galleries = document.querySelectorAll('.wp-block-zolo-image-gallery'); 65 66 if (galleries.length > 0) { 67 galleries.forEach((gallery) => { 68 const uniqueId = gallery.dataset.uniqueid; 69 70 // Collect captions into an array 71 const items = gallery.querySelectorAll('.zolo-item[data-caption]'); 72 const captions = []; 73 74 items.forEach((item) => { 75 const rawCaption = item.getAttribute('data-caption'); 76 if (rawCaption) { 77 const cleanCaption = sanitizeHtml(rawCaption); 78 captions.push(cleanCaption); 79 } else { 80 captions.push(''); // placeholder if no caption 81 } 82 }); 83 84 // Assign all captions at once 85 fsLightboxInstances[`gallery-${uniqueId}`].props.captions = captions; 86 }); 87 } 88}); 89
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.