Eli Grey

Jetpack API

Mozilla Labs’ latest creation, Jetpack, is a great way to extend Firefox. It currently has a poorly documented API that doesn’t mention all of the public methods and fields. Due to Mozilla Labs’ decision of not putting the API documentation on MDC or the MozillaWiki, I cannot update the documentation myself. Therefore, I will list all of Jetpack’s documented and undocumented features as of version 0.1.2 in this blog post.

(Not) Assigning Properties

You can’t do things like jetpack.tabs.focused.contentWindow.foo = "bar". I find this much too restrictive, as it hinders a developer’s ability to make an API for a webpage to communicate with a jetpack to do things that need more privileges. Ironically, it seems that jetpacks have full access to Firefox’s XPCOM (Components.*, ect.) which means, with a little hacking, it may be possible to bypass this restriction. The follow code shows an example of getting an nsIAlertsService and using it instead of jetpack.notifications.show.

var body = "Some text",
title = "Notification",
icon = "http://code.eligrey.com/favicon.ico",
 
classObj = Components.classes['@mozilla.org/alerts-service;1'],
alertService = classObj.getService(Components.interfaces.nsIAlertsService);
 
alertService.showAlertNotification(icon, title, body);

(more…)

textContent in IE8

I was creating a testcase for a bug that is present in every browser and I noticed IE still doesn’t support textContent as of IE8. I don’t like having to make code that supports both innerText and textContent so I implemented the standard myself using IE8′s support for ECMAScript 3.1 accessors. The following is all the code that you need to make textContent work in IE8.

if (Object.defineProperty && Object.getOwnPropertyDescriptor &&
    !Object.getOwnPropertyDescriptor(Element.prototype, "textContent").get)
  (function() {
    var innerText = Object.getOwnPropertyDescriptor(Element.prototype, "innerText");
    Object.defineProperty(Element.prototype, "textContent",
      { // It won't work if you just drop in innerText.get
        // and innerText.set or the whole descriptor.
        get : function() {
          return innerText.get.call(this)
        },
        set : function(x) {
          return innerText.set.call(this, x)
        }
      }
    );
  })();

Save it as textContent.js and then include the following code to use it.

<!--[if gte IE 8]><script type="text/javascript" src="http://code.eligrey.com/textcontent.js/latest/textcontent.min.js"></script><![endif]-->

Why you shouldn’t use XDomainRequest

I just recently installed Windows and downloaded IE8 again and it seems that pmxdr works fine with the exception of one small MessageEvent.source bug in the host library that I fixed in version 0.0.5.

I went to check out if the XDomainRequest examples I created worked, and to my astonisment, they ALL failed except for the simplest example. It turns out, contrary to what I assumed of it only not supporting responseXML, XDomainRequest also doesn’t support much of the basic HTTP header functionality offered in XMLHttpRequest, such as setRequestHeader, getResponseHeader, and getAllResponseHeaders. This means that my implementation of XDomainRequest actually offered more functionality than IE8′s implementation.

Due to this, I have changed the XXDomainRequest library to implement a generic XDR constructor and I have renamed the library from XXDomainRequest to libxdr. The examples have been changed to use new XDR() instead of new XDomainRequest() so now every example works in IE8.

XDomainRequest is no longer IE-only

XDomainRequest is Internet Explorer 8′s cross-domain request function. It would be easy to add support for it in Firefox 3.5 using native cross-domain XMLHttpRequests, but that wouldn’t work in Firefox 3, Opera 9.6-10, and Safari 4. I have created a library named XXDomainRequest (means “Cross-browser XDomainRequest”) that builds on the pmxdr client library to create a fully API compatible version of XDomainRequest. Go to the XXDomainRequest project page to see (and run) the examples that request resources on code.eligrey.com.

APNG feature detection

I have made a simple script that utilizes the HTML5 <canvas> API in only 9 functional lines of JavaScript to detect if a browser supports APNG images. It can be useful for deciding when to serve a client browser APNG images instead of GIF images.
This will set the variable, apng_supported to true if the browser supports APNG.
I have also created a demo that uses this script.

(function() {
	"use strict";
	var apngTest = new Image(),
	ctx = document.createElement("canvas").getContext("2d");
	apngTest.onload = function () {
		ctx.drawImage(apngTest, 0, 0);
		self.apng_supported = ctx.getImageData(0, 0, 1, 1).data[3] === 0;
	};
	apngTest.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACGFjVEwAAAABAAAAAcMq2TYAAAANSURBVAiZY2BgYPgPAAEEAQB9ssjfAAAAGmZjVEwAAAAAAAAAAQAAAAEAAAAAAAAAAAD6A+gBAbNU+2sAAAARZmRBVAAAAAEImWNgYGBgAAAABQAB6MzFdgAAAABJRU5ErkJggg==";
	// frame 1 (skipped on apng-supporting browsers): [0, 0, 0, 255]
	// frame 2: [0, 0, 0, 0]
}());