A better fix was introduced in e36c702 for this issue.
The actual problem was that Safari when sends a message from the
background to content, then it passes to all the frames in the target tab,
but it doesn't make copies, it passes only references to the same object,
so if one frame modifies the message, then other frames would have
received the modified message.
Adds possibility to build extension files (Chrome and Safari) from
command line.
To run from the project directory:
python tools/build.py [meta]
If the optional `meta` argument is set, then only the manifest and
language files are uptated.
Without that everything is being built (extension files too) into the
`dist/build/version_number` folder.
For Chrome there will be two files, a crx, and a .zip file which
includes the key.pem private key (so this must not be shared,
it's just a bit help for publishing it to the Chrome Web Store).
Beside the extension files, update-files are generated too (for self
hosting - Safari needs it).
Checking the message name (and connectorId) is mandatory for Safari,
because when the background page sends a response back to a document,
then all the frames in its owner tab will receive the exact same
message, which could confuse the script in some cases.
The beforeNavigate event wasn't reliable (sometimes didn't fire, sometimes
fired unnecessary when opening a link with the middle click - which had a
workaround previously, but that's also removed by this commit).
When the event didn't fire, the bindTabToPageStats method didn't run,
and the requests related to the tab weren't blocked.
Safari's extension API doesn't provide a way to intercept requests
initiated by plugins, so those cases need special care (or at least the
popular sites).
This commit adds a new JS file (sitepatch-safari.js), which will store the
patches (if it's possible to create one) for specific sites.
As an example, this commit includes a technique for removing in-video ads
from YouTube videos.
Click couldn't be initiated with JavaScript in Safari if the input was
hidden with display: none. Using visibility: hidden or opacity: 0 solves
the problem.
Alternative solution would be to hide (opacity: 0) the input and slide it
(position: absolute; top: 0; left: 0; width: 100%; height: 100%) over the
button, which would work in all browsers, and wouldn't require JavaScript.
It works similarly to the xhr intercepting, except here the window.open
global function is being overridden.
Note that it could only work if the site's Content Security Policy allows
inline scripts, and the script on the webpage doesn't have a copy of the
original window.open function (it can happen only if the page has an
inline script in its head element, where the reference to the original
function can be obtained - likely this cannot be prevented in Safari).
- Indentation whitespace fixes.
- Use built-in getBoundingClientRect() function instead of self-made.
- Use built-in DOM API for manipulating the class attributes instead of
altering the className property.
- Add pointer-events: none to the svgRoot when using
document.elementFromPoint(), but if the browser (older Safari for
example) doesn't take the pointer-events into account, then fall back to
display: none.
- Initiate every part of the picker at the same time; when the message is
received from the background. This way the selected element will have
the red overlay immediately, instead of showing first the black overlay,
then a few milliseconds later the red.