From 9bd31f1362ac2c2635e376047b055527f62f68d7 Mon Sep 17 00:00:00 2001 From: Deathamns Date: Tue, 27 Jan 2015 16:37:02 +0100 Subject: [PATCH] Firefox: each frame should have a unique ID --- platform/firefox/frameModule.js | 39 +++++++++++++++++++++++------ platform/firefox/vapi-background.js | 31 ++++++++++++++++------- 2 files changed, 53 insertions(+), 17 deletions(-) diff --git a/platform/firefox/frameModule.js b/platform/firefox/frameModule.js index 98338e32f..5e0f74f21 100644 --- a/platform/firefox/frameModule.js +++ b/platform/firefox/frameModule.js @@ -30,7 +30,7 @@ const {Services} = Cu.import('resource://gre/modules/Services.jsm', null); const hostName = Services.io.newURI(Components.stack.filename, null, null).host; let uniqueSandboxId = 1; -// let {console} = Cu.import('resource://gre/modules/devtools/Console.jsm', null); +// Cu.import('resource://gre/modules/devtools/Console.jsm'); /******************************************************************************/ @@ -112,6 +112,13 @@ const contentObserver = { ); }, + getFrameId: function(win) { + return win + .QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDOMWindowUtils) + .outerWindowID; + }, + // https://bugzil.la/612921 shouldLoad: function(type, location, origin, context) { if ( !context ) { @@ -122,10 +129,17 @@ const contentObserver = { return this.ACCEPT; } - let openerURL, frameId; + let openerURL = null; if ( type === this.MAIN_FRAME ) { - frameId = -1; + // When an iframe is loaded, it will be reported first as type = 6, + // then immediately after that type = 7, so ignore the first report. + // Origin should be "chrome://browser/content/browser.xul" here. + // The lack of side-effects are not guaranteed though. + if ( origin === null || origin.schemeIs('chrome') === false ) { + return this.ACCEPT; + } + context = context.contentWindow || context; try { @@ -134,9 +148,6 @@ const contentObserver = { } } catch (ex) {} } else { - // TODO: frameId from outerWindowID? - // https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIDOMWindowUtils - frameId = context === context.top ? 0 : 1; context = (context.ownerDocument || context).defaultView; } @@ -146,11 +157,23 @@ const contentObserver = { return this.ACCEPT; } + let isTopLevel = context === context.top; + let frameId = isTopLevel ? 0 : this.getFrameId(context); + let parentFrameId; + + if ( isTopLevel ) { + parentFrameId = -1; + } else if ( context.parent === context.top ) { + parentFrameId = 0; + } else { + parentFrameId = this.getFrameId(context.parent); + } + let messageManager = getMessageManager(context); let details = { frameId: frameId, - openerURL: openerURL || null, - parentFrameId: context === context.top ? -1 : 0, + openerURL: openerURL, + parentFrameId: parentFrameId, type: type, url: location.spec }; diff --git a/platform/firefox/vapi-background.js b/platform/firefox/vapi-background.js index 9fec753d5..e3cdd6cb2 100644 --- a/platform/firefox/vapi-background.js +++ b/platform/firefox/vapi-background.js @@ -958,7 +958,13 @@ var httpObserver = { } try { - // [type, tabId, sourceTabId - given if it was a popup] + /*[ + type, + tabId, + sourceTabId - given if it was a popup, + frameId, + parentFrameId + ]*/ channelData = channel.getProperty(location.host + 'reqdata'); } catch (ex) { return; @@ -1047,7 +1053,13 @@ var httpObserver = { if ( channel instanceof Ci.nsIWritablePropertyBag ) { channel.setProperty( location.host + 'reqdata', - [lastRequest.type, lastRequest.tabId, sourceTabId] + [ + lastRequest.type, + lastRequest.tabId, + sourceTabId, + lastRequest.frameId, + lastRequest.parentFrameId + ] ); } }, @@ -1074,20 +1086,21 @@ var httpObserver = { return; } + // TODO: what if a behind-the-scene request is being redirected? + // This data is present only for tabbed requests, so if this throws, + // the redirection won't be evaluated and canceled (if necessary) var channelData = oldChannel.getProperty(location.host + 'reqdata'); - var [type, tabId, sourceTabId] = channelData; - if ( this.handlePopup(URI, tabId, sourceTabId) ) { + if ( this.handlePopup(URI, channelData[1], channelData[2]) ) { result = this.ABORT; return; } var details = { - type: type, - tabId: tabId, - // well... - frameId: type === this.MAIN_FRAME ? -1 : 0, - parentFrameId: -1 + type: channelData[0], + tabId: channelData[1], + frameId: channelData[3], + parentFrameId: channelData[4] }; if ( this.handleRequest(newChannel, URI, details) ) {