Duplicate onBlockableItem events
Environment
- Extension using this toolkit: test-mv2
- Commit hash: cca0bfdd (this is the master branch at time of writing)
Issue
While working on https://gitlab.com/eyeo/adblockplus/abc/webext-sdk/-/issues/135, I discovered that our tests for onBlockableItem tend to check that the expected onBlockableItem event is being emitted, but they do not check that additional events are NOT emitted. Unfortunately, I've discovered that some of the events are emitted multiple times in certain situations.
What to change
- Update the tests to catch extra unexpected onBlockableItem events
- Fix duplicate events
Example Duplication (updating the tests will find additional issues)
- Start the test server, and make sure the EWE test extension is installed.
- Add an allowing filter for a popup
EWE.filters.add("localhost:3000/popup.html$popup")EWE.filters.add("@@localhost:3000/popup.html$popup")
- Add an event listener to log allowlisting onBlockableItem events to the console
EWE.reporting.onBlockableItem.addListener(console.log, {filterType: "allowing"})
- Navigate to http://localhost:3000/popup-opener.html
- Click the "Link-based popup" link
- Observe the logged events in the console
Expected behaviour: The allowing filter for the popup is logged to the console exactly once.
Actual behaviour: The allowing filter for the popup is logged three times.
Integrator Notes
The following duplicate onBlockableItem events were found and fixed
- Allowlisted popups were checked for relevant filters up to 3 times, and logged their allowlisting filter on each occasion.
- Requests which were allowlisted because of $document filters were being logged on every stage a request filter goes through (onBeforeRequest and onHeadersReceived). This is now only logged on the first event in the pipeline (onBeforeRequest).
- Frame-state would previously re-find all allowlisting filters for the frame when its headers were updated, and duplicate its logs for each one. This specifically caused duplicate events when the iframe was cached on Firefox. I've added the ability to update the existing allowlisting filters instead to avoid duplicate events.
- In frame-state, some of the events used seem to arrive in different orders for different browsers, so the onHeadersReceived event needs to be able to work regardless of if it was called before or after onCommitted. This was also causing duplicate allowlisting events for a frame. Fixing this appears to have also fixed https://gitlab.com/eyeo/adblockplus/abc/webext-sdk/-/issues/139.
Edited by Justin Wernick