mirror of
https://github.com/gorhill/uBlock.git
synced 2024-11-13 10:17:34 +01:00
Merge pull request #548 from chrisaljoudi/master
More fixes and performance improvements to Safari event handling and dispatching
This commit is contained in:
commit
965f3cfc29
2 changed files with 70 additions and 119 deletions
|
@ -188,33 +188,23 @@ vAPI.tabs = {
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
vAPI.tabs.registerListeners = function() {
|
vAPI.tabs.registerListeners = function() {
|
||||||
var onNavigation = this.onNavigation;
|
|
||||||
|
|
||||||
safari.application.addEventListener('beforeNavigate', function(e) {
|
safari.application.addEventListener('beforeNavigate', function(e) {
|
||||||
if ( !e.target || !e.target.url || e.target.url === 'about:blank' ) {
|
if ( !vAPI.tabs.popupCandidate || !e.target || e.url === 'about:blank' ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var url = e.target.url, tabId = vAPI.tabs.getTabId(e.target);
|
var url = e.url, tabId = vAPI.tabs.getTabId(e.target);
|
||||||
if ( vAPI.tabs.popupCandidate ) {
|
var details = {
|
||||||
var details = {
|
url: url,
|
||||||
url: url,
|
tabId: tabId,
|
||||||
tabId: tabId,
|
sourceTabId: vAPI.tabs.popupCandidate
|
||||||
sourceTabId: vAPI.tabs.popupCandidate
|
};
|
||||||
};
|
vAPI.tabs.popupCandidate = false;
|
||||||
vAPI.tabs.popupCandidate = false;
|
if ( vAPI.tabs.onPopup(details) ) {
|
||||||
if ( vAPI.tabs.onPopup(details) ) {
|
e.preventDefault();
|
||||||
e.preventDefault();
|
if ( vAPI.tabs.stack[details.sourceTabId] ) {
|
||||||
if ( vAPI.tabs.stack[details.sourceTabId] ) {
|
vAPI.tabs.stack[details.sourceTabId].activate();
|
||||||
vAPI.tabs.stack[details.sourceTabId].activate();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onNavigation({
|
|
||||||
url: url,
|
|
||||||
frameId: 0,
|
|
||||||
tabId: tabId
|
|
||||||
});
|
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
// onClosed handled in the main tab-close event
|
// onClosed handled in the main tab-close event
|
||||||
|
@ -586,9 +576,6 @@ vAPI.messaging.broadcast = function(message) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
vAPI.net = {};
|
vAPI.net = {};
|
||||||
|
@ -649,6 +636,14 @@ vAPI.net.registerListeners = function() {
|
||||||
|
|
||||||
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;
|
block = vAPI.net.onBeforeRequest;
|
||||||
|
|
||||||
|
|
|
@ -191,95 +191,63 @@ if ( location.protocol === 'safari-extension:' ) {
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var beforeLoadEvent = document.createEvent('Event');
|
|
||||||
beforeLoadEvent.initEvent('beforeload');
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
|
// Inform that we've navigated
|
||||||
|
if(frameId === 0) {
|
||||||
|
safari.self.tab.canLoad(beforeLoadEvent, {
|
||||||
|
url: location.href,
|
||||||
|
type: 'main_frame',
|
||||||
|
navigatedToNew: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
var linkHelper = document.createElement('a');
|
var linkHelper = document.createElement('a');
|
||||||
var onBeforeLoad = function(e, details) {
|
var nodeTypes = {
|
||||||
if ( e.url && e.url.lastIndexOf('data:', 0) === 0 ) {
|
'frame': 'sub_frame',
|
||||||
return;
|
'iframe': 'sub_frame',
|
||||||
}
|
'script': 'script',
|
||||||
|
'img': 'image',
|
||||||
linkHelper.href = details ? details.url : e.url;
|
'input': 'image',
|
||||||
var url = linkHelper.href;
|
'object': 'object',
|
||||||
|
'embed': 'object',
|
||||||
if ( url.lastIndexOf('http:', 0) === -1 && url.lastIndexOf('https:', 0) === -1) {
|
'link': 'stylesheet'
|
||||||
return;
|
};
|
||||||
}
|
var shouldBlockDetailedRequest = function(details) {
|
||||||
|
linkHelper.href = details.url;
|
||||||
if ( details ) {
|
details.url = linkHelper.href;
|
||||||
details.url = url;
|
|
||||||
} else {
|
|
||||||
details = {
|
|
||||||
url: url
|
|
||||||
};
|
|
||||||
|
|
||||||
switch ( e.target.nodeName.toLowerCase() ) {
|
|
||||||
case 'frame':
|
|
||||||
case 'iframe':
|
|
||||||
details.type = 'sub_frame';
|
|
||||||
break;
|
|
||||||
case 'script':
|
|
||||||
details.type = 'script';
|
|
||||||
break;
|
|
||||||
case 'img':
|
|
||||||
case 'input': // type=image
|
|
||||||
details.type = 'image';
|
|
||||||
break;
|
|
||||||
case 'object':
|
|
||||||
case 'embed':
|
|
||||||
details.type = 'object';
|
|
||||||
break;
|
|
||||||
case 'link':
|
|
||||||
var rel = e.target.rel.trim().toLowerCase();
|
|
||||||
|
|
||||||
if ( rel.indexOf('icon') !== -1 ) {
|
|
||||||
details.type = 'image';
|
|
||||||
break;
|
|
||||||
} else if ( rel === 'stylesheet' ) {
|
|
||||||
details.type = 'stylesheet';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
details.type = 'other';
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// This can run even before the first DOMSubtreeModified event fired
|
|
||||||
if ( firstMutation ) {
|
|
||||||
firstMutation();
|
|
||||||
}
|
|
||||||
|
|
||||||
// tabId is determined in the background script
|
|
||||||
// details.tabId = null;
|
|
||||||
details.frameId = frameId;
|
details.frameId = frameId;
|
||||||
details.parentFrameId = parentFrameId;
|
details.parentFrameId = parentFrameId;
|
||||||
details.timeStamp = Date.now();
|
details.timeStamp = Date.now();
|
||||||
|
return !(safari.self.tab.canLoad(beforeLoadEvent, details));
|
||||||
var response = safari.self.tab.canLoad(e, details);
|
}
|
||||||
|
var onBeforeLoad = function(e) {
|
||||||
if ( !response ) {
|
if(e.url.lastIndexOf('data:', 0) === 0) {
|
||||||
if ( details.type === 'main_frame' ) {
|
|
||||||
window.stop();
|
|
||||||
} else {
|
|
||||||
e.preventDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Local mirroring, response should be a data: URL here
|
|
||||||
if ( typeof response !== 'string' ) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
linkHelper.href = e.url;
|
||||||
|
var url = linkHelper.href;
|
||||||
|
var details = {
|
||||||
|
url: url,
|
||||||
|
type: nodeTypes[e.target.nodeName.toLowerCase()] || 'other',
|
||||||
|
// tabId is determined in the background script
|
||||||
|
frameId: frameId,
|
||||||
|
parentFrameId: parentFrameId,
|
||||||
|
timeStamp: Date.now()
|
||||||
|
};
|
||||||
|
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();
|
e.preventDefault();
|
||||||
|
|
||||||
// Content Security Policy with disallowed inline scripts may break things
|
// Content Security Policy with disallowed inline scripts may break things
|
||||||
details = document.createElement('script');
|
details = document.createElement('script');
|
||||||
details.textContent = atob(response.slice(response.indexOf(',', 20) + 1));
|
details.textContent = atob(response.slice(response.indexOf(',', 20) + 1));
|
||||||
|
@ -308,11 +276,9 @@ var firstMutation = function() {
|
||||||
var randEventName = uniqueId();
|
var randEventName = uniqueId();
|
||||||
|
|
||||||
window.addEventListener(randEventName, function(e) {
|
window.addEventListener(randEventName, function(e) {
|
||||||
var result = onBeforeLoad(beforeLoadEvent, e.detail);
|
if(shouldBlockDetailedRequest(e.detail)) {
|
||||||
|
|
||||||
if ( result === false ) {
|
|
||||||
e.detail.url = false;
|
e.detail.url = false;
|
||||||
}
|
};
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
// the extension context is unable to reach the page context,
|
// the extension context is unable to reach the page context,
|
||||||
|
@ -409,18 +375,8 @@ var onContextMenu = function(e) {
|
||||||
|
|
||||||
self.addEventListener('contextmenu', onContextMenu, true);
|
self.addEventListener('contextmenu', onContextMenu, true);
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
// 'main_frame' simulation
|
|
||||||
if ( frameId === 0 ) {
|
|
||||||
onBeforeLoad(beforeLoadEvent, {
|
|
||||||
url: location.href,
|
|
||||||
type: 'main_frame'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
Loading…
Reference in a new issue