<?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; npobject</title>
	<atom:link href="http://colonelpanic.net/tag/npobject/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</generator>
		<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>
		<item>
		<title>Building a firefox plugin – part three</title>
		<link>http://colonelpanic.net/2009/08/building-a-firefox-plugin-part-three/</link>
		<comments>http://colonelpanic.net/2009/08/building-a-firefox-plugin-part-three/#comments</comments>
		<pubDate>Wed, 05 Aug 2009 05:20:46 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[Browser Plugin Development]]></category>
		<category><![CDATA[NPAPI]]></category>
		<category><![CDATA[browser]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[npobject]]></category>
		<category><![CDATA[npruntime]]></category>
		<category><![CDATA[npvariant]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://colonelpanic.net/?p=72</guid>
		<description><![CDATA[Note: For a better way to create a Browser Plugin (that will work on all browsers, not just NPAPI), check out the FireBreath project. Getting help: For a better place to ask NPAPI-related questions, check out the FireBreath Forums. Yes, there is a forum there for NPAPI plugins that don&#8217;t use FireBreath as well. Previous [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Note: </strong>For a better way to create a Browser Plugin (that will work on all browsers, not just NPAPI), check out the <a href="http://www.firebreath.org">FireBreath project</a>.</p>
<p><strong>Getting help: </strong>For a better place to ask NPAPI-related questions, check out the <a href="http://forum.firebreath.org">FireBreath Forums</a>. Yes, there is a forum there for NPAPI plugins that don&#8217;t use FireBreath as well.</p>
<h2>Previous posts</h2>
<p>The purpose of this post is to cover the basics of providing an interface by which javascript can interface with an NPAPI plugin in a cross platform manner.  The primary focus of this post will be on <a title="Mozilla Plugin API Reference : Scripting Plugins" href="https://developer.mozilla.org/en/Gecko_Plugin_API_Reference/Scripting_plugins" target="_blank">npruntime</a>, which is recommended by the Mozilla development team (or at least seems to be from the <a title="Mozilla Plugin API Reference" href="https://developer.mozilla.org/En/plugins">meager and confusing documentation</a> available from Mozilla).  More importantly, of course, it is the framework that I recommend, which is all-important, since I&#8217;m the one writing this post. =]</p>
<h2><span id="more-72"></span>Previous posts</h2>
<p>If you are new to NPAPI plugins, you may want to go back and read <a title="Building a firefox plugin - part one" href="http://colonelpanic.net/2009/03/building-a-firefox-plugin-part-one/" target="_blank">part one</a> and <a title="Building a firefox plugin - part two" href="http://colonelpanic.net/2009/05/building-a-firefox-plugin-part-two/">part two</a> of this series, which cover the basic architecture and lifecycle of an NPAPI plugin.</p>
<h2>What is npruntime?</h2>
<p>I&#8217;m so glad you ask.  This confused the daylights out of me when I first got into building browser plugins; there are references to XPCOM and references to LiveConnect and references to NPRuntime, which I never did quite get straightened out until I ran into <a title="Netscape Plugin Application Programming Interface" href="http://en.wikipedia.org/wiki/Netscape_Plugin_Application_Programming_Interface" target="_blank">a Wikipedia article on NPAPI</a>.  I recommend that you read it if you want further background information.</p>
<p>Beyond the simple question of &#8220;what is recommended?&#8221; is the consideration of practical needs.  For me, the primary considerations that led me to decide that NPRuntimeis the only mechanism that should be used on any new plugin are:</p>
<ul>
<li>NPRuntime allows dynamic interfaces &#8212; more on this, and why it is useful, later</li>
<li>NPRuntime is the plugin scripting standard supported by Mac Plugins, Safari (even on windows), Chrome, and Opera.  My goal is always to make things as cross-platform as possible.</li>
<li>Firefox 3.6 drops support for XPCOM plugins (e.g. xpt file scripting interfaces aren&#8217;t recognized)</li>
</ul>
<h2>Getting Started</h2>
<p>Throughout this post, I will be referring to Scriptable Objects a lot.  A Scriptable Object is simply an object that can be &#8220;scripted&#8221;, or accessed and used by javascript.  In firefox, a Scriptable Object is always a <a title="NPObject - MDC" href="https://developer.mozilla.org/en/NPObject" target="_blank">NPObject</a>:</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">struct</span> NPObject <span style="color: #008000;">&#123;</span>
  NPClass <span style="color: #000040;">*</span>_class<span style="color: #008080;">;</span>
  <span style="color: #0000ff;">uint32_t</span> referenceCount<span style="color: #008080;">;</span>
  <span style="color: #ff0000; font-style: italic;">/*
   * Additional space may be allocated here by types of NPObjects
   */</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre>
</div>
</div>
<p>As you can see, a NPObject is nothing more than a reference counted object with a pointer to a <a title="NPClass - MDC" href="https://developer.mozilla.org/en/NPClass">NPClass</a>.  As of the latest (as of this writing) Gecko SDK, 1.9, NPClass is defined as follows:</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">struct</span> NPClass
<span style="color: #008000;">&#123;</span>
  <span style="color: #0000ff;">uint32_t</span> structVersion<span style="color: #008080;">;</span> <span style="color: #666666;">// Version of the structure (to determine which features may be missing)</span>
  NPAllocateFunctionPtr allocate<span style="color: #008080;">;</span> <span style="color: #666666;">// Called to create a new instance of this object</span>
  NPDeallocateFunctionPtr deallocate<span style="color: #008080;">;</span> <span style="color: #666666;">// Called to free the instance of this object</span>
  NPInvalidateFunctionPtr invalidate<span style="color: #008080;">;</span> <span style="color: #666666;">// Called on live objects that belong to a plugin instance that is being destroyed. This call is always followed by a call to the &lt;code&gt;deallocate&lt;/code&gt; function, or &lt;code&gt;free()&lt;/code&gt;. Any attempt to use an invalidated object will result in undefined behavior.</span>
  NPHasMethodFunctionPtr hasMethod<span style="color: #008080;">;</span> <span style="color: #666666;">// Called to query if a method exists on the NPObject</span>
  NPInvokeFunctionPtr invoke<span style="color: #008080;">;</span> <span style="color: #666666;">// Used to invoke a method on the NPObject</span>
  NPInvokeDefaultFunctionPtr invokeDefault<span style="color: #008080;">;</span> <span style="color: #666666;">// Used to invoke the NPObject as a function</span>
  NPHasPropertyFunctionPtr hasProperty<span style="color: #008080;">;</span> <span style="color: #666666;">// Called to query if a property exists on the NPObject</span>
  NPGetPropertyFunctionPtr getProperty<span style="color: #008080;">;</span> <span style="color: #666666;">// Called to get the value of a property on the NPObject</span>
  NPSetPropertyFunctionPtr setProperty<span style="color: #008080;">;</span> <span style="color: #666666;">// Called to set the value of a property on the NPObject</span>
  NPRemovePropertyFunctionPtr removeProperty<span style="color: #008080;">;</span> <span style="color: #666666;">// Called to remove/delete a property on the NPObject</span>
  NPEnumerationFunctionPtr enumerate<span style="color: #008080;">;</span> <span style="color: #666666;">// Used to get a list of properties and methods that exist on the NPObject (new in FF 3, Gecko SDK 1.9)</span>
  NPConstructFunctionPtr construct<span style="color: #008080;">;</span> <span style="color: #666666;">// Used when the new keyword is called in javascript to create a new instance of the NPObject (new in FF 3, Gecko SDK 1.9)</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre>
</div>
</div>
<h2>Making it Object Oriented</h2>
<p>The Gecko SDK is intentionally written to use structs instead of objects; this allows it to work across many platforms, with many different types of compilers, and never worry about binary compatibility.  If you haven&#8217;t figured it out yet, the NPClass structure contains a list of function pointers that should be called by the browser (or anyone else) to talk to the NPObject.  These should never be called explicitly, but rather they should be called through the NPN_ functions that I briefly mentioned towards the end of <a title="Building a firefox plugin - part one" href="http://colonelpanic.net/2009/03/building-a-firefox-plugin-part-one/" target="_blank">part one</a>.  When one wishes to create a new instance of an NPObject, you call the <a title="NPN_CreateObject - MDC" href="https://developer.mozilla.org/en/NPN_CreateObject">NPN_CreateObject</a> function and give it the class that should be used.</p>
<p>Fortunately, since all the browser cares about is the NPClass, its function pointers, and the reference count, any class that inherits from NPObject can easily satisfy that requirement; that means that it is not difficult to make a smart NPObject; simply create static methods for each of the pointers in the NPClass struct, dereference the NPObject* that they pass in, and call a member function.</p>
<h2>Simple class definition and implementation:</h2>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &quot;npapi.h&quot;</span>
<span style="color: #339900;">#include &quot;npupp.h&quot;</span>
&nbsp;
<span style="color: #0000ff;">class</span> MyScriptableNPObject <span style="color: #008080;">:</span> <span style="color: #0000ff;">public</span> NPObject
<span style="color: #008000;">&#123;</span>
<span style="color: #0000ff;">protected</span><span style="color: #008080;">:</span>
    <span style="color: #666666;">// Class member functions that do the real work</span>
    <span style="color: #0000ff;">void</span> Deallocate<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">void</span> Invalidate<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">bool</span> HasMethod<span style="color: #008000;">&#40;</span>NPIdentifier name<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">bool</span> Invoke<span style="color: #008000;">&#40;</span>NPIdentifier name, <span style="color: #0000ff;">const</span> NPVariant <span style="color: #000040;">*</span>args, <span style="color: #0000ff;">uint32_t</span> argCount, NPVariant <span style="color: #000040;">*</span>result<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">bool</span> InvokeDefault<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> NPVariant <span style="color: #000040;">*</span>args, <span style="color: #0000ff;">uint32_t</span> argCount, NPVariant <span style="color: #000040;">*</span>result<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">bool</span> HasProperty<span style="color: #008000;">&#40;</span>NPIdentifier name<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">bool</span> GetProperty<span style="color: #008000;">&#40;</span>NPIdentifier name, NPVariant <span style="color: #000040;">*</span>result<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">bool</span> SetProperty<span style="color: #008000;">&#40;</span>NPIdentifier name, <span style="color: #0000ff;">const</span> NPVariant <span style="color: #000040;">*</span>value<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">bool</span> RemoveProperty<span style="color: #008000;">&#40;</span>NPIdentifier name<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">bool</span> Enumerate<span style="color: #008000;">&#40;</span>NPIdentifier <span style="color: #000040;">**</span>identifier, <span style="color: #0000ff;">uint32_t</span> <span style="color: #000040;">*</span>count<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">bool</span> Construct<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> NPVariant <span style="color: #000040;">*</span>args, <span style="color: #0000ff;">uint32_t</span> argCount, NPVariant <span style="color: #000040;">*</span>result<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
    <span style="color: #666666;">// This is the method used to create the NPObject</span>
    <span style="color: #666666;">// This method should not be called explicitly</span>
    <span style="color: #666666;">// Instead, use NPN_CreateObject</span>
    <span style="color: #0000ff;">static</span> NPObject<span style="color: #000040;">*</span> Allocate<span style="color: #008000;">&#40;</span>NPP npp, NPClass <span style="color: #000040;">*</span>aClass<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        <span style="color: #0000ff;">return</span> <span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span><span style="color: #0000dd;">new</span> MyScriptableNPObject<span style="color: #008000;">&#40;</span>npp<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #666666;">/////////////////////////////</span>
    <span style="color: #666666;">// Static NPObject methods //</span>
    <span style="color: #666666;">/////////////////////////////</span>
    <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> _Deallocate<span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span>npobj<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> _Invalidate<span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span>npobj<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">bool</span> _HasMethod<span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span>npobj, NPIdentifier name<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">bool</span> _Invoke<span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span>npobj, NPIdentifier name, <span style="color: #0000ff;">const</span> NPVariant <span style="color: #000040;">*</span>args, <span style="color: #0000ff;">uint32_t</span> argCount, NPVariant <span style="color: #000040;">*</span>result<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">bool</span> _InvokeDefault<span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span>npobj, <span style="color: #0000ff;">const</span> NPVariant <span style="color: #000040;">*</span>args, <span style="color: #0000ff;">uint32_t</span> argCount, NPVariant <span style="color: #000040;">*</span>result<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">bool</span> _HasProperty<span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span> npobj, NPIdentifier name<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">bool</span> _GetProperty<span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span>npobj, NPIdentifier name, NPVariant <span style="color: #000040;">*</span>result<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">bool</span> _SetProperty<span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span>npobj, NPIdentifier name, <span style="color: #0000ff;">const</span> NPVariant <span style="color: #000040;">*</span>value<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">bool</span> _RemoveProperty<span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span>npobj, NPIdentifier name<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">bool</span> _Enumerate<span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span>npobj, NPIdentifier <span style="color: #000040;">**</span>identifier, <span style="color: #0000ff;">uint32_t</span> <span style="color: #000040;">*</span>count<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">bool</span> _Construct<span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span>npobj, <span style="color: #0000ff;">const</span> NPVariant <span style="color: #000040;">*</span>args, <span style="color: #0000ff;">uint32_t</span> argCount, NPVariant <span style="color: #000040;">*</span>result<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">static</span> NPClass _npclass<span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">protected</span><span style="color: #008080;">:</span>
    NPP m_Instance<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre>
</div>
</div>
<p>Due to code ownership issues, I&#8217;m not able to give you the actual code that I&#8217;m using, but if there are any compiler errors I&#8217;m sure they&#8217;ll be simple to straighten out.  The implementation for these static members will be pretty straightforward:</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// static</span>
<span style="color: #0000ff;">void</span> MyScriptableNPObject<span style="color: #008080;">::</span>_Invalidate<span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span>obj<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>MyScriptableNPObject<span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span>obj<span style="color: #008000;">&#41;</span><span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>Invalidate<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
<span style="color: #0000ff;">void</span> MyScriptableNPObject<span style="color: #008080;">::</span><span style="color: #007788;">Invalidate</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    <span style="color: #666666;">// Invalidate the control however you wish</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #666666;">// static</span>
<span style="color: #0000ff;">void</span> MyScriptableNPObject<span style="color: #008080;">::</span>_Deallocate<span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span>obj<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>MyScriptableNPObject<span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span>obj<span style="color: #008000;">&#41;</span><span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>Deallocate<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000dd;">delete</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>MyScriptableNPObject<span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span>obj<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
<span style="color: #0000ff;">void</span> MyScriptableNPObject<span style="color: #008080;">::</span><span style="color: #007788;">Deallocate</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    <span style="color: #666666;">// Do any cleanup needed</span>
<span style="color: #008000;">&#125;</span></pre>
</div>
</div>
<p>For brevity, I&#8217;m not going to include all of the methods here; I will go into more detail on them later.  For now, suffice it to say that after you have implemented the rest of these functions, all that is left is to define the NPClass itself:</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;">NPClass MyScriptableNPObject<span style="color: #008080;">::</span>_npclass <span style="color: #000080;">=</span> <span style="color: #008000;">&#123;</span>
    NP_CLASS_STRUCT_VERSION,
    MyScriptableNPObject<span style="color: #008080;">::</span><span style="color: #007788;">Allocate</span>,
    MyScriptableNPObject<span style="color: #008080;">::</span>_Deallocate,
    MyScriptableNPObject<span style="color: #008080;">::</span>_Invalidate,
    MyScriptableNPObject<span style="color: #008080;">::</span>_HasMethod,
    MyScriptableNPObject<span style="color: #008080;">::</span>_Invoke,
    MyScriptableNPObject<span style="color: #008080;">::</span>_InvokeDefault,
    MyScriptableNPObject<span style="color: #008080;">::</span>_HasProperty,
    MyScriptableNPObject<span style="color: #008080;">::</span>_GetProperty,
    MyScriptableNPObject<span style="color: #008080;">::</span>_SetProperty,
    MyScriptableNPObject<span style="color: #008080;">::</span>_RemoveProperty,
    MyScriptableNPObject<span style="color: #008080;">::</span>_Enumerate,
    MyScriptableNPObject<span style="color: #008080;">::</span>_Construct
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre>
</div>
</div>
<h2>Creating the NPObject</h2>
<p>Once you have your custom NPObject created and your NPClass defined, we can cover the basics of the NPObject lifecycle.  Creating an NPObject is pretty straightforward:</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;">NPObject <span style="color: #000040;">*</span>newObj <span style="color: #000080;">=</span> NPN_CreateObject<span style="color: #008000;">&#40;</span>m_Instance, <span style="color: #000040;">&amp;</span>amp<span style="color: #008080;">;</span>MyScriptableNPObject<span style="color: #008080;">::</span>_npclass<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
NPN_RetainObject<span style="color: #008000;">&#40;</span>newObj<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre>
</div>
</div>
<p>As you can see, all that is needed is the NPP instance handler (see <a title="Building a firefox plugin - part two" href="http://colonelpanic.net/2009/05/building-a-firefox-plugin-part-two/">part two</a>) and a pointer to the class.  Since the class is very specific to a specific NPObject, I like to create a static function to instantiate the object, like so:</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">static</span> MyScriptableNPObject<span style="color: #000040;">*</span> NewObject<span style="color: #008000;">&#40;</span>NPP npp<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    MyScriptableNPObject<span style="color: #000040;">*</span> newObj <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span>MyScriptableNPObject<span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span>NPN_CreateObject<span style="color: #008000;">&#40;</span>npp, <span style="color: #000040;">&amp;</span>amp<span style="color: #008080;">;</span>_npclass<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">return</span> newObj<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre>
</div>
</div>
<p>This is completely voluntary, of course, but it also allows you some additional control of the creation process; for example, you may want to pass in additional parameters and have them set on the object as soon as it is created.</p>
<h2>NPObject lifecycle</h2>
<p>As you might guess, <a title="NPN_RetainObject - MDC" href="https://developer.mozilla.org/En/NPN_RetainObject">NPN_RetainObject </a>increments the reference count on a given NPObject.  Similarly, <a title="NPN_ReleaseObject - MDC" href="https://developer.mozilla.org/En/NPN_ReleaseObject" target="_blank">NPN_ReleaseObject </a>decrements the reference count.  When the reference count hits zero, the object will be destroyed by calling the specified Deallocate function, just like the Allocate function is called by NPN_CreateObject to create the object.</p>
<p>When code in one DLL allocates something and it is deallocated by a different DLL, heap corruption can (and often does) occur.  For this reason, all things that belong to you will ultimately get created and destroyed in your code.  All things that belong to the browser will get created and freed in browser code.  This way everyone stays happy =]  Make sure you keep track of your Retains and Releases; just like any reference counting, this can cause you a lot of hard to track problems.</p>
<p>Another important thing to keep in mind about the lifecycle of a NPObject is that you don&#8217;t know exactly when it will go away; the browser will release it whenever it chooses to do so.  Therefore, you need to be able to handle things gracefully even if things are destroyed in a different order than you expect.</p>
<h2>Giving the correct NPObject to the browser</h2>
<p>Now that you know what an NPObject is and rougly what it does, you need to know how the browser finds out about it.  If you&#8217;ll refer back to <a title="Building a firefox plugin - part two" href="../2009/05/building-a-firefox-plugin-part-two/">part two</a> and look at the plugin lifecycle, you&#8217;ll see on entry #5 that &#8220;Plugin creates a scriptable NPObject and returns a pointer to it (after calling <a title="NPN_RetainObject SDK docs" href="https://developer.mozilla.org/En/NPN_RetainObject" target="_blank">NPN_RetainObject</a> on it.)&#8221;  Simply put, at that point in the initialization sequence (or somewhere in there; the spec is ambiguous about the order), the Browser will call GetValue on the plugin and ask for a NPObject.  If our plugin supports NPObjects, it simply needs to create one, call <a title="NPN_RetainObject SDK docs" href="https://developer.mozilla.org/En/NPN_RetainObject" target="_blank">NPN_RetainObject</a> on it, and return it as a void pointer.  <strong>*NOTE: Make sure that you typecast it as a NPObject* before assigning it to the void pointer; I made that mistake once and spent a week trying to figure out why the wrong functions were getting called.</strong></p>
<p>Here is an example implementation of GetValue:</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;">NPError PluginInstance<span style="color: #008080;">::</span><span style="color: #007788;">NpapiGetValue</span><span style="color: #008000;">&#40;</span>NPPVariable variable, <span style="color: #0000ff;">void</span> <span style="color: #000040;">*</span>value<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
   NPError rv <span style="color: #000080;">=</span> NPERR_NO_ERROR<span style="color: #008080;">;</span>
   <span style="color: #0000ff;">switch</span><span style="color: #008000;">&#40;</span>variable<span style="color: #008000;">&#41;</span>
   <span style="color: #008000;">&#123;</span>
      <span style="color: #0000ff;">case</span> NPPVpluginNameString<span style="color: #008080;">:</span>
          value <span style="color: #000080;">=</span> <span style="color: #000040;">*</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">char</span> <span style="color: #000040;">**</span><span style="color: #008000;">&#41;</span>value<span style="color: #008000;">&#41;</span> <span style="color: #000080;">=</span> STRINGS_PRODUCTNAME<span style="color: #008080;">;</span>
          <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
      <span style="color: #0000ff;">case</span> NPPVpluginDescriptionString<span style="color: #008080;">:</span>    <span style="color: #666666;">// Plugin description</span>
          <span style="color: #000040;">*</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">char</span> <span style="color: #000040;">**</span><span style="color: #008000;">&#41;</span>value<span style="color: #008000;">&#41;</span> <span style="color: #000080;">=</span> STRINGS_FILEDESCRIPTION<span style="color: #008080;">;</span>
          <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
      <span style="color: #0000ff;">case</span> NPPVpluginScriptableNPObject<span style="color: #008080;">:</span><span style="color: #666666;">// Scriptable plugin interface (for accessing from javascript)</span>
          <span style="color: #000040;">*</span><span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">**</span><span style="color: #008000;">&#41;</span>value <span style="color: #000080;">=</span> this<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>getScriptableObject<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
          <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
      <span style="color: #0000ff;">case</span> NPPVpluginWindowBool<span style="color: #008080;">:</span>
          <span style="color: #000040;">*</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>PRBool <span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span>value<span style="color: #008000;">&#41;</span> <span style="color: #000080;">=</span> this<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>isWindowed<span style="color: #008080;">;</span>
          <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
      <span style="color: #0000ff;">default</span><span style="color: #008080;">:</span>
          rv <span style="color: #000080;">=</span> NPERR_GENERIC_ERROR<span style="color: #008080;">;</span>
  <span style="color: #008000;">&#125;</span>
  <span style="color: #0000ff;">return</span> rv<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
NPObject <span style="color: #000040;">*</span>PluginInstance<span style="color: #008080;">::</span><span style="color: #007788;">getScriptableObject</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
   NPObject <span style="color: #000040;">*</span>retval<span style="color: #008080;">;</span>
   <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>this<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>npobj <span style="color: #000040;">!</span><span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span>
      retval <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span>this<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>npobj<span style="color: #008080;">;</span>
   <span style="color: #0000ff;">else</span>
      retval <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span>MyScriptableNPObject<span style="color: #008080;">::</span><span style="color: #007788;">NewObject</span><span style="color: #008000;">&#40;</span>this<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>npp<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
   NPN_RetainObject<span style="color: #008000;">&#40;</span>retval<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
   <span style="color: #0000ff;">return</span> retval<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre>
</div>
</div>
<h2>HasMethod and HasProperty</h2>
<p>On to the meat of the article: Say you have a javascript function like so:</p>
<pre>var objTag = document.getElementById("myObjectTag");
alert(objTag.doSomeCoolFunction);</pre>
<p>You may think that this looks a little strange, since &#8220;doSomeCoolFunction&#8221; sounds like a function call, but it is clearly accessed like a parameter here.  In Javascript, this is legal even if that is a function, because it can be used to determine if a function exists without calling it.  Therefore, you cannot have a method and a property on the same object with the same name.</p>
<p>When this call is made, the browser will call two functions on the NPObject:</p>
<ol>
<li><a title="NPN_HasMethod - MDC" href="https://developer.mozilla.org/en/NPN_HasMethod" target="_blank">HasMethod</a>(NPIdentifier name);</li>
<li><a title="NPN_HasProperty - MDC" href="https://developer.mozilla.org/en/NPN_HasProperty" target="_blank">HasProperty</a>(NPIdentifier name);</li>
</ol>
<p>The purpose of these two calls is to ascertain whether or not a property or method exists on the NPObject (as you might have guessed).  So, what is with this <a title="NPIdentifier - MDC" href="https://developer.mozilla.org/en/NPIdentifier" target="_blank">NPIdentifier </a>thing?  Well, a NPIdentifier can map to either an integer or a string.  a NPIdentifier can be converted to a string (if it is a string identifier) with <a title="NPN_UTF8FromIdentifier - MDC" href="https://developer.mozilla.org/en/NPN_UTF8FromIdentifier" target="_blank">NPN_UTF8FromIdentifier</a>.  To find out if it is a string identifier, use <a href="https://developer.mozilla.org/en/NPN_IdentifierIsString" target="_blank href=">NPN_IdentifierIsString</a>.  If it is an integer, you can use <a href="https://developer.mozilla.org/en/NPN_IntFromIdentifier" rel="custom nofollow" target="_blank">NPN_IntFromIdentifier</a>.</p>
<p>Now, the purpose of integer identifiers may not be immediately apparent to everyone; it wasn&#8217;t to me at first.  Once I figured it out, however, I was thrilled.  If you are familiar with javascript, you are doubtlessly familiar with the concept that everything in javascript is an object; arrays are actually just objects with integer keys.  So, to allow array-style access, simply handle integer identifiers!</p>
<p>Once you have converted the identifier into something you can deal with, decide if your object has that property or method (I&#8217;ll let you figure out which goes in which function) and return true or false.</p>
<p>Oh, and after you get a string wtih NPN_UTF8FromIdentifier, don&#8217;t forget to release the memory with <a href="https://developer.mozilla.org/en/NPN_MemFree" rel="internal">NPN_MemFree()</a>.</p>
<h2>NPVariant</h2>
<p>Before I go any further, I need to spend a brief paragraph or two on the <a title="NPVariant structure documentation" href="https://developer.mozilla.org/en/NPVariant" target="_blank">NPVariant structure</a>.</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">typedef</span> <span style="color: #0000ff;">struct</span> _NPVariant <span style="color: #008000;">&#123;</span>
  NPVariantType type<span style="color: #008080;">;</span>
  <span style="color: #0000ff;">union</span> <span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">bool</span> boolValue<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">int32_t</span> intValue<span style="color: #008080;">;</span>
    double_t doubleValue<span style="color: #008080;">;</span>
    NPString stringValue<span style="color: #008080;">;</span>
    NPObject <span style="color: #000040;">*</span>objectValue<span style="color: #008080;">;</span>
  <span style="color: #008000;">&#125;</span> value<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span> NPVariant<span style="color: #008080;">;</span></pre>
</div>
</div>
<p>NPVariant is the datatype used by the browser to pass variables into and out of NPObjects.  From the MDC docs, the following types are valid:</p>
<table border="1" cellspacing="0" cellpadding="2">
<tbody>
<tr>
<th>JavaScript type</th>
<th><code>NPVariantType</code></th>
</tr>
<tr>
<td><code>undefined</code></td>
<td><code>NPVariantType_Void</code></td>
</tr>
<tr>
<td><code>null</code></td>
<td><code>NPVariantType_Null</code></td>
</tr>
<tr>
<td><code>boolean</code></td>
<td><code>NPVariantType_Bool</code></td>
</tr>
<tr>
<td><code>number</code></td>
<td><code>NPVariantType_Int32</code> or <code>NPVariantType_Double</code></td>
</tr>
<tr>
<td><code>string</code></td>
<td><code>NPVariantType_String</code></td>
</tr>
<tr>
<td>All other types</td>
<td><code>NPVariantType_Object</code></td>
</tr>
</tbody>
</table>
<p>Since it&#8217;s getting late and I&#8217;ve already put too much in this post (I&#8217;m over 2000 words), I&#8217;ll leave it as an excercise to the reader to <a title="NPVariant docs" href="https://developer.mozilla.org/en/NPVariant" target="_blank">read up on the macros and such for using this structure</a>.</p>
<h2>Properties</h2>
<p>At this point, you should be getting a pretty good idea of how everything works.  Getting and setting properties is fairly straightforward:</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;">    <span style="color: #0000ff;">bool</span> GetProperty<span style="color: #008000;">&#40;</span>NPIdentifier name, NPVariant <span style="color: #000040;">*</span>result<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">bool</span> SetProperty<span style="color: #008000;">&#40;</span>NPIdentifier name, <span style="color: #0000ff;">const</span> NPVariant <span style="color: #000040;">*</span>value<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre>
</div>
</div>
<p>To get a property, simply check the name to see what you&#8217;re going to be doing and store the value to return in *result.  If the operation succeeds, you should return true.  If not, false.</p>
<p>To set a property, again check the name to see which property you&#8217;re working with and save the value of the NPVariant parameter however you wish.  Again, return true if success, false if failure.</p>
<h2>Methods</h2>
<p>Methods aren&#8217;t much more difficult.  The only real difference is that now you have parameters to worry about.  No problem!  Parameters are passed in as an array of NPVariants:</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;">    <span style="color: #0000ff;">bool</span> Invoke<span style="color: #008000;">&#40;</span>NPIdentifier name, <span style="color: #0000ff;">const</span> NPVariant <span style="color: #000040;">*</span>args, <span style="color: #0000ff;">uint32_t</span> argCount, NPVariant <span style="color: #000040;">*</span>result<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">bool</span> InvokeDefault<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> NPVariant <span style="color: #000040;">*</span>args, <span style="color: #0000ff;">uint32_t</span> argCount, NPVariant <span style="color: #000040;">*</span>result<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre>
</div>
</div>
<p>The difference between Invoke and InvokeDefault is that InvokeDefault does not ever have an identifier.  If you call &#8220;objTag.funcName()&#8221; Invoke gets called; if you call &#8220;objTag()&#8221;, then InvokeDefault gets called.</p>
<p>As with properties, store the return value in the pointer given in the last argument and handle the other arguments however you wish.</p>
<h2>Wrapping it up</h2>
<p>Alright, I know I haven&#8217;t covered everything, but this is already too long.  If you have specific questions, ask them in the comments and I&#8217;ll do my best to answer; the comments may determine the direction of my next post.</p>
<p>Since dealing with the NPIdentifiers can get to be such a pain, I recommend using a map or hashtable to store structures with function pointers to map a string name to functions to handle it; that way you don&#8217;t end up with giant if/then or case statements, and everything ends up being much cleaner.</p>
<p>Another idea for the adventuresome: abstract the actual logic (properties and methods) into another object that can be wrapped with your NPObject class, and then make another wrapper class that implements <a title="MSDN: IDispatch" href="http://msdn.microsoft.com/en-us/library/ms221608.aspx" target="_blank">IDispatch </a>so that your scriptable objects are cross platform (IDispatch objects are scriptable on Internet Explorer).</p>
<p>Good luck!</p>
<p><a title="Building a firefox plugin - part one" href="http://colonelpanic.net/2009/03/building-a-firefox-plugin-part-one/">Building a firefox plugin &#8211; part one</a></p>
<p><a title="Building a firefox plugin - part two" href="http://colonelpanic.net/2009/05/building-a-firefox-plugin-part-two/">Building a firefox plugin &#8211; part two</a></p>
<p><a title="Building a firefox plugin - part three" href="http://colonelpanic.net/2009/08/building-a-firefox-plugin-part-three/">Building a firefox plugin &#8211; part three</a></p>
<p><a title="Building a firefox plugin - part four" href="http://colonelpanic.net/2011/07/building-a-firefox-plugin-part-four/">Building a firefox plugin &#8211; part four</a></p>
<h2>Getting more help</h2>
<p><strong>Update May 14, 2011:</strong> Many people have been asking questions in the comments; while I don&#8217;t mind that, it would probably be more useful if you ask your question on <a href="http://forum.firebreath.org">the FireBreath forums</a>. There is a forum there for those just using NPAPI as well!</p>
]]></content:encoded>
			<wfw:commentRss>http://colonelpanic.net/2009/08/building-a-firefox-plugin-part-three/feed/</wfw:commentRss>
		<slash:comments>199</slash:comments>
		</item>
	</channel>
</rss>

