mirror of
https://github.com/gorhill/uBlock.git
synced 2024-11-09 12:22:33 +01:00
Merge pull request #596 from chrisaljoudi/master
Big fixes to Safari vAPI stuff
This commit is contained in:
commit
f69b38f089
@ -19,9 +19,6 @@
|
|||||||
Home: https://github.com/gorhill/uBlock
|
Home: https://github.com/gorhill/uBlock
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* global ytspf */
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
// Adding new URL requires to whitelist it in the background script too (addContentScriptFromURL)
|
// 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.
|
// 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) ) {
|
if ( /^www\.youtube(-nocookie)?\.com/.test(location.host) ) {
|
||||||
vAPI.sitePatch = function() {
|
vAPI.sitePatch = function() {
|
||||||
|
@ -29,8 +29,6 @@
|
|||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
var vAPI = self.vAPI = self.vAPI || {};
|
var vAPI = self.vAPI = self.vAPI || {};
|
||||||
|
|
||||||
vAPI.safari = true;
|
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() {
|
vAPI.net.registerListeners = function() {
|
||||||
var µb = µBlock;
|
var µb = µBlock;
|
||||||
|
|
||||||
// Since it's not used
|
// Until Safari has more specific events, those are instead handled
|
||||||
this.onBeforeSendHeaders = null;
|
// in the onBeforeRequestAdapter; clean them up so they're garbage-collected
|
||||||
this.onHeadersReceived = null;
|
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) ) {
|
var onBeforeRequestAdapter = function(e) {
|
||||||
onBeforeRequest.types = [];
|
if(e.name !== "canLoad") {
|
||||||
}
|
|
||||||
|
|
||||||
onBeforeRequest = onBeforeRequest.callback;
|
|
||||||
this.onBeforeRequest.callback = function(e) {
|
|
||||||
var block;
|
|
||||||
|
|
||||||
if ( e.name !== 'canLoad' ) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
e.stopPropagation && e.stopPropagation();
|
||||||
// No stopPropagation if it was called from beforeNavigate event
|
switch(e.message.type) {
|
||||||
if ( e.stopPropagation ) {
|
case "isWhiteListed":
|
||||||
e.stopPropagation();
|
e.message = !µb.getNetFilteringSwitch(e.message.url);
|
||||||
}
|
break;
|
||||||
|
case "navigatedToNew":
|
||||||
if ( e.message.isURLWhiteListed ) {
|
vAPI.tabs.onNavigation({
|
||||||
// https://github.com/gorhill/uBlock/issues/595
|
url: e.message.url,
|
||||||
// Do not access µb.netWhitelist directly
|
frameId: 0,
|
||||||
e.message = !µb.getNetFilteringSwitch(e.message.isURLWhiteListed);
|
tabId: vAPI.tabs.getTabId(e.target)
|
||||||
return e.message;
|
});
|
||||||
}
|
break;
|
||||||
|
case "popup":
|
||||||
// When the URL changes, but the document doesn't
|
if(e.message.url === 'about:blank') {
|
||||||
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);
|
vAPI.tabs.popupCandidate = vAPI.tabs.getTabId(e.target);
|
||||||
e.message = true;
|
e.message = true;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
e.message = !vAPI.tabs.onPopup({
|
e.message = !vAPI.tabs.onPopup({
|
||||||
url: e.message.url,
|
url: e.message.url,
|
||||||
tabId: 0,
|
tabId: 0,
|
||||||
sourceTabId: vAPI.tabs.getTabId(e.target)
|
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;
|
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.hostname = µb.URI.hostnameFromURI(e.message.url);
|
||||||
e.message.tabId = vAPI.tabs.getTabId(e.target);
|
e.message.tabId = vAPI.tabs.getTabId(e.target);
|
||||||
block = onBeforeRequest(e.message);
|
var blockVerdict = onBeforeRequestClient(e.message);
|
||||||
|
if(blockVerdict && blockVerdict.cancel) {
|
||||||
// Truthy return value will allow the request,
|
|
||||||
// except when redirectUrl is present
|
|
||||||
if ( block && typeof block === 'object' ) {
|
|
||||||
if ( block.cancel === true ) {
|
|
||||||
e.message = false;
|
e.message = false;
|
||||||
} else if ( e.message.type === 'script'
|
}
|
||||||
&& typeof block.redirectUrl === 'string' ) {
|
else {
|
||||||
e.message = block.redirectUrl;
|
|
||||||
} else {
|
|
||||||
e.message = true;
|
e.message = true;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
e.message = true;
|
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
return e.message;
|
|
||||||
};
|
};
|
||||||
|
safari.application.addEventListener("message", onBeforeRequestAdapter, true);
|
||||||
safari.application.addEventListener(
|
|
||||||
'message',
|
|
||||||
this.onBeforeRequest.callback,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -27,9 +27,7 @@
|
|||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
/******************************************************************************/
|
var vAPI = self.vAPI = self.vAPI || {};
|
||||||
|
|
||||||
self.vAPI = self.vAPI || {};
|
|
||||||
vAPI.safari = true;
|
vAPI.safari = true;
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
@ -177,7 +175,7 @@ vAPI.messaging = {
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
vAPI.canExecuteContentScript = function() {
|
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,
|
// This file can be included into extensin pages,
|
||||||
// but the following code should run only in content 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var frameId = window === window.top ? 0 : Date.now() % 1E5;
|
var frameId = window === window.top ? 0 : Date.now() % 1E5;
|
||||||
var parentFrameId = frameId ? 0 : -1;
|
var parentFrameId = (frameId ? 0 : -1);
|
||||||
var beforeLoadEvent = new Event('beforeload'); // Helper event to message background
|
var beforeLoadEvent = new Event("beforeload"); // Helper event to message background
|
||||||
|
|
||||||
// Inform that we've navigated
|
// Inform that we've navigated
|
||||||
if(frameId === 0) {
|
if(frameId === 0) {
|
||||||
safari.self.tab.canLoad(beforeLoadEvent, {
|
safari.self.tab.canLoad(beforeLoadEvent, {
|
||||||
url: location.href,
|
url: location.href,
|
||||||
type: 'main_frame',
|
type: "navigatedToNew"
|
||||||
navigatedToNew: true
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var linkHelper = document.createElement('a');
|
var linkHelper = document.createElement("a");
|
||||||
var nodeTypes = {
|
var nodeTypes = {
|
||||||
'frame': 'sub_frame',
|
"frame": "sub_frame",
|
||||||
'iframe': 'sub_frame',
|
"iframe": "sub_frame",
|
||||||
'script': 'script',
|
"script": "script",
|
||||||
'img': 'image',
|
"img": "image",
|
||||||
'input': 'image',
|
"input": "image",
|
||||||
'object': 'object',
|
"object": "object",
|
||||||
'embed': 'object',
|
"embed": "object",
|
||||||
'link': 'stylesheet'
|
"link": "stylesheet"
|
||||||
};
|
};
|
||||||
var shouldBlockDetailedRequest = function(details) {
|
var shouldBlockDetailedRequest = function(details) {
|
||||||
linkHelper.href = details.url;
|
linkHelper.href = details.url;
|
||||||
@ -224,7 +221,7 @@ var shouldBlockDetailedRequest = function(details) {
|
|||||||
return !(safari.self.tab.canLoad(beforeLoadEvent, details));
|
return !(safari.self.tab.canLoad(beforeLoadEvent, details));
|
||||||
}
|
}
|
||||||
var onBeforeLoad = function(e) {
|
var onBeforeLoad = function(e) {
|
||||||
if(e.url.lastIndexOf('data:', 0) === 0) {
|
if(e.url.lastIndexOf("data:", 0) === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
linkHelper.href = e.url;
|
linkHelper.href = e.url;
|
||||||
@ -240,28 +237,6 @@ var onBeforeLoad = function(e) {
|
|||||||
var response = safari.self.tab.canLoad(e, details);
|
var response = safari.self.tab.canLoad(e, details);
|
||||||
if(!response) {
|
if(!response) {
|
||||||
e.preventDefault();
|
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
|
// block pop-ups, intercept xhr requests, and apply site patches
|
||||||
var firstMutation = function() {
|
var firstMutation = function() {
|
||||||
document.removeEventListener('DOMSubtreeModified', firstMutation, true);
|
document.removeEventListener('DOMContentLoaded', firstMutation, true);
|
||||||
firstMutation = false;
|
firstMutation = false;
|
||||||
|
|
||||||
var randEventName = uniqueId();
|
var randEventName = uniqueId();
|
||||||
@ -302,7 +277,7 @@ var firstMutation = function() {
|
|||||||
'};'
|
'};'
|
||||||
];
|
];
|
||||||
|
|
||||||
if ( frameId === 0 ) {
|
if(frameId === 0) {
|
||||||
tmpScript.push(
|
tmpScript.push(
|
||||||
'var pS = history.pushState, rS = history.replaceState,',
|
'var pS = history.pushState, rS = history.replaceState,',
|
||||||
'onpopstate = function(e) {',
|
'onpopstate = function(e) {',
|
||||||
@ -322,22 +297,20 @@ var firstMutation = function() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
var block = safari.self.tab.canLoad(beforeLoadEvent, {
|
var whiteListed = safari.self.tab.canLoad(beforeLoadEvent, {
|
||||||
isURLWhiteListed: location.href
|
type: "isWhiteListed",
|
||||||
|
url: location.href
|
||||||
});
|
});
|
||||||
|
if(vAPI.sitePatch && !whiteListed) {
|
||||||
if ( vAPI.sitePatch && !block ) {
|
|
||||||
tmpScript.push('(' + vAPI.sitePatch + ')();');
|
tmpScript.push('(' + vAPI.sitePatch + ')();');
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpScript.push('})();');
|
tmpScript.push('})();');
|
||||||
tmpJS.textContent = tmpScript.join('');
|
tmpJS.textContent = tmpScript.join('');
|
||||||
document.documentElement.removeChild(
|
document.documentElement.removeChild(document.documentElement.appendChild(tmpJS));
|
||||||
document.documentElement.appendChild(tmpJS)
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
document.addEventListener('DOMSubtreeModified', firstMutation, true);
|
document.addEventListener('DOMContentLoaded', firstMutation, true);
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user