/* Cosmetic ad blocking -- UA origin sheet, enabled by css_adblock.
 *
 * Originally http://texturizer.net/firefox/adblock.html
 * (Block Ads v.2004-06-12 by Neil Jenkins, with portions from Joe Francis'
 * floppymoose.com sheet and Mike Hokenson's gozer.org/mozilla/ad_blocking).
 *
 * ---------------------------------------------------------------------------
 * WHY THIS SHEET IS SMALL, AND MUST STAY SMALL
 *
 * Every selector here is tested against every element of every page, forever.
 * libcss files a selector by the first thing it can key on -- id, then class,
 * then element name -- and everything else lands in the UNIVERSAL chain, which
 * is walked for EVERY element with no bloom filtering to save it (a compound
 * with no name/class/id contributes nothing to a chain bloom, so
 * css_chain_bloom_in always says yes). A universal `*[src*="..."]` therefore
 * costs one dom_element_get_attribute plus one sliding case-insensitive scan
 * on every element in the document.
 *
 * The 2004 sheet had 102 selectors in that chain. On airbnb (12k elements,
 * nothing here matching) that was ~25% of all selection time -- 180ms with the
 * sheet against 135ms without.
 *
 * So three rules for anything added below:
 *
 *   1. NEVER block a bare hostname here. res/adblock.dat already blocks those
 *      domains at fetch time (see kolibri_adblock.c) -- the resource is never
 *      requested, so there is nothing left to hide, and the selector is pure
 *      cost. Only PATH and FILENAME patterns, which a domain table cannot see,
 *      belong in CSS.
 *   2. NEVER write a bare `*[attr...]`. Qualify it with the elements that can
 *      actually carry the attribute and draw a box (`img`, `iframe`, `embed`,
 *      `a`, `div`, `ins`). That moves it out of the universal chain into the
 *      element chain, so the 90% of the DOM that is div/span/a/p/li never
 *      tests it. `[data-*="..."]` on a rare attribute name is the exception:
 *      the lookup misses immediately and the tag set is unknowable.
 *   3. Prefer `.cls` / `#id` to `[class="cls"]` / `[id="id"]`. They are the
 *      same match for our purposes but file into the class/id hashes, which
 *      are keyed lookups rather than chain walks. (`div#x` is a specificity
 *      step up from `div[id="x"]`, which is harmless: origin beats specificity
 *      in the cascade, and nothing in this sheet competes with itself.)
 *
 * Deleted in the 2026 pass, for the record: ~60 hostname rules that adblock.dat
 * already covers (doubleclick, atdmt, mediaplex, fastclick, valueclick,
 * advertising.com, tribalfusion, falkag, bluestreak, clickxchange, netdirect,
 * tradedoubler, adbutler, qksrv/qkimg, rcm.amazon, statse.webtrendslive,
 * hitbox, atwola, ...); ~35 rules for sites and hosts that no longer exist
 * (geocities, imdb Vpics/CMSIcons/apix/kpix, freshmeat button, sportsbybrooks
 * farkbutton, cash4banner, hit-now, crazypopups, sexcounter, klipmart,
 * popupad.net, thebugs.ws, bannermania.nom.pl, tryaol, soapcity, martindale,
 * rd.yahoo.com, salon Creatives, toms_skyscraper, us.yimg.com/a/ya, two bare
 * IPs); all 16 `embed[type="application/x-shockwave-flash"]` rules (there is no
 * Flash); 11 `table[width="160"][height="329"][bgcolor=...]`-style pixel-exact
 * layout-table rules; and the `a:link[href*=".ad"] img` family together with
 * the `display:inline` block that existed only to undo its false positives.
 * ------------------------------------------------------------------------- */


/* --- Ad frames. iframe/embed are rare, so these stay cheap where they are. */
iframe[src*="/ad-"],
iframe[src*="/ad."],
iframe[src*="/ad/"],
iframe[src*="/ad_"],
iframe[src*="/adframe"],
iframe[src*="/ads"],
iframe[src*="/adv"],
iframe[src*="/adx"],
iframe[src*="/click"],
iframe[src*="?click"],
iframe[src*="=click"],
iframe[src*="/banner"],
iframe[src*="?banner"],
iframe[src*="advert"],
iframe[src*="promos"],
iframe[name="bsadframe"],
iframe#adFrame,
iframe#splashFrame,
embed[src*="/ads"],
embed[src*="/adv"],
embed[src*="advert"],
embed[src*="/banner"],

/* --- Ad images. Path and filename patterns only; the hosts these used to
 *     name are handled by adblock.dat before the request goes out.
 *
 *     `img[src*=".ad"]` is deliberately NOT here. It matched logo.adaptive.png
 *     and header.ad.svg as readily as an ad, which is what the old
 *     `display:inline` whitelist block was trying (and failing) to patch up. */
img[src*="/ad-"],
img[src*="/ad."],
img[src*="/ad/"],
img[src*="/ad_"],
img[src*="/ads"],
img[src*="/adv"],
img[src*="/adx"],
img[src*="_ad_"],
img[src*="-ad-"],
img[src*="?ad"],
img[src*="/adimage"],
img[src*="/adimg"],
img[src*="advert"],
img[src*="/click"],
img[src*="?click"],
img[src*="=click"],
img[src*="/banner/"],
img[src*="?banner"],
img[src*="banners."],
img[src*="banner_ads"],
img[src*="banman.asp"],
img[src*="bannerman"],
img[src*="sideads/"],
img[src*="/sponsors/"],
img[src*="_sponsor_"],
img[src*="/publicidad/"],
img[src*="/jump/"],
img[src*="120x80"],
img[alt*="advert"],
img[alt*="Sponsored Links"],
img[alt*="Click Here To Visit Our Sponsor"],
a[href*="/banner"] img,

/* --- Ad links. `href` only draws a box on `a`; `area` and `link` do not. */
a[href*="banman.asp"],
a[href*="bannerman"],
a[href*="?banner"],
a[href*="/banner/"],
a[href*="/jump/"],
a[href*="websponsors"],

/* --- Ad containers. The exact-match ones are written as #id/.class so they
 *     file into the id/class hashes instead of walking a chain. */
div[id*="advert"],
div[id*="sponsor"],
div[id*="popup"],
div[id*="popover_"],
div[style*="/ads/"],
div#adstrip,
div#dropin,
div#dwindow,
div#dcv_EchangeLay,
div#mntl,
div#quack,
div#splashLayer,
div#yschsec,
div#contextualLinks,
div.ovt,
table.metatable,
table#RefAd,
td.cnnNavAd,
td.RHBarBody,
td.sl-table,
td span.aoltextad,
.ad {
        display: none /*!important*/;
}

/* Words that legitimately contain a blocked substring. Kept only for the
 * patterns above that can still collide: `/adv` inside `/advance`, `/click`
 * inside a `/click_` sprite, `/ad` inside `logo2.mad`. */
img[src*=".advance"],
img[src*="/advance"],
img[src*="/click_"],
img[src*="/logo2.m"] {
        display: inline /*!important*/;
}

/* ---- KolibriOS port additions (2026): empty ad-slot placeholders. ------
   Modern sites reserve fixed-height ad containers (against layout shift)
   that are only ever filled by javascript ad loaders. Without those ads
   the reservations render as large blank bands between content sections
   (e.g. bbc.com reserves 278-293px + margins per slot). This sheet is UA
   origin, so !important beats the author's height/display rules.

   The `[class*=...]` entries are qualified by tag on purpose: unqualified
   they sat in the universal chain and ran a sliding substring scan over the
   class attribute of every element -- which on airbnb, where a single
   element carries 300+ characters of `atm_*` classes, was the single most
   expensive thing in this file. Ad slots are div/ins/aside/section; nothing
   is lost by saying so.

   `[data-component]`/`[data-testid]` stay unqualified: the attribute name is
   rare enough that the lookup misses on the first probe for almost every
   element, and there is no sensible tag set to name. */

[data-component="ad-slot"],
[data-testid="ad-unit"],
.dotcom-ad,
#dotcom-interstitial,
div[id^="dotcom-"],
.adsbygoogle,
ins.adsbygoogle,
div[id^="google_ads_"],
ins[id^="google_ads_"],
iframe[id^="google_ads_"],
div[class*="AdSlot"],
ins[class*="AdSlot"],
aside[class*="AdSlot"],
section[class*="AdSlot"],
div[class*="ad-slot"],
ins[class*="ad-slot"],
aside[class*="ad-slot"],
section[class*="ad-slot"],
div[class*="advertisement-slot"],
section[class*="advertisement-slot"],
/* DoubleClick for Publishers reservations. tomshardware.com puts a
 * `div.dfp-leaderboard-container` (100px here, 250px in Chrome) between the
 * masthead and the first content band, and it is only ever filled by the GPT
 * loader -- so it renders as a blank strip above "TRENDING". "leaderboard" and
 * "dfp-" is an ad-industry slot prefix, never content -- unlike a bare
 * "leaderboard", which a sports or gaming site uses for real content. */
div[class*="dfp-"],
ins[class*="dfp-"],
aside[class*="dfp-"],
section[class*="dfp-"],
div[id*="dfp-"],
ins[id*="dfp-"],
iframe[id*="dfp-"],
.ad-banner, .ad-container, .ad-wrapper, .ad-placeholder, .ad-unit {
	display: none !important;
}

/* Reservations whose only content is an ad the loader never brought.
   Hiding the ad ITSELF is not enough when the site sizes the slot in CSS:
   speedtest.net gives `.top-placeholder` a flat `height: 110px` and its
   `#stnext_*` slots `min-height: 110px`, so a blocked banner leaves a blank
   band above the page's own content, and the reserved 318px right-hand
   column pushes everything off centre. These are the wrappers, not the ads,
   so they must be listed separately.

   `stnext_` is Ookla's own ad namespace (leaderboard, lowerboard, footer,
   rectangle) -- site-specific, like the dotcom- and dfp- entries above. */
div[class*="-ad-rectangle"],
div[class*="-ad-skyscraper"],
div.ads-column,
div[id^="stnext_"] {
	display: none !important;
}

/* The height reservations themselves are only ZEROED, not hidden. "placeholder"
   is a word skeleton loaders use too, and a UA !important cannot be argued with
   by the author -- so a wrapper that turns out to hold real content still draws
   it (overflow is visible), it just stops holding a blank 110px band open. */
div.top-placeholder,
div.lowerboard-placeholder {
	height: 0 !important;
	min-height: 0 !important;
}
