You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by Apache Wiki <wi...@apache.org> on 2013/02/01 22:35:25 UTC

[Cordova Wiki] Update of "PluginDesign" by FilMaj

Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Cordova Wiki" for change notification.

The "PluginDesign" page has been changed by FilMaj:
http://wiki.apache.org/cordova/PluginDesign?action=diff&rev1=8&rev2=9

Comment:
Added alunny's plugin spec

- = Plugin Design =
+ = Cordova Plugin Specification =
  
- Great first pass at a [[https://github.com/deedubbu/cordova-blackberry-pluggable|big picture pluggable BlackBerry WebWorks-based implementation]] courtesy of Drew. Awesome start!
+ Last edited August 16, 2012
  
- == Plugin Name Convention ==
+ == About this document ==
  
+ This document defines a format for distributing and packaging plugins for use with Apache Cordova, nee PhoneGap. It is based on the work done as part of the PhoneGap Build (https://build.phonegap.com) web service, where many of the tools and techniques have been implemented. Originally this document was authored at http://github.com/alunny/cordova-plugin-spec.
-  * cordova-plugin-xxx
-   * clearly a plugin for the Cordova framework
-   * in the Web community, lowercase and dashes are common
-  * cordova-xxx
-   * shorter name
-   * puts a plugin on par with a framework, which can be confusing
  
- == Directory Structure ==
- 
- Below are examples based on existing prototype implementations.
- 
-  * Based on [[https://github.com/deedubbu/cordova-blackberry-pluggable|Drew's prototype]], JavaScript and native code is packaged in the same directory. It is a bit tied to the specifics of the WebWorks platform, but the general structure is:
-   * All plugins plus the core framework are encapsulated as extensions, which is a WebWorks concept. These extensions package up any necessary JS and native code.
-   * Each extension is included with your final application via declaring specific {{{<feature>}}} elements in your application's config.xml file. Each {{{<feature>}}} maps to a specific extension: either the core framework or a plugin.
- 
- == Meta Files ==
- 
- TBD
- 
- == Documentation ==
- 
-  * handwritten in Markdown
-  * rendered at build-time from tooling
-  * rendered from Markdown file or embedded comments
-  * simple process, think README.md
- 
- == JavaScript files ==
- 
-  * Taking advantage of the plugin interfaces defined in the [[http://git-wip-us.apache.org/repos/asf?p=cordova-js.git;a=summary|cordova-js]] project:
-   * Using the {{{exec}}} function that is referencerable by calling {{{cordova.require('cordova/exec')}}} regardless of platform.
-    * {{{exec}}} function has the signature {{{function(successCallback, errorCallback, service, action, args}}}, with the arguments:
-     * {{{successCallback}}} - function that native can invoke by calling their {{{success}}} method and optionally pass in arguments
-     * {{{errorCallback}}} - function that native can invoke by calling their {{{error}}} method and optionally pass in arguments
-     * {{{service}}} - the native plugin label that maps to the desired native plugin. Each native platform has a different mapping mechanism - see the below Native Files section for more details
-     * {{{action}}} - the native plugin method label that maps to the desired native plugin method. Each native platform has a different mapping mechanism - see below under Native Files section for more details
-     * {{{args}}} - an Array of parameters to pass into the native plugin methods
-   * Recommended to use {{{cordova.define}}} as module definition wrapper that conforms with cordova.
-  * No JavaScript requirements on namespacing plugins (used to be that all plugins were added to a {{{window.plugins}}} object). This should be up to the plugin author.
- 
- == Native Files ==
- 
-  * Taking advantage of the plugin interfaces defined for each platform:
-   * iOS: The [[http://git-wip-us.apache.org/repos/asf?p=cordova-ios.git;a=blob;f=CordovaLib/Classes/CDVPlugin.h;h=662d4e9de9a3369b0fd14ceb225a83f9f87b4e69;hb=HEAD|CDVPlugin interface]]. Also available is a [[http://git-wip-us.apache.org/repos/asf?p=cordova-ios.git;a=blob;f=guides/Cordova+Plugin+Upgrade+Guide.md;h=e0e4b3ca8f2e9369da7d6984823e41afcb9b367c;hb=HEAD|Cordova Plugin Upgrade guide]]. iOS has an explicit mapping of JavaScript {{{exec}}} function's {{{service}}} plugin labels to iOS class names in the [[http://git-wip-us.apache.org/repos/asf?p=cordova-ios.git;a=blob;f=Cordova-based+Application/Cordova.plist;h=eaf4824f3b5627637ed8715e9603b76b688d5883;hb=HEAD|Cordova.plist file]]. {{{exec}}}'s {{{service}}} parameter maps directly to methods implemented in the CDVPlugin.
-   * Android: The [[http://git-wip-us.apache.org/repos/asf?p=cordova-android.git;a=blob;f=framework/src/org/apache/cordova/api/Plugin.java;h=648e86d6c3eb9a0c62726cc9d238dcb4c19ccd54;hb=HEAD|Plugin]] interface. Android maps JavaScript {{{exec}}} {{{service}}} labels to Android Plugin classes using the [[http://git-wip-us.apache.org/repos/asf?p=cordova-android.git;a=blob;f=framework/res/xml/plugins.xml;h=ce978fb48b9b171283739e057b58226924ccf75b;hb=HEAD|plugins.xml file]]. The Plugin class' {{{execute}}} [[http://git-wip-us.apache.org/repos/asf?p=cordova-android.git;a=blob;f=framework/src/org/apache/cordova/api/Plugin.java;h=648e86d6c3eb9a0c62726cc9d238dcb4c19ccd54;hb=HEAD#l46|method]] picks up on the {{{service}}} label as a parameter.
-   * WP7: The [[https://github.com/apache/cordova-wp7/blob/master/framework/Cordova/Commands/BaseCommand.cs|BaseCommand]]. BaseCommands are created by reflecting on assemblies at runtime (thus lazily loaded) and mapping the {{{service}}} parameter directly to the class name. Similarly the {{{action}}} label maps directly to the method name.
-   * BlackBerry: Identical to Android's implementation. There is a [[https://github.com/apache/cordova-blackberry-webworks/blob/master/framework/ext/src/org/apache/cordova/api/Plugin.java|Plugin]] class. A [[https://github.com/apache/cordova-blackberry-webworks/blob/master/template/project/www/plugins.xml|plugins.xml]] file maps {{{service}}} labels to class names. The Plugin's {{{execute}}} function should parse the passed-in {{{action}}} label to determine what method to fire on the native plugin.
-   * Playbook: TBD
-   * Bada: TBD
- 
- == Tooling ==
+ == Sample Tooling ==
  
- TBD
+  * plugman: a node.js based tool to install and remove compliant plugins: https://github.com/imhotep/plugman
+  * Sample Plugins
+   * ChildBrowser: https://github.com/alunny/ChildBrowser
+   * PG-SQLite Plugin: https://github.com/ApplicationCraft/PGSQLitePlugin
  
+ == Design Goals ==
+ 
+ The goals of this format are:
+ 
+  * facilitate programmatic installation and manipulation of plugins
+  * detail the dependencies and components of individual plugins
+  * allow code reuse between different target platforms
+ 
+ == Structure of a plugin ==
+ 
+ A plugin is typically a combination of some web/www code, and some native code. However, plugins may have only one of these things - a plugin could be a single JavaScript, or some native code with no corresponding JavaScript.
+ 
+ Assuming both web code and native code are present, the plugins should be structured like so:
+ 
+ {{{
+ foo-plugin # top-level directory
+ -- plugin.xml # xml-based manifest, described below
+ -- src # native source-code, to be compiled for a single platform
+   -- android
+     -- Foo.java
+   -- ios
+     -- CDVFoo.h
+     -- CDVFoo.m
+ -- www # assets to be copied into the www directory of the Cordova project
+   -- foo.js
+   -- foo.png
+ }}}
+ 
+ == Plugin Manifest Format ==
+ 
+ The plugin.xml file is an XML document in the plugins namespace - http://www.phonegap.com/ns/plugins/1.0. It contains a top-level plugin element defining the plugin, and children that define the structure of the plugin.
+ 
+ {{{#!wiki caution
+ '''Namespace'''
+ 
+ The above namespace likely needs to be looked at from an Apache Cordova perspective.
+ }}}
+ 
+ A sample plugin element:
+ 
+ {{{
+ <plugin xmlns="http://www.phonegap.com/ns/plugins/1.0"
+     xmlns:android="http://schemas.android.com/apk/res/android"
+     id="com.alunny.foo"
+     version="1.0.2">
+ }}}
+ 
+ === <plugin> element ===
+ 
+ The plugin element is the top-level element of the plugin manifest. It has the following attributes:
+ 
+ ==== xmlns (required) ====
+ 
+ The plugin namespace - http://www.phonegap.com/ns/plugins/1.0. If the document contains XML from other namespaces - for example, tags to be added ot the AndroidManifest.xml file - those namespaces should also be included in the top-level element.
+ 
+ ==== id (required) ====
+ 
+ A reverse-domain style identifier for the plugin - for example, com.alunny.foo
+ 
+ ==== version (required) ====
+ 
+ A version number for the plugin, that matches the following major-minor-patch style regular expression:
+ 
+ {{{
+ ^\d+[.]\d+[.]\d+$
+ }}}
+ 
+ === Child elements ===
+ 
+ ==== <engines> element ====
+ 
+ The child elements of the <engines> element specify versions of Apache Cordova-based frameworks that this plugin supports. An example:
+ 
+ {{{
+ <engines>
+     <engine name="cordova" version="1.7.0" />
+     <engine name="cordova" version="1.8.1" />
+     <engine name="worklight" version="1.0.0" />
+ </engines>
+ }}}
+ 
+ Similarly to the version attribute for the <plugin> element, the version string specified should matcha a major-minor-patch string conforming to the regular expression:
+ 
+ {{{
+ ^\d+[.]\d+[.]\d+$
+ }}}
+ 
+ Engine elements may also have fuzzy matches to avoid repetition, and reduce maintenance when the underlying platform is updated. A minimum of >, >=, < and <= should be supported by tools, such as:
+ 
+ {{{
+ <engines>
+     <engine name="cordova" version=">=1.7.0" />
+     <engine name="cordova" version="<1.8.1" />
+ </engines>
+ }}}
+ 
+ Tools may abort plugin installation if the target project does not meet the engine constraints.
+ 
+ ==== <name> element ====
+ 
+ A human-readable name for the plugin. The text content of the element contains the name of the plugin. An example:
+ 
+ {{{
+ <name>Foo</name>
+ }}}
+ 
+ At this point in time, the tools prototyped for this format do not make use of this element. If this document progresses, localization will also need to be accounted for.
+ 
+ ==== <asset> element ====
+ 
+ One or more elements listing the files or directories to be copied into a Cordova app's www directory. A couple of samples:
+ 
+ {{{
+ <!-- a single file, to be copied in the root directory -->
+ <asset src="www/foo.js" target="foo.js" />
+ <!-- a directory, also to be copied in the root directory -->
+ <asset src="www/foo" target="foo" />
+ }}}
+ 
+ All assets tags require both a src attribute and a target attribute.
+ 
+ ===== src (required) =====
+ 
+ Where the file or directory is located in the plugin package, relative to the plugin.xml document.
+ 
+ ===== target (required) =====
+ 
+ Where the file or directory should be located in the Cordova app, relative to the www directory.
+ 
+ Assets can be targeted to subdirectories - for instance:
+ 
+ {{{
+ <asset src="www/new-foo.js" target="js/experimental/foo.js" />
+ }}}
+ 
+ would create the js/experimental directory in the www directory, if not present, and then copy the file new-foo.js as foo.js into that directory.
+ 
+ If a file exists at the target location, tools based on this specification should stop the installation process and notify the user of the conflict.
+ 
+ ==== <platform> ====
+ 
+ Platform tags identify platforms that have associated native code. Tools using this specification can identify supported platforms and install the code into Cordova projects.
+ 
+ A sample platform tag:
+ 
+ {{{
+ <platform name="android">
+ <!-- android specific elements -->
+ </platform>
+ <platform name="ios">
+ <!-- ios specific elements -->
+ </platform>
+ }}}
+ 
+ ===== name (required) =====
+ 
+ The name attribute identifies a platform as supported - it also associates the element's children with that platform.
+ 
+ Platform names should be all-lowercase. Platform names, as arbitrarily chosen, are listed:
+ 
+ {{{
+ android
+ ios
+ blackberry
+ wp7
+ wp8
+ windows8
+ }}}
+ 
+ Tools may accept alternate names for platforms. Whatever.
+ 
+ ==== <source-file> ====
+ 
+ source-file elements identify executable source code that should be installed into a project. A couple of examples:
+ 
+ {{{
+ <!-- android -->
+ <source-file src="src/android/Foo.java"
+                 target-dir="src/com/alunny/foo" />
+ <!-- ios -->
+ <source-file src="CDVFoo.m" />
+ }}}
+ 
+ As with assets, if a source-file would overwrite an existing file, tools should notify the user and stop, like, right away.
+ 
+ ===== src (required) =====
+ 
+ Where the file is located, relative to the plugin.xml file.
+ 
+ ===== target-dir =====
+ 
+ A directory where the files should be copied into, relative to the root of the Cordova project.
+ 
+ In practice, this is most important for Java-based platforms, where a file in the package com.alunny.foo has be located under the directory com/alunny/foo. For platforms where the source directory is not important, plugin authors should omit this attribute.
+ 
+ ==== <config-file> ====
+ 
+ Identifies an XML-based configuration file to be modified, where in that document the modification should take place, and what should be modified.
+ 
+ At this stage in the spec, the config-file element only allows for appending new children into an XML document. The children are XML literals that are the to be inserted in the target document.
+ 
+ Example:
+ 
+ {{{
+ <config-file target="AndroidManifest.xml" parent="/manifest/application">
+     <activity android:name="com.foo.Foo"
+               android:label="@string/app_name">
+               <intent-filter>
+               </intent-filter>
+     </activity>
+ </config-file>
+ }}}
+ 
+ ===== target =====
+ 
+ The file to be modified, and the path relative to the root of the Cordova project.
+ 
+ If this file does not exist, tools should self-destruct over a period of ten minutes. Within the first five minutes, the self-destruct procedure MAY be cancelled with the appropriate security clearance. After five minutes have passed, the self-destruct procedure MUST complete.
+ 
+ Or they could just stop.
+ 
+ ===== parent =====
+ 
+ An absolute XPath selector pointing to the parent of the elements to be added to the config file.
+ 
+ ==== <plugins-plist> ====
+ 
+ Specifies a key and value to append to the correct AppInfo.plist file in an iOS Cordova project. Example:
+ 
+ {{{
+ <plugins-plist key="Foo"
+                string="CDVFoo" />
+ }}}
+ 
+ This may be an implementation detail leaking through, and could be merged with the config-file element at some later point.
+ 
+ ==== <resource-file> and <header-file> ====
+ 
+ Like source files, but specifically for platforms that distinguish between source files, headers, and resources (iOS)
+ 
+ Examples:
+ 
+ {{{
+ <resource-file src="CDVFoo.bundle" />
+ <resource-file src="CDVFooViewController.xib" />
+ <header-file src="CDVFoo.h" />
+ }}}
+ 
+ This is probably an implementation detail leaking through, and future versions of this document will likely merge these elements with source-file.
+ 
+ ==== <framework> ====
+ 
+ Identifies a framework (usually part of the OS/platform) that the plugin depends on. Example:
+ 
+ {{{
+ <framework src="libsqlite3.dylib" />
+ }}}
+ 
+ Tools should identify the framework through the src attribute and attempt to add the framework to the Cordova project, in the correct fashion for a given platform.
+ 
+ ===== Variables =====
+ 
+ In certain cases, a plugin may need to make configuration changes dependent on the target application. For example, to register for C2DM on Android, an app with package id com.alunny.message would need a permission like:
+ 
+ {{{
+ <uses-permission
+ android:name="com.alunny.message.permission.C2D_MESSAGE"/>
+ }}}
+ 
+ In cases like this (where the content inserted from the plugin.xml file is not known ahead of time), variables can be indicated by a dollar-sign and a series of capital letters, digits and underscores. For the above example, the plugin.xml file would include this tag:
+ 
+ {{{
+ <uses-permission
+ android:name="$PACKAGE_NAME.permission.C2D_MESSAGE"/>
+ }}}
+ 
+ Tools using this specification should replace variable references with the correct value, if specified, or the empty string otherwise.
+ 
+ The value of the variable reference may be detected by the plugin installation tool (in this case, by reading the AndroidManifest.xml file), or specified by the end-user. One approach could be using environment variables:
+ 
+ {{{
+ $ pluginstall android . ~/my-plugin PACKAGE_NAME=com.foo
+ }}}
+ 
+ Variable resolution could also be specified programmatically, depending how the plugin installer is called.
+ 
+ Certain variable names should be reserved - these are listed below.
+ 
+ '''''$PACKAGE_NAME'''''
+ 
+ The reverse-domain style unique identifier for the package - corresponding to the CFBundleIdentifier on iOS or the package attribute of the top-level manifest element in an AndroidManifest.xml file.
+ 
+ == Authors ==
+ 
+  * Andrew Lunny
+  * Fil Maj
+ 
+ == Contributors ==
+ 
+  * Michael Brooks
+  * Mike Reinstein
+