Extensões do Navegador Firefox
Entrar
Ícone da extensão

Histórico de versões do F.B. Sponsored/Ad Post Blocker - 25 versões

F.B. Sponsored/Ad Post Blocker por Inky

Ainda não existem avaliações
0 de 5 estrelas
5
0
4
0
3
0
2
0
1
0
Histórico de versões do F.B. Sponsored/Ad Post Blocker - 25 versões
  • Cuidado com versões antigas! Essas versões são exibidas com propósito de referência e testes.Devemos sempre usar a versão mais recente de uma extensão.

  • Versão mais recente

    Versão 1.1.76

    Lançado em 11 de set de 2026 - 92,96 KB
    Funciona em firefox 109.0 em diante, android 120.0 em diante
    Ads still losing their picture and keeping everything else — Wayfair by
    screenshot, and Great Rail Journeys straight from the panel, which listed the
    same card under HIDDEN BY SHAPE and under NOT HIDDEN. 1.1.75 fixed the
    wrong half of this.
    • The climb ran out of steps. It was capped at fourteen levels, and
      Facebook nests a call-to-action block twenty-odd elements below the card, so
      a climb starting at an outbound link never reached the card and kept whatever
      fitted on the way up — the media block. Raised to thirty.

    No fixture caught this because every fixture card was four levels deep. There
    is one thirty levels deep now, and it failed before this change.
    • Nothing enforced "hide whole cards". Whatever route picks an element, if
      it is feed-post width the thing to hide is the card, so the hide now walks up
      until the next step would leave it.
    • That walk could have taken the entire feed. It stops when a parent holds
      more than one card-shaped child — but a post that is already hidden has no
      box, so a feed column with everything else hidden looks exactly like a single
      card. On a short feed it would have hidden the lot. It now asks whether the
      siblings are posts rather than whether they are visible. Found by the
      harness, before it ever ran on a page.
    • Fixtures now sit beside a neighboring post. The sixteen nesting wrappers
      were indistinguishable from a card's own — each holding one child of the same
      width — so the expand-to-card walk climbed out of the fixture and into the
      harness itself. On a real page those wrappers belong to the card; here they
      do not, and nothing said so.
    • The panel reports which rule made each hide (via label / via shape).
      Both report "sponsored", so a partial hide looked identical whichever
      produced it, and telling them apart took a screenshot and a guess.

    Código fonte publicado sob Licença MIT

    Baixe o Firefox e instale a extensão
    Baixar arquivo
  • Versões mais antigas

    Versão 1.1.65

    Lançado em 11 de set de 2026 - 78,62 KB
    Funciona em firefox 109.0 em diante, android 120.0 em diante
    • DESKTOP-AD-LABELS.md — a record of every mechanism tried against ads
      whose label cannot be read from the DOM, and how each was ruled out. Eleven of
      them: leaf text, non-leaf own text, SVG <text>, <use> sprites, live
      aria-labelledby, rescue-from-removal, a documentElement-rooted observer,
      the /ads/about/ path, CSS ::before/::after content, background-image
      and mask-image.

    Written because the answer to "have we tried X?" was becoming expensive. The
    next attempt should start from what is already eliminated.


    data-ad-rendering-role is still not an ad marker, despite being all over
    these cards and looking ideal when nothing else was left. Measured on a live
    feed: a local buy-sell group post — "Oakland County, MI Sell…" — reported

    ad-roles=profile_name,story_message,meta,title ad-preview=yes ads/about=no


    Not an ad. data-ad-preview and data-ad-comet-preview are no better; the
    same post carried those too. The long-standing warning in classifyLabel now
    carries a 2026 date and this counter-example, in the code and in the doc.


    It does not hide ads whose label is absent from the page text — the Dyson and
    Power Crunch formats. textContent on a Dyson card reads
    Dyson Verified account · Shared with Public…: the icon titles are present
    and the word "Ad" simply is not. That is not obfuscation to see through; there
    is nothing there.

    The remaining option is a shape heuristic — advertiser domain, call-to-action,
    and a byline anchor with no path — left unimplemented because it would also
    match a friend sharing a news article. The fixture corpus and its
    expect: visible guards exist to make that decision measurable if it is ever
    taken.

    Código fonte publicado sob Licença MIT

    Baixar arquivo
  • Versão 1.1.56

    Lançado em 11 de set de 2026 - 70,89 KB
    Funciona em firefox 109.0 em diante, android 120.0 em diante
    • The unhidden-card report now shows how a label could be reached, not just
      what text is present.
      Two ad cards in a row reported this shape:

    #2 680x837 cls=x1lliihq
    span:"fairlife" span:"·" a:"#fairlifepartner" span:"FAIRLIFE.COM"


    Note the span:"·" — the separator that sits after "Ad" in Facebook's
    byline — with no "Ad" text anywhere on the card. Different advertisers, same
    absence, so on these cards the label is not rendered text and the panel had
    no way to say what it actually is.

    Each card now also reports the three remaining mechanisms by which "Ad" could
    be carried: <use> sprite references and what they resolve to,
    aria-labelledby targets (falling back to the label cache when Facebook has
    already deleted the span), and plain aria-label values. Example from a
    harness card with no "Ad" text at all:

    evidence: by#lbl1->"Ad" aria:"Sponsored content"

    Whichever line carries "Ad" is what detection has to read.


    Because every fix since 1.1.51 was chosen from a console probe, and probes race
    a DOM that deleted 125 of 128 label nodes in 40 seconds. Three of them looked
    right and none landed. This reports from inside the content script, against the
    same document the scan sees, and it costs nothing until the panel is opened.

    Código fonte publicado sob Licença MIT

    Baixar arquivo
  • Versão 1.1.55

    Lançado em 11 de set de 2026 - 69,89 KB
    Funciona em firefox 109.0 em diante, android 120.0 em diante
    • The VISIBLE, NOT HIDDEN report was unreadable. Its first live run came
      back as ten identical span:"Facebook" entries per card. Those are icon
      <title> elements — leaves with text, no box, dozens per card — and taking
      the first ten in DOM order crowded out every label that mattered.

    It now reports only leaves that actually render, each text once. The same
    card in a harness goes from ten span:"Facebook" to
    span:"Verkada" span:"Ad" span:"See more".
    • Landmarks were read off the wrong element. The report used
      getAttribute on the card's outermost div, so every card looked
      landmark-less — including ones the extension anchors without trouble. It now
      uses closest() and querySelector(), and says whether the landmark is on
      the card or one of its descendants.

    This matters for the open question: the live report showed 680x781 ad cards
    with no landmarks, while posts of the same width were being hidden
    successfully. That contradiction was an artefact of where the attribute was
    read, not a fact about the page.

    Código fonte publicado sob Licença MIT

    Baixar arquivo
  • Versão 1.1.54

    Lançado em 11 de set de 2026 - 69,19 KB
    Funciona em firefox 109.0 em diante, android 120.0 em diante
    • The diagnostics panel now reports what it is missing. A VISIBLE, NOT
      HIDDEN
      section lists the post-sized cards on screen that were not hidden,
      with each card's dimensions, landmark attributes, and the short texts found
      inside it:

    VISIBLE, NOT HIDDEN:
    #1 680x783 role=- posinset=- pagelet=-
    span:"Verkada" span:"Ad" span:"See more" span:"Like"


    Three releases in a row were aimed at ads that stayed visible, each built on
    a plausible reading of a console probe, and none of them landed. The reason
    is in the numbers from an earlier run: of 128 label nodes recorded over 40
    seconds, 125 were deleted by Facebook before they could be examined
    again. Every querySelectorAll probe sampled an instant of that, and five
    consecutive probes gave five different answers.

    Reporting from inside the content script is not subject to that race. It sees
    the same document the scan sees, and it says what the label element actually
    is — whatever Facebook wraps it in this week — instead of requiring a guess.

    Computed only when the panel is opened, so it costs nothing during browsing.


    matched 10, anchored 10 on 1.1.53 means everything recognised is being
    hidden, so the ads getting through are not being recognised at all. Nothing in
    the panel could say why, because it only described what the extension did.
    This closes that gap before any further attempt at the cause.

    Código fonte publicado sob Licença MIT

    Baixar arquivo
  • Versão 1.1.53

    Lançado em 11 de set de 2026 - 67,8 KB
    Funciona em firefox 109.0 em diante, android 120.0 em diante
    • Ads whose label is drawn as SVG text were never examined. Facebook renders
      some feed-ad labels as vector text rather than a <span> — an inline <svg>
      holding <text>Ad</text>. Inspecting one on a live feed said it exactly:

    classifies as Ad: true selectable: false

    classifyLabel recognises it fine; its leaf branch reads textContent like
    any other element. But LABEL_SELECTOR listed span, a, use, [aria-label],
    [aria-labelledby]
    and not text, so the scan never handed it over. Those ads
    were never looked at, whoever the advertiser was.

    text is now in the selector. SVG text nodes are rare next to spans, and the
    selector runs once per scanned subtree rather than per element, so the cost is
    negligible.

    Verified before and after against a harness with an ad card labelled by
    <text>Ad</text> at realistic depth: 1.1.52 leaves it visible, 1.1.53 hides
    it.


    Whether those ads can then be anchored. A viewport sweep found the visible
    ad card carried no role="article", no aria-posinset and no data-pagelet,
    so findPostContainer may still have nothing to grab even now that the label is
    seen.

    The diagnostics panel answers that without further probing: if matched now
    climbs above anchored, detection is fixed and anchoring is the remaining
    problem, and the fix is a card-sized-ancestor climb of the kind
    climbToChildOf already does for the sidebar rail.

    Código fonte publicado sob Licença MIT

    Baixar arquivo
  • Versão 1.1.52

    Lançado em 11 de set de 2026 - 66,79 KB
    Funciona em firefox 109.0 em diante, android 120.0 em diante
    • Ads whose label arrives in two steps were never hidden. Facebook inserts
      the label span empty and fills it a moment later:

    html
    <span id="_r_7bt_"></span> <!-- inserted -->
    <span id="_r_7bt_">Ad</span> <!-- text arrives separately -->


    rememberLabelTarget reads "" on insertion and bails, and the text that
    follows is a text node — which the observer's addedNodes loop skipped
    outright. The label was therefore never cached and the post never
    re-examined, leaving the ad on screen with everything needed to hide it
    present in the DOM.

    Confirmed on a live desktop feed: a visible 781px sponsored post, its label
    span present reading "Ad", its referrer inside an aria-posinset and not
    in a dialog — every condition for resolution satisfied, and not hidden.

    Text nodes now complete their parent label instead of being dropped. Kept to
    O(1): only a parent carrying an id and holding no element children can be
    one of these spans, so it is a textContent read on a leaf plus a Map set,
    not a subtree walk. rememberLabelTarget resolves forward from there, so no
    extra scan is scheduled.

    Verified before and after against a harness reproducing the two-step
    insertion at realistic depth: 1.1.51 leaves the post visible, 1.1.52 hides it.
    • The diagnostics panel reports late-text labels — how many labels completed
      this way. Non-zero confirms the path is live; zero on a feed with ads means
      they are being built some other way.


    This is why the DOM probes disagreed with each other all session. Of 128 labels
    recorded over 40 seconds on a live feed, 125 were removed by Facebook before
    they could be examined again. Sampling with querySelectorAll catches an
    instant of that; only the observer sees the transitions.

    Código fonte publicado sob Licença MIT

    Baixar arquivo
  • Versão 1.1.51

    Lançado em 26 de ago de 2026 - 65,65 KB
    Funciona em firefox 109.0 em diante, android 120.0 em diante
    • The extension silently did nothing on desktop. document.body was null
      when the content script ran, so this line threw:

    TypeError: MutationObserver.observe: Argument 1 is not an object
    content.js:1368


    Module evaluation stopped there. The observer never attached, the initial
    scan never ran, and main() never executed — but the message listener
    registers earlier in the file, so the popup kept answering and the extension
    looked completely healthy. Settings on, permission granted, no visible error,
    four sponsored posts sitting in the feed untouched.

    run_at: "document_idle" is supposed to guarantee a body exists. On
    facebook.com in Firefox it does not, at least sometimes. The startup now
    waits for ` to appear instead of assuming it, watchingdocument.documentElement` until it does.

    Verified before and after against a harness with document.body forced to
    null: the previous build throws, this one starts clean and completes once a
    body appears.
    • The diagnostics panel reports a BOOT: line whenever startup has not
      completed. This failure was invisible from the page and from the Browser
      Console — it only surfaced in the page console — and the panel showing
      "0 scans, 0 observer calls" after 147 seconds on a live feed is what led to
      it. Now it says so directly.


    Nothing was wrong with detection. Facebook had not changed anything: the
    labels, aria-labelledby portal spans and aria-posinset anchors were all
    present and would have resolved normally.

    Código fonte publicado sob Licença MIT

    Baixar arquivo
  • Versão 1.1.50

    Lançado em 16 de ago de 2026 - 64,48 KB
    Funciona em firefox 109.0 em diante, android 120.0 em diante
    • The mobile feed stopped paging because of a single attribute write.
      1.1.49 preserved every post's height and the feed still stalled, so the
      problem was never the geometry.

    Isolated by hand on a live phone feed, with the extension installed but all
    hiding switched off:

    | What was done to 6 feed children | Feed after 15s |
    | --- | --- |
    | Nothing (extension inert) | +58 posts — paging normally |
    | data-fbsb-hidden + inline style | stalled |
    | data-fbsb-hidden only, no styling | stalled |
    | visibility: hidden on their children | +34 posts — still paging |

    Setting one data attribute, changing nothing visible, was enough to stop
    Facebook's pager for the full window. Its own observers evidently treat a
    direct feed child that has been written to as changed underneath it, and stop
    reconciling.

    So the post element is now untouchable — no style, no attribute. Both go on
    its children instead: every element child gets visibility: hidden, and the
    marker attribute rides on the first of them. The children keep their boxes,
    so the post keeps its height, and Facebook sees a feed it still owns.

    hiddenPosts is still keyed by the post, so recycled-node detection resolves
    a marker to its parent when the marker is not itself a key.

    Desktop is unchanged: it removes posts with display: none as before, and
    nothing there is virtualised or reconciled this way.


    That the feed keeps paging with the extension actually doing the hiding, over a
    long scroll — the table above was measured by hand, six posts at a time. It
    also leaves blank space where each hidden post was, which is now the only known
    remaining problem on mobile rather than one of several.

    Código fonte publicado sob Licença MIT

    Baixar arquivo
  • Versão 1.1.49

    Lançado em 16 de ago de 2026 - 63,29 KB
    Funciona em firefox 109.0 em diante, android 120.0 em diante
    • The mobile feed stopped loading after about 15 seconds of scrolling, and
      it was us.
      Established by control test on stock Firefox for Android:
      extension disabled, the feed pages in new posts indefinitely; extension
      enabled, it stalls. Same account, same feed, same browser.

    Facebook virtualises that feed and decides what to page in next by measuring
    rendered content. display: none removes a post's height from that
    measurement, so hiding posts corrupts the figure the loop works from — hide
    enough and it stops paging entirely. This also explains two things that never
    quite added up: unchecking "Hide posts from Pages/Groups you don't follow",
    which hides the largest share of any feed, made the blackout go away; and
    1.1.44's pre-hiding, which hid far more posts than anything before it, made
    it dramatically worse.

    On mobile a post is now hidden with visibility: hidden instead. It becomes
    invisible while its box keeps exactly the height it had, so Facebook's
    accounting sees a feed that never changed shape.

    The cost is deliberate and visible: a hidden ad leaves blank space where it
    was, rather than vanishing.
    That is the same gap reported throughout
    testing, now accepted on purpose — blank space you can scroll past beats
    content you cannot reach. Desktop is unchanged and still removes posts
    outright; nothing there is virtualised this way.


    With placeholder mode on, mobile now shows both the placeholder bar and the
    blank space of the post behind it. Untidy, and left alone for now: the point of
    this release is to find out whether preserving height keeps the feed alive.

    Código fonte publicado sob Licença MIT

    Baixar arquivo
  • Versão 1.1.48

    Lançado em 16 de ago de 2026 - 62,16 KB
    Funciona em firefox 109.0 em diante, android 120.0 em diante
    • Real timings in the diagnostics panel. Three costs, kept apart, with each
      shown as a share of wall-clock time on the page:

    over 47s on page:
    scan 312ms 0.7% (204 scans, 18422 els)
    observer 88ms 0.2% (1310 calls)
    retry 4ms 0.0% (12 ticks)


    They are separated because they fail for different reasons, and 1.1.35
    proved a healthy scan figure says nothing about the other two: it reported
    1.0ms across 274 scans while the page was unusable, because the cost was in
    the retry loop, which never calls scanRoot. The observer had the same blind
    spot until 1.1.42. Now all three are visible, and on a phone, which is where
    none of them could be read before.

    The percentage is the number worth reading. Milliseconds alone mean nothing
    without knowing over how long they accumulated.

    Scan timing was already collected in release builds — reportStats returns
    early when DEBUG is false, so nothing ever reset it — it simply had no way
    to be seen. Observer timing is now collected unconditionally too: two
    performance.now() calls per callback cost far less than what they measure,
    and a figure that only exists in a build nobody installs is not a
    measurement. Retry timing is new.

    In a DEBUG build these are a rolling 2s window rather than cumulative,
    because reportStats resets them. Worth remembering before comparing figures
    between the two builds.

    Código fonte publicado sob Licença MIT

    Baixar arquivo
  • Versão 1.1.47

    Lançado em 16 de ago de 2026 - 60,88 KB
    Funciona em firefox 109.0 em diante, android 120.0 em diante
    • The mobile feed was slow to catch up, and it was the extension's fault.
      Confirmed by control test: with the extension disabled the same feed loaded
      quickly and normally.

    A label whose post Facebook hasn't rendered gets deferred to the reveal
    observer — but it was also being queued into the retry loop, which
    re-examines every entry every 50ms for a full 8 seconds. Those retries can
    never succeed: the candidate has no box and won't get one until Facebook
    reveals it, at which point the IntersectionObserver handles it anyway. On a
    virtualised feed most sponsored labels take that path, so the queue filled
    with work that was guaranteed to be wasted.

    This is the 1.1.35 regression's shape reached from a different direction — a
    flooded retry queue burning the 50ms loop — and the same lesson applies:
    queue only what can actually resolve later. Deferred labels are now left to
    the reveal observer, which is already waiting for exactly the event that
    would make them resolvable.

    unfollowed labels were already excluded on the same reasoning. This extends
    it to the case virtualisation creates.
    • The diagnostics panel reports reveals — how many scans the reveal path has
      triggered. It should track how far you have scrolled; climbing while the page
      is still means the observer is firing when it shouldn't.

    Código fonte publicado sob Licença MIT

    Baixar arquivo
  • Versão 1.1.46

    Lançado em 16 de ago de 2026 - 60,05 KB
    Funciona em firefox 109.0 em diante, android 120.0 em diante
    • The breakage warning fired on every mobile page load, blaming Facebook for
      the extension working correctly.
      Observed on a real device running 1.1.45:
    [fbsb] 20 labels matched, none could be anchored to a post ... If this is
    a phone, the mobile class was probably renamed.

    The mobile class had not been renamed — the warning says so itself two lines
    earlier, reporting the gate as mobile. What actually happened is that most
    of a virtualised feed is unrendered at any moment, those candidates have no
    box, and since 1.1.45 they are deliberately deferred to the reveal observer.
    The 1.1.42 check counted every deferral as a failure to anchor, so it
    tripped its threshold on any mobile feed within a second of loading.

    A miss on a post Facebook hasn't rendered is now counted separately and
    excluded from the threshold. What remains is what the check was written for:
    labels that should have anchored against something rendered, and didn't.

    This mattered beyond the noise. The warning is not DEBUG-gated, so it
    reached anyone with a console open, and it pointed confidently at the wrong
    cause — the exact failure mode 1.1.42 was built to prevent.
    • The diagnostics panel reports deferred alongside the other counts. A large
      number there next to a healthy anchored is the reveal mechanism working,
      not failing.

    Código fonte publicado sob Licença MIT

    Baixar arquivo
  • Versão 1.1.45

    Lançado em 16 de ago de 2026 - 59 KB
    Funciona em firefox 109.0 em diante, android 120.0 em diante

    Código fonte publicado sob Licença MIT

    Baixar arquivo
  • Versão 1.1.44

    Lançado em 15 de ago de 2026 - 57,28 KB
    Funciona em firefox 109.0 em diante, android 120.0 em diante
    • Ads kept appearing on a phone while the badge said posts were hidden.
      Both statements were true. Facebook virtualises the mobile feed: only a
      window of posts is rendered, the rest sit at display: none with a filler
      element reserving their scroll height. Measured on a live phone feed, 42 of
      64 feed children were hidden at once, behind a filler 13,226px tall.

    A virtualised-out post reports offsetWidth 0 — it has no box. The width
    rule in findMobilePostContainer read that as "narrower than 60% of the
    feed" and returned null, so every off-screen ad was classified, rejected,
    and forgotten. Facebook then revealed it on scroll, unfiltered. The posts
    that were on screen resolved normally, which is why the badge kept
    climbing while ads stayed visible.

    The rule exists to reject nested carousel items — real boxes that happen to
    be narrow. It can say nothing about an element with no box at all, so it is
    now applied only to elements that have one. "Not currently rendered" and
    "too narrow to be a post" are different claims, and only the second is
    evidence against something being a post.

    Desktop is unaffected: nothing there is virtualised this way, so every
    candidate has a box and the rule applies exactly as before.


    Long blank gaps between posts are a separate problem with the same root.
    Facebook sizes that filler assuming the posts it virtualised still occupy
    their heights; hiding one shrinks the content without shrinking the filler.
    This release does not address that.

    It is also not yet known whether a hide applied while a post is virtualised
    out survives Facebook revealing it — if Facebook overwrites the inline style,
    the ad returns, and the observer would not notice because it watches
    childList only, not attributes. That is the next thing to measure, and the
    reason this ships as one change rather than two.

    Código fonte publicado sob Licença MIT

    Baixar arquivo
  • Versão 1.1.42

    Lançado em 15 de ago de 2026 - 53,39 KB
    Funciona em firefox 109.0 em diante, android 120.0 em diante
    • Structural breakage now announces itself. Every mobile code path is gated
      on ` and the app banner on.fixed-container.bottom`. Both names are Facebook's to change, and when
      either goes the symptom is silence: labels still classify, nothing anchors,
      and the extension looks completely healthy while hiding nothing. 1.1.39 spent
      three stacked fixes inside exactly that blind spot.

    The check is not "does html-renderer still match" — that only catches the
    rename already imagined. It counts classified labels against anchored ones,
    and warns once per page if 20 labels match while none resolve. That signature
    means detection works and container resolution does not, which is what a
    structural rename looks like on either layout, desktop landmarks included.
    The warning reports which layout gate was taken so the two cases can be told
    apart immediately.

    The app banner gets its own check, since it is the one target anchored by
    selector rather than by climbing: reaching resolution at all means the text
    matched and the layout gate passed, so failing to find the bar is
    unambiguous and needs no threshold.

    This one is deliberately not DEBUG-gated. A diagnostic that only speaks
    in a build the user isn't running does not fix a silent failure. It is one
    console.warn, at most once per page, and it cannot fire on a page where
    anything at all was successfully hidden.


    It warns; it does not adapt. A structural fallback was considered and rejected:
    guessing the layout from "no ARIA landmarks, shallow document" would let a
    wrong guess disable every mobile path silently — reintroducing the failure mode
    this is meant to remove, one level further down.

    Código fonte publicado sob Licença MIT

    Baixar arquivo
  • Versão 1.1.41

    Lançado em 14 de ago de 2026 - 51,52 KB
    Funciona em firefox 109.0 em diante, android 120.0 em diante
    • Declared an Android compatibility floor of 120. AMO validation flagged
      permissions.request as unimplemented at the stated minimum, and it was
      right: per Mozilla's compatibility data that API landed in Firefox for
      Android 120, while the manifest claimed 109. Below 120 the "Allow on
      facebook.com" button in both the popup and the setup page would have done
      nothing at all — on the one platform 1.1.39 exists to serve. 120 is also
      where Firefox for Android gained general extension support, so it is the
      floor at which any of this is installable anyway.

    gecko_android sets a compatibility range separate from desktop, which is
    what it is for. Desktop stays at 109.


    AMO still warns that data_collection_permissions postdates the stated
    minimum (140 desktop, 142 Android). Those are left alone deliberately: it is
    a manifest key, unknown keys are ignored by older browsers, and nothing
    behaves differently. Silencing them would mean raising the desktop floor from
    109 to 140 — cutting off every user between — to quiet a cosmetic warning
    about a key whose entire content is a declaration that no data is collected.

    Código fonte publicado sob Licença MIT

    Baixar arquivo
  • Versão 1.1.39

    Lançado em 14 de ago de 2026 - 49,77 KB
    Funciona em firefox 109.0 em diante
    • Works on Facebook's mobile web layout. Installed on a phone the
      extension hid nothing at all, while looking perfectly healthy: permissions
      granted, content script injected, no errors. Three separate faults were
      stacked behind that, each invisible until the one before it was fixed.

    Container resolution had nothing to anchor to. Mobile web ("weblite" —
    it tags ` withhtml-renderer) is a different app, not a narrow
    desktop. It exposes no ARIA landmarks whatsoever: no
    role="article", noaria-posinset, nodata-pagelet, norole="complementary", and the
    author header is a plain
    <div>rather than a heading. Every strategy infindPostContainerkeys off one of those, so all of them returnednull.findMobilePostContainerclimbs instead: that layout's feed is a single
    container whose direct children are the posts, so the post is the last
    ancestor before the first ancestor with many children. A width check
    rejects nested carousels, which can also clear the child-count bar. For
    unfollowed, the label must sit inside the container's first child —isAuthorLevelLabel`'s "don't hide a post over a quoted author's Follow
    button" rule, expressed without headings to key off.

    Ad labels were unmatchable. Weblite draws its icons from a font mapped
    into the Private Use Area and packs them into the same span as the text, so
    an ad's label is literally "Ad\u{F078B}\u{F17E0}". Those glyphs are
    category Co, and INVISIBLE_CHARS_RE stripped only Cf and Mn, so the
    cleaned text never equalled "Ad". This is precisely why mobile hid
    unfollowed posts but never ads: "Follow" happens to sit in a span of its
    own, with no icons alongside it.

    The decoy filter threw the labels away before either fix could matter.
    isImplausiblyShallow treats anything within 10 levels of ` as a
    portal/decoy span, which holds on desktop where real posts sit 15+ deep.
    Weblite's entire document is about 11 levels and an ad label measures
    exactly 10, so every real ad was discarded before resolution was attempted.
    The limit is now layout-aware (
    MOBILE_SHALLOW_DEPTH_LIMIT`).

    Desktop behaviour is unchanged. The Co strip does apply to both, but it
    can only shorten text: the neighbouring organic-post span is a timestamp
    plus the same icons, "1h\u{F212D}\u{F3196}", which cleans to "1h" and
    matches no target. Confirmed against a live desktop feed as well as mobile.

    Código fonte publicado sob Licença MIT

    Baixar arquivo
  • Versão 1.1.38

    Lançado em 13 de ago de 2026 - 46,91 KB
    Funciona em firefox 109.0 em diante
    • The DEBUG perf line now reports MutationObserver cost separately. It
      previously timed scanRoot only, so everything the observer callback does
      including cacheLabelTargets walking every subtree Facebook inserts during
      its initial render was invisible. That blind spot had already hidden one
      regression: the retry-loop freeze fixed in 1.1.35 reported a healthy
      1.0ms across 274 scans while the page was unusable.

    Measured on a real feed, the observer costs 2–16ms per 2s window and falls
    after load rather than spiking during it, which ruled it out as the cause of
    a slow first paint that had been attributed to it.
    - README leads with an Install section pointing at the store listings.
    Both sideload sections are now labelled Development: a temporary add-on
    disappears on restart and never updates, so it is the wrong way to install
    this for normal use.

    No behaviour change in release builds: the instrumentation is DEBUG-only.

    Código fonte publicado sob Licença MIT

    Baixar arquivo
  • Versão 1.1.37

    Lançado em 13 de ago de 2026 - 45,66 KB
    Funciona em firefox 109.0 em diante
    • A setup page opens once, on first install. The popup prompt added in
      1.1.36 only helps someone who opens the popup, and a new Firefox user has no
      reason to: the extension appears installed and simply does nothing. The page
      explains that facebook.com access is still needed and requests it directly.

    It reads the current permission state rather than assuming: where access is
    already granted always the case on Chromium it shows a short "you're all
    set" confirmation instead of asking for anything. Gated on
    reason === "install" so upgrades don't reopen it, and the tabs.create
    call is wrapped, because failing to open a setup page must not take the
    background script down with it.
    - build.ps1 copies onboarding/. The payload is an explicit file list, so a
    new directory ships only when added here — worth remembering when adding
    another.

    Código fonte publicado sob Licença MIT

    Baixar arquivo
  • Versão 1.1.35

    Lançado em 13 de ago de 2026 - 41,37 KB
    Funciona em firefox 109.0 em diante
    The feed stopped loading. 1.1.30 queued any element carrying an
    aria-labelledby whose target didn't resolve, on the theory that ad labels
    arrive late; 1.1.33 then tightened the retry loop to one frame. Facebook has
    a great many elements with dangling label references a 300-post feed
    carries roughly 1,800 — so the queue flooded and every entry was
    re-examined every 16ms for the full 8s window.

    The theory was wrong regardless: late-arriving labels were never what hid
    feed ads. Following the sprite reference (1.1.32) was. That queueing is
    removed, and the retry loop is back to 50ms.
    - The retry queue is now capped (MAX_PENDING_LABELS). It exists for ads
    staged in a hidden node and reparented a moment later, which is a handful of
    entries at most; a future change that queues too eagerly should degrade
    detection, not the page.

    Código fonte publicado sob Licença MIT

    Baixar arquivo
  • Versão 1.1.33

    Lançado em 13 de ago de 2026 - 39,25 KB
    Funciona em firefox 109.0 em diante

    Código fonte publicado sob Licença MIT

    Baixar arquivo
  • Versão 1.1.21

    Lançado em 12 de ago de 2026 - 31,31 KB
    Funciona em firefox 109.0 em diante
    Added CHANGELOG.md for version update notes

    Código fonte publicado sob Licença MIT

    Baixar arquivo
  • Versão 1.1.20

    Lançado em 12 de ago de 2026 - 28,77 KB
    Funciona em firefox 109.0 em diante
    F.B. Sponsored/Ad Post Blocker — 1.1.20

    Fixed
    Sponsored posts were not being hidden at all. Facebook's scrambled "Sponsored" label pads the real characters with decoy spans, distinguished by class-list length — but the direction of that signal had flipped. The filter was discarding the real characters (~22 classes) and keeping the decoys (~7). Detection now assembles every plausible partition and matches against any, so a future flip can't silently kill it again.
    Hidden posts immediately reappeared. Any node added inside a hidden post was treated as Facebook recycling the container, and the post was restored. Ads mutate constantly after being hidden (video players, lazy-loaded media), so they were un-hidden within milliseconds — and never re-examined, because scanning only ever runs on newly-added nodes. Restoring now re-checks the evidence first.
    Group posts were wrongly hidden. A post embedding a shared post inherited the quoted author's "Follow" button, so a group you're a member of quoting someone you don't follow was hidden entirely. Follow/Join now only counts for the post's own author.
    The toolbar counter reset by itself. The background script is an event page — Firefox suspends it after ~30s idle, discarding the in-memory tally. The badge then jumped back to 1 while the popup reported 0. The count is now read back from the badge itself, which survives suspension, with per-tab serialisation so concurrent updates can't lose increments.
    Performance
    Element text is now read only on leaves and character-split labels. Wrappers are skipped — the leaf holding the text is visited in its own right, so reading wrappers re-walked the same subtree once per nesting level.
    The getComputedStyle walk is gated behind a structural check, instead of running on any element with two or more children.
    Facebook's portal accessibility spans (<span id="r…_">, which contain the word "Sponsored" but belong to no post) are dropped before entering the retry queue.
    Unfollowed labels no longer enter the retry queue — a Follow button and its author header always render together, so retrying can't change the outcome.
    Changed
    DEBUG now defaults to false. When enabled it reports the running build version, a rolling scan-cost summary, and unresolved matches capped at 15.
    README rewritten to correct several stale claims and document the traps.
    Known issues
    Right-column sidebar ads are detected but not hidden. They have no aria-posinset, and the sidebar no longer carries the role="complementary" landmark the fallback relied on. Hiding nothing was preferred over risking an over-broad match.
    Unfollowed detection assumes the post's own author header is the first heading in the post. If it isn't, those posts are missed (fails quiet rather than hiding wrongly).
    Feed ad detection rests on the scrambled-text path; the "… sponsored content" aria-label only matches sidebar ads. Some feed ads may slip through.
    English-language labels only.

    Código fonte publicado sob Licença MIT

    Baixar arquivo
  • Versão 1.1.10

    Lançado em 12 de ago de 2026 - 23,01 KB
    Funciona em firefox 109.0 em diante
    Fixes a bug where a "Follow [creator]" button in a Reels comment panel could be mistakenly resolved through the sidebar ad detection path, incorrectly hiding the entire comments panel. The "hide unfollowed Pages/Groups" feature no longer uses that fallback at all, it's now restricted to genuine feed posts only. No other behavior changes.

    Código fonte publicado sob Licença MIT

    Baixar arquivo
Ir para a página inicial da Mozilla

Extensões

  • Sobre
  • Blog de extensões do Firefox
  • Workshop de extensões
  • Central do desenvolvedor
  • Diretivas do desenvolvedor
  • Blog da comunidade
  • Fórum
  • Relatar um erro
  • Guia de análise

Baixar

  • Download Firefox
  • Windows
  • macOS
  • iOS
  • Android
  • Linux
  • All

Versões mais recentes

  • Nightly
  • Beta

Firefox para empresas

  • Enterprise

Comunidade

  • Connect
  • Contribute
  • Developer

Seguir

  • Instagram
  • YouTube
  • TikTok
  • Bluesky
  • Podcast
  • Privacidade
  • Cookies
  • Jurídico

Exceto onde de outra forma notado, o conteúdo deste site está licenciado sob a Creative Commons Licença de Atribuição Compartilha-Igual v3.0 ou qualquer versão posterior.