<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="wordpress/2.1.2" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	>

<channel>
	<title>BookSmarts!</title>
	<link>http://www.getbooksmarts.org</link>
	<description>A Firefox extension / tutorial</description>
	<pubDate>Mon, 23 Apr 2007 21:57:00 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.1.2</generator>
	<language>en</language>
			<item>
		<title>A quick apology.</title>
		<link>http://www.getbooksmarts.org/news/2007/04/23/a-quick-apology/</link>
		<comments>http://www.getbooksmarts.org/news/2007/04/23/a-quick-apology/#comments</comments>
		<pubDate>Mon, 23 Apr 2007 21:57:00 +0000</pubDate>
		<dc:creator>andy</dc:creator>
		
		<category><![CDATA[Idea]]></category>

		<guid isPermaLink="false">http://www.getbooksmarts.org/news/2007/04/23/a-quick-apology/</guid>
		<description><![CDATA[Just in case anyone&#8217;s desperate for more updates, I haven&#8217;t forsaken you. Screengrab has taken my attention of late, as there&#8217;s been a few teething issues with it&#8217;s latest version. The issue was actually with me as it happens.
One of the things that I&#8217;ve been doing is retrofitting Screengrab to use my new include architecture. [...]]]></description>
			<content:encoded><![CDATA[<p>Just in case anyone&#8217;s desperate for more updates, I haven&#8217;t forsaken you. Screengrab has taken my attention of late, as there&#8217;s been a few teething issues with it&#8217;s latest version. The issue was actually with me as it happens.</p>
<p>One of the things that I&#8217;ve been doing is retrofitting Screengrab to use my new include architecture. You could think of it as a proof of concept. It has actually worked out really really well. I&#8217;m very impressed with the way the code hangs together now. Version 0.94 will be interesting for those who like to view the source.</p>
<p>I&#8217;ll be picking up BookSmarts again very soon. I also have another new project on the go. It doesn&#8217;t have a real name yet (it&#8217;s working title is Transfoxite), but it is essentially going to be a website that provides a large number of reference translations extracted from Firefox extensions for the purpose of making localisation of said extensions a little easier. Things like &#8220;Save As&#8221; and &#8220;Default save location&#8221; are used over and over again in apps, so I&#8217;m hoping to make a website that will allow people to select the phrases they want and then get most of their translations done for free. I&#8217;ll be leaning pretty heavily on the work done by <a href="http://babelzilla.org">babelzilla.org</a>. It&#8217;s not meant as a replacement, I would just like to be less of a burden on their over-stretched community.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.getbooksmarts.org/news/2007/04/23/a-quick-apology/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Code highlighting in Wordpress</title>
		<link>http://www.getbooksmarts.org/news/2007/03/23/code-highlighting-in-wordpress/</link>
		<comments>http://www.getbooksmarts.org/news/2007/03/23/code-highlighting-in-wordpress/#comments</comments>
		<pubDate>Fri, 23 Mar 2007 16:48:49 +0000</pubDate>
		<dc:creator>andy</dc:creator>
		
		<category><![CDATA[Theme]]></category>

		<category><![CDATA[Thanks]]></category>

		<guid isPermaLink="false">http://www.getbooksmarts.org/news/2007/03/23/code-highlighting-in-wordpress/</guid>
		<description><![CDATA[I searched for a while, because my code looked like crap on the interweb, but beautiful in Eclipse.
I&#8217;m now using highlight which seems to happily colorize all types of code.
A word of warning though - it only provides a framework for doing code highlighting, by dynamically adding css classes to code fragments. You still have [...]]]></description>
			<content:encoded><![CDATA[<p>I searched for a while, because my code looked like crap on the interweb, but beautiful in Eclipse.</p>
<p>I&#8217;m now using <a href="http://softwaremaniacs.org/soft/highlight/en/">highlight</a> which seems to happily colorize all types of code.</p>
<p>A word of warning though - it only provides a framework for doing code highlighting, by dynamically adding css classes to code fragments. You still have to pick which colors and format you want the classes to map to.</p>
<p>I didn&#8217;t realise this so I kind of &#8220;borrowed&#8221; some of the css from their website. I hope they don&#8217;t mind. I think it looks awesome. I didn&#8217;t take the little pictures in the corners though. That would be too rude if you don&#8217;t have permission. <img src='http://www.getbooksmarts.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Thank you to the guys at Software Maniacs!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.getbooksmarts.org/news/2007/03/23/code-highlighting-in-wordpress/feed/</wfw:commentRss>
		</item>
		<item>
		<title>How to access Java code from JavaScript (the easy way)</title>
		<link>http://www.getbooksmarts.org/news/2007/03/22/how-to-access-java-code-from-javascript-the-easy-way/</link>
		<comments>http://www.getbooksmarts.org/news/2007/03/22/how-to-access-java-code-from-javascript-the-easy-way/#comments</comments>
		<pubDate>Thu, 22 Mar 2007 09:13:24 +0000</pubDate>
		<dc:creator>andy</dc:creator>
		
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.getbooksmarts.org/news/2007/03/22/how-to-access-java-code-from-javascript-the-easy-way/</guid>
		<description><![CDATA[There are a few ways to invoke Java code from within Javascript, and when I made Screengrab, I used the easiest:

var list = new Packages.java.util.ArrayList();

Basically, to use any standard Java packages from within Javascript, you just use the fully qualified package name and append &#8220;Packages&#8221; to the front of it. This is kind of cumbersome, [...]]]></description>
			<content:encoded><![CDATA[<p>There are a few ways to invoke Java code from within Javascript, and when I made Screengrab, I used the easiest:</p>
<pre><code class="javascript">
var list = new Packages.java.util.ArrayList();
</code></pre>
<p>Basically, to <strong>use</strong> any standard Java packages from within Javascript, you just use the fully qualified package name and append &#8220;Packages&#8221; to the front of it. This is kind of cumbersome, but you can &#8216;include&#8217; classes by just assigning them to a local variable:</p>
<pre><code class="javascript">
var ArrayList = Packages.java.util.ArrayList;

var list = new ArrayList();
</code></pre>
<p>Now, this is all fine and it will get you through most Java work in Javascript (these concepts have worked fine for Screengrab!), but <strong>what if you need to implement a Java interface from within Javascript?</strong><br />
Well, I&#8217;ve tried. When I was trying to get clipboard support for the Java-based grabber in Screengrab I looked for answers and tried a few things, but I just couldn&#8217;t do it. I eventually gave up and currently Screengrab will only copy images to the clipboard using the Canvas-based grabber.</p>
<p>The only way to do this is to somehow create a Java class externally and then load it from within Firefox. This is possible, because Firefox lets you create components in other languages and link them in using some magic. The problem with components is that there is a massive amount of crap to write to get one to work.</p>
<p>Here <a href="http://simile.mit.edu/wiki/Java_Firefox_Extension">is a tutorial on creating a Java component for extension development</a> that I found. <a href="http://simile.mit.edu/repository/java-firefox-extension/src/edu/mit/simile/javaFirefoxExtension/Test.java">This</a> is the Java class it is trying to get access to.  And <a href="http://simile.mit.edu/repository/java-firefox-extension/firefox/components/FooComponent.js">this monolithic file</a> is the Javascript code that you have to write to get Firefox to understand it. I haven&#8217;t read it. I stopped about 2 pages in and thought &#8220;there has got to be a way to do this that doesn&#8217;t suck&#8221;.</p>
<p><strong>And there is</strong>&#8230;</p>
<p>From <a href="http://kb.mozillazine.org/Dev_:_Extensions_:_Example_Code_:_Calling_Java_from_Javascript">this page at Mozillazine</a> we find &#8220;the easy way&#8221; (and actually, as it turns out, the easy way comes from <a href="http://people.csail.mit.edu/dfhuynh/">the same guy</a> that did the hard way.</p>
<p>As you can see from the tutorial, it boils down to using a ClassLoader. Essentially, since we can access most standard Java from inside Javascript, it stands to reason that we can create ClassLoaders and use reflection. And that&#8217;s what this code does. What it doesn&#8217;t do is tell you how to do this with a local url, pointing to a jar within your extension. Here&#8217;s how&#8230;</p>
<pre><code class="javascript">
var id = "booksmarts@getbooksmarts.org";
var ext = Components.classes["@mozilla.org/extensions/manager;1"]
    .getService(Components.interfaces.nsIExtensionManager)
    .getInstallLocation(id)
    .getItemLocation(id);

var cl = new Packages.java.net.URLClassLoader(
    [new Packages.java.net.URL(
        new Packages.java.io.File(ext.path + "/components/tiny.jar").toURL())]);

var aClass = Packages.java.lang.Class.forName("Tiny", true, cl);
var instance = aClass.newInstance();

ftst.logger.debug(instance.getMessage());
</code></pre>
<p>I&#8217;m pointing it to the components directory in my extension folder. When the extension is installed, the xpi is unzipped, but the chrome.jar isn&#8217;t, so if you want to load the your classes, you&#8217;ll need to put them somewhere that gets extracted. &#8220;components&#8221; seems like a good place for that, since it contains libs and the like.</p>
<p>Now obviously this is a bit ugly, but it could easily be wrapped in some code that does most of the work for you. To the point where you should be able to write code that looks like the following (or much much better):</p>
<pre><code class="javascript">
var tiny =
    jarLoader.using("tiny.jar")
        .createNew("org.getbooksmarts.Tiny", arg1, arg2, arg3);
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://www.getbooksmarts.org/news/2007/03/22/how-to-access-java-code-from-javascript-the-easy-way/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Log4js - It&#8217;s a little different now.</title>
		<link>http://www.getbooksmarts.org/news/2007/03/21/log4js-its-a-little-different-now/</link>
		<comments>http://www.getbooksmarts.org/news/2007/03/21/log4js-its-a-little-different-now/#comments</comments>
		<pubDate>Wed, 21 Mar 2007 08:39:52 +0000</pubDate>
		<dc:creator>andy</dc:creator>
		
		<category><![CDATA[Thanks]]></category>

		<category><![CDATA[Tutorial]]></category>

		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://www.getbooksmarts.org/news/2007/03/21/log4js-its-a-little-different-now/</guid>
		<description><![CDATA[One of the good parts about including things with scope is that you don&#8217;t have to worry about changing them into a more extension-friendly namespace format, which is nice.
So I didn&#8217;t have to adapt log4js to get it to play nicely in chrome at all. However, I did have to change it to make it [...]]]></description>
			<content:encoded><![CDATA[<p>One of the good parts about including things with scope is that you don&#8217;t have to worry about changing them into a more extension-friendly namespace format, which is nice.</p>
<p>So I didn&#8217;t have to adapt <a href="http://log4js.berlios.de">log4js</a> to get it to play nicely in chrome at all. However, I did have to <a href="http://getbooksmarts.org/svn/booksmarts/trunk/booksmarts/src/chrome/content/log4js/log4js.js">change it</a> to make it a little more Andy friendly.</p>
<p>Basically, I wanted the log output to hit the console (using dump()) and to look like&#8230;</p>
<p>startTime logLevel [fileName:lineNum] message\n<br />
eg.</p>
<pre><code>
23/03/07 22:10:11:342 DEBUG [overlay.js:14] A debug message
23/03/07 22:10:12:589 DEBUG [overlay.js:21] Another message
</code></pre>
<p>Log4js can&#8217;t log to a command prompt using <code>dump()</code>. That was an easy change, we just needed to add another appender, as below.</p>
<pre><code class="javascript">
/**
 * Appender writes the logs to the Shell of Firefox when it is launched with
 * firefox -console (and has the necessary properties enabled)
 * PLEASE NOTE - Only works in Firefox
 * @constructor
 * @extends Appender
 * @param logger log4js instance this appender is attached to
 * @author Andrew Mutton
 */
function FirefoxConsoleAppender(logger) {
...
	this.layout = new MozStackLayout(true);
}

FirefoxConsoleAppender.superclass = Appender.prototype;
FirefoxConsoleAppender.prototype = {
	/**
	 * @see Appender#doAppend
	 */
	doAppend: function(loggingEvent) {
		dump(this.layout.format(loggingEvent));
	},
...
</code></pre>
<p>So now we can dump to the console. Notice that there&#8217;s a new Layout there too? You probably didn&#8217;t, since not many people use log4js I imagine. </p>
<p>The new layout is there to take advantage of the information we can get from <code>Components.stack</code> - notably, line numbers and source files.</p>
<pre><code class="javascript">
/**
 * MozStackLayout is a layout that takes advantage of stack data from Mozilla.
 *
 * startTime logLevel [fileName:lineNum] messagen
 *
 *
 * @constructor
 * @extends Layout
 * @author Andrew Mutton
 */
function MozStackLayout(showDate) {
	this.LINE_SEP  = "n";
	this.showDate = showDate;
}
MozStackLayout.prototype = {
	format: function(loggingEvent) {
	    if (this.showDate &#038;&#038; Log4js.simpledate) {
    	    var d = new Log4js.simpledate.SimpleDate(loggingEvent.startTime.getTime());
          	return d.toFormattedString("~d/~k/~y ~H:~m:~s:~S") + " " + loggingEvent.level.toString() + " [" +  loggingEvent.getStackFileName() + ":" + loggingEvent.getStackLineNum() + "] " + loggingEvent.message + this.LINE_SEP;
	    } else {
	        return loggingEvent.level.toString() + " [" +  loggingEvent.getStackFileName() + ":" + loggingEvent.getStackLineNum() + "] " + loggingEvent.message + this.LINE_SEP;
	    }
	},
...
</code></pre>
<p>this is the bit that uses simpledate: to format the date in a less ugly way than you usually get for free from Javascript. I honestly have no idea why there isn&#8217;t a nice date formatter built into the language. It is ridiculous.</p>
<p>There&#8217;s a few more changes here as well. I had to change the <code>log()</code> method so that it attempts to get stack data (if it&#8217;s available).</p>
<pre><code class="javascript">
log: function(message, logLevel) {
    if (Components &#038;&#038; Components.stack) {
        var stack = Components.stack.caller;
        if (stack.toString().indexOf("log4js.js") != -1) {
            stack = stack.caller;
        }
        var loggingEvent = new Log4js.LoggingEvent(this.category, logLevel, message, this, stack.toString());
    } else {
        var loggingEvent = new Log4js.LoggingEvent(this.category, logLevel, message, this);
    }
...
</code></pre>
<p>and also LoggingEvent, so that it can give the stack information</p>
<pre><code class="javascript">
getStackFileName : function() {
    if (this.stackInfo != null) {
        var split = this.stackInfo.split(" :: ");
        var fileName = split[1];
        if (fileName.lastIndexOf("/") != -1) {
            var pathSplit = fileName.split("/");
            fileName = pathSplit[pathSplit.length - 1];
        }
        return fileName
    }
    return null;
},

getStackLineNum : function() {
    if (this.stackInfo != null) {
        var split = this.stackInfo.split(" :: ");
        var lineNum = split[3].split(" ")[1];
        return lineNum;
    }
    return null;
}
</code></pre>
<p>So there you have it. Not very interesting today, but this should be the last infrastructure post. I think we can begin doing things properly now.</p>
<p>I&#8217;m very interested in getting log4js to be configurable via a properties files (ala log.properties in log4j). This doesn&#8217;t seem too hard, so I may have to check it out. An alternative to log.properties would be to write the configuration in JS. Something like&#8230;</p>
<pre><code class="javascript">
logger("booksmarts.log").atLevel("DEBUG")
    .withAppender("FirefoxConsoleAppender")
    .andLayout("MozStackLayout");
</code></pre>
<p>this would be too simple though. Maybe something more elaborate. Who can really say eh?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.getbooksmarts.org/news/2007/03/21/log4js-its-a-little-different-now/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Includes, scoping and mozIJSSubScriptLoader</title>
		<link>http://www.getbooksmarts.org/news/2007/03/20/includes-scoping-and-mozijssubscriptloader/</link>
		<comments>http://www.getbooksmarts.org/news/2007/03/20/includes-scoping-and-mozijssubscriptloader/#comments</comments>
		<pubDate>Tue, 20 Mar 2007 08:39:09 +0000</pubDate>
		<dc:creator>andy</dc:creator>
		
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.getbooksmarts.org/news/2007/03/20/includes-scoping-and-mozijssubscriptloader/</guid>
		<description><![CDATA[I&#8217;ve finished (tenatively) my work on includes and it&#8217;s working really well.
There&#8217;s a reasonable example of its use in the code that sets it all up, include.js. In particular, you should take a look at the ftst.configureLogger() method and the ftst.include(ftst.getMain()) call at the bottom.
Basically, a call to ftst.include will include the specified file in [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve finished (tenatively) my work on includes and it&#8217;s working really well.</p>
<p>There&#8217;s a reasonable example of its use in the code that sets it all up, <a href="http://getbooksmarts.org/svn/booksmarts/trunk/booksmarts/src/chrome/content/include.js">include.js</a>. In particular, you should take a look at the <code>ftst.configureLogger()</code> method and the <code>ftst.include(ftst.getMain())</code> call at the bottom.</p>
<p>Basically, a call to <code>ftst.include</code> will include the specified file in that place. A call to <code>ftst.includeInScope</code> will include the file within a confined scope and return an object that holds that scope.</p>
<p>Why do I care about scoping so much? Because <strong>all extension development in Firefox is in a shared scope</strong>. Your code is in everyone else&#8217;s way and theirs is in yours. That&#8217;s why it&#8217;s so important to compartmentalise your code. This isn&#8217;t such a problem in normal web-development. In a webpage all of your JS shares the same scope, but you control it all. In extension dev there can be all sorts of stuff running around, which is a nightmare. Because of this, it&#8217;s best to limit your footprint as much as possible.</p>
<p>In include.js, you can see that I&#8217;m using <a href="http://log4js.berlios.de/">Log4js</a> to do logging, and I&#8217;m including it in a hidden scope, so that it doesn&#8217;t get into the global namespace. I&#8217;ve changed it (I&#8217;ll explain why in my next post) and now it also uses <a href="http://www.comet.co.il/en/articles/date/article.html">this date formatting code</a>, which I configure into it after it&#8217;s initialised (from another hidden scope). <strong>Why don&#8217;t I just include it directly?</strong> Well, because there are&#8230;</p>
<p><strong>Problems with mozIJSSubScriptLoader and scope</strong><br />
Remember that this is the code that sets up the loader.</p>
<pre><code class="javascript">
var jsLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
    .getService(Components.interfaces.mozIJSSubScriptLoader)
</code></pre>
<p>then we call (1)<code>jsLoader.loadSubscript(filename)</code> to load a JS file into the global scope, or (2)<code>jsLoader.loadSubscript(filename, localScope)</code> to load a JS file into the variable localScope.</p>
<p>The complication happens when we try to include one JS from within another. You can call (1) from within (1), (1) from within (2) and (2) from within (1). What you absolutely can&#8217;t do is call (2) from within (2). <strong>You can&#8217;t include something in a localScope when you are a script that is being included in a localScope</strong> no visible error occurs, but your script will halt and nothing will happen.</p>
<p>That would be alright, if it weren&#8217;t for this problem: <strong>A script included in a global scope from a script that is being included in a localScope will be globally available outside the local scope</strong>. If you include (1) from (2), (2) is confined to its localScope, but (1) is completely global. This seems wrong to me. It could be argued both ways, but I think that a script included from (2) should be confined to (2).</p>
<p>Anyway, what this means is that for Log4js to use simpledate, simpledate must either be included globally (by include.js or Log4js) or it can be included locally by include.js and then set into Log4js after it is loaded. I care a lot about scope (as you can tell) so I&#8217;m doing the latter.</p>
<p>The very worst thing about Firefox extension development is the shared JS context that every extension shares.</p>
<p><strong>PS</strong><br />
I know that <a href="http://http://dojotoolkit.org/">dojo</a> does something similar to this, but from reading, it doesn&#8217;t seem to do it right (particularly for chrome) and also does a lot more than I want.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.getbooksmarts.org/news/2007/03/20/includes-scoping-and-mozijssubscriptloader/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Debug output &#038; logging in Firefox.</title>
		<link>http://www.getbooksmarts.org/news/2007/03/17/debug-output-logging-in-firefox/</link>
		<comments>http://www.getbooksmarts.org/news/2007/03/17/debug-output-logging-in-firefox/#comments</comments>
		<pubDate>Sat, 17 Mar 2007 15:59:42 +0000</pubDate>
		<dc:creator>andy</dc:creator>
		
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.getbooksmarts.org/news/2007/03/17/debug-output-logging-in-firefox/</guid>
		<description><![CDATA[Doing any sort of development requires logging and dumping stuff to a console. Firefox extension development is no exception to this (Venkmann is useful, but he sure can be a pain).
There&#8217;s two ways that I know of to do this&#8230; The first outputs to a shell and the second uses the Error Console.
Using dump()
Firefox has [...]]]></description>
			<content:encoded><![CDATA[<p>Doing any sort of development requires logging and dumping stuff to a console. Firefox extension development is no exception to this (Venkmann is useful, but he sure can be a pain).</p>
<p>There&#8217;s two ways that I know of to do this&#8230; The first outputs to a shell and the second uses the Error Console.</p>
<p><strong>Using <code>dump()</code></strong><br />
Firefox has a function called <code>dump()</code> that will just dump whatever you give it to a standard console. To use it you have to&#8230;</p>
<ul>
<li>Start Firefox in console mode - from a command prompt type &#8220;/path_to_firefox_app/firefox -console&#8221;</li>
<li>Set &#8220;browser.dom.window.dump&#8221; to true in <a href="about:config">about:config</a> - the excellent <a href="http://ted.mielczarek.org/code/mozilla/extensiondev/">Extension Developer&#8217;s extension</a> can do this for you.</li>
<li>Use <code>dump("My message\n");</code> to dump to the console.</li>
</ul>
<p>It isn&#8217;t pretty, but it works.</p>
<p><strong>The Console Service</strong><br />
The other way is to use the console service, which will put debug statements into Firefox&#8217;s Error Console.</p>
<pre><code class="javascript">
var consoleService = Components.classes["@mozilla.org/consoleservice;1"]
        .getService(Components.interfaces.nsIConsoleService);
    consoleService.logStringMessage("My Message");
</code></pre>
<p>It&#8217;s easier, and requires less config, but it isn&#8217;t working so well for me right now. Sigh&#8230;</p>
<p>What we really need for logging in Firefox is a log4j style logging framework. That would be super sweet!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.getbooksmarts.org/news/2007/03/17/debug-output-logging-in-firefox/feed/</wfw:commentRss>
		</item>
		<item>
		<title>The correct MIME type for XPI installers</title>
		<link>http://www.getbooksmarts.org/news/2007/03/17/the-correct-mime-type-for-xpi-installers/</link>
		<comments>http://www.getbooksmarts.org/news/2007/03/17/the-correct-mime-type-for-xpi-installers/#comments</comments>
		<pubDate>Sat, 17 Mar 2007 15:14:04 +0000</pubDate>
		<dc:creator>andy</dc:creator>
		
		<category><![CDATA[Tutorial]]></category>

		<category><![CDATA[Mental note]]></category>

		<guid isPermaLink="false">http://www.getbooksmarts.org/news/2007/03/17/the-correct-mime-type-for-xpi-installers/</guid>
		<description><![CDATA[I forgot that you have to set the MIME type for XPIs right, otherwise you get that annoying problem where someone who clicks a link for it just ends up seeing a page of bytes that starts with PKZIP.
The MIME type for XPIs is &#8220;application/x-xpinstall&#8221;.
(this is mostly just a mental note for me - I [...]]]></description>
			<content:encoded><![CDATA[<p>I forgot that you have to set the MIME type for XPIs right, otherwise you get that <a href="http://www.screengrab.org/home/help/#comment-15">annoying problem</a> where someone who clicks a link for it just ends up seeing a page of bytes that starts with PKZIP.</p>
<p>The MIME type for XPIs is &#8220;application/x-xpinstall&#8221;.</p>
<p>(this is mostly just a mental note for me - I always forget to configure this on my servers)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.getbooksmarts.org/news/2007/03/17/the-correct-mime-type-for-xpi-installers/feed/</wfw:commentRss>
		</item>
		<item>
		<title>How to do dynamic Javascript imports in XUL chrome</title>
		<link>http://www.getbooksmarts.org/news/2007/03/13/how-to-do-dynamic-javascript-imports-in-xul-chrome/</link>
		<comments>http://www.getbooksmarts.org/news/2007/03/13/how-to-do-dynamic-javascript-imports-in-xul-chrome/#comments</comments>
		<pubDate>Tue, 13 Mar 2007 00:22:44 +0000</pubDate>
		<dc:creator>andy</dc:creator>
		
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.getbooksmarts.org/news/2007/03/13/how-to-do-dynamic-javascript-imports-in-xul-chrome/</guid>
		<description><![CDATA[Having spend the last couple of hours trying, I&#8217;d almost concluded that this was impossible. And it was! The way I was trying to do it.
The dynamic injection of script was stupid. It won&#8217;t work in XUL (but it will work in HTML).
The secret is found in two things.

An XPCOM interface (isn&#8217;t it always?): mozIJSSubScriptLoader
A [...]]]></description>
			<content:encoded><![CDATA[<p>Having spend the last couple of hours trying, I&#8217;d almost concluded that this was impossible. And it was! The way I was trying to do it.</p>
<p>The dynamic injection of script was stupid. It won&#8217;t work in XUL (but it will work in HTML).</p>
<p>The secret is found in two things.</p>
<ol>
<li>An XPCOM interface (isn&#8217;t it always?): <a href="http://www.xulplanet.com/references/xpcomref/ifaces/mozIJSSubScriptLoader.html">mozIJSSubScriptLoader</a></li>
<li>A JS hook into an XPCOM interface: http://www.mozilla.org/scriptable/components_object.html#_stack</li>
</ol>
<p>The first one lets you <a href="http://weblogs.mozillazine.org/weirdal/archives/008101.html">load Javascript dynamically within XUL apps</a>. You call it as follows&#8230;</p>
<pre><code class="javascript">
var jsLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
    .getService(Components.interfaces.mozIJSSubScriptLoader);
jsLoader.loadSubScript("chrome://booksmarts/content/overlay.js");
</code></pre>
<p>The cool thing is that you can also pass it in a scope object, so all of the members of the JS file you load will be attached to it. If overlay had a function called <code>jon()</code>, then the code above would&#8217;ve loaded it up into the global scope and I could just call <code>jon()</code> to access it. </p>
<p>But if I&#8217;d called <code>loadSubScript(chrome://booksmarts/content/overlay.js, anObject)</code> then I would call <code>anObject.jon()</code> to access it. Brilliant!</p>
<p>So we can load Javascript. But I said I wanted to do it with one file. Now this is where it gets hacky. <img src='http://www.getbooksmarts.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> In HTML, my one-file plan involved navigating the DOM to find my script element and then getting the src value from it. So the script tag would look like <code>&lt;script src="include.js?main=another.js"&gt;</code>.</p>
<p>Well it turns out that doesn&#8217;t work in XUL. As far as I can tell, the script tags are destroyed after they&#8217;re loaded in an overlay (document.getElementById can&#8217;t find it, so it must be lost). So instead, I <a href="http://www.mozilla.org/scriptable/components_object.html#_stack">discovered</a> (accidentally while I was trying to find out how to load scripts) that you can get a Javascript stack dump from XPConnect by calling <code>Components.stack</code>. This yields something like:</p>
<pre><code>
JS frame :: chrome://booksmarts/content/include.js?main=chrome://booksmarts/content/overlay.js :: anonymous :: line 56
</code></pre>
<p>Notice that Firefox loaded the script perfectly, despite the URL params AND it preserved them into the stack trace. AWESOME!</p>
<p>If you assign that to a string and <a href="http://www.w3schools.com/jsref/jsref_split.asp">split</a> it with <code>split(" :: ")</code> you get an array, the second value of which is your url <code>chrome://booksmarts/content/include.js?main=chrome://booksmarts/content/overlay.js</code>.</p>
<p>From that, a handy bit of <a href="http://www.netlobo.com/url_query_string_javascript.html">URL parsing courtesy of a helpful person on the internet</a> and you get your parameter. Brilliant.</p>
<p>That&#8217;s basically all of the pieces you need to do dynamic imports in Javascript. Which I&#8217;ll continue next time&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.getbooksmarts.org/news/2007/03/13/how-to-do-dynamic-javascript-imports-in-xul-chrome/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Venkman is your friend.</title>
		<link>http://www.getbooksmarts.org/news/2007/03/12/venkman-is-your-friend/</link>
		<comments>http://www.getbooksmarts.org/news/2007/03/12/venkman-is-your-friend/#comments</comments>
		<pubDate>Mon, 12 Mar 2007 22:23:52 +0000</pubDate>
		<dc:creator>andy</dc:creator>
		
		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://www.getbooksmarts.org/news/2007/03/12/venkman-is-your-friend/</guid>
		<description><![CDATA[I was going to start doing some actual work on the extension tonight, and investigate the new database support in Firefox (I think this is something that will be very useful)&#8230;
Instead, I started dealing with one of my pet Javascript peeves. I hate having to put multiple &#60;script&#62; tags in my code to include lots [...]]]></description>
			<content:encoded><![CDATA[<p>I was going to start doing some actual work on the extension tonight, and investigate the new database support in Firefox (I think this is something that will be very useful)&#8230;</p>
<p>Instead, I started dealing with one of my pet Javascript peeves. I hate having to put multiple <code>&lt;script&gt;</code> tags in my code to include lots of JS files. If one piece of Javascript depends on another piece of Javascript then I WANT IT TO SAY SO!</p>
<p>I&#8217;d hoped that someone else would&#8217;ve figured out a neat way of doing this by now, but they haven&#8217;t (dojo comes close, but it&#8217;s not good enough).</p>
<p>Here&#8217;s what I want&#8230;</p>
<ol>
<li>import(&#8221;org.getbooksmarts.SomeClass&#8221;) should load the JS at org/getbooksmarts/SomeClass.js from the root.</li>
<li>the root should be definable by a parameter</li>
<li>my importer should be able to start my other js. It should act as a bootstrap loader using something like <code>&lt;script src="import.js?main=org.getbooksmarts.Booksmarts"&gt;</code></li>
<li>ideally it will work in chrome and html, but I can live with just chrome for now</li>
</ol>
<p>It&#8217;s conceptually not too hard. The addition of new JS files is done by adding new <code>&lt;script&gt;</code> tags into the DOM. That works fine in HTML, I&#8217;m just having trouble in chrome for some reason.</p>
<p>This is why <a href="https://addons.mozilla.org/firefox/216/">Venkman</a>. Everyone thinking about developing extensions NEEDS the Mozilla Javascript debugger. This is not an optional step.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.getbooksmarts.org/news/2007/03/12/venkman-is-your-friend/feed/</wfw:commentRss>
		</item>
		<item>
		<title>I changed the theme&#8230;</title>
		<link>http://www.getbooksmarts.org/news/2007/03/11/i-changed-the-theme/</link>
		<comments>http://www.getbooksmarts.org/news/2007/03/11/i-changed-the-theme/#comments</comments>
		<pubDate>Sun, 11 Mar 2007 08:18:02 +0000</pubDate>
		<dc:creator>andy</dc:creator>
		
		<category><![CDATA[Theme]]></category>

		<category><![CDATA[Thanks]]></category>

		<guid isPermaLink="false">http://www.getbooksmarts.org/news/2007/03/11/i-changed-the-theme/</guid>
		<description><![CDATA[I really loved the other one, but it didn&#8217;t exactly scream &#8220;FIREFOX EXTENSION DEVELOPMENT HERE&#8221;. It was more like &#8220;GET YOUR LEAVES HERE&#8221;.
So I took the theme from Screengrab (because I&#8217;m so original and clever) and tweaked it a bit so that I can tell which site I&#8217;m writing things for. Also I made a [...]]]></description>
			<content:encoded><![CDATA[<p>I really loved the other one, but it didn&#8217;t exactly scream &#8220;FIREFOX EXTENSION DEVELOPMENT HERE&#8221;. It was more like &#8220;GET YOUR LEAVES HERE&#8221;.</p>
<p>So I took the theme from Screengrab (because I&#8217;m so original and clever) and tweaked it a bit so that I can tell which site I&#8217;m writing things for. Also I made a logo for this project (why should Screengrab get all the logos?).</p>
<p>Actually&#8230; when I say &#8220;made&#8221; I mean &#8220;took&#8221;&#8230;</p>
<p>&#8230; Thanks go, once again, to Nick La of <a href="http://www.ndesign-studio.com">N.Design Studio</a> for the <a href="http://www.ndesign-studio.com/blog/updates/first-wordpress-theme">site template</a> and for the awesome <a href="http://www.ndesign-studio.com/resources/vector-cliparts/">free vector clipart</a> on his site, which a man with zero graphic design skills (me) cunningly took and used.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.getbooksmarts.org/news/2007/03/11/i-changed-the-theme/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
