-
Notifications
You must be signed in to change notification settings - Fork 37
Description
in resource_assembler.rs you can find the explanation about the new format.
There is the line
A short prelude containing an array of
[{{1}}, {{2}}, {{3}}, ...]can be used to backport the newer scriptlet format into the older one; the new one will be directly supported in a future update.
you can find the line:
const wrapScriptletArgFormat = (fnString, dependencyPrelude) => `{
const args = ["{{1}}", "{{2}}", "{{3}}", "{{4}}", "{{5}}", "{{6}}", "{{7}}", "{{8}}", "{{9}}"];
let last_arg_index = 0;
for (const arg_index in args) {
if (args[arg_index] === '{{' + (Number(arg_index) + 1) + '}}') {
break;
}
last_arg_index += 1;
}
${dependencyPrelude}
(${fnString})(...args.slice(0, last_arg_index))
}`that gets added to every scriptlet rule causing a bunch of duplication code everywhere.
Why not use this which will use the new format?
const wrapScriptletArgFormat = (fnString, dependencyPrelude) => `${fnString}
${dependencyPrelude}`While I know the limitation of Brave's current implementation compared to the 'new format' compared to what uBlock does, it can still be used, and works great, it is exactly what I have been using for more than two months without any issues.
First differences or limitations are:
- Brave only uses the first function/the function that is at the top for the arguments even if that function doesn't have any arguments, while uBlock will be able to use the one at the bottom or the top, that means
${fnString}has no real value in how Brave parses it. - Brave will still duplicate code, because the
${dependencyPrelude}is still applied per scriptlet, while uBlock will just place a single dependency for every Scriptlet.
For 1. the solution is simple, add the ${fnString} at the top and then ${dependencyPrelude}, 2 or 3 months ago, uBlock started doing that in some commit (maybe this one gorhill/uBlock@b381ced or some other, who knows) started to place the ${fnString} at the top, and that means Brave would look almost the same as what uBlock is doing that.
For 2., yes, the JS will get duplicated like if two different scriptlets ave the safe-self.js, there will be two safe-self functions in both Scriptlets, which means, it is not like uBlock, where there would only be one.
But using the 'new' format avoids to add the same duplicate Scriptlet code over and over again only because you have multiple Adblocker Scriptlet rules having different values.
So for example, instead of having 3 different trused-set-cookie functions with all their dependencies duplicates just to add different arguments, using the new format will add a single Scriptlet code, and then add:
try {
trustedSetCookie("name", "value123", "1year", "", "reload", "1", "domain", ".example.com", "dontOverwrite", "0")
} catch ( e ) { }
try {
trustedSetCookie("name2", "value123", "1year", "", "reload", "1", "domain", ".example.com", "dontOverwrite", "0")
} catch ( e ) { }
try {
trustedSetCookie("name3", "value123", "1year", "", "reload", "1", "domain", ".example.com", "dontOverwrite", "0")
} catch ( e ) { }That means it will reduce completely the JS being injected because it doesn't need to add 3 different trustedSetCookie, setCookieFn, safeSelf, for those 3 rules, and instead it will just have them once per Scriptlet and only add the arguments at the end.
Now all I did was to go to adBlockRustUtils.js and change the lines for the simplest and done:
const wrapScriptletArgFormat = (fnString, dependencyPrelude) => `${fnString}
${dependencyPrelude}`I have been using it this way and it works fine.
Another reason why new format is better is because of the arguments, old format was limited to 9 arguments, but as you can see, in the trustedSetCookie I provided, it has 10, which means if you use:
example.com##+js(trusted-set-cookie, name, value123, 1year , , reload, 1, domain, .example.com, dontOverwrite, 0)With the old format, it will start to refresh the page endlessly, which is bad. Of course, not all Scriptlets have many arguments like trusted-set-cookie, but it shows that new format having pretty much no limitation in the arguments, will be better to avoid any issues like that if ever happens.
But this is a question too, maybe you are aware of this and you just don't do it because the old format still works, but just the JS duplication of the old format makes the partially-almostfully supported new format a better alternative since having a single Scriptlet for multiple rules, is better than 3 or 10 or 50 different Scriptlets JS code being injected because you had a long list of set-local-storage items or something like that.
Also I don't know if it has anything to do with adblock-rust not being Browser only or some iOS incompatibility or something, but I have been using this new format for a while and no issues in Chromium Brave.
So for example using:
example.com##+js(trusted-set-cookie, name, value123)
example.com##+js(trusted-set-cookie, name2, value123)
example.com##+js(trusted-set-cookie, name3, value123)
example.com##+js(trusted-set-cookie, name4, value123)
example.com##+js(trusted-set-cookie, name5, value123)with old format has 1592 lines of code
while using the same in new format will only use 333 lines of JS code.
example.com##+js(trusted-set-local-storage-item, name, value123)
example.com##+js(trusted-set-local-storage-item, name2, value123)
example.com##+js(trusted-set-local-storage-item, name3, value123)
example.com##+js(trusted-set-local-storage-item, name4, value123)
example.com##+js(trusted-set-local-storage-item, name5, value123)will only use 309 in new format while old format is 1472
example.com##+js(rpnt, #text, Example, TEST)
example.com##+js(rpnt, #text, Domain, TEST2)
example.com##+js(rpnt, #text, documents, TEST3)
example.com##+js(rpnt, #text, permission, TEST4)
example.com##+js(rpnt, #text, information, TEST5)New format = 359 and with old format 1722 lines.
So the gain is better than anything else, especially when the compatibility regardless of partiality is still working fine compared to what uBlock is currently doing when injecting their Scriptlets.