1(function (Drupal) { 2 'use strict'; 3 4 async function getFileMimeType(url) { 5 const response = await fetch(url, { method: 'HEAD' }); 6 if (!response.ok) { 7 throw new Error(`Failed to fetch file: ${response.status}`); 8 } 9 return response.headers.get('Content-Type'); 10 } 11 12 function getAltText(mimeType) { 13 if (!mimeType) return 'Document'; 14 if (mimeType === 'application/pdf') return 'PDF'; 15 if (mimeType.includes('word')) return 'Word document'; 16 if (mimeType.includes('powerpoint') || mimeType.includes("wordprocessingml")) return 'PowerPoint'; 17 if (mimeType.includes('excel') || mimeType.includes('spreadsheet')) return 'Excel'; 18 if (mimeType.includes('csv')) return 'CSV'; 19 if (mimeType.startsWith('image/')) return 'Image icon'; 20 return 'Document icon'; 21 } 22 23 function getIconPath(mimeType) { 24 if (mimeType === 'application/pdf') return 'bi bi-file-earmark-pdf'; 25 if (mimeType.includes('word')) return 'bi bi-file-earmark-word'; 26 if (mimeType.includes('powerpoint') || mimeType.includes('presentationml')) return 'bi bi-file-earmark-ppt'; 27 if (mimeType.includes('excel') || mimeType.includes('spreadsheet')) return 'bi bi-file-earmark-excel'; 28 if (mimeType.includes('csv')) return 'bi bi-file-earmark-binary'; 29 if (mimeType.startsWith('image/')) return 'bi bi-file-earmark-image'; 30 return 'bi bi-file-earmark'; 31 } 32 33 function getMimeTypeFromExtension(href) { 34 if (href.endsWith('.pdf')) return 'application/pdf'; 35 if (href.endsWith('.doc') || href.endsWith('.docx')) return 'application/msword'; 36 if (href.endsWith('.ppt') || href.endsWith('.pptx')) return 'application/vnd.ms-powerpoint'; 37 if (href.endsWith('.xls') || href.endsWith('.xlsx')) return 'application/vnd.ms-excel'; 38 if (href.endsWith('.csv')) return 'text/csv'; 39 if (href.match(/\.(jpg|jpeg|png|gif)$/i)) return 'image/*'; 40 return ''; 41 } 42 43 function insertIconInline(targetElem, iconPath, altText) { 44 var iconClass = iconPath + ' doc-icon-ignore-float'; 45 var i = document.createElement('i'); 46 i.className = iconClass; 47 i.setAttribute('role', 'img'); 48 i.setAttribute('aria-label', altText); 49 i.style.width = '1rem'; 50 i.style.height = '1rem'; 51 i.style.marginLeft = '0.15rem'; 52 targetElem.appendChild(i); 53 } 54 55 Drupal.behaviors.fileIcons = { 56 attach: function (context, settings, once) { 57 var links = context.querySelectorAll 58 ? context.querySelectorAll( 59 'a[href*="/download?attachment"]:not(.has-document-icon), ' + 60 'a[href*="/export/paragraph"]:not(.has-document-icon), ' + 61 'a[href$="/open"]:not(.has-document-icon), ' + 62 'a[href*="/documents/files"]:not(.has-document-icon)' 63 ) 64 : []; 65 links.forEach(function(link) { 66 var href = link.getAttribute('href'); 67 var altText = 'Document icon'; // Default alt text 68 if (!link.classList.contains('has-document-icon') && 69 Array.from(link.childNodes).every(node => node.nodeType === Node.TEXT_NODE) 70 ) { 71 getFileMimeType(href).then(function (mimeType) { 72 altText = getAltText(mimeType); 73 var iconPath = getIconPath(mimeType); 74 if(iconPath === 'bi bi-file-earmark' && href.endsWith('/open')) { 75 iconPath = ''; 76 } 77 else{ 78 insertIconInline(link, iconPath, altText); 79 link.classList.add('has-document-icon'); 80 } 81 }).catch(function (error) { 82 var mimeType = getMimeTypeFromExtension(href); 83 altText = getAltText(mimeType); 84 var iconPath = getIconPath(mimeType); 85 if (iconPath) { 86 insertIconInline(link, iconPath, altText); 87 link.classList.add('has-document-icon'); 88 } 89 console.error("Error fetching MIME type for href:", href, error); 90 }); 91 } 92 }); 93 } 94 }; 95})(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.