PageSourceSearch

https://www.alvikbasket.nu/js/header-banner.js

js alvikbasket.nu collected 2026-10-02 21:43:19 UTC 3,213 bytes, 56 lines download raw bytes

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.