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.
... for the sake of portability.
When including vapi-common.js in an HTML file, then the body element there
will have a "dir" attribute filled with the current locale's direction
(ltr or rtl).
The following languages are considered right-to-left: ar, he, fa, ps, ur.
Everything else is left-to-right.
After the "dir" attribute is set, we can decide in CSS which elements
should have different styling for rtl languages (e.g., body[dir=rtl] #id).
Chrome has getManifest(), Safari doesn't have anything, Firefox has an
asynchronous API...
So, instead of using extension APIs, store the common informations
(extension name, version, homepage url) in a file (vapi-appinfo.js), which
can be included when it's needed (its data will be available at vAPI.app.____).
The file's content is updated each time the extension is being built, so
it shouldn't be modified manually.
Benefits:
- Cross browser solution (however only for relatively new browsers)
- Doesn't need extra permission in Chrome
If the browser doesn't suppor the download attribute, then a new tab will
be opened with the exported data.
Other changes:
- Start the download only if the data is not empty (previously the
download started anyway)
- Reorder code in vapi-client.js for Safari, so unnecessary code doesn't
run on extension pages
- Add script injection to vAPI, plus a raw implementation for Safari
(element-picker.js requires it)
- Tweak element picker to work with Safari
- Revert a change from previous commit: element-picker.js' background
message handler (since actually it can have its own messaging channel)
- Don't send "undefined" reponses from background to content
- Include latest changes from gorhill/uBlock/master
- Append the pickerRoot container to document.documentElement instead
of document.body ("body > div" type CSS selectors are more common, so
they could overwrite the extension's styling with higher probability)
- Request localized strings from the background script instead of using
the i18n API in content scripts
- Fuse element-picker.js' message handling into contentscript-end.js', since
only one messaging channel can live at a time in a content script
By default, Safari doesn't resize the popup to its content, but it's
possible to set the size pragmatically.
The popup will be resized every time when a change happens in the DOM tree.
Earlier, a technique was used to open the extension's Options page when
the user clicked a checkbox input at Safari's extension settings. The method was removed because:
- the Options page can be opened via the extension's toolbar button (which
cannot be disabled in Safari, so it will be there all the time);
- involved more clicks than opening from the toolbar button;
- the string beside the checkbox couldn't be localized.
.jshintrc's otion-set is a personal choice, merely a suggestion.
Beside that, it includes some common globals for specific browsers, so
there's no need to set the globals in every .js file.
In order to force strict coding, "use strict" directive was added into
every .js file.
- Update assets from gorhill/uBlock/master
- Remove whitespace from element-picker.js
- Simplify code in profiler.js (btw, Date is still needed as fallback
for older browsers)
- Clarification for Safari's storage where the QUOTA_BYTES came from