Created
July 11, 2014 21:50
-
-
Save hallvors/16878737126e6c43d0aa to your computer and use it in GitHub Desktop.
Firefox test add-on, trying to find the simplest way to monitor loading of pages in tabs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"use strict"; | |
// exploring add-ons API | |
// Goal: monitor all tabs, run code when new page loads | |
// Optionally also listen for document mutations | |
// some standard vars / shortcuts into Gecko's internals: classes, interfaces, utils | |
const Cc = Components.classes; | |
const Ci = Components.interfaces; | |
const Cu = Components.utils; | |
// I want to have console.log() around, here's some code for that | |
var aConsoleService = Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService); | |
var console = {log:function(str){aConsoleService.logStringMessage(str);}} | |
// eventually we would like this method to run each time a page loads inside a tab | |
function tab_onLoad(evt){ | |
console.log('TAB DOMContentLoaded!') | |
console.log(evt.type + ' on ' + evt.target.wrappedJSObject + ' (currentTarget : ' + evt.currentTarget+ ')'); | |
// we need only one event per navigation, let's remove the listener again | |
evt.target.removeEventListener('DOMContentLoaded', tab_onLoad, false); | |
// manipulate document here.. presumably | |
} | |
// seems we have to attach something to every new window to start monitoring its tabs.. | |
function win_onLoad(evt){ | |
// adding tab progress listener in the new window | |
try{ | |
this.gBrowser.addTabsProgressListener(tabProgressListener); | |
}catch(e){ | |
console.log('this.gBrowser failed') | |
console.log(e); | |
} | |
} | |
var windowListener = { | |
onOpenWindow: function(aWindow) { | |
console.log('onOpenWindow ' + aWindow); | |
/*for(var prop in aWindow){ // explore the API manually.. | |
console.log(prop); | |
}*/ | |
// Wait for the window to finish loading | |
// some page on the internet says gBrowser might not be usable unless we do this.. | |
let domWindow = aWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow); | |
domWindow.addEventListener("load", win_onLoad, false); | |
}, | |
onCloseWindow: function(aWindow) { | |
// Do we have to clean up to avoid memory leaks? Or will the GC handle it all when the window is gone? | |
let domWindow = aWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow); | |
domWindow.removeEventListener("load", win_onLoad, false); | |
// If we need to clean up, we probably have to kill the progress listener too. This doesn't seem to work though: | |
// domWindow.gBrowser.removeTabsProgressListener(tabProgressListener); | |
}, | |
onWindowTitleChange: function(aWindow, aTitle) {} | |
}; | |
// To listen for the actual load event, we first detect location change events and attach load listener from there | |
var tabProgressListener = { onLocationChange:function(aBrowser, aWebProgress, aRequest, aLocation, aFlags){ | |
if(aBrowser && aRequest){ | |
if(aBrowser.getAttribute('type') === 'content-primary'){ | |
aBrowser.contentWindow.addEventListener('DOMContentLoaded', tab_onLoad, false); | |
} | |
} | |
}, onProgressChange: function(aBrowser, aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress){} }; | |
tabProgressListener.onSecurityChange = tabProgressListener.onStateChange = tabProgressListener.onStatusChange = tabProgressListener.onRefreshAttempted = tabProgressListener.onLinkIconAvailable = function(){} | |
function startup(aData, aReason) { console.log('startup ' + aData + ', ' + aReason); | |
// enumerate existing windows and add tab progress listener | |
let wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator); | |
let windows = wm.getEnumerator("navigator:browser"); | |
while (windows.hasMoreElements()) { | |
let domWindow = windows.getNext().QueryInterface(Ci.nsIDOMWindow); | |
domWindow.gBrowser.addTabsProgressListener(tabProgressListener); | |
} | |
// Load into any new windows | |
wm.addListener(windowListener); | |
} | |
function shutdown(aData, aReason) { | |
// When the application is shutting down we normally don't have to clean | |
// up any UI changes made | |
console.log('shutdown ' + aData + ' , ' + aReason); | |
if (aReason == APP_SHUTDOWN) | |
return; | |
let wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator); | |
// Stop listening for new windows | |
wm.removeListener(windowListener); | |
// Unload from any existing windows | |
let windows = wm.getEnumerator("navigator:browser"); | |
while (windows.hasMoreElements()) { | |
let domWindow = windows.getNext().QueryInterface(Ci.nsIDOMWindow); | |
domWindow.removeEventListener("load", onLoad, false); | |
} | |
// TODO: we have more events to remove, how? | |
} | |
function install(aData, aReason) {} function uninstall(aData, aReason) {} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment