Scripting plugins

  • Revision slug: Gecko_Plugin_API_Reference/Scripting_plugins
  • Revision title: Scripting plugins
  • Revision id: 73216
  • Created:
  • Creator: Kazssym
  • Is current revision? No
  • Comment /* The API extensions */ Correct version information.

Revision Content

{{template.PreviousNext("Gecko Plugin API Reference:Browser Side Plug-in API", "Gecko Plugin API Reference:Structures")}} {{template.Npapiref()}}

XXX: Dummy p element

NPAPI plugins that used to take advantage of being scriptable via LiveConnect in 4.x Netscape browsers lost this possibility in Mozilla (due to the JNI making the Netscape 4.x JRI obsolete). As an answer to this large gap in the Netscape Plugin API, an extension to the API has been developed that lets plugins be scriptable again, independent of Java. This extension will also let plugins access the script objects in the browser, and is thus a much stronger and more flexible API.

This document describes the new cross-browser NPAPI extensions that have been developed by a group of browser and plugin vendors, including the Mozilla Foundation, Adobe, Apple, Opera, and Sun Microsystems (see press release). This document also explains how to make a plugin use these new extensions to be scriptable as well as how to access objects in a browser.

The information in this section applies to Firefox 1.0 and Mozilla 1.7.5 and newer versions.

How the DOM handles scripting

The Mozilla DOM code now checks if a plugin supports this new scriptability API and if it exposes a scriptable object through this new mechanism. Mozilla does this by calling the old plugin API call {{template.Npapi("NPP_GetValue")}} with the new enumeration value that has been added to the {{template.Npapi("NPPVariable")}} enumeration.

The new NPPVariable enumeration is defined in <tt>npapi.h</tt> as:

NPPVpluginScriptableNPObject = 15

Threading model

This API is not designed to be thread safe. The threading model for this API is such that all calls through this API are synchronous and calls from a plugin to methods in this API must come from the thread on which the plugin was initiated, and likewise all calls to methods in this API by the browser are guaranteed to come from the same thread. Future revisions to this API might provide a mechanism for proxying calls from one thread to another to aid in using this API from other threads.

Security model

The security model for making calls through this API is much like the general same-origin security model enforced by the browser. That means that script from an origin other than the origin of the page that loaded the plugin is not able to access methods and properties on the plugin. The same thing applies the other way too, the plugin can reach only JavaScript objects in the same origin as the page that loaded the plugin.

In addition to this, a further extension to this API is being discussed that would give a plugin greater flexibility by letting the plugin control the origin of the calling code, so that the plugin can specify the origin of calls that come from internally loaded code from other origins. This way such code can be executed with only the privileges of the origin of the code, and not the privileges of the plugin page's origin.

What's in the plugin code?

A plugin that wishes to be scriptable using this new mechanism needs to return the appropriate {{template.Npapi("NPObject")}} (which is created by calling {{template.Funcref("NPN_CreateObject")}}) when the browser requests it by calling:

NPP_GetValue(npp, NPPVpluginScriptableNPObject, ...);

Accessing browser objects from a plugin

A plugin that wishes to access objects in the browser window that loaded the plugin can do this by getting the {{template.Npapi("NPObject")}} for the browsers window object, or the DOM element that loaded the plugin. This is done by using an extension to {{template.Funcref("NPN_GetValue")}}. The extensions are two additions to the {{template.Npapi("NPNVariables")}} enumeration, the new enumerations are NPNVWindowNPObject and NPNVPluginElementNPObject. By calling NPN_GetValue() with either of those new enumerations will return an NPObject representing the browser object, and from there, the functions in this API can be used to get and set properties, and to call methods on those browser objects.

And as always when working with reference counted NPObjects, the caller is responsible for calling {{template.Funcref("NPN_ReleaseObject")}} on the NPObject to drop the reference.

The new NPNVariable enumerations are defined in {{template.Source("modules/plugin/base/public/npapi.h", "npapi.h")}} as:

NPNVWindowNPObject = 15,
NPNVPluginElementNPObject = 16

How to call plugin native methods

The following HTML code will do the job:

<embed type="application/plugin-mimetype">
<script>
  var embed = document.embeds[0];
  embed.nativeMethod();
  alert(embed.nativeProperty);
  embed.nativeProperty.anotherNativeMethod();
</script>

The API extensions

The API extensions are based on four new structs:

  • {{template.Npapi("NPString")}}
  • {{template.Npapi("NPVariant")}}
    • {{template.Funcref("NPN_ReleaseVariantValue")}}
    • {{template.Funcref("NPN_GetStringIdentifier")}}
    • {{template.Funcref("NPN_GetStringIdentifiers")}}
    • {{template.Funcref("NPN_GetIntIdentifier")}}
    • {{template.Funcref("NPN_IdentifierIsString")}}
    • {{template.Funcref("NPN_UTF8FromIdentifier")}}
    • {{template.Funcref("NPN_IntFromIdentifier")}}
  • {{template.Npapi("NPObject")}}
    • {{template.Funcref("NPN_Construct")}} (since Firefox 3.0b1)
    • {{template.Funcref("NPN_CreateObject")}}
    • {{template.Funcref("NPN_RetainObject")}}
    • {{template.Funcref("NPN_ReleaseObject")}}
    • {{template.Funcref("NPN_Invoke")}}
    • {{template.Funcref("NPN_InvokeDefault")}}
    • {{template.Funcref("NPN_Enumerate")}} (since Mozilla 1.9a1)
    • {{template.Funcref("NPN_Evaluate")}}
    • {{template.Funcref("NPN_GetProperty")}}
    • {{template.Funcref("NPN_SetProperty")}}
    • {{template.Funcref("NPN_RemoveProperty")}}
    • {{template.Funcref("NPN_HasProperty")}}
    • {{template.Funcref("NPN_HasMethod")}}
    • {{template.Funcref("NPN_SetException")}}
  • {{template.Npapi("NPClass")}}

{{template.PreviousNext("Gecko Plugin API Reference:Browser Side Plug-in API", "Gecko Plugin API Reference:Structures")}}

{{ wiki.languages( { "pl": "pl/Dokumentacja_wtyczek_Gecko/Wtyczki_skryptowalne" } ) }}

Revision Source

<p>
{{template.PreviousNext("Gecko Plugin API Reference:Browser Side Plug-in API", "Gecko Plugin API Reference:Structures")}} {{template.Npapiref()}}
</p><p><span class="comment">XXX: Dummy p element</span>
</p>
<p><a href="en/Plugins">NPAPI plugins</a> that used to take advantage of being scriptable via LiveConnect in 4.x Netscape browsers lost this possibility in Mozilla (due to the <a class="external" href="http://java.sun.com/j2se/1.3/docs/guide/jni/spec/jniTOC.doc.html">JNI</a> making the Netscape 4.x JRI obsolete). As an answer to this large gap in the Netscape Plugin API, an extension to the API has been developed that lets plugins be scriptable again, independent of Java. This extension will also let plugins access the script objects in the browser, and is thus a much stronger and more flexible API.</p>
<p>This document describes the new cross-browser NPAPI extensions that have been developed by a group of browser and plugin vendors, including the <a class="external" href="http://www.mozilla.org">Mozilla Foundation</a>, <a class="external" href="http://www.adobe.com">Adobe</a>, <a class="external" href="http://www.apple.com">Apple</a>, <a class="external" href="http://www.opera.com">Opera</a>, and <a class="external" href="http://www.sun.com">Sun Microsystems</a> (see <a class="external" href="http://www.mozilla.org/press/mozilla-2004-06-30.html">press release</a>).  This document also explains how to make a plugin use these new extensions to be scriptable as well as how to access objects in a browser.
</p>
<div class="note">
<p>The information in this section applies to Firefox 1.0 and Mozilla 1.7.5 and newer versions.
</p>
</div>
<h2 name="How_the_DOM_handles_scripting">How the DOM handles scripting</h2>
<p>The Mozilla DOM code now checks if a plugin supports this new scriptability API and if it exposes a scriptable object through this new mechanism. Mozilla does this by calling the old plugin API call {{template.Npapi("NPP_GetValue")}} with the new enumeration value that has been added to the {{template.Npapi("NPPVariable")}} enumeration.
</p><p>The new <code>NPPVariable</code> enumeration is defined in <tt>npapi.h</tt> as:
</p>
<pre class="eval">NPPVpluginScriptableNPObject = 15
</pre>
<h2 name="Threading_model">Threading model</h2>
<p>This API is not designed to be thread safe. The threading model for this API is such that all calls through this API are synchronous and calls from a plugin to methods in this API must come from the thread on which the plugin was initiated, and likewise all calls to methods in this API by the browser are guaranteed to come from the same thread. Future revisions to this API might provide a mechanism for proxying calls from one thread to another to aid in using this API from other threads.
</p>
<h2 name="Security_model">Security model</h2>
<p>The security model for making calls through this API is much like the general <a class="external" href="http://www.mozilla.org/projects/security/components/same-origin.html">same-origin</a> security model enforced by the browser. That means that script from an origin other than the origin of the page that loaded the plugin is not able to access methods and properties on the plugin. The same thing applies the other way too, the plugin can reach only JavaScript objects in the same origin as the page that loaded the plugin.
</p><p>In addition to this, a further extension to this API is being discussed that would give a plugin greater flexibility by letting the plugin control the origin of the calling code, so that the plugin can specify the origin of calls that come from internally loaded code from other origins. This way such code can be executed with only the privileges of the origin of the code, and not the privileges of the plugin page's origin.
</p>
<h2 name="What.27s_in_the_plugin_code.3F">What's in the plugin code?</h2>
<p>A plugin that wishes to be scriptable using this new mechanism needs to return the appropriate {{template.Npapi("NPObject")}} (which is created by calling {{template.Funcref("NPN_CreateObject")}}) when the browser requests it by calling:
</p>
<pre class="eval">NPP_GetValue(npp, NPPVpluginScriptableNPObject, ...);
</pre>
<h2 name="Accessing_browser_objects_from_a_plugin">Accessing browser objects from a plugin</h2>
<p>A plugin that wishes to access objects in the browser window that loaded the plugin can do this by getting the {{template.Npapi("NPObject")}} for the browsers window object, or the DOM element that loaded the plugin. This is done by using an extension to {{template.Funcref("NPN_GetValue")}}. The extensions are two additions to the {{template.Npapi("NPNVariables")}} enumeration, the new enumerations are <code>NPNVWindowNPObject</code> and <code>NPNVPluginElementNPObject</code>. By calling <code>NPN_GetValue()</code> with either of those new enumerations will return an <code>NPObject</code> representing the browser object, and from there, the functions in this API can be used to get and set properties, and to call methods on those browser objects.
</p><p>And as always when working with reference counted <code>NPObject</code>s, the caller is responsible for calling {{template.Funcref("NPN_ReleaseObject")}} on the <code>NPObject</code> to drop the reference.
</p><p>The new <code>NPNVariable</code> enumerations are defined in {{template.Source("modules/plugin/base/public/npapi.h", "npapi.h")}} as:
</p>
<pre class="eval">NPNVWindowNPObject = 15,
NPNVPluginElementNPObject = 16
</pre>
<h2 name="How_to_call_plugin_native_methods">How to call plugin native methods</h2>
<p>The following HTML code will do the job:
</p>
<pre class="eval">&lt;embed type="application/plugin-mimetype"&gt;
&lt;script&gt;
  var embed = document.embeds[0];
  embed.nativeMethod();
  alert(embed.nativeProperty);
  embed.nativeProperty.anotherNativeMethod();
&lt;/script&gt;
</pre>
<h2 name="The_API_extensions">The API extensions</h2>
<p>The API extensions are based on four new structs:
</p>
<ul><li> {{template.Npapi("NPString")}}
</li><li> {{template.Npapi("NPVariant")}}
<ul><li> {{template.Funcref("NPN_ReleaseVariantValue")}}
</li><li> {{template.Funcref("NPN_GetStringIdentifier")}}
</li><li> {{template.Funcref("NPN_GetStringIdentifiers")}}
</li><li> {{template.Funcref("NPN_GetIntIdentifier")}}
</li><li> {{template.Funcref("NPN_IdentifierIsString")}}
</li><li> {{template.Funcref("NPN_UTF8FromIdentifier")}}
</li><li> {{template.Funcref("NPN_IntFromIdentifier")}}
</li></ul>
</li><li> {{template.Npapi("NPObject")}}
<ul><li> {{template.Funcref("NPN_Construct")}} (since Firefox 3.0b1)
</li><li> {{template.Funcref("NPN_CreateObject")}}
</li><li> {{template.Funcref("NPN_RetainObject")}}
</li><li> {{template.Funcref("NPN_ReleaseObject")}}
</li><li> {{template.Funcref("NPN_Invoke")}}
</li><li> {{template.Funcref("NPN_InvokeDefault")}}
</li><li> {{template.Funcref("NPN_Enumerate")}} (since Mozilla 1.9a1)
</li><li> {{template.Funcref("NPN_Evaluate")}}
</li><li> {{template.Funcref("NPN_GetProperty")}}
</li><li> {{template.Funcref("NPN_SetProperty")}}
</li><li> {{template.Funcref("NPN_RemoveProperty")}}
</li><li> {{template.Funcref("NPN_HasProperty")}}
</li><li> {{template.Funcref("NPN_HasMethod")}}
</li><li> {{template.Funcref("NPN_SetException")}}
</li></ul>
</li><li> {{template.Npapi("NPClass")}}
</li></ul>
<p>{{template.PreviousNext("Gecko Plugin API Reference:Browser Side Plug-in API", "Gecko Plugin API Reference:Structures")}}
</p>{{ wiki.languages( { "pl": "pl/Dokumentacja_wtyczek_Gecko/Wtyczki_skryptowalne" } ) }}
Revert to this revision