<?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>ColonelPanic &#187; Browser Plugin Development</title>
	<atom:link href="http://colonelpanic.net/category/plugindev/feed/" rel="self" type="application/rss+xml" />
	<link>http://colonelpanic.net</link>
	<description>Dumping our corps so you don&#039;t have to</description>
	<lastBuildDate>Mon, 30 Jan 2012 17:50:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Building a firefox plugin &#8211; part four</title>
		<link>http://colonelpanic.net/2011/07/building-a-firefox-plugin-part-four/</link>
		<comments>http://colonelpanic.net/2011/07/building-a-firefox-plugin-part-four/#comments</comments>
		<pubDate>Tue, 05 Jul 2011 03:41:01 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[Browser Plugin Development]]></category>
		<category><![CDATA[FireBreath]]></category>
		<category><![CDATA[NPAPI]]></category>

		<guid isPermaLink="false">http://colonelpanic.net/?p=520</guid>
		<description><![CDATA[The traffic going to my &#8220;Building a firefox plugin&#8221; series over the last year or two has been incredible. Granted, I knew that the other documenation was poor, but in recent times I have encountered links to my previous posts in all sorts of strange places &#8212; even in the comments in a project I [...]]]></description>
			<content:encoded><![CDATA[<p>The traffic going to my &#8220;Building a firefox plugin&#8221; series over the last year or two has been incredible. Granted, I knew that the other documenation was poor, but in recent times I have encountered links to my previous posts in all sorts of strange places &#8212; even in the comments in a project I ended up reviewing for an employer where the original author had not previously met me. I never inteded those to be the end of the series, but it has been quite some time since I last posted an update.  The main reason for this is that for all but a few uses &#8212; android in particular &#8212; I no longer recommend anyone write a NPAPI plugin from scratch. The reason for this is that the popular <a href="http://www.firebreath.org">FireBreath</a> framework makes all of this so easy and fixes so many edge cases in different browser versions that it isn&#8217;t worth doing it by hand anymore.</p>
<p>Yes, I wrote <a href="http://www.firebreath.org">FireBreath</a>. A lot of others have contributed.</p>
<h2>A different approach to learning NPAPI</h2>
<p>Now that I have a good example already up and running, it seems pointless to keep trying to describe things with words and code snippets when I can simply walk you through what I have done &#8212; what is in use and works well. To that end, and in hopes that it will foster more capable NPAPI developers to help with FireBreath development (we still don&#8217;t support printing, for example), I have created a series of 5 minute screencasts providing a brief overview of FireBreath&#8217;s NPAPI framework.</p>
<p>I don&#8217;t expect that this is as comprehensive as it should be; I&#8217;m hoping that comments will help me see what future segments I should create.  I have posted these screencasts on youtube and will link to them from here. You can also find a more complete series that includes this one <a href="http://www.firebreath.org/display/documentation/FireBreath+development+video+tutorials">on the FireBreath website</a>.</p>
<p><iframe class="youtube-player" type="text/html" width="640" height="385" src="http://www.youtube.com/embed/ehHfsxj2xSk" frameborder="0"><br />
</iframe><br />
<iframe class="youtube-player" type="text/html" width="640" height="385" src="http://www.youtube.com/embed/VbHW4HvitIg" frameborder="0"><br />
</iframe><br />
<iframe class="youtube-player" type="text/html" width="640" height="385" src="http://www.youtube.com/embed/RtPyEpiTFxY" frameborder="0"><br />
</iframe><br />
<iframe class="youtube-player" type="text/html" width="640" height="385" src="http://www.youtube.com/embed/c17kvVxoNGU" frameborder="0"><br />
</iframe><br />
<iframe class="youtube-player" type="text/html" width="640" height="385" src="http://www.youtube.com/embed/SQtduyKCAZ8" frameborder="0"><br />
</iframe><br />
<iframe class="youtube-player" type="text/html" width="640" height="385" src="http://www.youtube.com/embed/4NxLMDUHufE" frameborder="0"><br />
</iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://colonelpanic.net/2011/07/building-a-firefox-plugin-part-four/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>FireBreath Tips: Asynchronous Javascript Calls</title>
		<link>http://colonelpanic.net/2010/12/firebreath-tips-asynchronous-javascript-calls/</link>
		<comments>http://colonelpanic.net/2010/12/firebreath-tips-asynchronous-javascript-calls/#comments</comments>
		<pubDate>Thu, 02 Dec 2010 00:12:58 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[FireBreath]]></category>
		<category><![CDATA[blocking calls]]></category>
		<category><![CDATA[firebreath]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jsapi]]></category>
		<category><![CDATA[jsobject]]></category>
		<category><![CDATA[thread]]></category>

		<guid isPermaLink="false">http://colonelpanic.net/?p=463</guid>
		<description><![CDATA[Never block a Javascript call! One cardinal rule of browser plugins is that you should never block the thread when processing a method or property call from Javascript.  In FireBreath, that means that any method or property on your JSAPI must never block, but should return in a timely manner. The reason for this is [...]]]></description>
			<content:encoded><![CDATA[<h2>Never block a Javascript call!</h2>
<p>One cardinal rule of browser plugins is that you should never block the thread when processing a method or property call from Javascript.  In FireBreath, that means that any method or property on your JSAPI must <em><strong>never</strong></em> block, but should return in a timely manner.</p>
<p>The reason for this is that Javascript is effectively not a multi-threaded language. The way that Javascript handles setTimeout and setInterval varies, but from the perspective of your plugin, all JSAPI calls come in on the same thread &#8212; the UI thread. If you block on a JSAPI call the whole web browser will lock up until you finish.</p>
<p>In the programming circles that I hang out in, this is considered a Bad Thing.</p>
<p>However, there are often cases when you may need to perform some operation that is inherently blocking &#8212; such as searching the filesystem, processing a large file, or making a network request. There are doubtless several ways you could deal with this, but perhaps the easiest is to run the blocking operation on a new thread, and then call back into Javascript when you&#8217;re done.</p>
<p>If you think about it, this is why AJAX calls are all asynchronous.</p>
<h2>FB::JSObjectPtr to the rescue!</h2>
<p>One of the types supported by FireBreath is <a href="http://www.firebreath.org/display/documentation/class+FB+JSObject"  target="_blank">FB::JSObject</a>.  This represents any type of Javascript object that is passed in &#8212; so basically anything other than a primitive datatype. This includes arrays, raw objects (key : value stores), and functions as well as other things like DOM objects.</p>
<p>FB:JSObject has a method <a href="http://www.firebreath.org/display/documentation/class%20FB%20JSObject%20InvokeAsync" target="_blank">InvokeAsync</a> that works the same way as Invoke would on a normal <a href="http://www.firebreath.org/display/documentation/class%20FB%20JSAPI">JSAPI</a> object except that the call is asynchronous, so it doesn&#8217;t have a return value and thus doesn&#8217;t wait for the call to complete before returning. If we want, we can even pass back a reference to the current API object in the callback. To call a function (instead of a method on an object), we pass an empty string in for the method name when we call <a href="http://www.firebreath.org/display/documentation/class%20FB%20JSAPI%20Invoke%20%282%29" target="_blank">Invoke</a> or InvokeAsync.</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// Say we have a FB::JSObjectPtr callback</span>
callback<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>InvokeAsync<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;&quot;</span>, FB<span style="color: #008080;">::</span><span style="color: #007788;">variant_list_of</span><span style="color: #008000;">&#40;</span>shared_from_this<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre>
</div>
</div>
<h2>Creating a thread</h2>
<p>FireBreath relies on the boost thread library; this means that it is quite simple to create a new thread, particularly to run something minor.  Keep in mind that my purpose isn&#8217;t to talk about proper techniques for multithreaded programming, so you&#8217;ll have to worry about things like making sure that your threads have all ended before shutting down and so forth on your own.</p>
<p>With boost thread, basically you just create a function that will be run on the other thread and use boost::bind to provide that method object<del datetime="2011-01-19T20:25:08+00:00"> (with a shared_from_this to the object instance to keep it from going away while the thread is running) to the thread constructor</del>. <strong>Edit 1/19/2010:</strong> Someone rightly pointed out that using shared_from_this may not be (in fact usually is not) optimal. If you want to stop the thread when the JSAPI object goes away, you should pass &#8220;this&#8221; instead of shared_from_this.  The code below has been updated to reflect that.</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;">    boost<span style="color: #008080;">::</span><span style="color: #007788;">thread</span> t<span style="color: #008000;">&#40;</span>boost<span style="color: #008080;">::</span><span style="color: #007788;">bind</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>MyPluginAPI<span style="color: #008080;">::</span><span style="color: #007788;">doSomethingTimeConsuming_thread</span>,
         <span style="color: #0000dd;">this</span>, num, callback<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre>
</div>
</div>
<h2>Putting it together</h2>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">bool</span> MyPluginAPI<span style="color: #008080;">::</span><span style="color: #007788;">doSomethingTimeConsuming</span><span style="color: #008000;">&#40;</span> <span style="color: #0000ff;">int</span> num, FB<span style="color: #008080;">::</span><span style="color: #007788;">JSObjectPtr</span> <span style="color: #000040;">&amp;</span>callback <span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    boost<span style="color: #008080;">::</span><span style="color: #007788;">thread</span> t<span style="color: #008000;">&#40;</span>boost<span style="color: #008080;">::</span><span style="color: #007788;">bind</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>MyPluginAPI<span style="color: #008080;">::</span><span style="color: #007788;">doSomethingTimeConsuming_thread</span>,
         <span style="color: #0000dd;">this</span>, num, callback<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span><span style="color: #008080;">;</span> <span style="color: #666666;">// the thread is started</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">void</span> MyPluginAPI<span style="color: #008080;">::</span><span style="color: #007788;">doSomethingTimeConsuming_thread</span><span style="color: #008000;">&#40;</span> <span style="color: #0000ff;">int</span> num, FB<span style="color: #008080;">::</span><span style="color: #007788;">JSObjectPtr</span> <span style="color: #000040;">&amp;</span>callback <span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #666666;">// Do something that takes a long time here</span>
    <span style="color: #0000ff;">int</span> result <span style="color: #000080;">=</span> num <span style="color: #000040;">*</span> <span style="color: #0000dd;">10</span><span style="color: #008080;">;</span>
    callback<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>InvokeAsync<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;&quot;</span>, FB<span style="color: #008080;">::</span><span style="color: #007788;">variant_list_of</span><span style="color: #008000;">&#40;</span>shared_from_this<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span>result<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre>
</div>
</div>
<p>As you can see, when doSomethingTimeConsuming is called it accepts a callback. It creates a new thread and gives it the callback function.</p>
<h2>Synchronous calls</h2>
<p>It should also be noted that calls to Invoke on a FB::JSObject will also be threadsafe &#8212; they can be called from any thread. Keep in mind that a mutex and signal are being used behind to scenes to block until after the call is made to Javascript on the main thread, so there will be a performance hit for this.</p>
]]></content:encoded>
			<wfw:commentRss>http://colonelpanic.net/2010/12/firebreath-tips-asynchronous-javascript-calls/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>FireBreath Tips: Drawing on Windows</title>
		<link>http://colonelpanic.net/2010/11/firebreath-tips-drawing-on-windows/</link>
		<comments>http://colonelpanic.net/2010/11/firebreath-tips-drawing-on-windows/#comments</comments>
		<pubDate>Wed, 24 Nov 2010 18:17:55 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[FireBreath]]></category>
		<category><![CDATA[drawing]]></category>
		<category><![CDATA[firebreath]]></category>
		<category><![CDATA[gdi]]></category>
		<category><![CDATA[hwnd]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://colonelpanic.net/?p=461</guid>
		<description><![CDATA[FireBreath Window Abstraction It is an interesting thing to me that so many people seem to have a hard time understanding how the FireBreath windowing abstraction works, since to me it seems fairly clear. Of course, I wrote it, so that&#8217;s probably the reason =] There are a few things you should understand before you [...]]]></description>
			<content:encoded><![CDATA[<h1>FireBreath Window Abstraction</h1>
<p>It is an interesting thing to me that so many people seem to have a hard time understanding how the FireBreath windowing abstraction works, since to me it seems fairly clear. Of course, I wrote it, so that&#8217;s probably the reason =] There are a few things you should understand before you start trying to do your drawing on Windows:</p>
<h2>PluginWindow</h2>
<p>Every platform has a <a href="http://www.firebreath.org/display/documentation/class+FB+PluginWindow" target="_blank">PluginWindow</a>.  In fact, some platforms (<a href="http://www.firebreath.org/display/documentation/Mac+Plugins" target="_blank">most notably Mac</a>) have several different types of PluginWindow depending on which drawing model and event model you use.  The PluginWindow is the source of all system events for the plugin.</p>
<p>In the default plugin skeleton generated by fbgen there are several Events mapped:</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;">BEGIN_PLUGIN_EVENT_MAP<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
    EVENTTYPE_CASE<span style="color: #008000;">&#40;</span>FB<span style="color: #008080;">::</span><span style="color: #007788;">AttachedEvent</span>, onWindowAttached, FB<span style="color: #008080;">::</span><span style="color: #007788;">PluginWindow</span><span style="color: #008000;">&#41;</span>
    EVENTTYPE_CASE<span style="color: #008000;">&#40;</span>FB<span style="color: #008080;">::</span><span style="color: #007788;">DetachedEvent</span>, onWindowDetached, FB<span style="color: #008080;">::</span><span style="color: #007788;">PluginWindow</span><span style="color: #008000;">&#41;</span>
END_PLUGIN_EVENT_MAP<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span></pre>
</div>
</div>
<p>Then the matching handlers are:</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">bool</span> onWindowAttached<span style="color: #008000;">&#40;</span>FB<span style="color: #008080;">::</span><span style="color: #007788;">AttachedEvent</span> <span style="color: #000040;">*</span>evt, FB<span style="color: #008080;">::</span><span style="color: #007788;">PluginWindow</span> <span style="color: #000040;">*</span>wnd<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">bool</span> onWindowDetached<span style="color: #008000;">&#40;</span>FB<span style="color: #008080;">::</span><span style="color: #007788;">DetachedEvent</span> <span style="color: #000040;">*</span>evt, FB<span style="color: #008080;">::</span><span style="color: #007788;">PluginWindow</span> <span style="color: #000040;">*</span>wnd<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre>
</div>
</div>
<p><a href="http://www.firebreath.org/display/documentation/class+FB+AttachedEvent" target="_blank">FB::AttachedEvent</a> will be fired each time a window is attached to the plugin.  <a href="http://www.firebreath.org/display/documentation/class+FB+DetachedEvent" target="_blank">FB::DetachedEvent</a> will be fired each time a window is detached from the plugin.  <em><strong>NOTE:</strong></em> <em>Though in practice each of these usually get fired only once per plugin instance, there is no guarantee in the browser contract that it won&#8217;t take away the window it gave you and give you a different one.</em></p>
<h2>PluginWindowWin</h2>
<p>The main plugin object is, by default, a platform agnostic object.  There are several ways that you can do your windows specific drawing:</p>
<ol>
<li>Make your plugin object windows specific<br />
<blockquote><p>This is certainly the easiest way, though the least friendly to cross-platform development; you could just change the type of the event source specified in EVENTTYPE_CASE to FB::PluginWindowWin (as well as the type in the handlers) and you will have your object cast in the way you need it.</p></blockquote>
<blockquote><p>Note that FB::PluginWindowWin is in
<pre>#include "Win/PluginWindowWin.h"</pre>
</blockquote>
</li>
<li>Create a platform specific subclass of your plugin object<br />
<blockquote><p>This is actually fairly easy. Simply create an object (Such as MyPluginWin) in the Win/ directory that extends your main (MyPlugin) object and move Factory.cpp into your Win/ directory.  If you support other platforms, you&#8217;ll need to create a subclass and factory for each platform you want to support.  Then modify each Factory.cpp so that createPlugin returns the platform-specific plugin object.  Then you can make platform-specific event code to get your PluginWindowWin object.</p></blockquote>
</li>
<li>Use #ifdef FB_WIN to have platform specific code in your plugin object<br />
<blockquote><p>Don&#8217;t do this.  It&#8217;s messy and ugly.  Still, you can if you want. To get a PluginWindowWin* from your PluginWindow* object, you can do:</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;">FB<span style="color: #008080;">::</span><span style="color: #007788;">PluginWindowWin</span> <span style="color: #000040;">*</span>pwnd <span style="color: #000080;">=</span> wnd<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>get_as<span style="color: #000080;">&lt;</span>FB<span style="color: #008080;">::</span><span style="color: #007788;">PluginWindowWin</span><span style="color: #000040;">*</span><span style="color: #000080;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre>
</div>
</div>
</blockquote>
</li>
<li>Create a platform specific object and pass the window and other information to it to draw<br />
<blockquote><p>Use the same method mentioned previously to convert the PluginWindow to a PluginWindowWin. This is the method that the BasicMediaPlayer example (found in examples/) uses.</p></blockquote>
</li>
</ol>
<p>Once you have your <a href="http://www.firebreath.org/display/documentation/class+FB+PluginWindowWin" target="_blank">PluginWindowWin</a> object, you can get the information you need to do the actual drawing with a few functions:</p>
<ol>
<li><a href="http://www.firebreath.org/display/documentation/class+FB+PluginWindowWin+getHWND" target="_blank">getHWND</a>() &#8211; returns the HWND assigned to the browser plugin</li>
<li><a href="http://www.firebreath.org/display/documentation/class+FB+PluginWindowWin+getBrowserHWND" target="_blank">getBrowserHWND</a>() &#8211; returns the HWND of the top-level browser window</li>
<li><a href="http://www.firebreath.org/display/documentation/class+FB+PluginWindowWin+InvalidateWindow" target="_blank">InvalidateWindow</a>() &#8211; instructs the browser to invalidate the window and give you a <a href="http://www.firebreath.org/display/documentation/class+FB+RefreshEvent" target="_blank">RefreshEvent</a> (fired when a WM_PAINT is received)</li>
</ol>
<h2>When to draw</h2>
<p>Once you have the HWND, the next thing you need to know is when you can draw.  There are a few guidelines:</p>
<ul>
<li>Whenever a RefreshEvent is received, you <strong>must</strong> redraw. If you are using a secondary thread to draw, make sure you have some way of passing the message to that thread or you will get flickering.</li>
<li>You can create your own rendering / drawing loop and draw whenever you want. In order to do this, you must create thread to handle the drawing; remember that in the instance of a DetachedEvent you should be able to tell this to stop drawing! If you choose to use something like OpenGL or D3D, you should (sometimes <strong>must</strong>) do all initialization and drawing on the same secondary thread.</li>
<li>Remember that these are windowed plugins, which means that the plugin will &#8220;float&#8221; above everything else on the page.</li>
</ul>
<h2>Handling custom windows messages (your own WINPROC)</h2>
<p>If you need to handle the windows messages directly rather than using the FireBreath abstractions, there are two ways to do this.</p>
<ol>
<li>Extend PluginWindowWin and override the virtual function CustomWinProc<br />
<blockquote><p>This is the most direct way; CustomWinProc will get called for all unhandled messages.  If you don&#8217;t do anything but return false in <a href="http://www.firebreath.org/display/documentation/class+FB+PluginEventSink+HandleEvent" target="_blank">HandleEvent</a>, all messages will be unhandled. To override which object is created for the PluginWindow, implement the <a href="http://www.firebreath.org/display/documentation/file%20FactoryBase.cpp#l00056" target="_blank">createPluginWindowWin</a> method on your Factory to return your custom window class (which <strong>must</strong> extend PluginWindowWin)</p></blockquote>
</li>
<li>Handle <a href="http://www.firebreath.org/display/documentation/class+FB+WindowsEvent">WindowsEvent</a><br />
<blockquote><p>This is the way that we recommend. This can be done by simply adding an EVENTTYPE_CASE line. All of the arguments given in an event loop are available as members of the WindowsEvent object. This makes it possible to pass the object through to the correct place without having a platform-specialized class, if desired.</p></blockquote>
</li>
</ol>
<h1>FireBreath is flexible</h1>
<p>One of the main design goals of FireBreath is to allow a user to extend it however they want to make it work how they are most accustomed; that is why there are so many options. Some restrictions are imposed externally by the nature of browser plugins. In all things, we recommend doing the simplest thing and only override existing classes if you need to &#8212; those are the solutions most likely to break with future versions.</p>
<p>As always, if you have questions or need help, feel free to <a href="http://www.firebreath.org/display/documentation/IRC+Access" target="_blank">drop into the IRC room</a>!</p>
]]></content:encoded>
			<wfw:commentRss>http://colonelpanic.net/2010/11/firebreath-tips-drawing-on-windows/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>FireBreath Tips: Working with Source Control</title>
		<link>http://colonelpanic.net/2010/11/firebreath-tips-working-with-source-control/</link>
		<comments>http://colonelpanic.net/2010/11/firebreath-tips-working-with-source-control/#comments</comments>
		<pubDate>Fri, 19 Nov 2010 23:39:36 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[Browser Plugin Development]]></category>
		<category><![CDATA[FireBreath]]></category>
		<category><![CDATA[best practices]]></category>
		<category><![CDATA[browser plugin]]></category>
		<category><![CDATA[firebreath]]></category>
		<category><![CDATA[source control]]></category>

		<guid isPermaLink="false">http://colonelpanic.net/?p=446</guid>
		<description><![CDATA[FireBreath, Source Control, and You Recently I have been asked repeatedly about how to properly use Source Control systems with FireBreath.  Everyone has their own idea of how this should work, and that&#8217;s fine &#8212; in fact, most of my suggestions you may decide to ignore.  However, I want to put forth what I consider [...]]]></description>
			<content:encoded><![CDATA[<h2>FireBreath, Source Control, and You</h2>
<p>Recently I have been asked repeatedly about how to properly use Source Control systems with FireBreath.  Everyone has their own idea of how this should work, and that&#8217;s fine &#8212; in fact, most of my suggestions you may decide to ignore.  However, I want to put forth what I consider to be the &#8220;4 Best Practices&#8221; for keeping your FireBreath plugin in source control.<span id="more-446"></span></p>
<h3>1. Use Source Control</h3>
<p>I prefer to use Git, myself, with bzr or mercurial as close seconds.  Whatever source control system you prefer, though, I really highly recommend using something.  This isn&#8217;t advice specific to FireBreath, of course; it&#8217;s just good sense.</p>
<h3>2. Move your projects/ directory outside of the FireBreath root</h3>
<h4>Directory Structure</h4>
<p>This was one of the most requested features for a long time, and in 1.2.0 we finally added it. After you use fbgen.py to create your plugin project, move the projects/ dir somewhere outside of the root.  I use the following structure:</p>
<ul>
<li><strong>code/ </strong></li>
<li><strong>code/firebreath/</strong> &#8211; check out Firebreath here, or extract archive from the downloads area</li>
<li><strong>code/fbprojects/</strong> &#8211; place your projects/ directory here, or wherever you want &#8212; it&#8217;s up to you</li>
<li><strong>code/fbprojects/MyPluginProject/</strong> &#8211; this is what fbgen created, originally in firebreath/projects/MyPluginProject/</li>
</ul>
<h4>Generating the project files</h4>
<p>From the code/ folder, you can then <a title="Prep Script docs" href="http://www.firebreath.org/display/documentation/Prep+Scripts" target="_blank">generate your project </a>for XCode on Mac like so:</p>
<pre>./firebreath/prepmac.sh fbprojects fbbuild
</pre>
<p>or if you are on Windows:</p>
<pre>firebreath\prep2010.cmd fbprojects fbbuild
</pre>
<p>Linux users can use prepmake.sh or one of the others.</p>
<p><strong><em>Please note: </em></strong><span style="color: #ff0000;">The Prep scripts are not intended to be run just once.  They should be run on each computer you build on, and they should be run anytime you add new files to your project or change plugin configuration options.  This is how <a href="http://www.firebreath.org/display/documentation/Using+CMake+With+FireBreath" target="_blank">CMake works</a>, and FireBreath plugins rely on CMake to build. You can ignore this advice, but <em><strong>you will regret doing so.</strong></em></span></p>
<h3>3. Don&#8217;t put your build directory in version control</h3>
<p>The build directory should not be in version control.  As many have noted, the paths are all absolute and not relative, and even if you were to fix this it would just make it harder to update FireBreath or change your plugin configuration.</p>
<p>The project files (.vcproj, .xcodeproj, makefiles, etc) <a href="http://www.firebreath.org/display/documentation/Using+CMake+With+FireBreath" target="_blank">are not intended to ever be edited by you</a>.  Resist the urge to do so; I know this is a change for many, but it will simplify your lives.  The only files you should ideally change for project configuration are the cmake files in your project directory.</p>
<h3>4. Don&#8217;t put FireBreath in the same source control tree</h3>
<p>Many people want to keep their own copy of FireBreath internally.  This is, of course, just fine &#8212; it&#8217;s licensed under the New BSD license, so you can do about whatever you want. I strongly recommend that if you decide to do this, keep in in a git clone/fork. That way you can easily submit patches back to the FireBreath project if you make any changes, which means many others will be testing your fixes, and you can also more easily get patches from the FireBreath project into your local copy.</p>
<p>If you decide not to do this, still at least keep FireBreath and your projects seperate, because then you can easily update FireBreath when needed.</p>
<h2>Wrapping up</h2>
<p>I hope that clears up some things on this tricky topic. If you have any suggestions on how things can be improved, please feel free to let us know!  Of course, if your suggestion is &#8220;Don&#8217;t use cmake&#8221;, please make sure you have taken the time to understand <a href="http://www.firebreath.org/display/documentation/Using+CMake+With+FireBreath#UsingCMakeWithFireBreath-Problemssolvedusingcmake" target="_blank">why we are using it </a>and have solutions for all the many problems that it solves =] That particular dead horse has been beaten nearly to oblivion.</p>
<p>Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://colonelpanic.net/2010/11/firebreath-tips-working-with-source-control/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>FireBreath Tips: Dealing with JSAPI objects</title>
		<link>http://colonelpanic.net/2010/11/firebreath-tips-dealing-with-jsapi-objects/</link>
		<comments>http://colonelpanic.net/2010/11/firebreath-tips-dealing-with-jsapi-objects/#comments</comments>
		<pubDate>Wed, 10 Nov 2010 05:25:04 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[Browser Plugin Development]]></category>
		<category><![CDATA[FireBreath]]></category>
		<category><![CDATA[featured]]></category>

		<guid isPermaLink="false">http://colonelpanic.net/?p=421</guid>
		<description><![CDATA[FireBreath Tips and Tricks I have decided to start writing some tutorial type information for solving specific problems using FireBreath.  I don&#8217;t know how often I will post on this topic, but my goal is to do a series of short &#8220;tips and tricks&#8221; posts whenever I think of something that may not be obvious [...]]]></description>
			<content:encoded><![CDATA[<h1>FireBreath Tips and Tricks</h1>
<p>I have decided to start writing some tutorial type information for solving specific problems using FireBreath.  I don&#8217;t know how often I will post on this topic, but my goal is to do a series of short &#8220;tips and tricks&#8221; posts whenever I think of something that may not be obvious to someone starting out with the framework.</p>
<p>This post will discuss some best practices for using JSAPI objects.  Feel free to request future articles in the comments.<br />
<span id="more-421"></span></p>
<h1>boost::shared_ptr</h1>
<p>The <a href="http://www.firebreath.org/display/documentation/typedef+FB+JSAPIPtr" target="_blank">FB::JSAPIPtr</a> type in FireBreath is just a convenience alias &#8212; mostly because I&#8217;m lazy &#8212; for boost::shared_ptr&lt;<a href="http://www.firebreath.org/display/documentation/class+FB+JSAPI" target="_blank">FB::JSAPI</a>&gt;.  This is very important to understand, because if you try to use a normal pointer to your <a href="http://www.firebreath.org/display/documentation/class+FB+JSAPI" target="_blank">JSAPI </a>derived objects without using shared_ptr, you&#8217;re likely to have your object disappear out from under you.</p>
<h2>How it works</h2>
<p>Basically when you create a <a href="http://www.boost.org/doc/libs/1_44_0/libs/smart_ptr/shared_ptr.htm" target="_blank">boost::shared_ptr </a>object, it allocates a small structure for holding two reference counts.  The first and most important is the use_count.  The second is the weak_count, and we&#8217;ll discuss that later.  The important thing to know is that every time you assign your shared_ptr to another, it increments the use_count.  Whenever a shared_ptr gets destroyed / goes out of scope, it decrements it.  Once that count hits 0, the object inside the shared_ptr goes away.</p>
<p>This is critical in FireBreath for JSAPI objects because we don&#8217;t know when the Browser will let go of our objects, and we can&#8217;t be deleting them while the browser still has a reference.</p>
<h2>Creating objects</h2>
<p>The best way to create a new object is to put it directly into a JSAPIPtr (or other shared_ptr).  You can (and should) also use boost::make_shared to be explicit. For example:</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;">FB<span style="color: #008080;">::</span><span style="color: #007788;">JSAPIPtr</span> myAPI<span style="color: #008000;">&#40;</span>boost<span style="color: #008080;">::</span><span style="color: #007788;">make_shared</span><span style="color: #000080;">&lt;</span>FBTestPluginAPI<span style="color: #000080;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre>
</div>
</div>
<p>This creates a new FBTestPluginAPI object and stuffs it into the myAPI JSAPIPtr.  Now, usually you&#8217;ll be passing something into the constructor, so it&#8217;ll look more like this:</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;">FB<span style="color: #008080;">::</span><span style="color: #007788;">JSAPIPtr</span> myAPI<span style="color: #008000;">&#40;</span>boost<span style="color: #008080;">::</span><span style="color: #007788;">make_shared</span><span style="color: #000080;">&lt;</span>FBTestPluginAPI<span style="color: #000080;">&gt;</span><span style="color: #008000;">&#40;</span>FB<span style="color: #008080;">::</span><span style="color: #007788;">ptr_cast</span><span style="color: #000080;">&lt;</span>FBTestPlugin<span style="color: #000080;">&gt;</span><span style="color: #008000;">&#40;</span>shared_ptr<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>, m_host<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre>
</div>
</div>
<p>Of course, you may want a shared_ptr that allows you better access to your object.  If so, you can also do this:</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;">boost<span style="color: #008080;">::</span><span style="color: #007788;">shared_ptr</span><span style="color: #000080;">&lt;</span>FBTestPluginAPI<span style="color: #000080;">&gt;</span> myAPI<span style="color: #008000;">&#40;</span>boost<span style="color: #008080;">::</span><span style="color: #007788;">make_shared</span><span style="color: #000080;">&lt;</span>FBTestPluginAPI<span style="color: #000080;">&gt;</span><span style="color: #008000;">&#40;</span>FB<span style="color: #008080;">::</span><span style="color: #007788;">ptr_cast</span><span style="color: #000080;">&lt;</span>FBTestPlugin<span style="color: #000080;">&gt;</span><span style="color: #008000;">&#40;</span>shared_ptr<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>, m_host<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre>
</div>
</div>
<p>You can return this in a function that returns FB::JSAPIPtr and it will cast up-cast it implicitly just like a normal pointer.</p>
<p>There are a few unexpected things here:</p>
<ul>
<li><a href="http://www.firebreath.org/display/documentation/class+FB+PluginEventSink+shared_ptr" target="_blank">shared_ptr() </a>- return a boost::shared_ptr&lt;PluginEventSink&gt; object, which is the  ultimate base class for all Plugin objects (PluginCore derives from  it).</li>
<li><a href="http://www.firebreath.org/display/documentation/function+FB+ptr_cast" target="_blank">FB::ptr_cast</a>&lt;FBTestPlugin&gt;(shared_ptr()) &#8211; FB::ptr_cast does a dynamic cast of a shared_ptr. This is basically an alias for boost::dynamic_ptr_cast, which is more of a pain to type.</li>
<li>m_host &#8211; this is the BrowserHost object, which is useful to have around.  Think of it as a dependency injection container that gives you access to the browser functions and tools.</li>
</ul>
<p>An important thing to realize here is that we aren&#8217;t storing the shared_ptr to the plugin object inside the JSAPI class. Instead, we&#8217;ll use a <a href="http://www.boost.org/doc/libs/1_44_0/libs/smart_ptr/weak_ptr.htm" target="_blank">boost::weak_ptr</a>.  A weak_ptr uses the other reference count, and the reference counting structure is not destroyed until both the use_count and weak_count hit 0.  To use the plugin from a weak_ptr, you use the .lock() method on the weak_ptr to get the shared_ptr for that class, which prevents it from being destroyed while you&#8217;re holding it. However, when you&#8217;re not using the plugin, it can be destroyed when the time comes.</p>
<p>This is important because the Plugin object usually has a reference to the API object, and we really don&#8217;t want circular references =]</p>
<p>Best practices state that you should always check to see if .lock() returns a NULL pointer indicating that the plugin has gone away.  We recommend a getPlugin() method on your API object like this:</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;">boost<span style="color: #008080;">::</span><span style="color: #007788;">shared_ptr</span><span style="color: #000080;">&lt;</span>FBTestPlugin<span style="color: #000080;">&gt;</span> FBTestPluginAPI<span style="color: #008080;">::</span><span style="color: #007788;">getPlugin</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    boost<span style="color: #008080;">::</span><span style="color: #007788;">shared_ptr</span><span style="color: #000080;">&lt;</span>FBTestPlugin<span style="color: #000080;">&gt;</span> plugin <span style="color: #000080;">=</span> m_pluginWeak.<span style="color: #007788;">lock</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">!</span>plugin<span style="color: #008000;">&#41;</span>
        <span style="color: #0000ff;">throw</span> FB<span style="color: #008080;">::</span><span style="color: #007788;">script_error</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;The plugin object has been destroyed&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">return</span> plugin<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre>
</div>
</div>
<p>When you need to use it, simply call getPlugin() and make sure you let go of the resulting shared_ptr when you&#8217;re done.</p>
<h1>Storing JSAPI objects</h1>
<p>If you want to store an array of JSAPI objects, that&#8217;s just fine&#8230; but make sure you store them in an array of boost::shared_ptrs or boost::weak_ptrs depending on whether you want storing them to keep them around as long as your list is around.</p>
<h1>Casting JSAPI objects</h1>
<p>If you have a FB::JSAPIPtr and you want to cast it to your plugin API type, you can use either boost::dynamic_pointer_cast<type> or FB::ptr_cast<type>.  For example:</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;">boost<span style="color: #008080;">::</span><span style="color: #007788;">shared_ptr</span><span style="color: #000080;">&lt;</span>FBTestPluginAPI<span style="color: #000080;">&gt;</span> api<span style="color: #008000;">&#40;</span> FB<span style="color: #008080;">::</span><span style="color: #007788;">ptr_cast</span><span style="color: #000080;">&lt;</span>FBTestPluginAPI<span style="color: #000080;">&gt;</span><span style="color: #008000;">&#40;</span>m_api<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre>
</div>
</div>
<h1>That&#8217;s it!</h1>
<p>That&#8217;s it! The #1 thing to remember is to <em><strong>NEVER EVER EVER</strong></em> store or pass around a JSAPI object as a raw pointer.  That&#8217;ll get you in trouble =]</p>
]]></content:encoded>
			<wfw:commentRss>http://colonelpanic.net/2010/11/firebreath-tips-dealing-with-jsapi-objects/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>A year in the life of an open source project &#8211; FireBreath 1.2 released</title>
		<link>http://colonelpanic.net/2010/09/a-year-in-the-life-of-an-open-source-project/</link>
		<comments>http://colonelpanic.net/2010/09/a-year-in-the-life-of-an-open-source-project/#comments</comments>
		<pubDate>Wed, 15 Sep 2010 21:48:03 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[Browser Plugin Development]]></category>
		<category><![CDATA[FireBreath]]></category>
		<category><![CDATA[ActiveX]]></category>
		<category><![CDATA[firebreath]]></category>
		<category><![CDATA[IDispatch]]></category>
		<category><![CDATA[NPAPI]]></category>
		<category><![CDATA[open source project]]></category>

		<guid isPermaLink="false">http://colonelpanic.net/?p=341</guid>
		<description><![CDATA[Starting a new open source project Beginning an open source project is probably one of the more cliché things to do in the industry. How many open source projects are out there that have almost no support, haven&#8217;t been updated in years, or are just plain useless? This is the story of how I created FireBreath [...]]]></description>
			<content:encoded><![CDATA[<h2>Starting a new open source project</h2>
<table cellspacing="0" cellpadding="0" align="right">
<tbody>
<tr>
<td>
<p style="text-align: center;"><a title="FireBreath home page" href="http://www.firebreath.org" target="_blank"><img class="alignnone size-full wp-image-343" title="FirebreathHeading" src="http://colonelpanic.net/wp-content/uploads/2010/09/Screen-shot-2010-09-15-at-1.42.00-PM.png" alt="" width="288" height="52" /></a></p>
<p style="text-align: center;"><a title="FireBreath home page" href="http://www.firebreath.org" target="_blank"><img class="alignnone size-full wp-image-342" title="FireBreathActivity Sep152010" src="http://colonelpanic.net/wp-content/uploads/2010/09/Screen-shot-2010-09-15-at-1.38.59-PM.png" alt="" width="250" height="153" /></a></p>
<div align="center"><script type="text/javascript" src="http://www.ohloh.net/p/442122/widgets/project_thin_badge.js"></script></div>
</td>
</tr>
</tbody>
</table>
<p>Beginning an open source project is probably one of the more cliché things to do in the industry. How many open source projects are out there that have almost no support, haven&#8217;t been updated in years, or are just plain useless?</p>
<p>This is the story of how I created <a title="FireBreath home page" href="http://www.firebreath.org" target="_blank">FireBreath</a> &#8212; and how it has remained a &#8220;high activity&#8221; project for a full year on Google Code. If you are short on time, I recommend skipping to the end of this article and reading the &#8220;Things I have learned&#8221; part.</p>
<h2><span id="more-341"></span>The need for the project</h2>
<p>A year ago I had an idea for a project that I felt would be benefited most &#8212; both in terms of project development and for anyone who would use it &#8212; by making the project open source. I wanted to create a framework for creating browser plugins. The problem? I just didn&#8217;t have the time to do it on my own time.</p>
<p>My big break came when a company out of California contacted me about building them a cross platform browser plugin framework. Now, let me explain a bit about my schedule: I was working full time for Move Networks, taking 10 credit hours at Utah Valley University, and my firstborn son was about 6 months old.</p>
<p>After some consideration, I agreed to do the project; my one stipulation was that they had to agree to allow me to release the code as open source. That week, I created the <a title="FireBreath home page" href="http://www.firebreath.org" target="_blank">Google Code project for FireBreath</a> (a name I selected randomly from a bunch I brainstormed) and uploaded the initial code &#8212; which was still mostly code generated by Visual Studio.</p>
<p>I also posted my <a title="Call for Plugin Developers" href="http://colonelpanic.net/2009/09/call-for-plugin-developers/">Call for Plugin Developers</a> here on colonelpanic and posted links to it on the NPAPI newsgroup.</p>
<h2>The growth of the project</h2>
<h3>Getting started</h3>
<p>I created the Google Code project September 16, 2009 &#8212; a year ago. Obviously, the project was ambitious; to provide a framework that not only allowed you to write plugins that would work in both Firefox and Internet Explorer, but to make it easy to simultaneously write them for Windows, Mac, and Linux &#8212; and to make it easier to write a plugin using FireBreath than straight NPAPI or ActiveX. I don&#8217;t care who you are or how brilliant you are, no one person by themselves can make a truly great project.</p>
<h3>First Contributors</h3>
<p>Several people expressed some interest, but then quickly disappeared (and in some cases simply stopped responding to emails.) <strong>Georg Fritzsche</strong> contacted me with some ideas about using C++ meta-programming to simplify the JSAPI interface. I&#8217;ll be honest &#8212; when I first read his explanation of what he wanted to do, my first thought was &#8220;This is crazy, and there is no way it can get simpler than it is.&#8221; However, it was one of the first direct offers of help that I&#8217;d seen, so I told him to share some more details with me on the mailing list and I&#8217;d look at what he had.</p>
<p>Nearly two weeks later, I had basically forgotten Georg and his suggestions that he could improve my Javascript interface when suddenly he posted a set of patches to the list. What was more, when I took a close look I realized that his ideas fit perfectly with the approach I was taking, and furthermore that I hadn&#8217;t the slightest idea how it worked. Georg&#8217;s understanding of meta-programming is still so far beyond mine that I ask him for help frequently whenever I mess with it. His &#8220;crazy&#8221; contributions now make up the JSAPIAuto class that nearly all Javascript API objects in FireBreath are built on.</p>
<p>From that point onward, Georg quickly made himself invaluable to the project; he wasn&#8217;t getting paid for his work (though he deserves it), so he didn&#8217;t spend as much time as I did, but it wasn&#8217;t too long before I just made him an owner of the project and started checking with him when I made changes. FireBreath would not be what it is without his early contributions, as well as those he has continued to make since then.</p>
<h3>First releases</h3>
<p>In December 2009 I posted <a title="FireBreath is ready for testing" href="http://colonelpanic.net/2009/12/firebreath-ready-for-testing/">FireBreath is Ready for Testing</a> and posted a link on the NPAPI newsgroup. We now felt that FireBreath was far enough along that you could build a Windows plugin with it &#8212; although still no support for Linux or Mac. We started to see some real interest in the project outside the company I was working for: I had a couple people contact me asking for subcontracting help with FireBreath, and several individuals joined the project and asked about getting Linux and Mac support going.</p>
<p>Once there were some developers expressing interest, I gave them what information I could, and then in a fit of insanity took a few hours one night and got the initial support for Linux implemented. A few weeks later I did the same for Mac, after having a company contact both Georg and myself about possibly having us do a Mac plugin for them, although that never panned out.</p>
<p>Another piece, contributed initially by Ben Loveridge and Jarom Loveridge (brothers), is the &#8220;fbgen&#8221; tool &#8212; a tool that creates a skeleton plugin project for use with FireBreath. I believe this contributed significantly to the initial uptake of FireBreath.</p>
<h3>Period of lower development</h3>
<p>As all contracts inevitably do, the contract I was under for 10 hours a week of development on the browser plugin framework came to an end at the end of January 2010. I could no longer justify spending much time on FireBreath, but I knew it still wasn&#8217;t done. FireBreath lacked support for streams (HTTP downloads), good Mac and Linux windowing and system event integration, and threading support, to name just a few deficiencies.</p>
<p>However, the seeds had been planted: this really was a project that had the potential to save people a lot of time. Slowly at first, but then a little bit more as people found the project, developers started using FireBreath and contributing fixes for things that were missing. Georg and I continued to monitor the mailing list and answer questions, though neither of us had much time. But, little by little, users started to contribute fixes and enhancements for the missing functionality.</p>
<h3>The project is picking up</h3>
<p>One of the funnest things to do with this project has been to watch the Google Analytics reports for the project. In January of 2010 there were about 900 hits to the FireBreath website; last month there were about 2500. Granted, this isn&#8217;t a lot compared to large websites, but for a small open source project it isn&#8217;t bad.</p>
<p>One month that was particularly fun was when ajaxian.com put up a (very) short blog post about us. There were 4000 hits that day. That month had 10,000. We are also now up to about 100 members on the mailing list.</p>
<p>The latest and most encouraging development is that a little company in California called Facebook (heard of them?) has hired me as a contractor and is sponsoring some development with FireBreath. I can&#8217;t comment yet on what they may do with it, but the upshot is that I&#8217;m back to spending some real time on the project, and there are several nice features (like Unicode support) that 1.2 has that were contributed by Facebook.</p>
<p>Today we released <strong>FireBreath 1.2</strong>. It contains more features than any other browser plugin creation tool that I know of, fully supports Unicode characters both in processing and in method/property names, simplifies many tasks that would otherwise be extraordinarily painful, and allows you to create a basically cross-platform browser plugin in 10 minutes (if you have Python and Cheetah installed &#8212; although we are actively looking into removing the Cheetah dependency).</p>
<h2>Lessons Learned</h2>
<p>There are a lot of lessons to be learned from the experience of starting an open source project. Though its user-base may be small, I consider FireBreath to be a successful small project.</p>
<p>In no particular order, here are some things that I have learned:</p>
<ul>
<li>Once the initial feature set is in, it is more important to help newcomers than it is to code new features
<ul>
<li>Coding new features is more fun, but if you have time for just one &#8212; help people use your project</li>
</ul>
</li>
<li>Don&#8217;t be too obnoxious, but don&#8217;t be shy about telling people about your project.
<ul>
<li>Post short, tasteful mentions of your project on forums, preferably while you are helping someone</li>
</ul>
</li>
<li>Don&#8217;t ever write off someone&#8217;s idea without hearing it first
<ul>
<li>I can&#8217;t even remember how many times I have heard an idea that I initially thought &#8220;Huh, that wouldn&#8217;t work well,&#8221; but on further inspection turned out to be a great improvement. Almost invariably, these are the types of improvements that make the project glow.</li>
</ul>
</li>
<li>There is always something about your project that newcomers don&#8217;t appreciate or understand &#8212; be patient with them
<ul>
<li>The most criticized part of FireBreath&#8217;s design is that the project system relies on CMake. Windows developers in particular hate this. However, there are reasons; my standard response is &#8220;If you have a better idea that solves &lt;problems solved by CMake&gt;, please share.&#8221; I have never had any takers.</li>
</ul>
</li>
<li>Take the time to help others who are working in the same area
<ul>
<li>Competition is great, but if you&#8217;re really good at what you do, you don&#8217;t need to worry about helping others solve trivial problems. One of the top referrers for FireBreath is <a href="http://stackoverflow.com" target="_blank">stackoverflow</a>, where Georg and I have both answered many questions (often with links to FireBreath)</li>
</ul>
</li>
<li>Use a distributed version control system like Mercurial, Git, or Bzr if you can
<ul>
<li>Yes, I know that everyone knows how to use subversion; but when you have people who want to keep their own clone of your code and then be able to easily contribute back, distributed versioning tools are invaluable. (Oh, and that&#8217;s exactly what you want people to do.)</li>
</ul>
</li>
<li>Create an IRC chatroom
<ul>
<li>I was hesitant, but it has been a great way to interact with the users of the project</li>
</ul>
</li>
<li>Use the most permissive license type that makes sense
<ul>
<li>We started out using EPL, but found that many didn&#8217;t want to use our codebase because of licensing; we eventually switched to BSD, and people contribute back simply because they know their code will work better if their changes are vetted and tested by more people. In a framework, this makes sense; for an application, it may not.</li>
</ul>
</li>
</ul>
<h2>Special Thanks To</h2>
<p>While Georg has made some particularly valuable contributions to the project &#8212; contributing more code than anyone besides me &#8212; there are many others who have donated code snippets and time. Here is an incomplete list of people that I could find doing some simple searches in no particular order:</p>
<ul>
<li><strong>Anson MacKeracher (amackera)</strong> &#8211; Built out Georg&#8217;s Mac drawing code to a fully usable state; if it&#8217;s Mac-specific and Anson didn&#8217;t write it, he still knows how it works.</li>
<li><strong>nitrogenycs</strong> &#8211; Streams support, and many other small bugfixes.</li>
<li><strong>Kalev Lember</strong> &#8211; Numerous small fixes, one of the main testers and tweakers for linux.</li>
<li><strong>Antti Andreimann</strong> <strong>(anttix)</strong>- Helped to build the initial XEmbed support for linux, and wrote EvaluateJavascript.</li>
<li><strong>schmoo</strong> &#8211; Provided the initial patch to support Visual Studio 2010 as well as other minor fixes.</li>
<li><strong>Schnapple</strong> &#8211; Miscellaneous bugfixes.</li>
<li><strong>Ben and Jarom Loveridge</strong> &#8211; One started and one finished the fbgen tool. Jarom is working to remove the Cheetah dependency.</li>
<li><strong>Kevin Menard (nirvdrum) </strong>- Testing, ideas, and support.</li>
</ul>
<p>And, of course, thanks to everyone who uses FireBreath; you make this project successful!</p>
<hr />If you would like to keep track of what FireBreath is doing, you can <a href="http://twitter.com/thefirebreath">Follow us on Twitter</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://colonelpanic.net/2010/09/a-year-in-the-life-of-an-open-source-project/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Get help for browser plugins and firebreath</title>
		<link>http://colonelpanic.net/2010/09/get-help-for-browser-plugins-and-firebreath/</link>
		<comments>http://colonelpanic.net/2010/09/get-help-for-browser-plugins-and-firebreath/#comments</comments>
		<pubDate>Tue, 07 Sep 2010 21:58:10 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[Browser Plugin Development]]></category>
		<category><![CDATA[FireBreath]]></category>

		<guid isPermaLink="false">http://colonelpanic.net/?p=338</guid>
		<description><![CDATA[Having problems? The comments on this blog are full of questions particularly about browser plugins, and even more specifically about NPAPI plugins.  Now, I don&#8217;t mind helping people out at all; that&#8217;s how we all learn.  However, in an effort to help everyone help each other, I wanted to bring the IRC chat room for [...]]]></description>
			<content:encoded><![CDATA[<h2>Having problems?</h2>
<p>The comments on this blog are full of questions particularly about browser plugins, and even more specifically about NPAPI plugins.  Now, I don&#8217;t mind helping people out at all; that&#8217;s how we all learn.  However, in an effort to help everyone help each other, I wanted to bring the IRC chat room for FireBreath to everyone&#8217;s attention.</p>
<h2>IRC Chatroom</h2>
<p>To date, there are about 4 of us who are usually in the chatroom, and we discuss more than just FireBreath.  FireBreath is a project that combines experience with NPAPI, ActiveX/COM, and cross platform development in a fairly unique way.  We benefit from interaction with anyone working on any of these technologies.  What I&#8217;m trying to say is, feel free to bring your plugin questions of *any* type to that room.  We won&#8217;t do your work for you and we don&#8217;t promise to have an answer to every question, but we have a pretty decent understanding of the subject between us.</p>
<h2>Where it is</h2>
<p>The server is irc.freenode.net.  The channel is #firebreath.</p>
<p>See you there.</p>
]]></content:encoded>
			<wfw:commentRss>http://colonelpanic.net/2010/09/get-help-for-browser-plugins-and-firebreath/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Browser Plugins vs Extensions – the difference</title>
		<link>http://colonelpanic.net/2010/08/browser-plugins-vs-extensions-the-difference/</link>
		<comments>http://colonelpanic.net/2010/08/browser-plugins-vs-extensions-the-difference/#comments</comments>
		<pubDate>Tue, 10 Aug 2010 13:42:01 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[ActiveX]]></category>
		<category><![CDATA[Browser Plugin Development]]></category>
		<category><![CDATA[FireBreath]]></category>
		<category><![CDATA[NPAPI]]></category>
		<category><![CDATA[bho]]></category>
		<category><![CDATA[browser plugin]]></category>
		<category><![CDATA[extension]]></category>

		<guid isPermaLink="false">http://colonelpanic.net/?p=312</guid>
		<description><![CDATA[Overloaded terms One of the least understood concepts in the Browser Plugin world is &#8212; browser plugins.  What they are, and even more: what they are not.  Probably at least once a week I answer a question somewhere on a forum or on the comments on this blog and say &#8220;You can&#8217;t do that with [...]]]></description>
			<content:encoded><![CDATA[<h2>Overloaded terms</h2>
<p>One of the least understood concepts in the Browser Plugin world is &#8212; browser plugins.  What they are, and even more: what they are not.  Probably at least once a week I answer a question somewhere on a forum or on the comments on this blog and say &#8220;You can&#8217;t do that with a plugin; you need an extension&#8221;.</p>
<p>Many people confuse plugins and extensions in the browser world. They sound like they should be the same thing, but in fact they are very different.</p>
<h2>What you can do with a plugin</h2>
<p>A plugin is, quite simply, a third party library that &#8220;plugs in&#8221; to the browser that can be embedded inside a web page using an &lt;embed&gt; tag or a &lt;object&gt; tag.  Many of them then draw pretty pictures or animations, though that&#8217;s not required.  Many allow you to talk to them through javascript, though that&#8217;s not required.  In short, a plugin affects only a specific page in which it is placed.</p>
<p>Examples of common plugins include:</p>
<ul>
<li><span id="more-312"></span>Macromedia Flash</li>
<li>Microsoft Silverlight</li>
<li>Apple Quicktime</li>
<li>Adobe Reader (at least this includes a plugin in addition to the rest of the application)</li>
</ul>
<p>Some plugins respond to a mime type and can run in place of the page, such as Adobe Reader, which allows you to view PDF files in your web browser.  Again, however, it affects only that page, and no others.  In Firefox, Chrome, Opera, and Safari, these plugins are usually called &#8220;NPAPI plugins&#8221;, since they are written using the <a title="NPAPI on wikipedia" href="http://en.wikipedia.org/wiki/NPAPI">NPAPI</a>.  In Safari, you could also use a <a href="http://developer.apple.com/mac/library/documentation/InternetWeb/Conceptual/WebKit_PluginProgTopic/WebKitPluginTopics.html">Webkit Plugin</a>.  In Internet Explorer you would do this with an ActiveX Control.</p>
<h2>What a plugin cannot do</h2>
<p>Plugins have to either handle a mime type or be embedded into a web page.  They don&#8217;t get put there automatically. They don&#8217;t create toolbars.  They don&#8217;t affect browser menus.  They don&#8217;t know about tabs, or even about other pages in the same browser process.  They don&#8217;t make coffee, tea, or hot chocolate, though they could be written to control an external appliance to do so if you really wanted.  They don&#8217;t automatically process the content of every web page loaded.</p>
<p>&#8220;But wait!&#8221; I hear you all cry.  &#8220;We have seen these magical things done! (well, except the hot chocolate machine)&#8221;</p>
<p>&#8220;Yes,&#8221; I reply.  &#8220;Those are extensions.&#8221;</p>
<h2>Extensions</h2>
<p>Extensions, or &#8220;add-ons&#8221;, can often do these magical things.  They can add onto the browser UI, process pages that the browser loads.  They do all sorts of things.  However, they are not the same thing as plugins; they affect the web browser itself, not really the page.  They may affect a page as well, of course.  In fact, you can even put a plugin inside an extension, at least in Firefox.  However, if you write an extension for Firefox, you&#8217;ll probably have to write it again for Chrome, Safari, and IE&#8230; one for each.  Perhaps there is a framework out there for writing portable extensions, though.  It&#8217;s not really my area of expertise, so I don&#8217;t know.</p>
<p>Examples of extensions / add-ons:</p>
<ul>
<li><a href="http://www.downthemall.net/">DownThemAll</a> for Firefox</li>
<li><a href="http://getfirebug.com/" target="_blank">Firebug</a> for Firefox</li>
<li><a href="https://chrome.google.com/extensions/detail/kcnhkahnjcbndmmehfkdnkjomaanaooo" target="_blank">Google Voice extension</a> for Chrome</li>
<li><a href="http://kanab.hys.cz/let-there-be-comic-sans/">Let there be Comic Sans</a> for Safari</li>
</ul>
<p>And many, many, many more.  Extensions can be written in different languages depending on the browser.  In Firefox you can write them in C++ or javascript, and on Internet Explorer you write them as special ActiveX controls called <a href="http://en.wikipedia.org/wiki/Browser_Helper_Object">Browser Helper Objects</a>, or BHOs.</p>
<h2>An extension could contain a plugin, but a plugin can&#8217;t contain an extension</h2>
<p>One very common way to install a plugin in Firefox is to use a .xpi file.  <strong><em>This is an extension</em></strong>.  It may have a NPAPI plugin inside of it, but it is still an extension.  It will not work on other web browsers, even though your NPAPI plugin may work perfectly fine on Chrome and Safari if installed in another way.</p>
<p>Conversely, a plugin by nature does not include an extension.</p>
<h2>FireBreath</h2>
<p>Nearly a year ago now I began a project called FireBreath, which is a cross-platform browser plugin architecture.  FireBreath is, frankly, awesome. You can literally get a plugin up and going in under 10 minutes if you already have everything installed.  That means you can spend your time doing other more important things, like actually developing your functionality, rather than spending all your time figuring out how to deal with the plugin APIs.</p>
<p>That said, FireBreath is a cross-platform browser <span style="text-decoration: underline;"><em><strong>PLUGIN</strong></em></span> framework.  It does not create extensions.  It will never be able to create extensions.  If you need an extension, you need something else.</p>
<h2>When not to use a plugin</h2>
<p>Finally, and this is a topic that people seem to think is a little strange coming from me, there are many cases when it is not a good idea to use a browser plugin.  In fact, a good rule of thumb is that if you can do what you need to do without one, don&#8217;t use one.</p>
<p>Why?</p>
<ul>
<li>There are no really good ways to install browser plugins that will work 100% of the time
<ul>
<li>XPI install only works on one profile in firefox</li>
<li>CAB install only works in Internet Explorer and is sometimes a little unreliable</li>
<li>ClickOnce works only in Windows and only if .Net is installed</li>
<li>Java installers only work reliably and consistently on Mac OS</li>
<li>MSI or EXE installers while being the best method IMHO require a little more work on the part of the user, and the average user is&#8230; less savvy than you are, shall we say.</li>
</ul>
</li>
<li>Plugins have to take into account a large range of hardware types
<ul>
<li>If you use graphics libraries such as OpenGL or DirectX keep in mind that every graphics card works a little differently with these technologies.  You will run into weird cases where your plugin doesn&#8217;t work on someone&#8217;s computer.  If your luck is like mine, that computer will belong to an executive at a fortune 500 company (yes, that happened to me.  no, it wasn&#8217;t fun)</li>
</ul>
</li>
<li>Plugins don&#8217;t work until they have been installed
<ul>
<li>This is a major limiting factor to uptake of your site.  Many users don&#8217;t want to install yet another plugin on their machine, and many get lost in the incredibly complicated task of downloading and running the installer.</li>
</ul>
</li>
</ul>
<h2>Moving on</h2>
<p>If all of those things haven&#8217;t convinced you that what you want isn&#8217;t actually a browser plugin &#8212; great!  That&#8217;s why I&#8217;m still posting about this stuff.  Despite all the reasons not to use a plugin, there are also a lot of cases where it&#8217;s a good idea. Browesr plugin development can be a lot of fun!  Good luck!</p>
]]></content:encoded>
			<wfw:commentRss>http://colonelpanic.net/2010/08/browser-plugins-vs-extensions-the-difference/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Firefox 3.6 has removed support for XPCOM plugins!</title>
		<link>http://colonelpanic.net/2010/01/firefox-3-6-has-removed-support-for-xpcom-plugins/</link>
		<comments>http://colonelpanic.net/2010/01/firefox-3-6-has-removed-support-for-xpcom-plugins/#comments</comments>
		<pubDate>Fri, 29 Jan 2010 16:19:02 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[ActiveX]]></category>
		<category><![CDATA[Browser Plugin Development]]></category>
		<category><![CDATA[NPAPI]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[mozilla]]></category>
		<category><![CDATA[npruntime]]></category>
		<category><![CDATA[xpcom]]></category>

		<guid isPermaLink="false">http://colonelpanic.net/2010/01/firefox-3-6-has-removed-support-for-xpcom-plugins/</guid>
		<description><![CDATA[Most who are deep in the plugin world already know this, but I will repeat it quickly for those who only dabble: Firefox 3.6 has removed support for XPCOM plugins. This means that if you use XPCOM for your javascript interface (i.e. you have an IDL file on your npapi plugin, you us nsScriptablePeer, etc) [...]]]></description>
			<content:encoded><![CDATA[<p>Most who are deep in the plugin world already know this, but I will repeat it quickly for those who only dabble:</p>
<p>Firefox 3.6 has removed support for XPCOM plugins.</p>
<p>This means that if you use XPCOM for your javascript interface (i.e. you have an IDL file on your npapi plugin, you us nsScriptablePeer, etc) your plugin will no longer be able to communicate with javascript in Firefox 3.6.</p>
<p>Thus I repeat advice that I have given in the past:  Never, never, *never*, *ever* use XPCOM for your javascript interface in your plugin.</p>
<p>There might conceivably be reasons to use other aspects of XPCOM in a plugin, that might even work in other browsers.  At present, I don&#8217;t know of them.  Please enlighten me if there are (cookies?).</p>
<p>Oh, yeah, and FireBreath now has linux and mac support (experimental) as well as windows support (stable).  Come join the fun.  http://firebreath.googlecode.com</p>
<p>Thank you. :-P</p>
]]></content:encoded>
			<wfw:commentRss>http://colonelpanic.net/2010/01/firefox-3-6-has-removed-support-for-xpcom-plugins/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>Cross-Browser Scripting – Part one</title>
		<link>http://colonelpanic.net/2009/12/cross-browser-scripting-part-one/</link>
		<comments>http://colonelpanic.net/2009/12/cross-browser-scripting-part-one/#comments</comments>
		<pubDate>Mon, 28 Dec 2009 05:31:04 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[ActiveX]]></category>
		<category><![CDATA[Browser Plugin Development]]></category>
		<category><![CDATA[FireBreath]]></category>
		<category><![CDATA[NPAPI]]></category>
		<category><![CDATA[browser plugin]]></category>
		<category><![CDATA[Common Scripting Interface]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[IDispatch]]></category>
		<category><![CDATA[IDispatchEx]]></category>
		<category><![CDATA[npobject]]></category>
		<category><![CDATA[npruntime]]></category>
		<category><![CDATA[plugin]]></category>

		<guid isPermaLink="false">http://colonelpanic.net/?p=117</guid>
		<description><![CDATA[The Problem: I&#8217;ll be up-front about something here; I don&#8217;t particularly like ActiveX.  I understand a lot of the reasons for creating it, and I won&#8217;t go so far as to claim that it shouldn&#8217;t exist or anything like that; in fact, it does very well for certain types of things.  The main thing I [...]]]></description>
			<content:encoded><![CDATA[<h1>The Problem:</h1>
<p>I&#8217;ll be up-front about something here; I don&#8217;t particularly like ActiveX.  I understand a lot of the reasons for creating it, and I won&#8217;t go so far as to claim that it shouldn&#8217;t exist or anything like that; in fact, it does very well for certain types of things.  The main thing I don&#8217;t like about it is the complexity; it&#8217;s not something that you just pick up and start using one day.  You have to do a lot of research to understand what is happening, and though I&#8217;ve been working on ActiveX Controls hosted in Internet Explorer for over a year now, there is still a lot I don&#8217;t understand about what is really happening under the covers.</p>
<p>Because of this, I am a big fan of NPAPI.  I think it&#8217;s a great technology.  It&#8217;s simple.  It&#8217;s straightforward.  It provides an interface for one purpose, and that is to allow 3rd party developers to write browser plugins.  It&#8217;s great.  But, there is a problem: in my world, you can&#8217;t just say &#8220;I like Firefox better than IE, so I&#8217;m not going to support IE.&#8221;  Why?  I will make no claims here about security, usability, viability, or even disability of any browsers.  I will simply refer to one statistic: according to the <a title="W3Schools browser stats" href="http://www.w3schools.com/browsers/browsers_stats.asp" target="_blank">w3schools browser statistics</a>, Internet Explorer accounted for over 25% of the total web traffic every month last year.</p>
<p>So we find the classic challenge of all browser plugin developers: Internet Explorer only supports ActiveX controls, other browsers support NPAPI, and a plugin written for one isn&#8217;t neccesarily going to be easy to just port to the other.  Thus was born <a title="Firebreath overview" href="http://colonelpanic.net/2009/12/firebreath-ready-for-testing/">FireBreath</a>, in an attempt to solve this issue.  Today, however, I want to address only one piece of the solution that we use in FireBreath:  How to create a scripting interface that will be &#8220;write once, run anywhere&#8221; on web browsers.</p>
<h1><span id="more-117"></span>Common Scripting Interface</h1>
<p>When I first began working on plugins, I worked on a project that had 3 seperate defintions of the javascript interface to the plugin.  One was for Mac, one for Internet Explorer on Windows, and one for Firefox on Windows.  The IE version was defined in an ActiveX .idl file and implemented in an ActiveX object.  The Firefox/win one was defined in an &#8220;XPCOM&#8221; .idl file and implemented in a nsScriptablePeer object (copied from a sample plugin from the mozilla source), and the Mac one was defined using NPRuntime and wrapped the XPCOM class.</p>
<p>This was, in short, a nightmare.</p>
<p>The problem I was initially trying to solve is that we had some APIs that had to be used differently on Mac and Windows, and they differed in less noticeable ways between Firefox and IE on Windows.  Don&#8217;t get me wrong &#8212; it all worked just fine.  However, from a maintenance point of view, this was certainly not optimal.  I could give a lot of meaningless history here, but eventually I came up with an idea that I dubbed (at that company) the Common Scripting Interface &#8212; a class that contained all the aspects that a good javascript object would need, but was not specific to any one browser.</p>
<h1>Down with the IDL</h1>
<p>Okay, this is where I&#8217;m going to start raising a lot of eyebrows.  I respectfully submit that using an IDL, as it is defined by Internet Explorer, is generally a bad idea on a control intended to be used from Javascript.  Why?  Simply put, Javascript is a dynamic language; when you pass parameters around, they are not type constrained.  Most javascript functions don&#8217;t care if you give them an integer, a string, a bool, or something else; they just use the parameters they are given.  Of course it&#8217;s a bit more complicated than that, but Javascript inherently is dynamic.  Thus, it can be important to have the ability to use a dynamic interface on a plugin that interfaces with it.</p>
<p>I hasten to remind you at this point that making an interface dynamic just for the sake of it being dynamic is a bad idea.  However, there are many use cases where you may have members (particularly properties that expose other javascript objects) that may only be named and become accessible at runtime; it&#8217;s too late to add something to the IDL.  I believe this is part of the reason that we have settled on NPRuntime on Gecko-based browsers, and Microsoft created an IDispatchEx interface to better support it on ActiveX.  Thus, we have all the tools we need to create a dynamic interface, and I have loosely patterned it after the NPAPI/NPRuntime interface, which I consider to be a fairly good interface for browser plugins.</p>
<h1>What is JSAPI?</h1>
<p>If you have looked at all at the FireBreath project that I have been working on for the last several months, you may have looked at or seen reference to the JSAPI class.  JSAPI stands for Javascript API.  JSAPI is intended to be a Javascript compatible object written in C++.  It relies heavily on the FB::variant class, which essentially is a class that you can put any datatype in.  If there is enough interest, I can blog more about that type later, but suffice it to say it&#8217;s very similar to boost::any but with data conversion tools built in.  A JSAPI object (an object that extends FB::JSAPI) provides all functionality that a Javascript object should, whether it is used or not.</p>
<h2>What does a Javascript object do?</h2>
<p>Let&#8217;s take a big step backwards now.  Forget anything you know about Browser Plugins or ActiveX Controls.  Forget anything you even know about C++, Java, C#, Logo, or any other language, even, except Javascript, HTML, DHTML, and CSS.  Those are the tools of the browser.  When we design the interface for a Browser Plugin, we shouldn&#8217;t be thinking like a C++ developer.  We should be looking at it the way we would if we were writing an object in Javascript; we should provide the interfaces that we would expect to find, and use the tools and syntax that we would expect to find in Javascript.</p>
<p>So, let&#8217;s look at what a Javascript object can do:</p>
<ul>
<li>Javascript objects can have methods that accept parameters and return a value
<ul>
<li>
<div class="wp_syntax">
<div class="code">
<pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> coolData <span style="color: #339933;">=</span> plugin.<span style="color: #660066;">doSomething</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">3</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">5</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;right now&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre>
</div>
</div>
</li>
</ul>
</li>
<li>Javascript objects can expose properties that a caller can get or set:
<ul>
<li>
<div class="wp_syntax">
<div class="code">
<pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> oldName <span style="color: #339933;">=</span> plugin.<span style="color: #000066;">name</span><span style="color: #339933;">;</span></pre>
</div>
</div>
</li>
<li>
<div class="wp_syntax">
<div class="code">
<pre class="javascript" style="font-family:monospace;">plugin.<span style="color: #000066;">name</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;Some cool name&quot;</span><span style="color: #339933;">;</span></pre>
</div>
</div>
</li>
</ul>
</li>
<li>Javascript objects can provide events, to which a caller can attach an event handler in the syntax of their browser:
<ul>
<li>
<div class="wp_syntax">
<div class="code">
<pre class="javascript" style="font-family:monospace;">plugin.<span style="color: #660066;">addEventHandler</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;click&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;The user clicked on me! Ouch!&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre>
</div>
</div>
</li>
<li>
<div class="wp_syntax">
<div class="code">
<pre class="javascript" style="font-family:monospace;">plugin.<span style="color: #660066;">attachEvent</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;onclick&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;The user clicked on me! Ouch!&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre>
</div>
</div>
</li>
</ul>
</li>
</ul>
<p>When you write it out like this, it doesn&#8217;t seem like much; remember, though, that a property of a javascript object could return any primitive datatype, an array, or even another javascript object, itself containing methods, properties, and events.</p>
<h2>The JSAPI Interface</h2>
<p>One additional thing to remember about a Javascript Object (now taking into account what we know about C++ as well) is that we don&#8217;t control the lifecycle of a javascript object.  What that means is that your plugin may go away before Javascript is done with the object that you gave it.  So, if that object uses any references to your plugin, (And what plugin javascript object wouldn&#8217;t? It&#8217;s the interface to the page, right?) you need to have a way to deal with not only cleaning up your object even after the plugin goes away, but making sure that the javascript object somehow finds out that the object it depends on is gone and invalidates itself in some way.  One way to do that is by using Shared pointers and Weak pointers, but that&#8217;s a topic for another day.</p>
<p>Like the NPObject and IDispatch types that provide its interface with the browser, JSAPI is reference counted, so that it will get destroyed whenever the browser.  Here are the method prototypes from JSAPI.h to satisfy the requirements mentioned above.  You can also look at <a title="JSAPI.h source" href="http://code.google.com/p/firebreath/source/browse/src/ScriptingCore/JSAPI.h" target="_blank">the full source of JSAPI.h</a> if you want.</p>
<h3>Methods</h3>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// ...</span>
    <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">bool</span> HasMethod<span style="color: #008000;">&#40;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">string</span> methodName<span style="color: #008000;">&#41;</span> <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">virtual</span> variant Invoke<span style="color: #008000;">&#40;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">string</span> methodName, std<span style="color: #008080;">::</span><span style="color: #007788;">vector</span><span style="color: #000040;">&amp;</span>lt<span style="color: #008080;">;</span>variant<span style="color: #000040;">&amp;</span>gt<span style="color: #008080;">;</span><span style="color: #000040;">&amp;</span>amp<span style="color: #008080;">;</span> args<span style="color: #008000;">&#41;</span> <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #666666;">// ...</span></pre>
</div>
</div>
<p>Not much is required; one call to find out if the method exists, one to invoke the method.  Notice that the arguments is passed in a STL vector of type variant; you can pass any datatypes in here, but that will be limited by the Browser-level wrapper that converts the arguments from the browser datatype (VARIANT on IE, NPVariant on firefox) to the JSAPI variant datatype.  I&#8217;ll discuss this in more detail in a later post.</p>
<h3>Properties</h3>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// ...</span>
    <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">bool</span> HasProperty<span style="color: #008000;">&#40;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">string</span> propertyName<span style="color: #008000;">&#41;</span> <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">bool</span> HasProperty<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> idx<span style="color: #008000;">&#41;</span> <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">virtual</span> variant GetProperty<span style="color: #008000;">&#40;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">string</span> propertyName<span style="color: #008000;">&#41;</span> <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">virtual</span> variant GetProperty<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> idx<span style="color: #008000;">&#41;</span> <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">void</span> SetProperty<span style="color: #008000;">&#40;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">string</span> propertyName, <span style="color: #0000ff;">const</span> variant value<span style="color: #008000;">&#41;</span> <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">void</span> SetProperty<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> idx, <span style="color: #0000ff;">const</span> variant value<span style="color: #008000;">&#41;</span> <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #666666;">// ...</span></pre>
</div>
</div>
<p>You&#8217;ll notice one strange thing right off the bat here; there are two of each method.  One takes a std::string for the first parameter, one takes an int.  Any thoughts on why?</p>
<p>Imagine the following code:</p>
<div class="wp_syntax">
<div class="code">
<pre class="javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> plugin.<span style="color: #660066;">files</span>.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span>plugin.<span style="color: #660066;">files</span><span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre>
</div>
</div>
<p>This is a pretty standard piece of javascript code, right?  Array access notation is pretty common in Javascript.  Javascript, however, treats everything as an object of one kind or another. An array to javascript is really just an object with numeric properties.  Similarly, we need to be able to support numeric properties for array style access.  That is why we have extra property methods for a property identified by an &#8220;int&#8221;.</p>
<h3>Events</h3>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// ...</span>
    <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">void</span> registerEventMethod<span style="color: #008000;">&#40;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">string</span> name, BrowserObjectAPI <span style="color: #000040;">*</span>event<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">void</span> unregisterEventMethod<span style="color: #008000;">&#40;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">string</span> name, BrowserObjectAPI <span style="color: #000040;">*</span>event<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">void</span> registerEventInterface<span style="color: #008000;">&#40;</span>BrowserObjectAPI <span style="color: #000040;">*</span>event<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">void</span> unregisterEventInterface<span style="color: #008000;">&#40;</span>BrowserObjectAPI <span style="color: #000040;">*</span>event<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">virtual</span> BrowserObjectAPI <span style="color: #000040;">*</span>getDefaultEventMethod<span style="color: #008000;">&#40;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">string</span> name<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">void</span> setDefaultEventMethod<span style="color: #008000;">&#40;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">string</span> name, BrowserObjectAPI <span style="color: #000040;">*</span>event<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">protected</span><span style="color: #008080;">:</span>
    <span style="color: #666666;">// Used to fire an event to the listeners attached to this JSAPI</span>
    <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">void</span> FireEvent<span style="color: #008000;">&#40;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">string</span> eventName, std<span style="color: #008080;">::</span><span style="color: #007788;">vector</span><span style="color: #000040;">&amp;</span>lt<span style="color: #008080;">;</span>variant<span style="color: #000040;">&amp;</span>gt<span style="color: #008080;">;</span><span style="color: #000040;">&amp;</span>amp<span style="color: #008080;">;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #666666;">// ...</span></pre>
</div>
</div>
<p>Events are by far the most difficult piece of this whole class; we have to make allowances for multiple methods of registering events and multiple browsers&#8217; methods for keeping track of the handlers. The BrowserObjectAPI type that you see used here is also a JSAPI object, but one that wraps a browser object (an NPObject or a IDispatch object, depending on the browser).</p>
<p>There are three different ways an event can be registered (at this point in time):</p>
<ol>
<li>Through a &#8220;user-defined&#8221; event registering method implemented by our browser scripting object wrapper (this is used by all objects on firefox and all but the root object on IE).
<ul>
<li>The BrowserObjectAPI object will essentially be a method that we can invoke by calling InvokeAsync with empty string (&#8220;&#8221;) as the method name</li>
</ul>
</li>
<li>Through the Connection Point interface on an ActiveX Control (obviously used on the root object in IE)
<ul>
<li>The BrowserObjectAPI object will be an object on which we can invoke a method of the same name as the event it is attached to</li>
</ul>
</li>
<li>Through a property of the same name as the event (old-style javascript events, as in &#8220;document.onload = &#8230;.&#8221;
<ol>
<li>The BrowserObjectAPI object will essentially be a method that we can invoke by calling InvokeAsync with empty string (&#8220;&#8221;) as the method name</li>
</ol>
</li>
</ol>
<p>These three types are the reason that we have three different register/unregister methods on the browser for events.  When FireEvent is called by the JSAPI child object (that you write), it iterates through all possible event handlers and invokes them asynchronously.  (Events have to be invoked on the main UI thread of the plugin, so the InvokeAsync call on BrowserObjectAPI automatically makes sure that is where it gets called; hence it&#8217;s async).</p>
<h1>Next time</h1>
<p>We have discussed and looked at the basic needs of the JSAPI object.  Part two will discuss the <a title="COMJavascriptObject.h source" href="http://code.google.com/p/firebreath/source/browse/src/ActiveXPlugin/COMJavascriptObject.h">COMJavascriptObject</a> class and the <a title="JSAPI_IDispatch.h source" href="http://code.google.com/p/firebreath/source/browse/src/ActiveXPlugin/JSAPI_IDispatchEx.h">JSAPI_IDispatch</a> helper class that constitute the interface between ActiveX and our JSAPI interfaces.  Part three will cover the <a title="NPJavascriptObject.h source" href="http://code.google.com/p/firebreath/source/browse/src/NpapiPlugin/NPJavascriptObject.h">NPJavascriptObject</a> that provides the interface between NPRuntime and JSAPI.  Feel free to read ahead in the source =]</p>
<p>In the mean time, if you like where this is going and want to play with FireBreath and see JSAPI in action for yourself, there are some <a title="Creating a new Plugin Project with FireBreath" href="http://code.google.com/p/firebreath/wiki/CreatingANewPluginProject">really easy getting started instructions</a> on the <a title="Firebreath project home page" href="http://code.google.com/p/firebreath/" target="_blank">FireBreath project page</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://colonelpanic.net/2009/12/cross-browser-scripting-part-one/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

