Related discussion:
- https://github.com/uBlockOrigin/uBlock-issues/discussions/2412#discussioncomment-4421741
The new option is `to=` and the value is a list of domain list with
similar syntax as `domain=` option. Entity-based syntax is supported,
and also negated hostname.
The main motivation is to give uBO's static network filtering engine
with an equivalent of DNR's `requestDomains` and `excludedRequestDomains`.
Essentially `to=` is a superset of `denyallow=`, but for now I decided
against deprecating `denyallow=`, which still does not support entity-
based syntax and for which negated domains are not allowed.
This commit also introduces the `from=` option, which is just an alias
for the `domain=` option. The logger will render network filters using
the `from=` version.
Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/1861
The "exceptor" feature has been rewritten, with the following
changes as a result:
- The excepted filters cease to exist when closing the logger
- It's now possible to temporary except network filters
When toggling on/off a temporary exception, filter lists are now
fully reloaded. This simplified managing temporary exceptions, and
made it easy to implement temporary exception for network filters,
but this also means there might be a perceptible delay when
adding/removing temporary exceptions. At this point I consider
this an acceptable side-effect just to bring the ability to easily
create temporary exception for network filters, while this
simplified the existing temporary exception code throughout.
Bring latest changes to procedural cosmetic filtering to uBOL.
Fix procedural filtering used in HTML filters.
Standardize quick hash algorithm used throughout to DJB2
(except that initialization step is skipped):
- http://www.cse.yorku.ca/~oz/hash.html#djb2
These two new pseudo selectors are _action_ operators, and thus can
only be used at the end of a selector. They both take as argument
a string or regex literal.
For `:remove-class()`, when the argument matches a class name, that
class name is removed.
For `:remove-attr()`, when the argument matches an attribute name,
that attribute is removed.
These operators are meant to replace `+js(remove-attr, ...)` and
`+js(remove-class, ...)`, which from now on are candidate for
deprecation in some future.
Once the next stable release is widespread, filter authors must use
these two new operators instead of their `+js()` counterparts.
Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/2329
The supported syntax is exactly as per AdGuard's documentation:
- https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters#extended-css-matches-attr
Though recommended, the quotes are not mandatory in uBO if
the argument does not cause the parser to fail and if there
are no ambiguities.
Additionally, improved the code to better unquote pseudo-operator
arguments, and to bring it closer to how AdGuard does it as per
documentation. When using quotes, `"` and `\` should be escaped
to preserve these characters in the unquoted version of the
argument.
Additionally, it is now possible to have `:has-text()` match the
empty string by just quoting the empty string:
...##foo:has-text("")
Related feedback:
- https://www.reddit.com/r/uBlockOrigin/comments/yzw5pt/
Some CSS4-based selectors are not supported in older browser versions
and this may cause cosmetic filtering to be wholly broken as a result.
The commit here is to isolate generic cosmetic filters from specific
ones in stylesheets such that unsupported CSS4 selectors in generic
cosmetic filters do not cause wholly breakage of cosmetic filtering
on all sites.
`uDom` is old and crusty and `dom` is meant as replacement. The
goal of `dom` is to be simpler and mainly just convenience
methods for handling the DOM with vanilla JS -- this is not a
framework.
Additionally, removed keyboard shortcuts pane which was useful
only on very old versions of Firefox.
Related feedback:
- https://www.reddit.com/r/uBlockOrigin/comments/ye6abt/
Possibly because the Opera sidebar window is a special
case, it appears the scriptlets must be injected at a
later time.
Use a global isolated window variable to detect whether
the scriptlets have really be injected, and ultimately
inject them at main content script time when it is found
they haven't been injected at that point.
This commit make it so scriptlet injections will occur
at the earliest possible time on all platform.
This should also fix the case reported at:
- https://www.reddit.com/r/uBlockOrigin/comments/ye6abt/
Which is caused by the fact that there is no webNavigation
events being fired by the browser. In such case, the changes
here will make it so that uBO will detect that the scriptlet
were not injected and will inject them at main content script
injection time.
This commit adds the ability to inject entity-based plain CSS
filters and also a set of the most commonly used entity-based
scriptlet injection filters.
Since the scripting API is not compatible with entity patterns,
the entity-related content scripts are injected in all documents
and the entity-matching is done by the content script themselves.
Given this, entity-based content scripts are enabled only when
working in the Complete filtering mode, there won't be any
entity-based filters injected in lower modes.
Also, since there is no way to reasonably have access to the
Public Suffix List in the content scripts, the entity-matching
algorithm is an approximation, though I expect false positives
to be rare (time will tell). In the event of such false
positive, simply falling back to Optimal mode will fix the
issue.
The following issues have been fixed at the same time:
Fixed the no-filtering mode related rules having lower priority
then redirect rules, i.e. redirect rules would still be applied
despite disabling all filtering on a site.
Fixed improper detection of changes to the generic-related CSS
content script, potentially causing undue delays when for example
trying to access the popup panel while working in Complete mode.
The scripting MV3 can be quite slow when registering/updating
large content scripts, so uBOL does its best to call the API only
if really needed, but there had been a regression in the recent
builds preventing uBO from properly detecting unchanged content
script parameters.
It's possible to salvage network rule with entity syntax-based
entries in their `domain=` option if there exists at least one
entry which is not entity syntax-based.
For negated entries, these can be unconditionally removed
safely.
This adds support for `redirect=` filters. As with `removeparam=`
filters, `redirect=` filters can only be enforced when the
default filtering mode is set to Optimal or Complete, since these
filters require broad host permissions to be enforced by the DNR
engine.
`redirect-rule=` filters are not supported since there is no
corresponding DNR syntax.
Additionally, fixed the dropping of whole network filters even though
those filters are still useful despite not being completely
enforceable -- for example a filter with a single (unsupported) domain
using entity syntax in its `domain=` option should not be wholly
dropped when there are other valid domains in the list.
With the new csstree-based parser, it should now be
safe to parse `-abp-has` as declarative. There are over
a hundred such cosmetic filters in EasyList, and we want
to have these filters declaratively enforced whenever
possible in order to let the browser do the work natively
rather than rely on JS code.
Consequently, AdGuard URL Tracking Protection (AUTP) has been
added to the set of available filter lists.
However, removeparam= equivalent DNR rules can only be enforced
when granting uBOL broad permissions. If broad permissions are
not granted, removeparam= equivalent DNR rules are ignored.
Exception removeparam= filters are not supported, and these are
present in AUTP and meant to unbreak some websites which are
known to break as a result of removing query parameters.
This is issue might be mitigated in the future by making the
conversion from filters to DNR rules more complicated but this
can never replace the accuracy of uBO's filtering engine being
able to fully enforce arbitrary exception removeparam= filters.
Also, it is not possible to translate regex-based removeparam=
values to DNR rules, so these are dropped at conversion time.
As with other filters to DNR rules conversion, the converter
coallesce many distinct removeparam= filters into fewer DNR
rules.
Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/2292
This will prevent unexpected oversezealous blocking if ever
this happens again. The internal void operator will ensure
no blocking takes place and issue a note about non-existing
operator to the dev tools console.
The new parser no longer uses the browser DOM to validate
that a cosmetic filter is valid or not, this is now done
through a JS library, CSSTree.
This means filter list authors will have to be more careful
to ensure that a cosmetic filter is really valid, as there is
no more guarantee that a cosmetic filter which works for a
given browser/version will still work properly on another
browser, or different version of the same browser.
This change has become necessary because of many reasons,
one of them being the flakiness of the previous parser as
exposed by many issues lately:
- https://github.com/uBlockOrigin/uBlock-issues/issues/2262
- https://github.com/uBlockOrigin/uBlock-issues/issues/2228
The new parser introduces breaking changes, there was no way
to do otherwise. Some current procedural cosmetic filters will
be shown as invalid with this change. This occurs because the
CSSTree library gets confused with some syntax which was
previously allowed by the previous parser because it was more
permissive.
Mainly the issue is with the arguments passed to some procedural
cosmetic filters, and these issues can be solved as follow:
Use quotes around the argument. You can use either single or
double-quotes, whichever is most convenient. If your argument
contains a single quote, use double-quotes, and vice versa.
Additionally, try to escape a quote inside an argument using
backslash. THis may work, but if not, use quotes around the
argument.
When the parser encounter quotes around an argument, it will
discard them before trying to process the argument, same with
escaped quotes inside the argument. Examples:
Breakage:
...##^script:has-text(toscr')
Fix:
...##^script:has-text(toscr\')
Breakage:
...##:xpath(//*[contains(text(),"VPN")]):upward(2)
Fix:
...##:xpath('//*[contains(text(),"VPN")]'):upward(2)
There are not many filters which break in the default set of
filter lists, so this should be workable for default lists.
Unfortunately those fixes will break the filter for previous
versions of uBO since these to not deal with quoted argument.
In such case, it may be necessary to keep the previous filter,
which will be discarded as broken on newer version of uBO.
THis was a necessary change as the old parser was becoming
more and more flaky after being constantly patched for new
cases arising, The new parser should be far more robust and
stay robist through expanding procedural cosmetic filter
syntax.
Additionally, in the MV3 version, filters are pre-compiled
using a Nodejs script, i.e. outside the browser, so validating
cosmetic filters using a live DOM no longer made sense.
This new parser will have to be tested throughly before stable
release.
This solves the following remaining issues regarding specific cosmetic
filtering:
- High rate of false positives in last build
- High number of generated content css files in the package
First iteration of adding scriptlet support. As with cosmetic
filtering, scriptlet niijection occurs only on sites for which
uBO Lite was granted extended permissions.
At the moment, only three scriptlets are supported:
- abort-current-script
- json-prune
- set-constant
More will be added in the future.
Specific plain CSS cosmetic filters are now supported.
Cosmetic filtering will occur only after the user explicitly
grant uBO extended permissions for a given site, so that it
can inject CSS on the site.
A new button in the popup panel allows a user to grant/revoke
extended permissions to/from uBO Lite for the current site.
More capabilities will be carefully added for when extended
permissions are granted on a site, so specific cosmetic
filtering through plain CSS is the first implemented capability.
Generic and procedural cosmetic filtering is not implemented.
The current implementation for plain CSS cosmetic filters is
through declarative content injection, which does not require
the service worker to be alive, the browser takes care to
inject the cosmetic filters.
However declarative CSS injection does not support user
styles, so the injected cosmetic filters are "weak". I consider
this is a browser issue, since user styles are supported by
Chromium, there is just no way in the API to specify user
styles for the injected content.
Also:
- Fixed dark theme issues
- Added Steven Black's hosts file
Keep in mind all this is very experimental and implementation
details in this release may (will) greatly change in the future.
This fixes https://github.com/uBlockOrigin/uBlock-issues/issues/2240 and
should get the desired behavior regardless of browser.
Delay showing the iframe until load to prevent flashing a white
background on the initial about:blank.
This commit deprecates matches-css-before() and matches-css-after(): these
should no longer be used once 1.45.0 is published and widespread. The
deprecated syntax will eventually be removed in some future.
The syntax of procedural operator matches-css() has been extended to also
be able to target pesudo elements. Examples:
Same as before:
example.com##p:matches-css(opacity: 0.5)
This is the new way to target an `::after` pseudo-element:
example.com##p:matches-css(after, content: Ads)
This is the new way to target a `::before` pseudo-element:
example.com##p:matches-css(before, content: Ads)
The new syntax also means any valid pseudo-element can now be used as
a target:
example.com##p:matches-css(first-letter, opacity: 0.5)
If the first argument does not match the pattern "property name: value",
then it will be deemed a pseudo-element to target, and the second argument
will be the "property name: value".
Related issue:
- https://github.com/AdguardTeam/ExtendedCss/issues/150
Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/2185
The argument must be a valid media query as documented on MDN, i.e.
what appears between the `@media` at-rule and the first opening
curly bracket (including the parentheses when required):
- https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries
Best practice:
Use `:matches-media()` after plain CSS selectors, if any.
Good:
example.com###target-1 > .target-2:matches-media((min-width: 800px))
Bad (though this will still work):
example.com##:matches-media((min-width: 800px)) #target-1 > .target-2
The reason for this is to keep the door open for a future optimisation
where uBO could convert `:matches-media()`-based filters into CSS media
rules injected declaratively in a user stylesheet.
These functions were renamed in 2018, before the WebAssembly 1.0 spec
was finalized. wabt 1.0.25 dropped support for pre-1.0 names and the
sources fail to compile with errors like:
```
$ wat2wasm lz4-block-codec.wat
lz4-block-codec.wat:71:5: error: unexpected token get_local, expected ).
get_local $ilen
^^^^^^^^^
lz4-block-codec.wat:78:5: error: unexpected token get_local.
get_local $ilen
^^^^^^^^^
```
If the removed stock list is labelled a "bad list", do not
convert it into an imported list.
This will allow to seamlessly merge resource-abuse stock list
with privacy stock list when 1.42.0 is widespread.
Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/2041
The value 0xFFFFFFFF will be used instead of 0 to mark the end of
a sequence of tokens, as the value 0xFFFFFFFF can't happen as a
result of computing a token hash, since the four most significant
bits are always 0 in a computed token hash.
Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/2002
The code was testing only the LSB of a 32-bit integer to detect
whether the current rule was a wildcard (`*`), while it had to
compare against the whole 32-bit integer.
The breakage occurred when the LSB of an offset to the character
buffer happened to match the ASCII code of `*` (42, 0x2A).
(An offset is used when a label is longer than 4 characters)
The purpose of this new procedural operator is to target
all elements _outside_ than the currently selected set of
elements.
For any element feeding into `others()`, the resultset
of the `others()` operator will include everything else
except:
- the descendants of a subject element
- the ancestors of a subject element
The resultset will contains the siblings of a subject
element _except_ when those siblings are either a
descendant or ancestor of another subject element.
Related discussion:
- https://www.reddit.com/r/uBlockOrigin/comments/slyjzp/
Though this operator is unlikely to be used in default lists,
it opens the door to create specialized filter lists which
purpose is some sort of "reader mode", where everything
_else_ than a selected set of elements are hidden from view.
Examples of usage:
twitter.com##:matches-path(/^/home/) [data-testid="primaryColumn"]:others()
nature.com##:matches-path(/^/articles//) :is(.c-breadcrumbs,.c-article-main-column):others()
The status is currently considered experimental and support
might be removed in the future if it turns out there is no
sufficient usage or if unforeseen difficult issues arise
implementation-wise.
The Create button was being unduly enabled for a fraction of
second while editing the content of the filter text.
This commit is candidate for a revision to current stable
release.
From what I gather looking at Firefox for Android, a
period is used in a sentence only when there were
prior usage of punctuation in the descripton, i.e.
a comma, or a a period in a previous sentence. Single
standalone sentence should not have a trailing period.
Additionally, have a list of preset colors for the color
picker (unlike Firefox, Chromium's built-in color picker
does not have a list of preset colors by default).
uBO will use the information from prefers-color-scheme to reduce
likelihood of background color flash. However this works only for
when prefers-color-scheme is properly set by the browser, and only
when uBO's theme selection is "auto", or when it happens to
match that of prefers-color-scheme.
Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/1284
Too many changes to list here, essentially there is now a
user interface setting to enable/disable dark theme, and
I've rearranged a bit the Settings pane as a result and
also altered other visuals in various places.
There are places which I know have not been thoroughly
tested (i.e. logger inspector).
Will fine-tune as per feedback.
Issues with the classic popup panel will not be addressed,
and if feedback is that it has become unusuable, it will be
outright removed.
Reported internally.
The issue involves `removeparam` filters with a regex value. When
such filter was visited before a selfie was created, this would cause
the created selfie to persist a RegExp object, which can't be
serialized. This would cause exceptions to be thrown when uBO would
be subsequently loaded with the tainted selfie, since uBO would try
to execute a plain Object as a RegExp.
This will allow to find out what is specifically blocked on the
page reported as having issues, potentially saving time
when volunteers try to diagnose issues.
Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/1912
Related commit:
- 7713597e3e
In above related commit, uBO was modified to cache the URL of the
last clicked link, and to use this cached URL to test for the
legitimacy of the newly opened tab.
The current commit add back a test against the URL of the last
clicked link to avoid false positives when navigating from within
the newly opened tab.
Related discussion:
- a0a9497b4a (commitcomment-62560291)
The new setting, when disabled (enabled by default), allows a user
to prevent uBO from waiting for all filter lists to be loaded
before allowing network activity at launch. The setting is enabled
by default, meaning uBO waits for all filter lists to be loaded in
memory before unsuspending network activity. Some users may find
this behavior undesirable, hence the new setting.
This gives the option to potentially speed up page load at launch,
at the cost of potentially not properly filtering network requests
as per filter lists/rules.
For platforms not supporting the suspension of network activity,
the setting will merely prevent whatever mechanism exists on the
platform to mitigate improper filtering of network requests at
launch. For example, in Chromium-based browsers, unchecking the
new setting will prevent the browser from re-loading tabs for
which there was network activity while in "suspended" state at
launch.
As the trie is not immediately created, in order to speed up
launch time, the `domain=` option was stored in the filterRefs
array until it was moved to the trie.
This commit instead stores the `domain=` option into the trie
container's character buffer.
This commit will force-reload active tabs at launch for
environments not supporting suspend network request listeners,
or configured to not suspend network request listeners.
Refactored heuristics to collate set of origin-related
filter units are collated into a hostname trie, and
for better reuse of existing classes.
Generalized pre-test idea for bucket of filters, such
that in addition to origin-related filter units, there is
now a class to collate regex-based pattern-related units
into a new pre-test bucket class, FilterBucketIfRegexHits,
in order to test with a single regex test whether there is
a chance of a hit in the underlying bucket of filters.
Instances of these are rare, but at time of commit I found
this occurs with AdGuard France filter list.
Fine-tuned the "SNFE: Dump" output -- this new ability to
see the internal details of the SNFE has been really key
into finding/fixing issues during refactoring.
As was done with generic pattern-based filters, the source
string of regex-based filters is now stored into the
bidi-trie (pattern) buffer.
Additionally, added a new "dev tools" page to more
conveniently peer into uBO's internals at run time, without
having to do so from the browser's dev console -- something
which has become more difficult with the use of JS modules.
The new page can be launched from the Support pane through
the "More" button in the troubleshooting section.
The benchmark button in the About pane has been moved to this
new "dev tools" page.
The new "dev tools" page is for development purpose only,
do not open issues about it.
There are currently over 160 patterns with such pointless
trailing `*^` in uBO's filter lists, which ended up being
compiled as generic pattern filters (i.e. regex-based
internally), while the trailing `*^` accomplishes nothing
since it will always match the end of a URL ( `^` can
also match the end of URL).
This commit discards pointless trailing `*^` in patterns,
thus allowing most of those filters to be compiled as
plain pattern filters.
The syntax highlighter will reflect that a trailing
`*^` is pointless.
Rearrange logic to instantiate and add `important` filters
to the block realm when compiled lists are loaded instead
of when lists are compiled.
Additionally, removed now unused properties following
commit 68e14793cc.
Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/1863
As per internal discussion with team, best to have a simpler
scriplet, and which is hard-coded to work only on a specific
set of domains -- only those seen used by BAB.
Turns out the various benchmarks show no benefits when compiling
filters whose pattern contains a single wildcard character into
specialized classes which threat the pattern as two sub-patterns,
and actually there is a slight improvement in performance as per
benchamrks when treating these patterns as generic ones.
This also fixes the following related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/1207
Fixed serious regression in previous dev build in applying
`csp=` filters. Reported internally by uBO team.
Promote usage of `removeparam` in code instead of `queryprune`,
which is to be deprecated.
Removed test against previously tested hostname in
FilterHostnameDict since as per various benchmark, the
test does not really help.
Remove serialization API in Node.js code as the API is now
present in SNFE itself.
All the auxiliary data structures must be fully loaded before
the data structure used as entry point is populated. The race
condition could lead to a case of the entry point data structure
being populated while the auxiliary data structures are still
unpopulated, potentially causing exceptions to be thrown at
launch when the static network filtering engine is queried.
I haven't been able to reproduce such exceptions -- but it
could happen on browsers which do not support being suspended
at launch time (i.e. chromium-based browsers).
Additionally, added convenience methods to easily
serialize/unserialize when SNFE is used as a npm package.
Related feedback:
- https://github.com/orgs/uBlockOrigin/teams/ublock-issues-volunteers/discussions/293
Related commit:
- 725e6931f5
Through all the changes, forgot to pay attention to scenarios
where the `filterData` needs to grow -- the buffer's defautl
size is set to accomodate default filter lists, and subscribing
to more lists would cause the static network filtering engine
to fail because the buffer was not resized when needed.
The original motivation is to further speed up launch time
for either non-selfie-based and selfie-based initialization
of the static network filtering engine (SNFE).
As a result of the refactoring:
Filters are no longer instance-based, they are sequence-of-
integer-based. This eliminates the need to create instances
of filters at launch, and consequently eliminates all the
calls to class constructors, the resulting churning of memory,
and so forth.
All the properties defining filter instances are now as much
as possible 32-bit integer-based, and these are allocated in a
single module-scoped typed array -- this eliminates the need
to allocate memory for every filter being instantiated.
Not all filter properties can be represented as a 32-bit
integer, and in this case a filter class can allocate slots
into another module-scoped array of references.
As a result, this eliminates a lot of memory allocations when
the SNFE is populated with filters, and this makes the saving
and loading of selfie more straightforward, as the operation
is reduced to saving/loading two arrays, one of 32-bit
integers, and the other, much smaller, an array JSON-able
values.
All filter classes now only contain static methods, and all
of these methods are called with an index to the specific
filter data in the module-scoped array of 32-bit integers.
The filter sequences (used to avoid the use of JS arrays) are
also allocated in the single module-scoped array of 32-bit
integers -- they used to be stored in their own dedicated
array.
Additionally, some filters are now loaded more in a deferred
way, so as reduce uBO's time-to-readiness -- the outcome of
this still needs to be evaluated, time-to-readiness is
especially a concern in Firefox for Android or less powerful
computers.
Add ability to bring back logger button in popup panel through
the advanced setting `uiPopupConfig`. Adding `+logger` token
to `uiPopupConfig` will bring back the logger icon in the mobile
version of the popup panel.
Additionally, the link to the logger in the Support pane will
take into account whether the <Shift> key is pressed, so as
to behave like the logger icon in the popup panel.
Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/1847
The troubleshooting information has been further fine-tuned to
report popup panel data related to the reported page, for better
diagnosis by disclosing any customization to uBO which was
affecting the reported page.
Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/1836
The URL to report can now be picked from a list of related
URLs in order to allow the reporter to publish edited version
of the reported URL.
Additionally, the hash, user name, and password which could be
present in a reported URL are always removed.
Unredacted settings is unlikely to be useful after all,
and removing the ability to unredact ensure users won't
mistakenly publish unredacted information.