The Opera plug-in interface

By Opera Software

Note: This documentation applies to version 9.0 and later of Opera for desktop, mobile phones, and devices.

If you're looking for information about Opera extensions (addons using JavaScript, CSS, etc.), here is our Opera extensions documentation.

Table of contents:

Introduction

This document describes the new cross-browser NPAPI extensions that has been developed by a group of browser and plugin vendors, including Opera Software, the Mozilla Foundation, Adobe, Apple, and Sun Microsystems. This document also talks about how to make a plugin use these new extensions to be scriptable, and how to access objects in a browser.

The new NPPVariable enumeration is defined in npapi.h as:

NPPVpluginScriptableNPObject = 15

MozillaPlugins registry key

Note that Opera supports and encourages the MozillaPlugins registry key for plugins on Windows, use of which is described in this article covering The First Install Problem. You should read up on this and employ it in your plugins, as it is the preferred way plugin developers can make sure the vast majority of NPAPI browsers (Opera, Firefox and Safari all support it) pick up on their plugins. Employing a MozillaPlugins registry entry also ensures that browsers can detect your plugin in whatever location it is installed, avoiding the need for ugly hacks.

As an example, some plugins refuse to install unless they find a specific browser on the system, typically Firefox (many NPAPI plugins seem to be named "Firefox plugins"). This is a bad practice, and should be avoided - adding the registry key completely eliminates the need to do this kind of installer "browser sniffing".

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.

What's in the plugin code?

A plugin that wishes to be scriptable using this new mechanism needs to return the appropriate NPObject (which is created by calling 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 NPObject for the browsers window object, or the DOM element that loaded the plugin. This is done by using an extension to NPN_GetValue(). The extensions are two additions to the 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 NPN_ReleaseObject() on the NPObject to drop the reference.

The new NPNVariable enumerations are defined in 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 language="javascript">
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, NPString, NPVariant, NPObject, and NPClass.

Common typedefs

NPUTF8 is a byte representing an 8-bit unit of a UTF-8 character.

typedef char NPUTF8;

NPIdentifier is an opaque type used for method and property identifiers, e.g. strings or integers. NPIdentifiers are unique, e.g. for any given string or integer, there is only one NPIdentifier. The lifetime of NPIdentifiers is controlled by the browser

typedef void *NPIdentifier;

NPString

NPString is a struct that holds a pointer to a sequence of 8-bit units (NPUTF8) making up a UTF-8 string, and the number of 8-bit units in the UTF-8 string.

Whenever an NPString owns its string data and the data may be released through a call to NPN_ReleaseVariantValue(), the string data must be allocated using NPN_MemAlloc().

The struct is defined as follows:

typedef struct _NPString {
 const NPUTF8 *utf8characters;
 uint32_t utf8length;
} NPString;

NPVariant

NPVariant is a struct that holds a value and the type of that value. The value is held in a union, and the type is one of types defined in the NPVariantType enumeration.

The NPVariantType enumeration and NPVariant struct is defined as follows:

typedef enum {
 NPVariantType_Void,
 NPVariantType_Null,
 NPVariantType_Bool,
 NPVariantType_Int32,
 NPVariantType_Double,
 NPVariantType_String,
 NPVariantType_Object
} NPVariantType;
typedef struct _NPVariant {
 NPVariantType type;
 union {
  bool boolValue;
  uint32_t intValue;
  double_t doubleValue;
  NPString stringValue;
  NPObject *objectValue;
 } value;
} NPVariant;

Plugin developers are not expected to directly manipulate or access the members of the NPVariant instance, instead, the function NPN_ReleaseVariantValue(), and the following macros are provided:

NPVARIANT_IS_VOID(v) Evaluates to true if v is of type NPVariantType_Void.
NPVARIANT_IS_NULL(v) Evaluates to true if v is of type NPVariantType_Null.
NPVARIANT_IS_BOOLEAN(v) Evaluates to true if v is of type NPVariantType_Bool.
NPVARIANT_IS_INT32(v) Evaluates to true if v is of type NPVariantType_Int32.
NPVARIANT_IS_DOUBLE(v) Evaluates to true if v is of type NPVariantType_Double.
NPVARIANT_IS_STRING(v) Evaluates to true if v is of type NPVariantType_String.
NPVARIANT_IS_OBJECT(v) Evaluates to true if v is of type NPVariantType_Object.
NPVARIANT_TO_BOOLEAN(v) Extracts the boolean value from v.
NPVARIANT_TO_INT32(v) Extracts a signed 32-bit integer value from v.
NPVARIANT_TO_DOUBLE(v) Extracts a double precision floating point value from v.
NPVARIANT_TO_STRING(v) Extracts the NPString value from v.
NPVARIANT_TO_OBJECT(v) Extracts the NPObject value from v.
VOID_TO_NPVARIANT(v) Initialize v to a variant of type NPVariantType_Void.
NULL_TO_NPVARIANT(v) Initialize v to a variant of type NPVariantType_Null.
BOOLEAN_TO_NPVARIANT(val, v) Initialize v to a variant of type NPVariantType_Bool with the value val.
INT32_TO_NPVARIANT(val, v) Initialize v to a variant of type NPVariantType_Int32 with the value val.
DOUBLE_TO_NPVARIANT(val, v) Initialize v to a variant of type NPVariantType_Double with the value val.
STRINGZ_TO_NPVARIANT(val, v) Initialize v to a variant of type NPVariantType_String with the value being an NPString holding the UTF-8 string value val.
STRINGN_TO_NPVARIANT(val, len, v) Initialize v to a variant of type NPVariantType_String with the value being an NPString holding the UTF-8 string value val with the length len.
OBJECT_TO_NPVARIANT(val, v) Initialize v to a variant of type NPVariantType_Object with the value val.

JavaScript type to NPVariantType enumeration mapping

When using NPVariants to access JavaScript objects in the browser, or vise versa, the mapping of JavaScript values to NPVariants is as follows:

JavaScript types NPVariantType
undefined NPVariantType_Void
null NPVariantType_Null
boolean NPVariantType_Bool
number NPVariantType_Int32 or NPVariantType_Double
string NPVariantType_String
All other JavaScript types NPVariantType_Object

NPN_ReleaseVariantValue()

NPN_ReleaseVariantValue releases the value in the given variant. This must always be called on result variants and such in this API, i.e. any NPVariant whose value comes from a call that passes back an NPVariant must be released using this function. Access to the value in an NPVariant that has been released will result in undefined behavior.

NPN_ReleaseVariantValue() will call NPN_ReleaseObject() on NPVariants of type NPVARIANTTYPE_OBJECT, and NPN_FreeMem() on NPVariants of type NPVARIANTTYPE_STRING.

NPN_ReleaseVariantValue() is defined as follows:

void NPN_ReleaseVariantValue(NPVariant *variant);

NPN_GetStringIdentifier()

NPN_GetStringIdentifier returns an opaque identifier for the string that is passed in. All calls for the same string are guaranteed to return the same exact identifier.

NPN_GetStringIdentifier() is defined as follows:

NPIdentifier NPN_GetStringIdentifier(const NPUTF8 *name);

NPN_GetStringIdentifiers()

NPN_GetStringIdentifiers returns (through the identifiers out param) an array of opaque identifiers for the names that are passed in. Just like with NPN_GetStringIdentifier(), all calls for the same strings are guaranteed to return the same exact identifiers.

NPN_GetStringIdentifiers() is defined as follows:

void NPN_GetStringIdentifiers(const NPUTF8 **names, int32_t nameCount,
         NPIdentifier *identifiers);

NPN_GetIntIdentifier()

NPN_GetIntIdentifier returns an opaque identifiers for the integer that is passed in. Just like with NPN_GetStringIdentifier() all calls for the same integer are guaranteed to return the same exact identifier.

NPN_GetIntIdentifier() is defined as follows:

NPIdentifier NPN_GetIntIdentifier(int32_t intid);

NPN_IdentifierIsString()

NPN_IdentifierIsString returns true if the given identifier is a string identifier, or false if it is an integer identifier.

NPN_IdentifierIsString() is defined as follows:

bool NPN_IdentifierIsString(NPIdentifier *identifier);

NPN_UTF8FromIdentifier()

NPN_UTF8FromIdentifier returns a pointer to a UTF-8 string as a sequence of 8-bit units (NPUTF8), or NULL if the given identifier is not a string identifier. Once the caller is done with the returned string, the caller is responsible for deallocating the memory used by the string by calling NPN_MemFree()).

NPN_UTF8FromIdentifier() is defined as follows:

NPUTF8 *NPN_UTF8FromIdentifier(NPIdentifier identifier);

NPN_IntFromIdentifier()

NPN_IntFromIdentifier returns the integer value for the given integer identifier. If the given identifier is not a integer identifier, the behavior is undefined.

NPN_IntFromIdentifier() is defined as follows:

int32_t NPN_IntFromIdentifier(NPIdentifier identifier);

NPObject

NPObject is a struct that holds a pointer to an NPClass and an integer reference count, and possibly also implementation specific (i.e. plugin specific, or browser specific) members after or before the struct as defined here. NPObject is the type used to express objects exposed by either the plugin or by the browser through this API. The browsers are expected to expose their window objects and everything reachable from it through this API. NPObjects are reference counted objects, so callers need to be aware and properly release acquired references to NPObjects. To aid with the reference counting and ownership management in general, the functions NPN_CreateObject(), NPN_RetainObject(), NPN_ReleaseObject(), and NPN_ReleaseVariantValue() are provided as part of this API.

NPObject behavior is implemented using the set of callback functions defined in NPClass.

The NPObject struct is defined as follows:

struct NPObject {
   NPClass *_class;
   uint32_t referenceCount;
 /*
  * Additional space may be allocated here by types of NPObjects
  */
};

NPClass

NPClass is a struct that holds a set of pointers to functions that make up the behavior of an instance of an NPClass (i.e. an NPObject).

NPClass contains the following function pointers:

Name Description Return value
allocate Called by NPN_CreateObject() if non-NULL, else malloc() is called by the browser. This function is expected to allocate and return enough storage to hold the NPObject that is being created. A pointer to the newly allocated NPObject.
deallocate Called by NPN_ReleaseObject() if non-NULL, else free() is called when an objects reference count goes to zero. N/A
invalidate Called on live objects that belong to a plugin instance that is being destroyed. This call is always followed by a call to deallocate, or free(). Any attempt to use an invalidated object will result in undefined behavior. N/A
hasMethod Called by NPN_HasMethod() to check whether a given method exists or not on a given NPObject. true if the method exists on the NPObject, else false.
invoke Called by NPN_Invoke() to invoke a specific method on a given NPObject. true if the method invocation was successful, false in case an error occurred.
invokeDefault Called by NPN_InvokeDefault() to invoke the default method, if available, on a given NPObject. true if the method invocation was successful, false in case an error occurred.
hasProperty Called by NPN_HasProperty() to check whether a given property exists or not on a given NPObject. true if the property exists on the NPObject, else false.
getProperty Called by NPN_GetProperty() to get the value of a given property on a given NPObject. true if the method exists on the NPObject, else false.
setProperty Called by NPN_SetProperty() to set the value of a given property on a given NPObject. true if the property was set NPObject, else false.
removeProperty Called by NPN_RemoveProperty() to remove a given property on a given NPObject. true if the property was removed from the NPObject, else false.

The function pointer types are defined as follows:

typedef NPObject *(*NPAllocateFunctionPtr)(NPP npp, NPClass *aClass);
typedef void (*NPDeallocateFunctionPtr)(NPObject *npobj);
typedef void (*NPInvalidateFunctionPtr)(NPObject *npobj);
typedef bool (*NPHasMethodFunctionPtr)(NPObject *npobj, NPIdentifier name);
typedef bool (*NPInvokeFunctionPtr)(NPObject *npobj, NPIdentifier name,
         const NPVariant *args, uint32_t argCount,
         NPVariant *result);
typedef bool (*NPInvokeDefaultFunctionPtr)(NPObject *npobj,
             const NPVariant *args,
             uint32_t argCount,
             NPVariant *result);
typedef bool (*NPHasPropertyFunctionPtr)(NPObject *npobj, NPIdentifier name);
typedef bool (*NPGetPropertyFunctionPtr)(NPObject *npobj, NPIdentifier name,
           NPVariant *result);
typedef bool (*NPSetPropertyFunctionPtr)(NPObject *npobj, NPIdentifier name,
           const NPVariant *value);
typedef bool (*NPRemovePropertyFunctionPtr)(NPObject *npobj,
           NPIdentifier name);

The NPClass struct is defined as follows:

struct NPClass
{
 uint32_t structVersion;
 NPAllocateFunctionPtr allocate;
 NPDeallocateFunctionPtr deallocate;
 NPInvalidateFunctionPtr invalidate;
 NPHasMethodFunctionPtr hasMethod;
 NPInvokeFunctionPtr invoke;
 NPInvokeDefaultFunctionPtr invokeDefault;
 NPHasPropertyFunctionPtr hasProperty;
 NPGetPropertyFunctionPtr getProperty;
 NPSetPropertyFunctionPtr setProperty;
 NPRemovePropertyFunctionPtr removeProperty;
};

structVersion holds the version (NP_CLASS_STRUCT_VERSION) of the NPClass. At the time of this writing the version is 1.

NPN_CreateObject()

NPN_CreateObject allocates a new NPObject. If the given NPClass provides an allocate function it is used allocate the storage for the object and the NPP argument passed to NPN_CreateObject() is passed along to the allocate function. If no allocate function is provided, malloc() is called to allocate enough memory to hold an NPObject. The newly created NPObjects reference count is initialized to 1 before it is returned.

The NPN_CreateObject() function is defined as follows:

NPObject *NPN_CreateObject(NPP npp, NPClass *aClass);

NPN_RetainObject()

NPN_RetainObject increments the reference count of the given NPObject.

The NPN_RetainObject() function is defined as follows:

NPObject *NPN_RetainObject(NPObject *npobj);

NPN_ReleaseObject()

NPN_ReleaseObject decrements the reference count of the given NPObject. If the reference count reaches 0, the NPObject is deallocated using the deallocate function, if provided, or free().

The NPN_ReleaseObject() function is defined as follows:

void NPN_ReleaseObject(NPObject *npobj);

NPN_Invoke()

NPN_Invoke invokes a method on the given NPObject. The method arguments are passed as an array of NPVariants, and the number of arguments is passed in. The result of the method invocation is returned through an NPVariant result parameter. If the method invocation succeeds, NPN_Invoke() returns true, else false. When called by a plugin instance, the plugin instance must be passed as the npp argument.

Callers must call NPN_ReleaseVariantValue() on the result to release the result.

The NPN_Invoke() function is defined as follows:

bool NPN_Invoke(NPP npp, NPObject *npobj, NPIdentifier methodName,
    const NPVariant *args, uint32_t argCount, NPVariant *result);

Note: This method used to be called NPN_Call() in earlier revisions of this API but was renamed to NPN_Invoke() to be more consistently named.

NPN_InvokeDefault()

NPN_InvokeDefault invokes the default method, if available, on the given NPObject. The arguments are passed as an array of NPVariants, and the number of arguments is passed in. The result of the default method invocation is returned through an NPVariant result parameter. If the method invocation succeeds, NPN_InvokeDefault() returns true, else false. When called by a plugin instance, the plugin instance must be passed as the npp argument.

Callers must call NPN_ReleaseVariantValue() on the result to release the result.

If NPN_InvokeDefault() is called on an NPObject that is a wrapper for a callable JavaScript object, the JavaScript object is called. In this case the scope and 'this' of the JavaScript function call is set to the JavaScript object wrapped by the NPObject.

The NPN_InvokeDefault() function is defined as follows:

bool NPN_InvokeDefault(NPP npp, NPObject *npobj, NPIdentifier methodName,
        const NPVariant *args, uint32_t argCount, NPVariant *result);

NPN_Evaluate()

NPN_Evaluate evaluate evaluates a script on the scope of a given NPObject. The script is evaluated in the context of the window that the calling plugin instance (the NPP argument) is loaded in. NPN_Evaluate() returns true if the script was evaluated successfully, else false.

Callers must call NPN_ReleaseVariantValue() on the result to release the result.

The NPN_Evaluate() function is defined as follows:

bool NPN_Evaluate(NPP npp, NPObject *npobj, NPString *script,
      NPVariant *result);

NPN_GetProperty()

NPN_GetProperty gets the value of a property on the given NPObject. The property is identified with an NPIdentifier and the value is returned in the result parameter. When called by a plugin instance, the plugin instance must be passed as the npp argument.

Callers must call NPN_ReleaseVariantValue() on the result to release the result.

The NPN_GetProperty() function is defined as follows:

bool NPN_GetProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName,
      NPVariant *result);

NPN_SetProperty()

NPN_SetProperty sets the value of a property on the given NPObject. The property is identified with an NPIdentifier. NPN_SetProperty returns true if the property was successfully set, else false. When called by a plugin instance, the plugin instance must be passed as the npp argument.

The NPN_SetProperty() function is defined as follows:

bool NPN_SetProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName,
      const NPVariant *value);

NPN_RemoveProperty()

NPN_RemoveProperty removes a property from the given NPObject. The property is identified with an NPIdentifier. NPN_RemoveProperty returns true if the property was successfully removed, else false. When called by a plugin instance, the plugin instance must be passed as the npp argument.

The NPN_ReleaseObject() function is defined as follows:

bool NPN_RemoveProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName);

NPN_HasProperty()

NPN_HasProperty checks if a given property exists on the given NPObject. NPN_HasProperty returns true if the property exists, else false. When called by a plugin instance, the plugin instance must be passed as the npp argument.

The NPN_HasProperty() function is defined as follows:

bool NPN_HasProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName);

NPN_HasMethod()

NPN_HasMethod checks if a given method exis/codets on the given NPObject. NPN_HasMethod returns true if the method exists, else false. When called by a plugin instance, the plugin instance must be passed as the npp argument.

The NPN_HasMethod() function is defined as follows:

bool NPN_HasMethod(NPP npp, NPObject *npobj, NPIdentifier methodName);

NPN_SetException()

NPN_SetException can be called by a plugin to indicate that a call to one of the plugins NPObjects generated an error.

The NPN_SetException() function is defined as follows:

void NPN_SetException(NPObject *npobj, const NPUTF8 *message);

Implementation Notes

This cross-browser NPAPI extension mechanism has been developed in cooperation by a group of browser and plugin vendors. This means that it should be possible to produce a plug-in working in all browsers supporting it following this specification.

This article is based on the Mozilla.org documentation, written by Johnny Stenback.

Read more...

This article is licensed under a Creative Commons Attribution, Non Commercial - Share Alike 2.5 license.

Comments

The forum archive of this article is still available on My Opera.

  • photo

    ekrem

    Monday, June 11, 2012

    I want to write a plugin for opera with javascript.Please help me to do it
  • photo

    ekrem

    Monday, June 11, 2012

    Can anyone send a simple example please ?
  • photo

    Daniel Davis

    Monday, September 3, 2012

    The best place to start to build an Opera extension with JavaScript is here:
    ../../../addons/extensions/
    It includes a Hello World tutorial, further examples and API documentation.
No new comments accepted.