summaryrefslogtreecommitdiff
path: root/webhelper
diff options
context:
space:
mode:
authorPhilip Chimento <philip@endlessm.com>2013-09-18 13:47:29 -0700
committerPhilip Chimento <philip@endlessm.com>2013-09-23 15:40:54 -0700
commit73f112d4cdff1e246f7635fbf4747a21db730329 (patch)
tree2663b26e302624b6e84c8ac8bc6b19b1e2cdce9c /webhelper
parent7789b3e02580b0e2f71537ce4a8a2ef6dad0080d (diff)
Update WebHelper API to be introspectable
- Replace _webActions with define_web_action() method and another define_web_actions() method for the Endless.js overrides file - Replace _translationFunction with set_translation_function() and get_translation_function() [endlessm/eos-sdk#310]
Diffstat (limited to 'webhelper')
-rw-r--r--webhelper/webhelper.js126
1 files changed, 103 insertions, 23 deletions
diff --git a/webhelper/webhelper.js b/webhelper/webhelper.js
index 1992973..dc1f842 100644
--- a/webhelper/webhelper.js
+++ b/webhelper/webhelper.js
@@ -1,6 +1,7 @@
const Endless = imports.gi.Endless;
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;
+const Lang = imports.lang;
const WebKit = imports.gi.WebKit;
const EOS_URI_SCHEME = 'endless://';
@@ -17,8 +18,8 @@ const EOS_URI_SCHEME = 'endless://';
*
* WebHelper solves that problem by detecting when the web page navigates to a
* custom action URI.
- * The custom URI corresponds to a function that you define in
- * <Application._webActions>, and you can pass parameters to the
+ * The custom URI corresponds to a function that you define using
+ * <Application.define_web_action()>, and you can pass parameters to the
* function.
*
* Another often-encountered problem is localizing text through the same API as
@@ -42,18 +43,70 @@ const Application = new Lang.Class({
Name: 'WebApplication',
Extends: Endless.Application,
+ _init: function(props) {
+ this._webActions = {};
+ this._translationFunction = null;
+ this.parent(props);
+ },
+
/**
- * Property: _webActions
- * Set of actions that may be invoked from a WebView
+ * Method: define_web_action
+ * Define an action that may be invoked from a WebView
+ *
+ * Parameters:
+ * - name: a string, which must be a valid URI location.
+ * - implementation: a function (see Callback Parameters below.)
*
- * Declare them as a function that takes a dict as a parameter, and use
- * links with the format "endless://actionName?parameter=value"
+ * Callback Parameters:
+ * - dict: object containing properties corresponding to the query
+ * parameters that the web action was called with
*
- * *Note* This API will likely disappear and be replaced by a method
- * add_web_action().
- * That is the reason for the underscore starting the name.
+ * Sets up an action that may be invoked from an HTML document inside a
+ * WebView, or from the in-browser Javascript environment inside a WebView.
+ * If you set up an action "setVolume" as follows:
+ * > app.define_web_action('setVolume', function(dict) { ... });
+ * Then you can invoke the action inside the HTML document, e.g. as the
+ * target of a link, as follows:
+ * > <a href="endless://setVolume?volume=11">This one goes to 11</a>
+ * Or from the in-browser Javascript, by navigating to the action URI, as
+ * follows:
+ * > window.location = 'endless://setVolume?volume=11'
+ *
+ * In both cases, the function would then be called with the _dict_
+ * parameter equal to
+ * > { "volume": "11" }
+ *
+ * If an action called _name_ is already defined, the new _implementation_
+ * replaces the old one.
*/
- _webActions: { },
+ define_web_action: function(name, implementation) {
+ if(typeof implementation != 'function') {
+ throw new Error('The implementation of a web action must be a ' +
+ 'function.');
+ }
+ this._webActions[name] = implementation;
+ },
+
+ /**
+ * Method: define_web_actions
+ * Define several web actions at once
+ *
+ * Parameters:
+ * dict - an object, with web action names as property names, and their
+ * implementations as values
+ *
+ * Convenience method to define more than one web action at once.
+ * Calls <define_web_action()> on each property of _dict_.
+ *
+ * *Note* This API is Javascript-only. It will not be implemented in C.
+ */
+ define_web_actions: function(dict) {
+ for(let key in dict) {
+ if(dict.hasOwnProperty(key)) {
+ this.define_web_action(key, dict[key]);
+ }
+ }
+ },
/**
* Callback: web_actions_handler
@@ -101,8 +154,9 @@ const Application = new Lang.Class({
if(this._webActions[function_name])
Lang.bind(this, this._webActions[function_name])(parameters);
else
- throw new Error("Undefined WebHelper action '%s'. Did you add it " +
- "to your app's _webActions object?".format(function_name));
+ throw new Error("Undefined WebHelper action '%s'. Did you define " +
+ "it with WebHelper.Application.define_web_action()?".format(
+ function_name));
policy_decision.ignore();
return true;
@@ -119,18 +173,43 @@ const Application = new Lang.Class({
},
/**
- * Property: _translationFunction
- * Function which transforms all translatable text
+ * Method: set_translation_function
+ * Define function which transforms all translatable text
+ *
+ * Parameters:
+ * translation_function - a function, or null
*
* When you plan to use the <translate_html()> function to translate text in
* your web application, set this property to the translation function.
* The function must take one parameter, a string, and also return a
- * string -- for example, gettext().
+ * string.
+ * The canonical example is gettext().
+ *
+ * Pass null for _translation_function_ to unset the translation function.
*
- * *Note* This API will likely disappear and be replaced by a read-write
- * translation_function property.
- * That is the reason for the underscore starting the name.
+ * If this function has not been called, or has most recently been called
+ * with null, then it is illegal to call <translate_html()>.
*/
+ set_translation_function: function(translation_function) {
+ if(translation_function !== null
+ && typeof translation_function !== 'function') {
+ throw new Error('The translation function must be a function, or ' +
+ 'null.');
+ }
+ this._translationFunction = translation_function;
+ },
+
+ /**
+ * Method: get_translation_function
+ * Retrieve the currently set translation function
+ *
+ * Returns:
+ * the translation function previously set with
+ * <set_translation_function()>, or null if none is currently set.
+ */
+ get_translation_function: function() {
+ return this._translationFunction;
+ },
/**
* Method: translate_html
@@ -152,12 +231,12 @@ const Application = new Lang.Class({
*
* Then after the web view has finished loading, call <translate_html()> on
* it, and each of the marked strings will be passed to the function that
- * you specify using the <_translationFunction> property.
- * The return value from <_translationFunction> will be substituted into the
- * HTML instead of the original string.
+ * you specify using <set_translation_function()> property.
+ * The return value from the translation function will be substituted into
+ * the HTML instead of the original string.
*
* Example:
- * > app._translationFunction = _;
+ * > app.set_translation_function(_);
* > webview.connect('notify::load-status',
* > Lang.bind(app, function(webview) {
* > if(webview.load_status == WebKit.LoadStatus.FINISHED)
@@ -177,7 +256,8 @@ const Application = new Lang.Class({
// Translate the text
if(typeof this._translationFunction !== 'function')
throw new Error("No suitable translation function was found. " +
- "Did you forget to set '_translationFunction' on your app?");
+ "Did you forget to call 'set_translation_function()' on " +
+ "your app?");
element.inner_html = this._translationFunction(element.inner_text);
}
}