The Opera plug-in interface
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
- MozillaPlugins registry key
- Security model
- What's in the plugin code?
- Accessing browser objects from a plugin
- How to call plugin native methods
- The API extensions
- Common typedefs
- NPString
- NPVariant
- JavaScript to NPVariant type mapping
- NPN_ReleaseVariantValue()
- NPN_GetStringIdentifier()
- NPN_GetStringIdentifiers()
- NPN_GetIntIdentifier()
- NPN_IdentifierIsString()
- NPN_UTF8FromIdentifier()
- NPN_IntFromIdentifier()
- NPObject
- NPClass
- NPN_CreateObject()
- NPN_RetainObject()
- NPN_ReleaseObject()
- NPN_Invoke()
- NPN_InvokeDefault()
- NPN_Evaluate()
- NPN_GetProperty()
- NPN_SetProperty()
- NPN_RemoveProperty()
- NPN_HasProperty()
- NPN_HasMethod()
- NPN_SetException()
The properties covered below are as follows:
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
NPObject
s, 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. NPIdentifier
s are unique, e.g. for any
given string or integer, there is only one
NPIdentifier
. The lifetime of
NPIdentifier
s 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 NPVariant
s to
access JavaScript objects in the browser, or vise versa, the
mapping of JavaScript values to NPVariant
s 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 NPVariant
s of
type NPVARIANTTYPE_OBJECT
, and
NPN_FreeMem()
on NPVariant
s 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. NPObject
s are reference counted objects, so
callers need to be aware and properly release acquired references
to NPObject
s. 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
NPObject
s 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 NPVariant
s, 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 NPVariant
s, 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 NPObject
s
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.
ekrem
Monday, June 11, 2012
ekrem
Monday, June 11, 2012
Daniel Davis
Monday, September 3, 2012
http://dev.opera.com/addons/extensions/
It includes a Hello World tutorial, further examples and API documentation.