1/* 2 * This Javascript will resize all puffs on the page to the height of their biggest sibling. 3 * 4 * Source: misc-js/same-heights-for-puffs.js 5 */ 6 7(() => { 8 const STYLE_SHEET_ID = 'custom-puff-heights'; 9 const MAIN_COLUMN_SELECTOR = '#Mittenspalt'; 10 const PUFF_SELECTOR = '.sv-se-uu-uit-webb-puff, .sv-se-uu-uit-webb-webapp-linked-cards-event, .sv-portlet:has([id^="Lankadmodul"]), .sv-se-uu-uit-webb-webapp-linked-cards-archive, .sv-se-uu-uit-webb-webapp-education-programme-link-pages'; 11 const CARD_BODY_SELECTOR = '.uu-blurb__content'; 12 const CARD_SELECTOR = `${CARD_BODY_SELECTOR}`; 13 const PARENT_SELECTOR = '.sv-layout .sv-row, .sv-layout .sv-horizontal, .sv-layout .sv-vertical'; 14 const CUSTOM_CLASS_PREFIX = 'custom-height-'; 15 const BREAKPOINT = 768; 16 const MAIN_COLUMN_ELEMENT = document.querySelector(MAIN_COLUMN_SELECTOR); 17 18 /** 19 * Gets a style sheet element in which to put custom CSS rules. 20 * Creates it if necessary. 21 */ 22 const getCustomStyle = () => { 23 let style = document.getElementById(STYLE_SHEET_ID); 24 if (!style) { 25 style = document.createElement('style'); 26 style.id = STYLE_SHEET_ID; 27 document.head.appendChild(style); 28 } 29 return style; 30 }; 31 32 /** 33 * Removes the custom style sheet from the DOM and its rules with it. 34 */ 35 const removeCustomStyle = () => { 36 const style = document.getElementById(STYLE_SHEET_ID); 37 if (style) { 38 style.disabled = true; 39 style.parentNode.removeChild(style); 40 } 41 }; 42 43 /** 44 * Tries to find an ancestor element that probably contains this puff's 45 * siblings by matching against a set of CSS classes. 46 */ 47 const findPuffContainer = (puff) => { 48 let element = puff; 49 while ( 50 !element.matches(PARENT_SELECTOR) && 51 element.parentNode && 52 // Don't go as high as the "Mittenspalt", since that would put all puffs 53 // in the same container. 54 element.parentNode !== MAIN_COLUMN_ELEMENT 55 ) { 56 element = element.parentNode; 57 } 58 return element; 59 }; 60 61 /** 62 * Finds all puffs on the page and makes them the same height as their immediate siblings. 63 * The biggest puff decides the height. 64 */ 65 const setPuffsToSameHeight = (puffSelector, cardSelector) => { 66 // Find the all the Sitevision generated divs that hold a number of puffs each. 67 // Since they have no good classes we need to find a puff generated by our puff 68 // module and then use its grand parent. 69 const puffSelectorList = [...document.querySelectorAll(puffSelector)]; 70 const puffContainers = puffSelectorList 71 .map((puff) => { 72 return findPuffContainer(puff); 73 }) 74 // Remove duplicates 75 .filter((value, index, self) => { 76 return self.indexOf(value) === index; 77 }); 78 79 // For each of these "puff containers" we'll iterate over its puffs and find the biggest height. 80 // Then we'll resize all of the puffs in the puff container to that height. 81 puffContainers.forEach((puffContainer) => { 82 // We want to exclude the main container that includes everything 83 if (!puffContainer.outerHTML.includes('<main')) { 84 let maxHeight = 0; 85 // Find biggest height 86 const cards = [...puffContainer.querySelectorAll(cardSelector)]; 87 cards.forEach( 88 (card) => { 89 maxHeight = Math.max(maxHeight, card.offsetHeight); 90 } 91 ); 92 93 // Create a new CSS class 94 const customClass = CUSTOM_CLASS_PREFIX + Math.floor(Math.random() * 100000000); 95 96 // First, remove any previous custom height classes 97 const puffContainerClassList = puffContainer.classList; 98 puffContainerClassList.forEach((className) => { 99 if (className.startsWith(CUSTOM_CLASS_PREFIX)) { 100 puffContainerClassList.remove(className); 101 } 102 }); 103 puffContainerClassList.add(customClass); 104 105 // Get the custom style sheet (or create a new) that will reference the custom class. 106 const style = getCustomStyle(); 107 // Add a rule for widths of at least BREAKPOINT pixels that sets the height to the 108 // biggest height 109 style.textContent += 110 `@media screen and (min-width: ${BREAKPOINT}px) { 111 .${customClass} ${CARD_BODY_SELECTOR} { 112 height: ${maxHeight}px !important; 113 } 114 }`; 115 } 116 }); 117 }; 118 119 /** 120 * Event handler that removes any previous custom styles set with this script 121 * and then calls setPuffsToSameHeight(). 122 */ 123 const readjustPuffHeights = () => { 124 // We need to remove the custom style sheet to prevent the page being flooded 125 // with style elements. 126 removeCustomStyle(); 127 setPuffsToSameHeight(PUFF_SELECTOR, CARD_SELECTOR); 128 }; 129 130 // Adjust puff heights on window resize 131 window.addEventListener('resize', readjustPuffHeights); 132 133 // Adjust puff heights immediately, but wait for fonts to load first to avoid measuring with 134 // fallback fonts (which would yield incorrect heights). 135 document.fonts.ready.then(() => { 136 setPuffsToSameHeight(PUFF_SELECTOR, CARD_SELECTOR); 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.