Background:
I'm authorised to "automate" a 3rd party site for the purpose of pushing "service orders" into it and monitoring the progress of those requests.
I tried taking a normal "scraping" approach (using WWW::Mechanize
, HTML::Query
, etc from Perl) but ran into a lot of issues predicting what the JavaScript in the site would do under a variety of circumstances. I intend to go back to this approach if I ever receive support from the vendor of the product which runs the 3rd party site, or can get hold of some better documentation w.r.t business-rules of the product.
To avoid second guessing the JavaScript code, and to save a lot of time, I ended up taking an approach were I load the 3rd party site in Firefox on a dedicated VM, and then execute "privileged" code (i.e: nsI*) in the context of the site to "drive" and "scrape" the site.
I'm currently using nsIWebProgressListener
/DOMContentLoaded
(when I already have a reference to a ChromeWindow), and nsIWindowMediator
window+tab enumeration called from setInterval
to find new windows and tabs (when I have no way to predict them opening, nor gain a reference to their DOMWindow objects due to scoping of 3rd party JavaScript).
Question:
How can I automatically install a "hook" into each Window/Tab opened now (and in the future) by the 3rd party site's JavaScript? Something like a "window watcher" nsI~
interface for the whole of the Firefox UI would be very useful in this case.
There are so many ways you could do this, so the right choice depends on how you're going about everything else.
Here are just a few ways of listening, rather than polling.
New Chrome Windows
function ChromeWindowObserver() {
this.observe = function(subject, topic, data) {
// subject is a ChromeWindow
}
}
Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
.getService(Components.interfaces.nsIWindowWatcher)
.registerNotification(new ChromeWindowObserver());
New Tabs
function tabListener(event) {
var browser = gBrowser.getBrowserForTab(event.target):
}
gBrowser.tabContainer.addEventListener("TabOpen", tabListener, false);
Observer Notifications (my favorite)
const dumpObserver = {
observe: function(subject, topic, data) { dump(topic + "\n"); }
}
const domObserver = {
observe: function(subject, topic, data) { dump(subject.location + "\n"); }
}
const ObserverService = Components.classes["@mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
/* debug log notifications */
ObserverService.addObserver(dumpObserver, "*", false);
/* debug log all new content locations */
ObserverService.addObserver(domObserver, "content-document-global-created", false);
Side note, check out JavaScript code modules. I think that might be helpful for you when sharing data between chrome windows.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With