These are a few mistakes I’ve caught myself and others making over and over, often causing very weird behaviour that may cause you to question jetpack’s sanity – or even your own.
Where am I?
A common mistake I’ve seen repeated several times (and caught myself making a few times too) goes something like this:
// Displays the page url when it loads
jetpack.tabs.onReady(function(){
jetpack.notifications.show(jetpack.tabs.focused.url);
});
Did you spot the mistake? This is a very concise example, so even if you did, you might not have in a larger more complicated script. The problem is of course, that the currently focused tab, might not have anything to do with the tab that fired the onReady event (the same goes for onFocus of course, though in the latter case, you can argue with slightly higher confidence that the event is probably fired by the currently focused tab.)
So how do you know where you are? the callback function is passed a single variable, but that is a reference to the document, and thus not of much use in this matter. Instead, you should use this.url, so the correct version becomes:
// Displays the page url when it loads
jetpack.tabs.onReady(function(){
jetpack.notifications.show(this.url);
});
Where’s the content?
This question usually stems from one of two issues. If you’re trying to access javascript objects in the document, you need to use the JSObject wrapper like so:
jetpack.tabs.onReady(function(doc){doc.JSObject.myVar});
But this might fail too, if the object isn’t defined in the main document, but is loaded via a script tag or similar. onReady is triggered before external scripts (and frames, images, etc) are loaded, which means that a lot of content might not yet be available at run time. The remedy, according to the tutorial, is to use onLoad instead, transforming the example thus
jetpack.tabs.onLoad(function(doc){doc.JSObject.myVar});
however, there is no such thing as jetpack.tabs.onLoad. Why it is in the tutorial, no-one seems to know.
So how do you do it? My best attempt is this:
function doStuff(doc) {
var window = this;
window.alert("test");
$(doc).find("body").css("background","red");
};
jetpack.tabs.onReady(function(doc){
$(this.contentWindow).load(function(){doStuff(doc);});
if (doc.readyState == "complete") {
doStuff(doc);
}
});
But that doesn’t work either, and I’m not sure why. If anyone has a way that actually works, I’d appreciate a comment.
API inconsistencies
Unlike onReady, onFocus does not pass a reference to the document to the callback function. This “feature” usually shows itself when you attempt something like this:
function showTitle(doc) {
jetpack.notifications.show(doc.title);
}
jetpack.tabs.onFocus(showTitle);
jetpack.tabs.onReady(ShowTitle);
Unfortunately, it is way too easy to forget to treat these events differently, and not always obvious what mistake you’ve made afterwards. The solution is to either change showTitle to this:
function showTitle() {
jetpack.notifications.show(this.contentDocument.title);
}
or the call to onFocus to this:
jetpack.tabs.onFocus(function() showTitle(this.contentDocument));
Sadly, this is just the tip of the iceberg of badly designed APIs in Jetpack. I’m hoping the reboot will allow for ripping out existing APIs (JEPs) and designing them properly.
Good notes, Christian. I’m with Blair—here’s to the reboot!