Skip to content

v1.22.0 — inline-CSS blocking, wider runtime resource blocking, GCM Advanced Consent Mode, +178 trackers

Choose a tag to compare

@fabiodalez-dev fabiodalez-dev released this 03 Jul 07:39
· 468 commits to main since this release

[1.22.0] — 2026-07-03

Added

  • Inline-CSS url() / @import blocking before consent. Third-party resources loaded from inline CSS — most commonly a Google Fonts @font-face { src: url(fonts.gstatic.com…) } or an @import "fonts.googleapis.com…" printed in a <style> tag — previously reached the provider (and the visitor's IP) with consent denied, because the script / iframe / <link> blockers never parsed CSS text. The plugin now neutralises any url() / @import pointing at a blocked provider in a denied category: the URL is swapped for an inert data: placeholder so no request is made, the original is remembered, and it is restored on consent. Server-rendered <style> tags (handled server-side in the output buffer) and direct HTMLStyleElement writes at runtime (style.textContent = …, and appendChild / insertBefore / replaceChild / removeChild of a text node inside a <style>) are covered by default; the restore follows the real DOM state, so a chunk removed or replaced while parked is not resurrected.

  • "Advanced inline CSS URL blocking" setting (Settings → Script Blocking, default off). An opt-in high-coverage mode that additionally hooks the broader runtime channels used by page builders and CSS-in-JS libraries — a <style> injected via Element.innerHTML / insertAdjacentHTML, CharacterData edits inside an existing <style> (.data / .nodeValue setters, appendData / insertData / deleteData / replaceData, replaceWith), HTMLStyleElement text insertion (replaceChildren, insertAdjacentText), and Constructable Stylesheets / CSSOM (CSSStyleSheet.replaceSync / replace attached through adoptedStyleSheets, and insertRule). These hooks touch global browser prototypes and can affect page builders, editors, icon fonts or CSS-in-JS libraries, so they stay off unless a site actually needs them. The default (server-rendered + direct <style>) blocking is unaffected either way, and the admin toggle carries an explicit compatibility warning.

  • Wider runtime resource blocking for <img> / <iframe> / <link> / <source> (extends #163 / #167). In addition to the src / href property setters, the plugin now gates the setAttribute('src' | 'href' | 'srcset', …) path and the srcset property setter, parks blocked <source> src and srcset candidates, and the runtime MutationObserver now also parks parsed img / link / source elements — so a blocked provider assigned through any of these channels (page builders, lazy-loaders, responsive-image code) is held until consent and then restored, instead of only the direct el.src = … assignment.

  • Advanced Consent Mode for Google Consent Mode v2 (#165). A new opt-in GCM toggle (default off). When on, the Google tag stack — gtag.js / GA4 / Google Ads — is allowed to load before consent with a synchronous consent default → denied printed inline in <head>, so Google sends cookieless/modeled pings (Google's "Advanced" mode, gcs=G100) and upgrades to granted measurement on consent. Everything else stays hard-blocked exactly as before: non-Google trackers (Meta, TikTok, LinkedIn, Hotjar…) and the Google Tag Manager container (gtm.js, which can host tags that don't read Consent Mode). The exemption is enforced on both the server-side output buffer and the client-side blocker (for dynamically-injected tags), and gcm.js skips its own consent default so there is never a duplicate. Off by default — existing installs keep doing Basic mode (tags only after consent). The admin UI carries an explicit notice that loading Google before consent is the site operator's legal call.

  • Manual service registration from the built-in catalogue (#161). An admin can pick a known provider from the built-in catalogue on the Cookies page and register its cookies into the declaration table (marked discovered, domain-scoped) without running a scan, so they are declared domain-wide and feed the Cookie Policy generator.

  • 178 more known trackers in the blocking database and one-click catalogue. Expanded Known_Providers (the engine behind server-side and client-side blocking, cookie shredding and scanner enrichment) and the admin blocker-template catalogue from 160 to 338 services, covering widely-used third parties not previously recognised:

    • Ad-tech / SSP / DMP: AdRoll, The Trade Desk, Xandr, PubMatic, Magnite/Rubicon, OpenX, Media.net, LiveRamp, Comscore, Nielsen, Yahoo, Adform, Teads, Sharethrough, Index Exchange, Equativ/Smart AdServer, GumGum, TripleLift, Yieldmo, ID5, Lotame, BidSwitch, 33Across, Tealium, Ensighten, Commanders Act.
    • Content recommendation: Revcontent, MGID, Mediavine, Ezoic, RTB House, Nativo, Infolinks.
    • B2B intent / lead intelligence: 6sense, Demandbase, Bombora, Leadfeeder, ZoomInfo.
    • Analytics & session replay: Chartbeat, Parse.ly, StatCounter, Inspectlet, Simple Analytics, Piwik PRO, Woopra, Countly, Ptengine, GoSquared, Histats, RudderStack, Quantum Metric, Glassbox, GoatCounter, WebEngage.
    • A/B testing & personalization: Dynamic Yield, AB Tasty, Monetate, Kameleoon.
    • Marketing automation / email: Brevo/Sendinblue, Constant Contact, GetResponse, Braze, Iterable, AWeber, Omnisend, MailerLite, Campaign Monitor, SendGrid, Mailjet, Moosend, Emarsys, SendPulse, Keap/Infusionsoft, Sailthru.
    • Chat / support: Help Scout, Gorgias, ManyChat, Smartsupp, Userlike, Chatra, SnapEngage, Podium, Birdeye, Kustomer.
    • Reviews / social proof: Yotpo, Bazaarvoice, REVIEWS.io, Judge.me, Loox, Feefo, Stamped.io, Fomo, TrustPulse.
    • Video: Brightcove, JW Player, Vidyard, Kaltura, Flowplayer, SproutVideo, Cloudflare Stream.
    • Social embeds: VK, Weibo, LINE.
    • Push notifications: OneSignal, PushEngage, iZooto, Webpushr, PushCrew.
    • Surveys / forms / popups: SurveyMonkey, Jotform, Qualtrics, Wufoo, Formstack, GetSiteControl.
    • Web fonts: Font Awesome, Monotype (fonts.com).
    • Consent managers: iubenda, CookieYes, Didomi, Termly, Osano, Sourcepoint, Cookie Script, Axeptio, CookieFirst, Civic Cookie Control, Enzuzo.
    • CDP / product analytics: mParticle, Freshpaint, June, Pirsch, Umami Cloud, Vercel Analytics, Medallia/Decibel, Naver.
    • Publisher ad monetisation: Sovrn/Lijit, Raptive/AdThrive, Freestar, Connatix, Monumetric, AdPushup.
    • More chat / support: HelpCrunch, Re:amaze, Chaport, Comm100, Gist.
    • More reviews / social proof: Okendo, PowerReviews, eKomi, ProveSource, Nudgify, Shopper Approved.
    • More A/B & personalization: Omniconvert, Personyze, Mutiny, Taplytics.
    • More email / CRM: Oracle Eloqua, Salesforce Marketing Cloud, Ontraport, Vero, Sendlane.
    • Maps: HERE, TomTom, Bing Maps, Esri ArcGIS.
    • More video: Panopto, Bunny Stream, Dacast.
    • More push: PushAlert, Aimtell, Truepush.
    • More forms / surveys: Paperform, Cognito Forms, Tally, involve.me.
    • More social embeds: Odnoklassniki, XING, Kakao.

    Every entry uses host- or path-scoped patterns (no bare CDN domains, no literal-* dead needles) so the runtime src/href gate and network interceptors cannot park a legitimate cross-origin asset; each batch was checked with a boundary-match simulation (0 false positives on adversarial legit URLs, all tracker URLs matched). Categories follow existing conventions (consent tools and fonts → functional, video → marketing, ad-tech/DMP → marketing, session/analytics → analytics).

Fixed

  • Map tiles, lazy-loaded embeds and runtime-injected stylesheets now blocked before consent (#163, #167). Three third-party patterns set a resource URL at runtime and slipped past the script/iframe/network blocker: map widgets (Leaflet/OpenStreetMap, the Bricks Map element) draw the map by assigning tile URLs to <img> (#163), Bricks' native lazy-load parks an embed URL in data-src and later does iframe.src = data-src when the element scrolls into view (#167), and Google Fonts loaded through Web Font Loader (webfont.js) creates a <link> and sets its href to a fonts.googleapis.com stylesheet after the page has loaded. In both cases the resource loaded (and the visitor's IP reached the third party) with consent denied. The src setter is now gated on the HTMLImageElement and HTMLIFrameElement prototypes, and the href setter on HTMLLinkElement: a cross-origin resource whose URL matches a blocked provider in a denied category is parked (the URL is held in data-faz-src / data-faz-href, no request is made) until consent, then restored by the standard restore pass (parked iframes are hidden and revealed again on restore; tiles are left in place so map layout is undisturbed; a stylesheet only loads once its href is restored). Tightly scoped and fast-pathed — same-origin, relative, data: and blob: resources bail immediately, so theme assets and media-library uploads are untouched and there is no per-resource provider scan on a normal page. The gate covers the el.src = … / el.href = … property assignment these libraries use. A URL committed at runtime via setAttribute(…) or srcset is out of scope for this gate: server-rendered markup is still handled by the output-buffer blocking, but a runtime setAttribute/srcset assignment on a main-document element is not intercepted. Reported on a Bricks site with a Leaflet map and a Bricks Video element (both verified blocked live on the reporter's sandbox), and the Web Font Loader case reported separately for Google Fonts.
  • Blocker-template catalogue re-synced with the blocking engine. 17 legacy one-click templates (Google Analytics, YouTube, Twitter/X, TikTok, LinkedIn, Hotjar, Matomo, HubSpot, Pinterest, Reddit, Instagram, Tumblr, Vimeo, Calendly, Typeform, Google Maps, Mixcloud) had drifted from the corresponding Known_Providers entries: patterns added to the engine over the years (inline signatures like twq(/ttq.load(/_gaq, URL variants like youtu.be/x.com/pin.it, WordPress-plugin bundle patterns) were missing from the templates an admin applies. Templates now carry the engine's pattern list verbatim; template-curated cookies that the engine was missing were folded back into the engine (_hjIncludedInPageviewSample, Vimeo __ssid, the Matomo _pk_*/mtm_*/MATOMO_SESSID family). The YouTube template's generic-named cookies (CONSENT, GPS, PREF) were dropped instead of promoted: in the global shred map they could exact-match an unrelated first-party cookie. A matomo-tag-manager template was added so the Tag Manager patterns (previously bundled into the Matomo template) stay available in the catalogue, matching the engine's separate entry.
  • Banner chrome now translates on non-English single-language sites (#164). "Always Active" and the cookie-audit-table column headers (Cookie / Duration / Description) follow the WordPress site locale when the FAZ default language is the stock en on a single-language site, instead of staying English; the resolved build locale is folded into the banner-template cache key so a WordPress locale switch invalidates the cached banner.
  • European Portuguese (pt-PT) banner content corrected (#159). Community fix to the bundled pt-PT banner strings.