1// Full-width banner logos in the old-design header (.sa-header). 2// 3// The design-3 ("toppbild") clubs that came over from the legacy site uploaded 4// a whole banner â club name baked into the artwork â into the slot the logo 5// card expects a logo in. Rendered as a logo it gets squeezed into the logo's 6// height beside .sa-header__title, so the club name prints twice and the 7// banner is unreadable. Nothing in the design row says which kind of image it 8// is, so classify it by shape once the browser has decoded it: wider than 3:1 9// is a banner, never a logo+text mark. .sa-header--banner then paints it as 10// the header's background, drops the <img> and clips the title down to screen 11// readers, which are the only ones left with no club name in the artwork. 12// 13// Pure-JS (the homepage renders as static SSR, so no Blazor event handlers) 14// and runs once per page load â there is no enhanced navigation to survive. 15(function () { 16 var BANNER_CLASS = 'sa-header--banner'; 17 // A logo+text mark is at most ~2.5:1 in practice; a legacy toppbild is 18 // 1000x120 and up. 3 sits in the gap with room on both sides. 19 var MIN_ASPECT_RATIO = 3; 20 21 function classify(img) { 22 // 0x0 means the image failed to decode. The inline onerror swaps in 23 // shield.webp, which is square and simply fails the ratio test below. 24 if (!img.naturalWidth || !img.naturalHeight) return; 25 if (img.naturalWidth / img.naturalHeight <= MIN_ASPECT_RATIO) return; 26 27 var header = img.closest('.sa-header'); 28 if (!header) return; 29 30 // The background image itself comes from --sa-header-logo-image, which 31 // DynamicStyles emits through the same allowlist as every other URL it 32 // writes. It drops the property when the CDN URL doesn't pass, and a 33 // band of empty background is worse than an oversized logo â so only 34 // take over the header when there is something to paint in it. 35 if (!getComputedStyle(header).getPropertyValue('--sa-header-logo-image').trim()) return; 36 37 // Hand the image's own shape to the CSS so the band is exactly as 38 // tall as the banner needs at the current width â a fixed height plus 39 // background-size would crop the ends off a wide one. Set before the 40 // class so the header is never laid out banner-sized without it. 41 header.style.setProperty('--sa-header-banner-ratio', img.naturalWidth + ' / ' + img.naturalHeight); 42 header.classList.add(BANNER_CLASS); 43 } 44 45 var logos = document.querySelectorAll('.sa-header__logo'); 46 for (var i = 0; i < logos.length; i++) { 47 // A cached image is already complete before this script runs and will 48 // never fire load, so measure those directly. One that is complete 49 // because it already failed gets measured here too and drops out at 50 // 0x0; no load listener goes on afterwards, so the shield the inline 51 // onerror swaps in is never classified â deliberately, it is square 52 // and would fail the ratio test anyway. 53 if (logos[i].complete) classify(logos[i]); 54 else logos[i].addEventListener('load', function () { classify(this); }); 55 } 56}());
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.