a11y-outline

web extension to navigate document outlines easily
git clone https://git.ce9e.org/a11y-outline.git

commit
7a25323402b8874b3e1306dd5af5662528976393
parent
91736e39fa067655d51bedc578d95169d6b5595e
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2024-06-20 06:40
fix: do not perform actions multiple times

Since 963c4585cf71ef984b10de2c745f1dad4a619167 we use the scripting API
to load content scripts. This was done so that the required permissions
could be restricted from `<all_urls>` to `activeTab` (see
https://developer.chrome.com/docs/extensions/develop/concepts/activeTab).

Unfortuntaly, the scripting API makes it really hard to do anything that
goes beyond the simple "turn the body red" example.

The specific issue I dealt with in this commit is that content scripts
are registered multiple times (on every action), and therefore message
listeners are registered multiple times, and therefore actions (e.g.
jump to next heading) are performed multiple times.

In an ideal world, we could use the old delerative approach to content
scripts, but they would only be loaded once they are needed for an
action. Instead, we got an imperative API that lets us inject code, but
doesn't tell us whether that was code already injected. Since event
pages are non-persistent, we also cannot store that info ourselves.

I also looked into `scripting.registerContentScripts()`, but the
documentation was very unclear and I didn't get the feeling that this is
what we need either.

So it seems like we have to live with the fact that content scripts are
loaded on every action. But can we prevent registering message listeners
multiple times? Not with `hasListener()`, because that takes a function
as an argument and since this is a new copy of the code, this is also a
new copy of the listener.

The workaround I ended up with is to store a flag on window and hope
that this is persistent.

Diffstat

M outline.js 9 ++++++++-

1 files changed, 8 insertions, 1 deletions


diff --git a/outline.js b/outline.js

@@ -237,7 +237,14 @@ var focusPrev = function(selector) {
  237   237 	}
  238   238 };
  239   239 
  240    -1 chrome.runtime.onMessage.addListener(function(request) {
   -1   240 var onMessage = function(listener) {
   -1   241 	if (!window.a11yOutlineRegistered) {
   -1   242 		window.a11yOutlineRegistered = true;
   -1   243 		chrome.runtime.onMessage.addListener(listener);
   -1   244 	}
   -1   245 }
   -1   246 
   -1   247 onMessage(function(request) {
  241   248 	if (document.getElementById(DIALOG_ID)) {
  242   249 		return;
  243   250 	} else if (request === 'showA11yOutline') {