From 03668551c27b77ee55cc67467988d3154fd9a0a0 Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 20 Jan 2015 00:11:26 -0700 Subject: [PATCH 1/3] More fixes and performance improvements to Safari event handling and dispatching --- platform/safari/vapi-background.js | 22 ++--- platform/safari/vapi-client.js | 144 ++++++++++------------------- 2 files changed, 60 insertions(+), 106 deletions(-) diff --git a/platform/safari/vapi-background.js b/platform/safari/vapi-background.js index 26b865923..cec28f415 100644 --- a/platform/safari/vapi-background.js +++ b/platform/safari/vapi-background.js @@ -188,13 +188,11 @@ vAPI.tabs = { /******************************************************************************/ vAPI.tabs.registerListeners = function() { - var onNavigation = this.onNavigation; - safari.application.addEventListener('beforeNavigate', function(e) { - if ( !e.target || !e.target.url || e.target.url === 'about:blank' ) { + if ( !e.target || e.url === 'about:blank' ) { 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 = { url: url, @@ -210,11 +208,6 @@ vAPI.tabs.registerListeners = function() { return; } } - onNavigation({ - url: url, - frameId: 0, - tabId: tabId - }); }, true); // onClosed handled in the main tab-close event @@ -586,9 +579,6 @@ vAPI.messaging.broadcast = function(message) { } }; -/******************************************************************************/ - - /******************************************************************************/ vAPI.net = {}; @@ -649,6 +639,14 @@ vAPI.net.registerListeners = function() { 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; diff --git a/platform/safari/vapi-client.js b/platform/safari/vapi-client.js index 46b9d385b..6a88dace0 100644 --- a/platform/safari/vapi-client.js +++ b/platform/safari/vapi-client.js @@ -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 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 onBeforeLoad = function(e, details) { - if ( e.url && e.url.lastIndexOf('data:', 0) === 0 ) { - return; - } - - linkHelper.href = details ? details.url : e.url; - var url = linkHelper.href; - - if ( url.lastIndexOf('http:', 0) === -1 && url.lastIndexOf('https:', 0) === -1) { - return; - } - - if ( details ) { - 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; +var nodeTypes = { + '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; + details.url = linkHelper.href; details.frameId = frameId; details.parentFrameId = parentFrameId; details.timeStamp = Date.now(); - - var response = safari.self.tab.canLoad(e, details); - - if ( !response ) { - 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 !(safari.self.tab.canLoad(beforeLoadEvent, details)); +} +var onBeforeLoad = function(e) { + if(e.url.lastIndexOf('data:', 0) === 0) { 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(); - // Content Security Policy with disallowed inline scripts may break things details = document.createElement('script'); details.textContent = atob(response.slice(response.indexOf(',', 20) + 1)); @@ -308,11 +276,9 @@ var firstMutation = function() { var randEventName = uniqueId(); window.addEventListener(randEventName, function(e) { - var result = onBeforeLoad(beforeLoadEvent, e.detail); - - if ( result === false ) { + if(shouldBlockDetailedRequest(e.detail)) { e.detail.url = false; - } + }; }, true); // the extension context is unable to reach the page context, @@ -409,18 +375,8 @@ var onContextMenu = function(e) { self.addEventListener('contextmenu', onContextMenu, true); -/******************************************************************************/ - -// 'main_frame' simulation -if ( frameId === 0 ) { - onBeforeLoad(beforeLoadEvent, { - url: location.href, - type: 'main_frame' - }); -} /******************************************************************************/ - })(); /******************************************************************************/ From 4901b11faeac7c11d69a21b5d2ae83bf28a6f127 Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 20 Jan 2015 00:44:04 -0700 Subject: [PATCH 2/3] Doh --- platform/safari/vapi-background.js | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/platform/safari/vapi-background.js b/platform/safari/vapi-background.js index cec28f415..1032af7e2 100644 --- a/platform/safari/vapi-background.js +++ b/platform/safari/vapi-background.js @@ -189,23 +189,20 @@ vAPI.tabs = { vAPI.tabs.registerListeners = function() { safari.application.addEventListener('beforeNavigate', function(e) { - if ( !e.target || e.url === 'about:blank' ) { + if ( !vAPI.tabs.popupCandidate || !e.target || e.url === 'about:blank' ) { return; } var url = e.url, tabId = vAPI.tabs.getTabId(e.target); - if ( vAPI.tabs.popupCandidate ) { - var details = { - url: url, - tabId: tabId, - sourceTabId: vAPI.tabs.popupCandidate - }; - vAPI.tabs.popupCandidate = false; - if ( vAPI.tabs.onPopup(details) ) { - e.preventDefault(); - if ( vAPI.tabs.stack[details.sourceTabId] ) { - vAPI.tabs.stack[details.sourceTabId].activate(); - } - return; + var details = { + url: url, + tabId: tabId, + sourceTabId: vAPI.tabs.popupCandidate + }; + vAPI.tabs.popupCandidate = false; + if ( vAPI.tabs.onPopup(details) ) { + e.preventDefault(); + if ( vAPI.tabs.stack[details.sourceTabId] ) { + vAPI.tabs.stack[details.sourceTabId].activate(); } } }, true); From 86aeaac9c0e445dfea8da3ae481ed008f3f3f83f Mon Sep 17 00:00:00 2001 From: polycopter Date: Tue, 20 Jan 2015 11:00:04 -0500 Subject: [PATCH 3/3] Update MANIFESTO.md add an 's' because "means" in this usage doesn't have a singular version without the 's'. --- MANIFESTO.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MANIFESTO.md b/MANIFESTO.md index 24f6155ea..2dd1c6f47 100644 --- a/MANIFESTO.md +++ b/MANIFESTO.md @@ -7,4 +7,4 @@ because the _"Acceptable Ads"_ marketing campaign is really the business plan of a for-profit entity. Users are best placed to know what is or is not acceptable to them. µBlock's -sole purpose is to give users the mean to enforce their own choices. +sole purpose is to give users the means to enforce their own choices.