freeze-element snippet
Background
abort-on-property-read
, abort-on-property-write
and abort-current-inline-script
snippets operate by attaching to a global variable and throwing an exception each time that variable is accessed. This approach works well for some of the inline scripts but many CV providers are trying to dodge that by obfuscating the code so the usage of the global variable is hidden or by not using accessible global variables at all.
The approach freeze-element
will use is similar to the one above. But, instead of attaching to a specific global variable, the snippet will attach to the DOM mutation properties of a specific DOM element. The snippet will block the usage of these properties. The result will be that the element we targeted is frozen from adding new content inside it.
How?
There are 2 major implementation steps:
Watching the document to react when the target element is being added to the DOM using MutationObserver Finding the parent element and configure it's DOM mutation properties with a getter/setter in order to be able to add a conditional blocking proxy for each of them by doing that, we will be able to decide if the property access should be blocked based on the content that is being added
DOM mutation properties
- appendChild
- append
- prepend
- insertBefore
- replaceChild
- replaceWith
- after
- before
- insertAdjacentElement
- insertAdjacentHTML
- insertAdjacentText
- innerHTML
- outerHTML
- textContent
- innerText
- nodeValue
Parameters
Name | Description | Example | Mandatory |
---|---|---|---|
selector | The CSS selector for the parent element that we want to freeze | '.left-content .container' |
yes |
options | A single parameter for snippet's options. A string containing all the options we want to pass, each of them separated by a plus character (+ ). Empty single quotes if none ('' ). Available options: subtree (if we want to freeze all the element's children as well), abort (throw an error every time an child element gets added) |
'' or subtree or abort or subtree+abort
|
no |
exceptions | An array of regex/selectors used to specify the nodes we don't want to prevent being added. Each array item can be: selector (targeting Element nodes), regex (targeting Text nodes, identified by slash) | .article #banner .navigation /.*/ |
no |
Examples
Filter | Result |
---|---|
freeze-element ol#b_results |
Any addition of an immediate child to the ol#b_results element will be blocked. |
freeze-element ol#b_results subtree |
Any addition of a node to the entire subtree of ol#b_results element will be blocked. |
freeze-element ol#b_results '' .organic-result |
Any addition of an immediate child to the ol#b_results element will be blocked except for the elements with the organic-result class. |
freeze-element ol#b_results '' .organic-result /hello/ |
Any addition of an immediate child to the ol#b_results element will be blocked except for the elements with the organic-result class and the Text nodes that match the /hello/ regex. |
freeze-element ol#b_results '' .organic-result /.*/ |
Any addition of an immediate child to the ol#b_results element will be blocked except for the elements with the organic-result class and any Text node. |
freeze-element ol#b_results '' .organic-result #header |
Any addition of an immediate child to the ol#b_results element will be blocked except for the elements with the organic-result class or the id of header. |
freeze-element ol#b_results subtree .organic-result #header |
Any addition of a node to the entire subtree of ol#b_results element will be blocked except for the elements with the organic-result class or the id of header. |
freeze-element ol#b_results abort |
Any addition of an immediate child to the ol#b_results element will throw an error. |
freeze-element ol#b_results abort+subtree |
Any addition of a node to the entire subtree of ol#b_results element will throw an error. |
freeze-element ol#b_results abort+subtree .organic-result |
Any addition of a node to the entire subtree of ol#b_results element will throw an error except for the elements with the organic-result class. |
Options syntax
In order to support multiple optional parameters, I proposed a syntax for the options parameter. For example, let's say in the future the snippet will need to support a new optional parameter. In this case, the second parameter needs to be skipped (see ''
proposal). What do you think about it?
Integration Note
Because this snippet implementation relies on having the same environment for all the snippet executions (aka #227 (closed)), this implementation has a dependency on this change on ABP chrome.
/cc @u.bernitt