@@ -315,8 +315,16 @@ HTTPSEverywhere.prototype = {
315315 }
316316 } ,
317317
318+ // Given an nsIChannel (essentially, a container for an HTTP or similar
319+ // resource request), try to find the relevant tab if there is one.
320+ // Specifically, find the XUL <browser> element for that tab. Note
321+ // there are multiple meanings for the word 'browser' in Firefox, described at:
322+ // https://developer.mozilla.org/en-US/Add-ons/Code_snippets/Tabbed_browser
323+ // We're looking for this one:
324+ // https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XUL/browser
325+ // Also note some requests, like Safe Browsing requests, will have no
326+ // associated tab.
318327 getBrowserForChannel : function ( channel ) {
319- // Obtain a browser element from a channel
320328 let loadContext ;
321329 try {
322330 loadContext = channel . notificationCallbacks . getInterface ( CI . nsILoadContext ) ;
@@ -325,17 +333,47 @@ HTTPSEverywhere.prototype = {
325333 loadContext = channel . loadGroup . notificationCallbacks
326334 . getInterface ( CI . nsILoadContext ) ;
327335 } catch ( e ) {
328- this . log ( NOTE , "no loadgroup notificationCallbacks for "
329- + channel . URI . spec + e ) ;
336+ this . log ( NOTE , "no loadGroup notificationCallbacks for "
337+ + channel . URI . spec + ': ' + e ) ;
330338 return null ;
331339 }
332340 }
333- if ( ! loadContext ) {
334- this . log ( NOTE , "No loadContext for: " + channel . URI . spec ) ;
341+ // On e10s (multiprocess, aka electrolysis) Firefox,
342+ // loadContext.topFrameElement gives us a reference to the XUL <browser>
343+ // element we need. However, on non-e10s Firefox, topFrameElement is null.
344+ if ( loadContext && loadContext . topFrameElement ) {
345+ return loadContext . topFrameElement ;
346+ } else if ( loadContext ) {
347+ // For non-e10s Firefox, get the XUL <browser> element using this rather
348+ // magical / opaque code cribbed from
349+ // https://developer.mozilla.org/en-US/Add-ons/Code_snippets/Tabbed_browser#Getting_the_browser_that_fires_the_http-on-modify-request_notification_(example_code_updated_for_loadContext)
350+
351+ // this is the HTML DOM window of the page that just loaded
352+ var contentWindow = loadContext . associatedWindow ;
353+ // aDOMWindow this is the firefox window holding the tab
354+ var aDOMWindow = contentWindow . top . QueryInterface ( Ci . nsIInterfaceRequestor )
355+ . getInterface ( Ci . nsIWebNavigation )
356+ . QueryInterface ( Ci . nsIDocShellTreeItem )
357+ . rootTreeItem
358+ . QueryInterface ( Ci . nsIInterfaceRequestor )
359+ . getInterface ( Ci . nsIDOMWindow ) ;
360+ // this is the gBrowser object of the firefox window this tab is in
361+ var gBrowser = aDOMWindow . gBrowser ;
362+ // this is the clickable tab xul element, the one found in the tab strip
363+ // of the firefox window, aTab.linkedBrowser is same as browser var above
364+ var aTab = gBrowser . _getTabForContentWindow ( contentWindow . top ) ;
365+ // this is the browser within the tab
366+ if ( aTab ) {
367+ var browser = aTab . linkedBrowser ;
368+ return browser ;
369+ } else {
370+ this . log ( NOTE , "getBrowserForChannel: aTab was null." ) ;
371+ }
372+ } else {
373+ this . log ( NOTE , "getBrowserForChannel: No loadContext for: " +
374+ channel . URI . spec ) ;
335375 return null ;
336376 }
337- let browser = loadContext . topFrameElement ;
338- return browser ;
339377 } ,
340378
341379 // the lists get made when the urlbar is loading something new, but they
0 commit comments