mirror of https://github.com/gorhill/uBlock.git
Big fixes to Safari vAPI stuff
This commit is contained in:
parent
da7398d585
commit
16f3a205e0
|
@ -19,9 +19,6 @@
|
|||
Home: https://github.com/gorhill/uBlock
|
||||
*/
|
||||
|
||||
/* global ytspf */
|
||||
'use strict';
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// Adding new URL requires to whitelist it in the background script too (addContentScriptFromURL)
|
||||
|
@ -30,7 +27,7 @@
|
|||
// from the extension scope won't be accessible in the sitePatch function.
|
||||
|
||||
|
||||
self.vAPI = self.vAPI || {};
|
||||
var vAPI = self.vAPI = self.vAPI || {};
|
||||
|
||||
if ( /^www\.youtube(-nocookie)?\.com/.test(location.host) ) {
|
||||
vAPI.sitePatch = function() {
|
||||
|
|
|
@ -29,8 +29,6 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var vAPI = self.vAPI = self.vAPI || {};
|
||||
|
||||
vAPI.safari = true;
|
||||
|
@ -590,104 +588,84 @@ vAPI.net = {};
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
// Fast `contains`
|
||||
|
||||
Array.prototype.contains = function(a) {
|
||||
var b = this.length;
|
||||
while(b --) {
|
||||
if(this[b] === a) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
vAPI.net.registerListeners = function() {
|
||||
var µb = µBlock;
|
||||
|
||||
// Since it's not used
|
||||
this.onBeforeSendHeaders = null;
|
||||
this.onHeadersReceived = null;
|
||||
// Until Safari has more specific events, those are instead handled
|
||||
// in the onBeforeRequestAdapter; clean them up so they're garbage-collected
|
||||
vAPI.net.onBeforeSendHeaders = null;
|
||||
vAPI.net.onHeadersReceived = null;
|
||||
|
||||
var onBeforeRequest = this.onBeforeRequest;
|
||||
var onBeforeRequest = vAPI.net.onBeforeRequest,
|
||||
onBeforeRequestClient = onBeforeRequest.callback,
|
||||
blockableTypes = onBeforeRequest.types;
|
||||
|
||||
if ( !Array.isArray(onBeforeRequest.types) ) {
|
||||
onBeforeRequest.types = [];
|
||||
}
|
||||
|
||||
onBeforeRequest = onBeforeRequest.callback;
|
||||
this.onBeforeRequest.callback = function(e) {
|
||||
var block;
|
||||
|
||||
if ( e.name !== 'canLoad' ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// No stopPropagation if it was called from beforeNavigate event
|
||||
if ( e.stopPropagation ) {
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
if ( e.message.isURLWhiteListed ) {
|
||||
// https://github.com/gorhill/uBlock/issues/595
|
||||
// Do not access µb.netWhitelist directly
|
||||
e.message = !µb.getNetFilteringSwitch(e.message.isURLWhiteListed);
|
||||
return e.message;
|
||||
}
|
||||
|
||||
// When the URL changes, but the document doesn't
|
||||
if ( e.message.type === 'popstate' ) {
|
||||
vAPI.tabs.onUpdated(
|
||||
vAPI.tabs.getTabId(e.target),
|
||||
{url: e.message.url},
|
||||
{url: e.message.url}
|
||||
);
|
||||
return;
|
||||
} else if ( e.message.type === 'popup' ) {
|
||||
// blocking unwanted pop-ups
|
||||
if ( e.message.url === 'about:blank' ) {
|
||||
vAPI.tabs.popupCandidate = vAPI.tabs.getTabId(e.target);
|
||||
e.message = true;
|
||||
} else {
|
||||
e.message = !vAPI.tabs.onPopup({
|
||||
url: e.message.url,
|
||||
tabId: 0,
|
||||
sourceTabId: vAPI.tabs.getTabId(e.target)
|
||||
});
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
if ( e.message.navigatedToNew ) {
|
||||
vAPI.tabs.onNavigation({
|
||||
url: e.message.url,
|
||||
frameId: 0,
|
||||
tabId: vAPI.tabs.getTabId(e.target)
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
block = vAPI.net.onBeforeRequest;
|
||||
|
||||
if ( block.types.indexOf(e.message.type) === -1 ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
e.message.hostname = µb.URI.hostnameFromURI(e.message.url);
|
||||
e.message.tabId = vAPI.tabs.getTabId(e.target);
|
||||
block = onBeforeRequest(e.message);
|
||||
|
||||
// Truthy return value will allow the request,
|
||||
// except when redirectUrl is present
|
||||
if ( block && typeof block === 'object' ) {
|
||||
if ( block.cancel === true ) {
|
||||
e.message = false;
|
||||
} else if ( e.message.type === 'script'
|
||||
&& typeof block.redirectUrl === 'string' ) {
|
||||
e.message = block.redirectUrl;
|
||||
} else {
|
||||
e.message = true;
|
||||
}
|
||||
} else {
|
||||
e.message = true;
|
||||
}
|
||||
|
||||
return e.message;
|
||||
var onBeforeRequestAdapter = function(e) {
|
||||
if(e.name !== "canLoad") {
|
||||
return;
|
||||
}
|
||||
e.stopPropagation && e.stopPropagation();
|
||||
switch(e.message.type) {
|
||||
case "isWhiteListed":
|
||||
e.message = !µb.getNetFilteringSwitch(e.message.url);
|
||||
break;
|
||||
case "navigatedToNew":
|
||||
vAPI.tabs.onNavigation({
|
||||
url: e.message.url,
|
||||
frameId: 0,
|
||||
tabId: vAPI.tabs.getTabId(e.target)
|
||||
});
|
||||
break;
|
||||
case "popup":
|
||||
if(e.message.url === 'about:blank') {
|
||||
vAPI.tabs.popupCandidate = vAPI.tabs.getTabId(e.target);
|
||||
e.message = true;
|
||||
}
|
||||
else {
|
||||
e.message = !vAPI.tabs.onPopup({
|
||||
url: e.message.url,
|
||||
tabId: 0,
|
||||
sourceTabId: vAPI.tabs.getTabId(e.target)
|
||||
});
|
||||
}
|
||||
break;
|
||||
case "popstate":
|
||||
vAPI.tabs.onUpdated(vAPI.tabs.getTabId(e.target),
|
||||
{url: e.message.url},
|
||||
{url: e.message.url});
|
||||
break;
|
||||
default:
|
||||
if(!blockableTypes.contains(e.message.type)) {
|
||||
e.message = true;
|
||||
return;
|
||||
}
|
||||
e.message.hostname = µb.URI.hostnameFromURI(e.message.url);
|
||||
e.message.tabId = vAPI.tabs.getTabId(e.target);
|
||||
var blockVerdict = onBeforeRequestClient(e.message);
|
||||
if(blockVerdict && blockVerdict.cancel) {
|
||||
e.message = false;
|
||||
}
|
||||
else {
|
||||
e.message = true;
|
||||
}
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
safari.application.addEventListener(
|
||||
'message',
|
||||
this.onBeforeRequest.callback,
|
||||
true
|
||||
);
|
||||
safari.application.addEventListener("message", onBeforeRequestAdapter, true);
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
|
|
@ -27,9 +27,7 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
self.vAPI = self.vAPI || {};
|
||||
var vAPI = self.vAPI = self.vAPI || {};
|
||||
vAPI.safari = true;
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -177,7 +175,7 @@ vAPI.messaging = {
|
|||
/******************************************************************************/
|
||||
|
||||
vAPI.canExecuteContentScript = function() {
|
||||
return /^https?:/.test(location.protocol);
|
||||
return (/^https?:/.test(location.protocol) && typeof safari === 'object');
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -185,35 +183,34 @@ vAPI.canExecuteContentScript = function() {
|
|||
// This file can be included into extensin pages,
|
||||
// but the following code should run only in content pages.
|
||||
|
||||
if ( location.protocol === 'safari-extension:' ) {
|
||||
if ( location.protocol === 'safari-extension:' || typeof safari !== 'object' ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var frameId = window === window.top ? 0 : Date.now() % 1E5;
|
||||
var parentFrameId = frameId ? 0 : -1;
|
||||
var beforeLoadEvent = new Event('beforeload'); // Helper event to message background
|
||||
var parentFrameId = (frameId ? 0 : -1);
|
||||
var beforeLoadEvent = new Event("beforeload"); // Helper event to message background
|
||||
|
||||
// Inform that we've navigated
|
||||
if(frameId === 0) {
|
||||
safari.self.tab.canLoad(beforeLoadEvent, {
|
||||
url: location.href,
|
||||
type: 'main_frame',
|
||||
navigatedToNew: true
|
||||
type: "navigatedToNew"
|
||||
});
|
||||
}
|
||||
|
||||
var linkHelper = document.createElement('a');
|
||||
var linkHelper = document.createElement("a");
|
||||
var nodeTypes = {
|
||||
'frame': 'sub_frame',
|
||||
'iframe': 'sub_frame',
|
||||
'script': 'script',
|
||||
'img': 'image',
|
||||
'input': 'image',
|
||||
'object': 'object',
|
||||
'embed': 'object',
|
||||
'link': 'stylesheet'
|
||||
"frame": "sub_frame",
|
||||
"iframe": "sub_frame",
|
||||
"script": "script",
|
||||
"img": "image",
|
||||
"input": "image",
|
||||
"object": "object",
|
||||
"embed": "object",
|
||||
"link": "stylesheet"
|
||||
};
|
||||
var shouldBlockDetailedRequest = function(details) {
|
||||
linkHelper.href = details.url;
|
||||
|
@ -224,7 +221,7 @@ var shouldBlockDetailedRequest = function(details) {
|
|||
return !(safari.self.tab.canLoad(beforeLoadEvent, details));
|
||||
}
|
||||
var onBeforeLoad = function(e) {
|
||||
if(e.url.lastIndexOf('data:', 0) === 0) {
|
||||
if(e.url.lastIndexOf("data:", 0) === 0) {
|
||||
return;
|
||||
}
|
||||
linkHelper.href = e.url;
|
||||
|
@ -240,28 +237,6 @@ var onBeforeLoad = function(e) {
|
|||
var response = safari.self.tab.canLoad(e, details);
|
||||
if(!response) {
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
// Local mirroring, response should be a data: URL here
|
||||
if(typeof response !== 'string') {
|
||||
return;
|
||||
}
|
||||
// Okay, we're mirroring...
|
||||
e.preventDefault();
|
||||
// Content Security Policy with disallowed inline scripts may break things
|
||||
details = document.createElement('script');
|
||||
details.textContent = atob(response.slice(response.indexOf(',', 20) + 1));
|
||||
|
||||
if ( e.target.hasAttribute('defer') && document.readyState === 'loading' ) {
|
||||
var jsOnLoad = function(ev) {
|
||||
this.removeEventListener(ev.type, jsOnLoad, true);
|
||||
this.body.removeChild(this.body.appendChild(details));
|
||||
};
|
||||
|
||||
document.addEventListener('DOMContentLoaded', jsOnLoad, true);
|
||||
} else {
|
||||
e.target.parentNode.insertBefore(details, e.target);
|
||||
details.parentNode.removeChild(details);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -270,7 +245,7 @@ document.addEventListener('beforeload', onBeforeLoad, true);
|
|||
/******************************************************************************/
|
||||
// block pop-ups, intercept xhr requests, and apply site patches
|
||||
var firstMutation = function() {
|
||||
document.removeEventListener('DOMSubtreeModified', firstMutation, true);
|
||||
document.removeEventListener('DOMContentLoaded', firstMutation, true);
|
||||
firstMutation = false;
|
||||
|
||||
var randEventName = uniqueId();
|
||||
|
@ -302,7 +277,7 @@ var firstMutation = function() {
|
|||
'};'
|
||||
];
|
||||
|
||||
if ( frameId === 0 ) {
|
||||
if(frameId === 0) {
|
||||
tmpScript.push(
|
||||
'var pS = history.pushState, rS = history.replaceState,',
|
||||
'onpopstate = function(e) {',
|
||||
|
@ -322,22 +297,20 @@ var firstMutation = function() {
|
|||
);
|
||||
}
|
||||
|
||||
var block = safari.self.tab.canLoad(beforeLoadEvent, {
|
||||
isURLWhiteListed: location.href
|
||||
var whiteListed = safari.self.tab.canLoad(beforeLoadEvent, {
|
||||
type: "isWhiteListed",
|
||||
url: location.href
|
||||
});
|
||||
|
||||
if ( vAPI.sitePatch && !block ) {
|
||||
tmpScript.push('(' + vAPI.sitePatch + ')();');
|
||||
if(vAPI.sitePatch && !whiteListed) {
|
||||
tmpScript.push('(' + vAPI.sitePatch + ')();');
|
||||
}
|
||||
|
||||
tmpScript.push('})();');
|
||||
tmpJS.textContent = tmpScript.join('');
|
||||
document.documentElement.removeChild(
|
||||
document.documentElement.appendChild(tmpJS)
|
||||
);
|
||||
document.documentElement.removeChild(document.documentElement.appendChild(tmpJS));
|
||||
};
|
||||
|
||||
document.addEventListener('DOMSubtreeModified', firstMutation, true);
|
||||
document.addEventListener('DOMContentLoaded', firstMutation, true);
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
|
Loading…
Reference in New Issue