<?xml version="1.0" encoding="UTF-8"?>
<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/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>David DeWinter &#187; Firefox</title>
	<atom:link href="http://blogs.rev-net.com/ddewinter/category/firefox/feed/" rel="self" type="application/rss+xml" />
	<link>http://blogs.rev-net.com/ddewinter</link>
	<description>A Developer's Melting Pot: LINQ to SQL, Entity Framework, .NET Security...</description>
	<lastBuildDate>Thu, 08 Apr 2010 17:32:14 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Don&#8217;t Change Your Firefox Add-On&#8217;s ID!</title>
		<link>http://blogs.rev-net.com/ddewinter/2009/03/28/dont-change-your-firefox-add-ons-id/</link>
		<comments>http://blogs.rev-net.com/ddewinter/2009/03/28/dont-change-your-firefox-add-ons-id/#comments</comments>
		<pubDate>Sun, 29 Mar 2009 02:01:29 +0000</pubDate>
		<dc:creator>David DeWinter</dc:creator>
				<category><![CDATA[Firefox]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[add-on]]></category>
		<category><![CDATA[addons.mozilla.org]]></category>
		<category><![CDATA[AMO]]></category>
		<category><![CDATA[extension]]></category>
		<category><![CDATA[firefox add-on]]></category>
		<category><![CDATA[firefox extension]]></category>
		<category><![CDATA[GUID]]></category>
		<category><![CDATA[ID]]></category>

		<guid isPermaLink="false">http://blogs.rev-net.com/ddewinter/2009/03/28/dont-change-your-firefox-add-ons-id/</guid>
		<description><![CDATA[That is, unless you want to experience pain.
Two weeks ago I blogged about how someone had taken an add-on of mine that was in production and uploaded a derived version to https://addons.mozilla.org (AMO) without changing its ID. This means that because the AMO web site identifies add-ons by their ID, it would not allow me [...]]]></description>
			<content:encoded><![CDATA[<p>That is, unless you <em>want</em> to experience pain.</p>
<p>Two weeks ago <a href="http://blogs.rev-net.com/ddewinter/2009/03/15/burned-by-amo-and-oss/">I blogged</a> about how someone had taken an add-on of mine that was in production and uploaded a derived version to <a href="https://addons.mozilla.org">https://addons.mozilla.org</a> (AMO) without changing its ID. This means that because the AMO web site identifies add-ons by their ID, it would not allow me to upload my add-on. I tried to solve this problem by engineering a solution to change my add-on&#8217;s ID.</p>
<p>I thought this would work and even provided some sample code for my ideas in my previous blog entry; however, there were just too many problems to overcome.</p>
<p>The sample code <em>might </em>work if Firefox&#8217;s UI gave users a pleasant experience when an add-on&#8217;s automatic update facility installs an add-on with a different ID. (I&#8217;m not blaming Firefox here; it&#8217;s probably not a supported scenario.)     </p>
<p>Instead this is what the user sees:     </p>
<p><a href="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2009/03/image2.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2009/03/image-thumb2.png" width="545" height="430" /></a>&#160; </p>
<p>Compare this to what they should see:     </p>
<p><a href="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2009/03/image3.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2009/03/image-thumb3.png" width="545" height="430" /></a>&#160;</p>
<p>Notice anything missing? 5 points if you said the &quot;Restart Firefox&quot; button. It&#8217;s pretty important.</p>
<p>&quot;OK,&quot; I say, full of resolve, &quot;let&#8217;s just create an update with the same ID that downloads the new version for them.&quot; Essentially, we use an update with the same ID to get around the problem laid out above, but all that update does is to download the newest version of the add-on automatically. Finally, it uninstalls itself and then restarts Firefox. Here&#8217;s what I envisioned for the user experience:</p>
<ol>
<li>Joe Bloggs sees there&#8217;s an update for one of his extensions. Firefox guides him through the update process, at which point he sees the picture above to restart Firefox to complete his changes. </li>
<li>Joe clicks &quot;Restart,&quot; and as soon as this intermediate version of the extension springs into action and downloads the newest version of the extension. Firefox doesn&#8217;t have time to show its windows again before the download completes, and Firefox is forced to restart by the intermediate extension. </li>
<li>Joe sees his windows and tabs being restored, and he has the newest version of your extension. </li>
</ol>
<p>Unfortunately, it never quite worked out that well. This is closer to the end user experience:</p>
<ol>
<li>Joe sees there&#8217;s an update for one of his extensions. Firefox guides him through the update process, at which point he sees the picture above to restart Firefox to complete his changes. </li>
<li>Joe clicks &quot;Restart,&quot; and as soon as this intermediate version of the extension springs into action and downloads the newest version of the extension. <strong>Meanwhile, Joe sees his windows and tabs being restored. All of a sudden, all of his windows disappear.</strong> </li>
<li>Joe at this point could try and relaunch Firefox, but that wouldn&#8217;t work since Firefox is technically already restarted. If he waits long enough he&#8217;ll see Firefox return, but <strong>all of his windows and tabs have gone.</strong> </li>
</ol>
<p>Whether these were technical limitations of Firefox itself or problems in my code I never confirmed. What I knew was that the investigation had cost a lot of time, and I was very nervous about deploying something that could potentially frustrate a large percentage of my user base.</p>
<p>Turns out I made the right call. <a href="http://www.osunick.com">Nick Nguyen</a>, who was my liaison at AMO, allowed me to take over the extension that used my add-on&#8217;s ID. No more problems, and definitely no more hitting my head against a brick wall.</p>
<p>So if you have deployed an add-on publically, and you&#8217;re thinking of changing its ID, don&#8217;t do it. There&#8217;s a better way to achieve what you want.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.rev-net.com/ddewinter/2009/03/28/dont-change-your-firefox-add-ons-id/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Burned by AMO and OSS (An Idea on How to Change Your Firefox Add-On&#8217;s ID)</title>
		<link>http://blogs.rev-net.com/ddewinter/2009/03/15/burned-by-amo-and-oss/</link>
		<comments>http://blogs.rev-net.com/ddewinter/2009/03/15/burned-by-amo-and-oss/#comments</comments>
		<pubDate>Mon, 16 Mar 2009 01:56:10 +0000</pubDate>
		<dc:creator>David DeWinter</dc:creator>
				<category><![CDATA[Firefox]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[add-on]]></category>
		<category><![CDATA[addons.mozilla.org]]></category>
		<category><![CDATA[AMO]]></category>
		<category><![CDATA[extension]]></category>
		<category><![CDATA[firefox add-on]]></category>
		<category><![CDATA[firefox extension]]></category>
		<category><![CDATA[GUID]]></category>
		<category><![CDATA[ID]]></category>

		<guid isPermaLink="false">http://blogs.rev-net.com/ddewinter/2009/03/15/burned-by-amo-and-oss/</guid>
		<description><![CDATA[I&#8217;ve helped to build a Firefox add-on called NAMFox over the past couple of years to help refine my skills with JavaScript and provide an avenue for more technical challenges. (Of course, I also like to provide value to customers, but that&#8217;s not the focus of this blog entry.) For add-on developers, AMO (https://addons.mozilla.org/) is [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve helped to build a Firefox add-on called <a href="http://code.google.com/p/namfox/">NAMFox</a> over the past couple of years to help refine my skills with JavaScript and provide an avenue for more technical challenges. (Of course, I also like to provide value to customers, but that&#8217;s not the focus of this blog entry.) For add-on developers, AMO (<a title="https://addons.mozilla.org/" href="https://addons.mozilla.org/">https://addons.mozilla.org/</a>) is THE site to use to host your add-on and put your work out there for other people to use. Of course, you can always host the add-on on your own server, but if you want integration with Firefox&#8217;s add-on searching (see below) or an easy way to manage automatic updates, then you&#8217;ll use AMO.</p>
<p><a href="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2009/03/image.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Firefox Add-On Search" border="0" alt="Firefox Add-On Search" src="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2009/03/image-thumb.png" width="553" height="440" /></a> </p>
<h3>The Situation</h3>
<p>In early 2008 I wanted to upload NAMFox onto AMO for the reasons mentioned above, and because the server it was already hosted on wasn&#8217;t very reliable. I set up a new account and went through the process to upload my add-on, when I encountered an error saying that I didn&#8217;t have permission to upload the add-on.* At the time I thought it was because the ID of my extension (superfastoz@neoseeker.com) didn&#8217;t match the email I registered with. (This was <em>not</em> the case; read further….) I gave up on trying to host it at AMO and continued using the same server the product had always used. </p>
<p>…Until a year later, when after some significant code rewrites I decided to try my luck again with AMO. I got the same error message and decided to investigate further. This time I discovered that it was actually because an add-on with the same ID already existed on AMO. I certainly didn&#8217;t remember uploading it before, and the previous project owner professed that he didn&#8217;t upload it on AMO either. I began writing a piece of software to download all the add-ons on AMO and check their IDs for conflicts, but I figured it would be a much more efficient use of my time to enlist some at Mozilla for help.</p>
<p>Enter <a href="http://osunick.com/">Nick Nguyen</a>, who helped me figure out that another user had uploaded <a href="https://addons.mozilla.org/en-US/firefox/addon/3995/">an add-on</a> with the same ID as mine. I was a bit disappointed; then I figured out that someone had taken NAMFox back in 2007, amended it to work with GameFAQs instead of Neoseeker, and then uploaded it to AMO with <em>the same ID</em>. I was flabbergasted. I had wasted so many hours trying to get NAMFox onto AMO, only to find this. Unfortunately all Nick and I could do was to email the original developer of that account to see if he would be willing to relinquish ownership of the project. Unfortunately I can&#8217;t just take it over, even though there is currently no download on the page, nor have there ever been (0 total downloads since 2007). If we didn&#8217;t hear back from the developer in a couple of <em>months</em>, I could perhaps take over the project then.</p>
<p>Well…</p>
<ol>
<li>We haven&#8217;t heard back from the developer, and it&#8217;s been about two weeks now. </li>
<li>A couple of months is such a long period to go without a release or an update, especially since the add-on enhances a web site which is prone to change (and break NAMFox) without notice. </li>
</ol>
<p>There was another alternative—I should change the ID of my add-on. Then I could easily upload it to AMO for people to use. There are a couple of problems with this:</p>
<ol>
<li>Firefox treats two different add-on files as the same add-on if they have the same ID and as two separate add-ons if they have different IDs. This means that if anyone who had the old NAMFox installed downloaded the new version with a different ID, their Firefox would have <strong>two</strong> instances of the add-on running, the old one <strong>and</strong> the new one. </li>
<li>The same problem occurs with automatic updates. I can tell Firefox to download this updated NAMFox with a new ID, but now the customers that download the updates will have two instances of the add-on running. </li>
</ol>
<p><em>In theory there is a way around this limitation, but I haven&#8217;t tried it…</em></p>
<h3>The (Tentative) Solution</h3>
<p><strong><span style="color: red">DISCLAIMER</span>: </strong>I have not used the following techniques/code when releasing my add-on into the wild, so you should be careful if you&#8217;re going to adopt it.</p>
<p><strong>UPDATE:</strong> <strong>Don&#8217;t try this! </strong><a href="http://blogs.rev-net.com/ddewinter/2009/03/28/dont-change-your-firefox-add-ons-id/">My Findings</a></p>
<p>The great thing about Firefox is that you can control just about every part of the browser, including the add-ons that the users have installed. If you&#8217;re like me, you&#8217;re probably thinking you can use this to get around the two limitations I listed above. In fact, <em>I believe</em> we can.</p>
<p>We&#8217;ve already identified the two scenarios that users can get your add-on with a new ID: through a direct download and through automatic updates.</p>
<p>If a user doesn&#8217;t have your add-on installed already, then we can agree that there is no problem.</p>
<p>If a user does have your old add-on installed already, then the new add-on must recognize this and uninstall it. This action is required regardless of whether the user used automatic updates to install the new add-on.</p>
<p>Turns out this is actually quite simple and only requires a few lines of code:</p>
<div style="font-family: courier new; background: white; color: black; font-size: 10pt">
<p style="margin: 0px"><span style="color: blue">var</span> oldId = <span style="color: #a31515">&quot;superfastoz@neoseeker.com&quot;</span>;</p>
<p style="margin: 0px"><span style="color: blue">var</span> extensionManager = Components.classes[<span style="color: #a31515">&quot;@mozilla.org/extensions/manager;1&quot;</span>].</p>
<p style="margin: 0px">&#160;&#160;&#160; getService(Components.interfaces.nsIExtensionManager);</p>
<p style="margin: 0px"><span style="color: blue">var</span> oldAddon = extensionManager.getItemForID(oldId);</p>
<p style="margin: 0px">&#160;</p>
<p style="margin: 0px"><span style="color: blue">if</span> (oldAddon) {</p>
<p style="margin: 0px">&#160;&#160;&#160; extensionManager.uninstallItem(oldId);</p>
<p style="margin: 0px">&#160;</p>
<p style="margin: 0px">&#160;&#160;&#160; <span style="color: blue">var</span> nsIAppStartup = Components.interfaces.nsIAppStartup;</p>
<p style="margin: 0px">&#160;&#160;&#160; <span style="color: blue">var</span> appManager = Components.classes[<span style="color: #a31515">&quot;@mozilla.org/toolkit/app-startup;1&quot;</span>].</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; getService(nsIAppStartup);</p>
<p style="margin: 0px">&#160;&#160;&#160; appManager.quit(nsIAppStartup.eForceQuit | nsIAppStartup.eRestart);</p>
<p style="margin: 0px">}</p>
</p></div>
<p>This code exists in the new add-on; for me it runs in an event listener for the window&#8217;s load event. It tries to find the old add-on with a certain ID. If it exists, it&#8217;s uninstalled and Firefox is restarted to commit the change. When Firefox restarts, only the new add-on remains.</p>
<p>I&#8217;m planning to try this soon. I&#8217;ll update this post with the good, the bad, and the ugly after I do.</p>
<p>*The AMO team did a great job of cleaning this error message up. You&#8217;ll now see this message, which is much clearer.</p>
<p><a href="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2009/03/image1.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2009/03/image-thumb1.png" width="636" height="139" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.rev-net.com/ddewinter/2009/03/15/burned-by-amo-and-oss/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Using FireUnit For Firefox Add-On Testing</title>
		<link>http://blogs.rev-net.com/ddewinter/2009/01/06/using-fireunit-for-firefox-add-on-testing/</link>
		<comments>http://blogs.rev-net.com/ddewinter/2009/01/06/using-fireunit-for-firefox-add-on-testing/#comments</comments>
		<pubDate>Tue, 06 Jan 2009 14:41:35 +0000</pubDate>
		<dc:creator>David DeWinter</dc:creator>
				<category><![CDATA[Firefox]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[firefox add-on]]></category>
		<category><![CDATA[fireunit]]></category>
		<category><![CDATA[unit testing]]></category>

		<guid isPermaLink="false">http://blogs.rev-net.com/ddewinter/2009/01/06/using-fireunit-for-firefox-add-on-testing/</guid>
		<description><![CDATA[A friend of mine recently sent me a link to John Resig&#8217;s blog entry on a new JavaScript unit testing extension/framework called FireUnit. After reading it, I was very excited to see something like this available, because unit testing JavaScript inside an add-on has not typically been a fun experience for me. I played with [...]]]></description>
			<content:encoded><![CDATA[<p>A friend of mine recently sent me a link to John Resig&#8217;s <a href="http://ejohn.org/blog/fireunit/">blog entry</a> on a new JavaScript unit testing extension/framework called FireUnit. After reading it, I was very excited to see something like this available, because unit testing JavaScript inside an add-on has not typically been a fun experience for me. I played with the extension this past weekend, and this entry documents my thoughts. (You should definitely read John&#8217;s post first if you are not familiar with FireUnit.)</p>
<p>The first step is obviously to download the extension, available at <a href="http://fireunit.org">http://fireunit.org</a>. I put a &quot;Hello World&quot;-type test together just to see the results. It should be no surprise that I saw the results in Firebug&#8217;s new Test panel when I opened the HTML page in Firefox.</p>
<div style="font-size: 10pt; background: white; color: black; font-family: courier new">
<p style="margin: 0px"><span style="color: blue">&lt;</span><span style="color: #a31515">script</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px">fireunit.ok(<span style="color: #a31515">&quot;Hello World&quot;</span>, <span style="color: #a31515">&quot;&#8217;Hello World&#8217; is truthy!&quot;</span>);</p>
<p style="margin: 0px"><span style="color: blue">&lt;/</span><span style="color: #a31515">script</span><span style="color: blue">&gt;</span></p>
</p></div>
<p><a href="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2009/01/image.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="127" alt="image" src="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2009/01/image-thumb.png" width="342" border="0" /></a> </p>
<p>So far so good. I noticed that FireUnit supported running tests from multiple HTML files, so I tried that based on what I found on the <a href="http://github.com/jeresig/fireunit/wikis/examples">FireUnit examples wiki page</a>.</p>
<div style="font-size: 10pt; background: white; color: black; font-family: courier new">
<p style="margin: 0px"><span style="color: blue">&lt;</span><span style="color: #a31515">script</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">if</span> (fireunit.forceHttp()) {</p>
<p style="margin: 0px">&#160;&#160;&#160; fireunit.runTests(<span style="color: #a31515">&quot;1.html&quot;</span>, <span style="color: #a31515">&quot;2.html&quot;</span>);</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px"><span style="color: blue">&lt;/</span><span style="color: #a31515">script</span><span style="color: blue">&gt;</span></p>
</p></div>
<p>I was a bit disappointed to see the following chrome error in Firebug when I ran this page:</p>
<p><a href="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2009/01/image1.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="34" alt="image" src="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2009/01/image-thumb1.png" width="432" border="0" /></a> </p>
<p>What I should&#8217;ve done immediately was to download the source, but I was already sucked into hacking my local version to get it to work. I eventually did download the <a href="http://github.com/jeresig/fireunit/">FireUnit source</a>, but I still received errors like &quot;nsHttpServer is not defined.&quot; (I tried to discover the cause of this problem, but after a couple hours of tweaking the <a href="http://github.com/jeresig/fireunit/tree/master/chrome/content/fireunit/httpd.js">httpd.js file</a>, I decided to cut my losses and try something else.)</p>
<p>Not to be deterred (mainly because I really like the idea of FireUnit), I set out on writing an alternative to running test suites. What I created wasn&#8217;t pretty, but it was functional. I overwrote the fireunit.runTests function to take each argument and make a synchronous XMLHttpRequest for that specific page. Once I received the page, I would import all of the scripts on that page (i.e. importing the scripts in all of the script elements that had a src attribute). After all the scripts were imported, I would eval() the remaining inline scripts on the page which contained the tests themselves. Finally, I would repeat the process for the next test file, until all tests in all test files had run. It took a while to get this just right, but now I&#8217;m happy building tests instead of test infrastructure.</p>
<p>Another way I&#8217;m being unorthodox with FireUnit is that my tests are actually HTML files embedded in the add-on itself. This offers a few advantages over using a local HTML page but also comes with its own set of disadvantages. The main advantage is that I don&#8217;t have to deal with enabling the UniversalXPConnect privilege in every test function or (more importantly) the code I&#8217;m testing. The main disadvantage is that Firebug will not show the source for script files that exist in chrome (probably with good reason); perhaps this is just a Firebug preference that I&#8217;m missing.</p>
<p><strong>Thoughts on FireUnit</strong>? I like what the extension aims to do and what it allows me to do already, albeit with some heavy tweaking. I know it&#8217;s in its early stages, but I can&#8217;t imagine that everyone would be willing to spend as much time as I did to set up the environment. On the other hand, it&#8217;s possible that not everyone will run into the same issues I did, especially with the nsHttpServer. I can&#8217;t think of much to improve besides making it much easier to run tests from multiple HTML files. About the only thing I would enjoy it would be great to see a <a href="http://docs.jquery.com/QUnit">QUnit-like HTML report</a> for tests, with each module being a separate HTML file.</p>
<p>Now back to testing&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.rev-net.com/ddewinter/2009/01/06/using-fireunit-for-firefox-add-on-testing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
