All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- XPath expressions support in
trusted-click-elementselectors, wrapped inxpath(), e.g.xpath(//button[contains(text(), "Accept")]), also combined with>>>combinator, e.g.div#host >>> xpath(descendant-or-self::button). Absolute paths after>>>are evaluated against the document in Chromium-based browsers before version 146, so e.g.xpath(//button)selects nothing there, and relative paths withdescendant-or-self::axis should be used instead. Invalid XPath expressions are logged once and the scriptlet exits. Errors which occur only on evaluation of page elements, e.g. a type error in a predicate like//button[count(1)], may not be detected and are not logged, and such expression selects nothing while the error occurs, e.g. while there is a button on the page, or after>>>only the elements of top-level elements of the shadow root without the error. isTrusted:allinextraMatchoftrusted-click-elementto spoofisTrustedfor all click-related events on the page, including the page's own ones, e.g. a click which a page handler dispatches on another element in response, similarly to the behavior before #582, but trusted events are passed unchanged, and all listeners of an event receive the same proxy. Only listeners added byaddEventListener()after the scriptlet has run receive spoofed events of the page; inlineon...handlers receive spoofed events only on the clicked element during an event of the scriptlet of the same type, including the page's own events of that type dispatched on it meanwhile, so other page events may reach them unspoofed. It is enabled for the whole page, including the clicks of other rules, and may break the page, e.g. its guards which compare events, or its code which passes events to native methods, so use it only if the page does not accept the clicks of the scriptlet otherwise. It can be combined with other conditions in any order, but for compatibility with older versions of the scriptlet, it should be the first or the only condition, e.g.isTrusted:all, !cookie:consent. Older versions ignore it only there, but take it after another condition as a part of that condition's value, e.g. with!cookie:consent, isTrusted:allthey click regardless of theconsentcookie, and withcontainsText:Accept, isTrusted:allthey never click.
- Minimum supported Microsoft Edge version is now Edge Chromium 80.
trusted-click-elementspoofsisTrustedby default only for its own clicks, and for the clicks which labels forward from them to their controls, as one event shared by all listeners, instead of all click-related events on the page, which replaced the page's own events with proxies and broke popup opening-event guards #582. The spoofed event is still not the same object aswindow.event. If a rule needs the page's own events to be spoofed as well, e.g. a click which a page handler dispatches in response,isTrusted:allshould be added to itsextraMatch, as the first condition for compatibility with older versions. It is needed as well for a click forwarded by a label in a closed shadow root which wraps the slot of the clicked element, as such label is not found by default. If an older version oftrusted-click-elementruns on the same page as well, e.g. in another AdGuard product, and this version hooks event listeners first, the clicks of the older version are not spoofed for event listeners until the page is reloaded, unless a rule of this version hasisTrusted:all. If the page has sealedEventTarget.prototypebefore the scriptlet runs,isTrustedis not spoofed for event listeners, which is logged, as the rules cannot share the hook then, but the elements are still clicked.trusted-click-elementvalidates its selectors once and exits if any of them is invalid, logging it with the reason, instead of throwing an error after hooking event listeners andattachShadow, or on each DOM change. So no element is clicked then, including the ones matched by valid selectors before the invalid one, e.g. a selector with a pseudo-class which is not supported by the browser.stackoftrusted-json-setis matched against the stack trace of the intercepted call without the frames of the scriptlet itself, which it contained before. Sostackvalues which matched these frames no longer match the calls from other scripts, e.g.inlineScriptif the scriptlet is injected as an inline script. Also, a call which does not matchstackis not processed at all, e.g. a JSON string returned by it is not parsed and serialized again, which removed its formatting before.trusted-replace-outbound-textwithstackcallshitonly for the calls which matchstack.json-prune-xhr-responseandtrusted-json-set-xhr-responseinterceptsetRequestHeader(),getResponseHeader(),getAllResponseHeaders()andabort()ofXMLHttpRequest.prototypeas well, instead ofsetRequestHeader()of each matched object, which no longer gets it as its own property, unless it has another method, which is wrapped then, e.g. its own one assigned by the page, or the hook of another rule of these scriptlets.loadandloadendof a modified response are dispatched asProgressEvent, instead ofEvent, with the progress of the original response for an asynchronous request, as by a native request, and with zero length otherwise.stackoftrusted-json-set-fetch-response,json-prune-fetch-response, and ofjson-pruneforResponse.prototype.json()is matched against the stack trace of the call offetch()orjson()without the frames of the scriptlet itself, which it contained before, as it was matched after the response was awaited. Sostackvalues which matched these frames no longer match the calls from other scripts, e.g.inlineScriptif the scriptlet is injected as an inline script. Also, in Chromium-based browsers, an async function which awaits the response no longer matches it if it is not in the stack whenfetch()orjson()is called, e.g. if the request is sent by a timer. In logging mode ofjson-prune-fetch-responseandjson-prune,stackis still not matched, and the stack trace of the call is logged with the content.- Documented that the
stackparameter ofabort-on-stack-tracescriptlet supports regular expressions #393.
- Edge Legacy support.
xml-pruneevaluating an XPath expression without the closing parenthesis with its last character dropped, e.g.xpath(//*[name()="Period"]/@durationas//*[name()="Period"]/@duratio, instead of logging it as invalid.- Fetch-based scriptlets failing to match requests when
fetchreceives aURLobject #577. - Scriptlets which re-apply themselves on DOM changes, e.g.
remove-attrandremove-class, no longer stop doing it after an error thrown on a DOM change, e.g. by the page for an element. Also,remove-attr,remove-class,remove-in-shadow-domandhide-in-shadow-domlog an error thrown for an element once, and continue with other elements, including ones added later, even if the error is thrown when the rule is applied. - Infinite mutation loop and repeated logging when several non-conflicting
set-attrortrusted-set-attrrules are applied on the same page: the attribute is no longer re-set, andhitis not called, if it already has the required value. Also,set-attrlogs a missing attribute to copy the value from once for each element until the attribute is found, even if the element already holds the copied value. An error thrown for an element, e.g. by the page, is logged once for the element and does not stop setting the attribute on other elements, including ones added later, or preventhitfor changed elements. An invalid name of the attribute to copy the value from, e.g.[data a]or[], is logged once as an invalid value, instead of setting the attribute tonullon each matched element. - Infinite mutation loop between several non-conflicting
href-sanitizerrules, andhitcalled on each DOM change:hrefis no longer re-set, andhitis not called, if the link, including SVG<a>element, already points to the sanitized URL. Also,href-sanitizerlogs invalid arguments only once, logs a failure to sanitize a link only once until itshrefor the value taken from the link is changed, or the URL resolved from it if the failure depends on the document base URL, and does not log a link sanitized by the rule as a failure, e.g. one without the URL parameter, or a base64 string which is not a URL if another one in the same value is decoded. An error thrown for a link, e.g. by the page, is logged once and does not stop sanitizing of other links. href-sanitizerresolving relative URLs against the page URL or its origin instead of the document base URL, e.g.removeHashandremoveParamtransforms rewrote a path-relative link to a wrong URL, or a link within the page, e.g.#comments, to another page.- Infinite mutation loop between an
href-sanitizerrule and another one which changes the URL set by it, e.g. a rule with link text and a rule withremoveParam:utm_sourceon the same link, or a rule with an attribute and a rule with?urlwhich unwraps the redirect set by the first one. Rules share their last actual write on the affected link, without awindowregistry or HTML attributes, so page edits of the link are still corrected, including ones which another rule has changed. href-sanitizernot sanitizing SVG<a>element by a URL parameter, e.g.?url.removeHashandremoveParamtransforms ofhref-sanitizernot setting the URL found in the link text, attribute or URL parameter if there is nothing to remove from it, as it is done without a transform.href-sanitizersetting link text which is not a URL as a relative URL or as a broken URL: link text is set only if it is an absolute URL or a path without whitespaces, e.g. notClick here,Download,?orhttps://example.org/ (external), and not if a tab or newline is between its words, e.g. between the URL and the title of a card, rather than next to a URL delimiter, e.g./. Also, a value of only whitespaces is not set, and neither is a placeholder hash, i.e.#or#!, unless it ishrefof the link.href-sanitizerdecoding+in the URL parameter as a whitespace if the parameter is a URL which is not encoded, e.g.?url=https://example.org/c++/docsor?url=https%3A//example.org/c++/docs.href-sanitizernot decoding base64 string in a relativehref, inhrefwithin the page, e.g.#<base64>, or in the hash if the query has no base64 encoded URL, e.g.https://example.org/?ref=1#<base64>.href-sanitizeraccepting any transform starting withremoveParam, e.g.removeParams, which removed all parameters.href-sanitizerunwrapping nested redirects in the URL parameter or base64 encoded ones only one by one on each DOM change; now up to 10 of them are unwrapped at once, and the rest right after that, as long as the link is still matched by the selector. Relative URL in the nested redirect, e.g. a parameter of the target with the same name, is not followed and not logged, since it is relative to the redirect, except for a scheme-relative one, e.g.//example.org/.- Repeated logging on each DOM change by
remove-attrif its selector matches elements without the attribute:hitis called only if some attribute has actually been removed. Also, invalid selector is logged only once. - Infinite mutation loop between several
hide-in-shadow-domrules whose targets are light DOM children of shadow hosts, andhitcalled on each DOM change: already hidden elements are no longer re-hidden, andhitis called only if some element has actually been hidden. hide-in-shadow-domandremove-in-shadow-domnot working ifbaseSelectormatches an element which is not a shadow host itself, e.g. a container of shadow hosts. Also, both scriptlets log an invalidselectororbaseSelectorinstead of throwing an error.- Invalid selector logged on each DOM change by
remove-class,set-attrandtrusted-set-attr, as well as invalid attribute name byset-attrandtrusted-set-attr: they are now validated and logged only once. remove-classandremove-attrnot removing classes or attributes whose names are not valid CSS identifiers, e.g.md:hiddenorx-on:click, if no selector is specified.trusted-click-elementsplitting selectors by commas inside pseudo-classes, e.g.:is(.accept, .agree), by commas inside quoted attribute values, e.g.[title="Accept, agree"], and by escaped commas, e.g.#accept\,agree, which made such selectors invalid. Also,>>>inside quoted strings or CSS comments, e.g. in[title=" >>> "], is no longer taken for the shadow combinator.trusted-click-elementignoringcontainsTextwhen it finds an element again because the found one was removed from DOM before the click, which could click another element matching the selector.trusted-click-elementnot clicking an element ifcontainsText, or the key of acookiecondition, is a regexp withgoryflag, as each next check started from the end of the previous match, e.g.cookie:/consent/g=/yes/did not matchconsent_a=no; consent_b=yes.trusted-click-elementclicking next elements of the sequence if a previous element was removed from DOM before the click and could not be found again.trusted-click-elementnot clicking elements after an empty selector, e.g.#acceptin#settings,, #accept, and not callinghitif there is a trailing comma, e.g. in#accept,: empty selectors, and ones with only a CSS comment, are skipped.trusted-click-elementhooking event listeners andattachShadoweven when it exits early because of invalid timeout, delay or reload values or unmatchedextraMatchconditions #582.trusted-click-elementfailing to remove or deduplicate listeners shared across event targets, registered with non-booleancapturevalues or with options which return a different value on each read, and failing to remove a listener registered before the scriptlet ran if the same listener was also added after it #582.trusted-click-elementnot finding elements in a closed shadow root attached with options which return a differentmodeon each read.trusted-click-elementnot clicking next elements of the sequence if a React click handler of the page throws, and clicking the element again when the sequence is continued, with the error not logged but reported as an unhandled rejection: the error is logged once and the next elements are clicked.trusted-click-elementsilently not spoofingisTrusted, or not tracking shadow roots attached later, if another script has madeaddEventListener(),removeEventListener()orattachShadow()read-only: it is logged now, and elements which can still be found are clicked.trusted-click-elementwith>>>combinator observing shadow roots attached after it has found all elements or its observer has timed out, which changed an attribute of thehtmlelement on each of their changes and so woke up all observers of the page for its whole lifetime.trusted-click-elementthrowing when inlineon*handlers or React handlers setcancelBubbleorreturnValueon a scriptlet click #582.trusted-click-elementrestoring inlineon*handlers of the clicked element that the page replaced or cleared during the click #582.trusted-click-elementexposing a boundconstructoron spoofed events and an untrustednativeEventto React handlers #582.trusted-click-elementpassing an untrusted event to an inlineon...handler of the clicked element which the page assigns during an earlier event of the click, e.g.onclickset onmousedown.trusted-click-elementreporting outdatedisDefaultPrevented()andisPropagationStopped()to React handlers if the default action or propagation is changed throughnativeEvent,returnValueorcancelBubble.trusted-json-setmodifying a nativePromisereturned by the intercepted method, e.g.Response.prototype.json, instead of the value it is fulfilled with #585. The value is modified now, and a new promise of it is returned, while a rejection is passed through. In logging-only mode, the value is logged, and the original promise is returned. Promises of polyfills or libraries which replacewindow.Promise, e.g. zone.js, are not supported.stackis matched when the method is called, so it works for such values as well. Also, the intercepted method is no longer called again if it throws an error.stackoftrusted-replace-outbound-text,trusted-suppress-native-method,json-prune-xhr-responseandtrusted-json-set-xhr-responsenot matching the function which calls the intercepted method in browsers whose stack traces have no error message line, e.g. Firefox, as the frame of that function was removed as the scriptlet's own one.stackoftrusted-json-set-fetch-response,json-prune-fetch-response, and ofjson-pruneforResponse.prototype.json(), not matching a function which returns the promise offetch()orjson(), as it was matched after the response was awaited, when the function was no longer in the stack. It is matched when the method is called now, and the calls which do not match it are passed through as is, sojson-prune-fetch-responseno longer callshitfor them.trusted-json-set-fetch-responseandjson-prune-fetch-responsesending the request again if it fails, e.g. a POST request, or if its response cannot be cloned. The rejection of the request is passed to the page now, and the response is returned as is if it cannot be cloned.trusted-replace-outbound-textnot modifying any content after the intercepted method is called from a function which does not matchstack, e.g. by another script of the page, or after it throws an error, e.g.JSON.stringifyof an object with a circular reference.trusted-replace-argumentcalling the intercepted method or constructor again if it throws an error, so its side effects were repeated, and the second call could even succeed.trusted-replace-argumentthrowing an error to the page instead of calling the intercepted method ifnullorundefinedis thrown while the arguments are processed, e.g. by a conversion of an argument to a string, or byErrorreplaced by the page while the stack trace forstackis created. The method is called with the original arguments now.trusted-replace-argumentnot matching an object argument by its string value if it cannot be serialized as JSON, and the error of it cannot be converted to a string to be logged, e.g.Object.create(null)thrown by itstoJSON(). The argument and the error are no longer converted to strings to be logged.call-nothrowthrowing an error to the page if the intercepted method throwsnullorundefined, as getting the message of such error threw another one.trusted-suppress-native-methodthrowing an error to the page and no longer intercepting the next calls after an error while a call is matched, e.g. thrown by a getter of an argument, or byErrorreplaced by the page while the stack trace forstackis created. Such call is not suppressed now.trusted-json-setandtrusted-json-set-fetch-responseprocessing a JSON string or response body again as line-delimited JSON if its modification fails, e.g. as the modified value cannot be serialized, so it was modified again, andhitcould be called twice. Such string or response is returned unchanged now.JSONPathrules ofjson-pruneandjson-prune-fetch-responsethrowing an error to the page, e.g. fromJSON.parse()or by rejecting the promise offetch(), ifnullor another value without a message is thrown while the content is processed, e.g. by a getter of the page, as getting the message of it to log it threw another error. The same applies tojson-prune,json-prune-fetch-response,evaldata-pruneandtrusted-prune-inbound-objectwhile messages are logged, if such value cannot be converted to a string, e.g.Object.create(null).trusted-json-setnot modifying anything, even withoutstack, if the stack trace cannot be read, e.g. because ofError.prepareStackTraceof the page orErrorreplaced by it. Only the rules withstackare not applied then. The same applies toJSONPathrules ofjson-prune,json-prune-fetch-responseandtrusted-json-set-fetch-response, and totrusted-json-set-fetch-responserules withverbose.trusted-json-setno longer reads the stack trace at all for rules withoutstack, except in logging-only mode or withverbose.json-prune-xhr-responseandtrusted-json-set-xhr-responsethrowing an error fromXMLHttpRequest.send(), so the request was not sent at all, even withoutstack, if the stack trace cannot be read, e.g. because ofError.prepareStackTraceof the page orErrorreplaced by it. Only the rules withstackare not applied then, and the request is sent as is. They no longer read the stack trace at all for rules withoutstack, except in logging mode ofjson-prune-xhr-responseor withverboseoftrusted-json-set-xhr-response.json-prune,json-prune-fetch-response,evaldata-pruneandtrusted-prune-inbound-objectin logging mode throwing an error to the page, e.g. fromJSON.parse(), if the stack trace cannot be read, e.g. because ofError.prepareStackTraceof the page orErrorreplaced by it. Also, the content matched byobligatoryPropswas not logged then, also byjson-prune-xhr-response. The content is logged without the stack trace now.json-prune,evaldata-pruneandtrusted-prune-inbound-objectin logging mode throwing an error to the page, e.g. fromJSON.parse()oreval(), or instead of calling the intercepted method, if the content cannot be serialized to be logged, e.g. a circular object or a too deeply nested one. Also,json-prune-fetch-responserejecting the promise offetch()then,json-prune-xhr-responsereturning the text of such response instead of its object forresponseTypejson, and the content matched byobligatoryPropsnot being logged then. Such content is logged only as an object now.trusted-json-set,trusted-json-set-fetch-responseandtrusted-json-set-xhr-responsewithverbosenot modifying the content if it cannot be serialized to be logged, e.g. a too deeply nested JSON response or an object whosetoJSON()throws. Such content is logged only as an object now.json-prune-xhr-responseandtrusted-json-set-xhr-responsenot firingloadfor the second matched request of a reusedXMLHttpRequestobject, as the props of its response could not be defined again, and returning the props of the previous response, e.g.readyStateandresponse, for a request on such an object which is not matched. Also, for such an object, sending the headers of each request again with the next ones, forging a request with the method and URL of the previousopen()if the object is opened again before it is sent, and delivering the response of a request after the object is opened again or the request is aborted byabort(), which dispatches the events of an aborted request now. Also,readystatechangeis dispatched when such object is opened again, as byopen()of a native object which is done.json-prune-xhr-responseandtrusted-json-set-xhr-responsedispatching the events of a modified response of a synchronous request afterXMLHttpRequest.send()has returned, so the page could not use the response in itsloadlistener right aftersend(). They are dispatched beforesend()returns now, as by a native request.json-prune-xhr-responseandtrusted-json-set-xhr-responsesending a request synchronously if it is opened withoutasync, e.g. byopen(method, url). Also,userandpasswordpassed toopen()were not used for the request.json-prune-xhr-responseandtrusted-json-set-xhr-responsethrowing an error fromXMLHttpRequest.send()for each matched request if the page has replacedXMLHttpRequestafter the scriptlet has run, e.g. by a library which wraps requests, as the forged request was created by it.json-prune-xhr-responseandtrusted-json-set-xhr-responsesending the request again if sending it fails, e.g. a synchronous POST request with a network error, so its side effects were repeated. The error is thrown to the page now, and the object is done with no response then, as a native one.json-prune-xhr-response,trusted-json-set-xhr-responseandtrusted-replace-outbound-text, andJSONPathrules ofjson-prune,json-prune-fetch-responseandtrusted-json-set-fetch-response, throwing an error to the page ifstackis an invalid regular expression, e.g. fromXMLHttpRequest.send(), so the request was not sent, or fromJSON.parse(), or rejecting the promise offetch()orResponse.prototype.json()with it. Such rules are not applied now, and the call is passed through. The same applies totrusted-replace-outbound-textiftextToReplaceis an invalid regular expression.json-prune-xhr-responseandtrusted-json-set-xhr-responsereturning no response headers fromgetResponseHeader()andgetAllResponseHeaders()of an interceptedXMLHttpRequestobject, e.g.nullforContent-Type, as the object is not sent itself. The headers of the response are returned now, as bytrusted-replace-xhr-response#419.json-prune-xhr-response,trusted-json-set-xhr-response,json-prune-fetch-response,call-nothrow,trusted-replace-outbound-textandtrusted-suppress-native-methodchangingtoString()of the intercepted methods, e.g.XMLHttpRequest.prototype.open.toString()orfetch.toString(), which returned the string of a native function without its name. It returns the original value now.json-prune-xhr-responseandtrusted-json-set-xhr-responsenever completing a request whose response could not be modified, e.g. as logging a too deeply nested JSON response withverbosethrew an error, or defined on the object, e.g. if the page has made it not extensible. The events of the response are dispatched now in both cases, with the original text of the response if it could not be modified, while the object keeps its state if the response could not be defined.json-prune-fetch-responserejecting the promise offetch()of a request which has succeeded, if its response could not be modified, e.g. as serializing a too deeply nested JSON response threw in browsers whoseJSON.stringify()is recursive. The original response is returned now.json-prune-xhr-responsein logging mode returning a JSON response as a string, even if anotherresponseTypeof the request is set, e.g.json,arraybufferorblob. A response which is not JSON is still returned as a string.json-prunecallingthen()of the promise ofResponse.prototype.json(), which the page may replace, to prune its value. Its ownthen()is still used only ifPromisehas been replaced before the scriptlet has run, e.g. by zone.js.trusted-replace-outbound-textwithstackthrowing an error to the page instead of the result of the intercepted method if the stack trace cannot be read, e.g. because ofError.prepareStackTraceof the page orErrorreplaced by it. The result is returned unmodified then.trusted-suppress-native-method,trusted-json-set,trusted-replace-argument,trusted-replace-outbound-text,trusted-prune-inbound-objectandcall-nothrownot intercepting methods oflocalStorageandsessionStorage, e.g.localStorage.setItem, in Firefox, and storing an item named after the method in the storage instead, e.g.setItem. The method is replaced inStorage.prototypenow, unless the page has assigned its own method to the storage, e.g. in Chrome, and only its calls on the storage of the rule are processed, also the ones made throughStorage.prototype.isValidStrPatternhelper not validating a regular expression pattern with flags, e.g./foo(/i, so such a pattern was treated as valid and scriptlets failed when converting it to a regexp.
2.5.1 - 2026-08-25
2.5.1-beta.1 - 2026-08-25
- Updated @adguard/agtree to v4.2.1.
2.5.1-beta.0 - 2026-08-05
- Support of
$now$,$currentDate$, and$currentISODate$keywords used as a part of the value, not as a standalone value only, e.g.'{"count":1,"firstTime":$now$}'; more than one keyword may be used in the value. Applies totrusted-set-cookie,trusted-set-cookie-reload,trusted-set-local-storage-item, andtrusted-set-session-storage-itemscriptlets #573. - Support of
$now$,$currentDate$, and$currentISODate$keywords inargumentValueoftrusted-json-set,trusted-json-set-fetch-response, andtrusted-json-set-xhr-responsescriptlets — as a whole value, as a part of it, and insidejson:andreplace:values, e.g.'json:{"count":1,"firstTime":$now$}'#573.
2.5.0 - 2026-07-27
json-edit,json-edit-xhr-response, andjson-edit-fetch-responsescriptlet aliases as uBO-compatible names forjson-prune,json-prune-xhr-response, andjson-prune-fetch-responserespectively #566.- Dot-prefixed JSONPath auto-detection in
resolveJsonSyntaxMode— expressions starting with.are now treated as JSONPath mode without explicitly passingmode=jsonpath#566. trusted-prevent-xhrscriptlet, a trusted variant ofprevent-xhrthat supports passing arbitrary literal text as the XHR response body #417.- Expanded
prevent-xhrrandomizedirective: addedemptyObj,emptyArr,emptyStr, single-valuelength:N(e.g.length:50). prevent-xhrandtrusted-prevent-xhrnow handledocumentandjsonXHRresponseTypevalues when intercepting matched requests.
- Updated @adguard/agtree to v4.2.0.
- UBO aliases for
prevent-babscriptlet and redirect.
trusted-replace-argument— whenreplace:is used and the argument is not a string, the argument is no longer blindly overwritten with the replacement value; the replacement is applied to its string form and the original value and type are kept when the pattern does not match #570.adjust-setTimeout,adjust-setInterval,prevent-setTimeout,prevent-setInterval, andprevent-requestAnimationFramenow handle callbacks with a modified prototype chain:isValidCallbackuses atypeofcheck instead ofinstanceof Function, and callback stringification uses the nativeFunction.prototype.toStringso thatmatchCallbackmatching and logging work for such callbacks and never throw #561.
2.4.3 - 2026-06-24
setConfigandgetConfigmethods togoogletagservices-gptredirect #560.- Delay range matching for
prevent-setTimeoutandprevent-setIntervalscriptlets. Supported formats:min-max,min-,-max, with!prefix for inversion #467.
listenerToStringhelper now uses nativeFunction.prototype.toStringto prevent issues where websites redefine it #292.prevent-fetchnow supports a structuredresponseConfigargument for overriding synthetic response fields such asok,redirected,status,statusText, and extendedtypevalues #529.
trusted-replace-xhr-responseresponse headers (getResponseHeader,getAllResponseHeaders) now return the correct values on intercepted XHR objects #419.Maximum call stack size exceedederror whentrusted-json-setortrusted-replace-argumentis called with method used inside scriptlet #565.- Infinite loop in
getRecursiveCandidatesinjson-path-utils#563. - Missing
google.ima.dai.api.ui,google.ima.dai.api.customUisurfaces and the defaultStreamRequest.uicontainer in thegoogle-ima3-dairedirect. - Missing
google.ima.dai.api.StreamRequest.StreamFormatobject to thegoogle-ima3-dairedirect. - Redirect resources with a
.tsextension are now converted to.js.
2.4.2 - 2026-04-24
- Scriptlets release version for
google-ima3-dai.
2.4.1 - 2026-04-23
google-ima3-dairedirect resource and scriptlet #239.
- Updated @adguard/agtree to v4.1.1
2.4.0-beta - 2026-04-21
- New
modeparameter to alljson-pruneandtrusted-json-setrelated scriptlets, which allows to specify the way of pruning JSON objects #522. - Line-delimited JSON processing in
trusted-json-setrelated scriptlets #522. $remove$value to alltrusted-json-setrelated scriptlets, which allows removing specific properties #522.- Support for
JSONPathinjson-prune,json-prune-fetch-response,json-prune-xhr-response,trusted-json-set,trusted-json-set-fetch-responseandtrusted-json-set-xhr-responsescriptlets #522.
trusted-json-setnow supports method-only logging, filtered log-only output, JSONPath-based log-only filters, and verbose logs only when a write actually happens #308.log-addEventListenerscriptlet: added new optionalnoProtectparameter, improving compatibility with other scriptlets that need to overrideaddEventListener#551.- Updated @adguard/agtree to v4.1.0-beta.
- Logging original object in
trusted-json-setscriptlet, previously original and modified object were pointing to the same reference, so the same content was logged, now deep copy is created for original object #308. trusted-click-elementno longer throws when event handlers setcancelBubbleon spoofed events #555.
v2.3.1 - 2026-03-24
- Updated @adguard/agtree to v4.0.3.
disable-newtab-linksnot preventing clicks when the element has its ownclickhandler added viaaddEventListener#483.
v2.3.0 - 2026-03-18
- New value to
set-cookieandset-cookie-reloadscriptlets:all#501. - New value to
set-cookieandset-cookie-reloadscriptlets:mandatory#518. - New value to
set-cookieandset-cookie-reloadscriptlets:declined#552. trusted-json-set,trusted-json-set-fetch-responseandtrusted-json-set-xhr-responsescriptlets #308.freewheel-admanagerredirect resource and scriptlet #401.getCreativeIdmethod toAdclass ingoogle-ima3redirect #515.
trusted-click-elementnow passes synthetic-like event objects to React handlers and supportsclickType:nativeinextraMatchto force native click #554.- Added
interceptChainProphelper to share intermediate chain property access logic acrossabort-on-property-read,abort-on-property-write,abort-on-stack-trace,abort-current-inline-script,debug-on-property-write,debug-on-property-read,debug-current-inline-scriptandlog-on-stack-tracescriptlets #513. prevent-window-opennow checks all parameters #549.- Updated @adguard/agtree to v4.0.2.
prevent-fetch— do not usemodifyResponseon redirected requests #545.- issue with assigning
windowto property which was not set inabort-on-property-read,abort-on-property-write,abort-on-stack-trace,abort-current-inline-script,debug-on-property-write,debug-on-property-read,debug-current-inline-scriptandlog-on-stack-tracescriptlets #513.
v2.2.16 - 2026-02-19
prevent-navigationscriptlet to prevent navigation to another URL, or reload website #532.prevent-constructorscriptlet to prevent constructor calls likenew Promise()ornew MutationObserver()#461.remove-request-query-parameterscriptlet to remove query parameters fromfetchandXMLHttpRequestrequests #329.- Trusted Types API support in
trusted-create-elementscriptlet #507. - Trusted Types API support in Firefox #528.
prevent-addEventListenerscriptlet: added new optionalnoProtectparameter, improving compatibility with other scriptlets that need to overrideaddEventListener#550.- Updated @adguard/agtree to v4.0.1.
prevent-xhrscriptlet,responseURLis now set atreadyState2, and the first state is skipped whenonreadystatechangeis assigned afterxhr.open()#485.- Anti-adblock detection in
spoof-cssscriptlet by using cloaked bound functions instead of Proxies #422. - Response corruption in
trusted-replace-fetch-responseandtrusted-replace-xhr-responsescriptlets when URL pattern matches but content pattern does not #486. - XHR handling in
trusted-replace-xhr-responseandxml-prunescriptlets:- added
withCredentialsto forged requests, - fixed duplicate headers when multiple scriptlets are used,
- used
ProgressEventforloadandloadendevents #486.
- added
- XHR scriptlet bypass vulnerability in
trusted-replace-xhr-response,prevent-xhr, andxml-prunescriptlets where settingxhr.shouldBePrevented = falsecould disable the scriptlet #386. - Parsing of regexp patterns containing pipe
|character insignatureStrarg oftrusted-suppress-native-methodscriptlet #473. - Stack matching in
set-constantandtrusted-set-constantscriptlets — now checked at property access time instead of scriptlet initialization #500. - Cloudflare captcha broken when
>>>combinator is used intrusted-click-elementscriptlet #491.
v2.2.15 - 2026-01-22
- Support for React elements that don't respond to native clicks
in
trusted-click-elementscriptlet #542.
- Updated @adguard/agtree to v4.0.0.
- Do not throw error on
nullevent type inprevent-addEventListenerscriptlet #539.
v2.2.14 - 2025-12-16
prevent-innerHTMLscriptlet #488.- Ability to configure observer timeout for
trusted-click-elementscriptlet with a newobserverTimeoutparameter #400. - Support for
window.Fingerprintvariable infingerprintjs2redirect (and scriptlet as well since it is an alias for redirect) #541.
- Updated @adguard/agtree to v3.4.3.
v2.2.13 - 2025-11-25
- New value to
set-cookieandset-cookie-reloadscriptlets:denied#512.
- Updated @adguard/agtree to v3.3.1.
- Determination of string values more precisely
for
trusted-set-constantscriptlet #499. - Support for negative priority suffix in UBO redirects rules.
v2.2.12 - 2025-11-12
- Updated @adguard/agtree to v3.2.5.
v2.2.11 - 2025-10-17
- Updated @adguard/agtree to v3.2.4.
v2.2.10 - 2025-09-11
-base64as an alias ofbase64decodeinhref-sanitizerscriptlet #493.
- Updated @adguard/agtree to v3.2.3.
v2.2.9 - 2025-08-14
trusted-replace-argumentscriptlet #405.
- Incorrectly escaped quotes in
trusted-replace-node-textscriptlet #517. TrustedScriptURLinprevent-element-src-loadingscriptlet #514.- Fix scriptlets compilation error in Safari 15 due to unsupported regex lookbehind #519.
v2.2.8 - 2025-07-08
- UBO aliases
ubo-nobab,nobab, andbab-defuserforprevent-babAdGuard scriptlet.
- Updated @adguard/agtree to v3.2.2.
trusted-set-cookie-reloadscriptlet infinite page reloading when cookie with time keyword is used #489.
v2.2.7 - 2025-06-04
- Updated @adguard/agtree to v3.2.1.
json-prunescriptlet to properly handlenullvalues while checking specified key in object #504.
v2.2.4 - 2025-05-23
- Updated @adguard/agtree to v3.2.0.
spoof-cssscriptlet — incorrectDOMRectsetting #498.
v2.2.1 - 2025-05-21
- Trusted types bundle.
v2.2.0 - 2025-05-21
- New values to
set-cookieandset-cookie-reloadscriptlets:emptyArr,emptyObj#497. - Ability to set random response content in
prevent-fetchscriptlet #416. - Ability to choose CSS injection method in
inject-css-in-shadow-domscriptlet #477. - TypeScript types for CoreLibs provided
ContentScriptApi. - Trusted Types API utility —
PolicyApi.
- Improved docs for
json-prune,xml-pruneandtrusted-prune-inbound-objectscriptlets #392. - Updated @adguard/agtree to v3.1.5.
- Escaping quotes in
trusted-replace-node-textscriptlet #440. trusted-suppress-native-methodscriptlet,isMatchingSuspendedwas not reset when the stack does not match, so in some cases given method was not prevented #496.
v2.1.7 - 2025-04-03
- Updated @adguard/agtree to v3.1.0.
- Ability in
prevent-addEventListenerscriptlet to match specific element and updatedlog-addEventListenerscriptlet to log target element #480.
v2.1.6 - 2025-03-06
- Incorrectly removing content from parsed array when using the
json-prunescriptlet #482.
v2.1.5 - 2025-02-28
- Updated @adguard/agtree to v3.0.1.
- Ability in
json-prunescriptlet to matchkeywith specificvalueand removearray/objectif it contains specificitem#183.
prevent-eval-ifandprevent-babscriptlets, noweval.toString()call returns original value #481.
v2.1.4 - 2025-01-20
- ESM-only bundle.
trusted-click-elementscriptlet, now whencontainsTextis used then it will search for all given selectors and click on the first element with matched text #468.
- Issue with
metrika-yandex-tagredirect when it's used as a scriptlet #472. - Issue with
trusted-click-elementscriptlet whendelaywas used and the element was removed and added again before it was clicked #391.
v2.0.1 - 2024-11-13
prevent-canvasscriptlet #451.- Trusted Types API support in
trusted-replace-node-textscriptlet #457. parentSelectoroption to search for nodes forremove-node-textscriptlet #397.transformoption withbase64decodevalue forhref-sanitizerscriptlet #455.removeParamandremoveHashvalues intransformoption forhref-sanitizerscriptlet #460.- New values to
set-cookieandset-local-storage-itemscriptlets:forbidden,forever#458.
- Set response
oktofalsebyprevent-fetchif response type isopaque#441. - Improve
prevent-xhr— modify response #415. - Improve
prevent-xhr— add missed events #414. Sourcetype instead ofIConfiguration.- API structure. Validators, Converters, Scriptlets and redirects are now separate modules.
- The minimum supported Safari version is now 13.
- Updated @adguard/agtree to v3.0.0-alpha.1.
- IIFE bundle.
- UMD bundle.
- Various conversion and validation functions including
isAdgRedirectRule,isAdgRedirectCompatibleWithUbo,isUboRedirectCompatibleWithAdg,isAbpRedirectCompatibleWithAdg,convertUboRedirectToAdg,convertAbpRedirectToAdg,convertRedirectToAdg, andconvertRedirectNameToAdgfunctions.
v1.12.1 - 2024-09-20
- Integrated @adguard/agtree library for working with rules, compatibility tables, validator and converter.
- Re-adding element on every DOM change in
trusted-create-elementscriptlet #450. - Setting cookie which name has special prefix
__Host-or__Secure-bytrusted-set-cookieandtrusted-set-cookie-reloadscriptlets #448.
v1.11.27 - 2024-08-29
reloadoption fortrusted-click-elementscriptlet #301.- Support for matching line number in
abort-on-stack-tracescriptlet wheninlineScriptorinjectedScriptoption is used #439. - New values to
set-cookieandset-cookie-reloadscriptlets:checked,unchecked#444. - New values to
set-local-storage-itemandset-session-storage-itemscriptlets:allowed,denied#445. - UBO aliases
noop-vast2.xml,noop-vast3.xml, andnoop-vast4.xmlfor correspondent AdGuard redirects. - New field
uniqueIdto scriptlet configuration, allowing scriptlets to be executed only once per context.
- UBO alias
noop-vmap1.0.xmlfornoopvmap-1.0redirect is replaced bynoop-vmap1.xml.
- Modifying
RegExp.$1, …, RegExp.$9values inlog-on-stack-traceandabort-on-stack-tracescriptlets #384.
v1.11.16 - 2024-08-01
trusted-set-session-storage-itemscriptlet #426.- New values to
set-cookieandset-cookie-reloadscriptlets:essential,nonessential#436. $currentISODate$as a new possible value toset-cookie,set-cookie-reload,set-local-storage-itemandset-session-storage-itemscriptlets #435.
- Re-adding element after removing it in
trusted-create-elementscriptlet #434. trusted-click-elementscriptlet does not click on an element that is already in the DOM #437.
v1.11.6 - 2024-07-08
- New values to
set-cookieandset-cookie-reloadscriptlets:hide,hidden#433. - New values to
set-local-storage-itemandset-session-storage-itemscriptlets:accept,accepted,reject,rejected#429. - Ability to log original and modified content in
trusted-replace-node-text,xml-prune,m3u-prune,trusted-replace-fetch-responseandtrusted-replace-xhr-responsescriptlets #411.
- Log message format CoreLibs#180.
v1.11.1 - 2024-06-13
trusted-dispatch-eventscriptlet #382.trusted-replace-outbound-textscriptlet #410.- Ability to click on the element with specified text in
trusted-click-elementscriptlet #409. - Ability to click element in closed shadow root in
trusted-click-elementscriptlet #423. isRedirectResourceCompatibleWithAdg()method to check compatibility of redirect resources with AdGuard without needing the full rule text #420.
ruleTextoption in theIConfiguration.
set-attrvalue cannot be set to minimum0and maximum32767possible value #425.
v1.10.25 - 2024-03-28
trusted-suppress-native-methodscriptlet #383.json-prune-fetch-responsescriptlet #361.json-prune-xhr-responsescriptlet #360.href-sanitizerscriptlet #327.no-protected-audiencescriptlet #395.- The ability for
prevent-fetchscriptlet to setcorsas a response type #394. - The ability for
trusted-click-elementscriptlet to click inside open shadow doms #323. - Domain value for setting cookie scriptlets #389.
- Multiple redirects can now be used as scriptlets #300:
amazon-apstag;didomi-loader;fingerprintjs2;fingerprintjs3;gemius;google-analytics;google-analytics-ga;google-ima3;googlesyndication-adsbygoogle;googletagservices-gpt;matomo;metrika-yandex-tag;metrika-yandex-watch;naver-wcslog;pardot-1.0;prebid;scorecardresearch-beacon.
- Validation of scriptlet rules with no name and args for multiple scriptlet exception rules #377.
- Cookie name is not encoded by cookie setting scriptlets #408.
- Increased the possible numeric value up to
32767forset-cookieandset-cookie-reloadscriptlets #388.
- UBO→ADG conversion of
$remove$scriptlet param #404. set-constantscriptlet not setting a constant over falsy values #403.
v1.10.1 - 2024-02-12
call-nothrowscriptlet #333.spoof-cssscriptlet #317.trusted-create-elementscriptlet #278.trusted-set-attrscriptlet #281.- Ability of
set-attrto set an attribute value as a copy of another attribute value of the same element. - UBO alias for
set-cookie-reloadscriptlet #332. - New values
t,f,necessary,requiredforset-cookieandset-cookie-reload#379.
v1.9.105 - 2023-12-25
OmidVerificationVendorobject togoogle-ima3redirect #353.ga.q(queued commands) togoogle-analyticsredirect #355.
addEventListenerinEventHandleringoogle-ima3redirect, now it binds context to callback #353.AdDisplayContainerconstructor ingoogle-ima3redirect, now it adds div element to container #353.getInnerErrormethod ingoogle-ima3redirect, now it returnsnull#353.
v1.9.101 - 2023-11-30
emptyStrvalue forresponseBodyinprevent-fetchscriptlet #364.setPrivacySettings()method togoogletagservices-gptredirect #344.- UBO alias
noop.jsonfornoopjsonredirect. - Library version number to the exports AdguardBrowserExtension#2237.
prevent-fetchscriptlet, ifresponseTypeis set toopaquethen now responsebodyis set tonull,statusis set to0andstatusTextis set to''#364.
v1.9.96 - 2023-11-15
- Regular expression support for removing items in
set-local-storage-itemandset-session-storage-itemscriptlets #256. - Ability to set proxy trap in
set-constantscriptlet #330.
v1.9.91 - 2023-11-13
trusted-prune-inbound-objectscriptlet #372.- New values to
set-cookiescriptlet:on,off,accepted,notaccepted,rejected,allowed,disallow,enable,enabled,disable,disabled#375. - New values to
set-local-storage-itemandset-session-storage-itemscriptlets:on,off#366.
- Setting proxy trap every time when property is accessed in
set-constantscriptlet #380. - Issue with
stackinevaldata-prunescriptlet #378. - Setting values to wrong properties in
set-constantscriptlet #373.
v1.9.83 - 2023-10-13
- ABP alias for the
logscriptlet.
- Issue with
trusted-replace-fetch-responsescriptlet in case if data URL was used and properties was set byObject.definePropertyto deceive scriptlet #367. - Adding the same header value in
trusted-replace-xhr-responsescriptlet when it is used multiple times for the same request #359. - Not pruning in
m3u-prunescriptlet if file contains carriage return #354. - Not overriding value in
set-constant(only partially, for cases where single scriptlet is used) #330.
v1.9.72 - 2023-08-25
- Conversion for scriptlets:
set-attr;set-cookie;set-local-storage-item;set-session-storage-item.
v1.9.70 - 2023-08-21
- Support for
XPathinxml-prunescriptlet #325. - Conversion of UBO's $redirect priority to the converter tsurlfilter#59.
- Issue with
stackinjson-prunescriptlet #348. - Issue with
obligatoryPropsinjson-prunescriptlet #345.
v1.9.62 - 2023-08-04
prevent-xhrclosure bug on multiple requests #347.
v1.9.61 - 2023-08-01
convertRedirectNameToAdg()method to convert redirect names to ADG #346.
v1.9.58 - 2023-07-27
- Escape commas in the params during conversion to ubo rules #343.
v1.9.57 - 2023-07-21
- Ability to remove an item from storage in
set-local-storage-itemandset-session-storage-itemscriptlets #338. - New values to
set-cookieandset-cookie-reloadscriptlets:Accept,Reject,y,n,N,No,allow,deny#336. - Ability to use flags in regular expression scriptlet parameters #303.
- Predefined values of
set-cookieandset-cookie-reloadare now case-insensitive #342.
- Overwriting
google.imavalue if it was already set #331. - Printing unnecessary logs to the console in
log-addEventListenerscriptlet #335. - Error throwing in
prevent-fetchandprevent-xhrscriptlets when a request is blocked #334.
v1.9.37 - 2023-06-06
evaldata-prunescriptlet #322.trusted-replace-node-textscriptlet #319.remove-node-textscriptlet #318.- Ability for
prevent-element-src-loadingscriptlet to prevent inlineonerrorand matchlinktag #276. - New special value modifiers for
set-constant#316.
trusted-set-cookieandtrusted-set-cookie-reloadscriptlets to not encode cookie name and value #311.- Improved
prevent-fetch: ifresponseTypeis not specified, original response type is returned instead ofdefault#297.
- Pruning when
addEventListenerwas used before callingsend()method inm3u-pruneandxml-prunescriptlets #315. - Issue with
updateTargetingFromMap()method ingoogletagservices-gptredirect #293. - Website reloading if
$now$/$currentDate$value is used intrusted-set-cookie-reloadscriptlet #291. getResponseHeader()andgetAllResponseHeaders()methods mock inprevent-xhrscriptlet #295.
v1.9.7 - 2023-03-14
- Ability for
trusted-click-elementscriptlet to click element ifcookie/localStorageitem doesn't exist #298. - Static delay between multiple clicks in
trusted-click-element#284.
- Improved the
convertScriptletToAdg()method — now it validates the input rule syntax if it is an ADG rule.
- Issue with
MutationObserver.disconnect()intrusted-click-element#284.
v1.9.1 - 2023-03-07
m3u-prunescriptlet #277.trueandfalsevalues forset-attrscriptlet #283.- UBO alias
noop.cssfornoopcssredirect.
- Decreased the minimal value for the
boostparameter to0.001foradjust-setTimeoutandadjust-setInterval#262.
prevent-element-src-loadingthrowing error ifthisArgisundefined#270.- Logging
nullinjson-prune#282. xml-prune: no pruning a request ifnew Request()is used, throwing an error while logging some requests #289.- Improve performance of the
isValidScriptletName()method.
v1.8.2 - 2023-01-19
trusted-set-constantscriptlet #137.inject-css-in-shadow-domscriptlet #267.throwFuncandnoopCallbackFuncprop values forset-constantscriptlet.recreateIframeForSlotmethod mock togoogletagservices-gptredirect #259.
- Added decimal delay matching for
prevent-setIntervalandprevent-setTimeout#247. - Debug logging to include rule text when available.
getScriptletFunctioncalls to throw error on unknown scriptlet names.
prevent-xhrandtrusted-replace-xhr-responseclosure bug on multiple requests #261.- Missing
googletagmanager-gtmin compatibility table.
v1.7.20 - 2022-12-26
isBlocking()method for Redirects class.filefield for redirect type.
- Redirects types.
v1.7.19 - 2022-12-22
prevent-addEventListenerandlog-addEventListenerloosing context. when encountering already bound.addEventListener.google-ima3conversion.
v1.7.14 - 2022-12-16
set-constantADG→UBO conversion foremptyArrandemptyObjuBlock-issues#2411.
v1.7.13 - 2022-12-13
isEmptyObjecthelper not countingprototypeas an object property.
v1.7.10 - 2022-12-07
trusted-set-cookie-reloadscriptlet.
set-cookie-reloadinfinite page reloading #265.- Breakage of
prevent-element-src-loadingdue towindowgetting intoapplywrapper #264. - Spread of args bug at
getXhrDatacall fortrusted-replace-xhr-response. - Request properties array not being served to
getRequestDataandparseMatchPropshelpers.
v1.7.3 - 2022-11-21
-
Trusted scriptlets with extended capabilities:
-
Scriptlets:
xml-prune#249.