You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by br...@apache.org on 2013/12/11 22:54:25 UTC
[06/15] refactoring to small modules
http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/lib/test/platform.js
----------------------------------------------------------------------
diff --git a/lib/test/platform.js b/lib/test/platform.js
deleted file mode 100644
index fcc31ae..0000000
--- a/lib/test/platform.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-module.exports = {
- id: 'test platform',
- bootstrap: function() {
- var propertyreplacer = require('cordova/propertyreplacer');
-
- require('cordova/builder').replaceHookForTesting = function(obj, key) {
- // This doesn't clean up non-clobbering assignments, nor does it work for
- // getters. It does work to un-clobber clobbered / merged symbols, which
- // is generally good enough for tests.
- if (obj[key]) {
- propertyreplacer.stub(obj, key);
- }
- };
- }
-};
http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/lib/test/propertyreplacer.js
----------------------------------------------------------------------
diff --git a/lib/test/propertyreplacer.js b/lib/test/propertyreplacer.js
deleted file mode 100644
index 18c5d3b..0000000
--- a/lib/test/propertyreplacer.js
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-
-// Use this helper module to stub out properties within Jasmine tests.
-// Original values will be restored after each test.
-
-var curStubs = null;
-
-function removeAllStubs() {
- for (var i = curStubs.length - 1, stub; stub = curStubs[i]; --i) {
- stub.obj[stub.key] = stub.value;
- }
- curStubs = null;
-}
-
-exports.stub = function(obj, key, value) {
- if (!curStubs) {
- curStubs = [];
- jasmine.getEnv().currentSpec.after(removeAllStubs);
- }
-
- curStubs.push({
- obj: obj,
- key: key,
- value: obj[key]
- });
- obj[key] = value;
-};
-
http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/lib/test/testmodule.js
----------------------------------------------------------------------
diff --git a/lib/test/testmodule.js b/lib/test/testmodule.js
deleted file mode 100644
index 80eaf94..0000000
--- a/lib/test/testmodule.js
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-module.exports = {
- func: function() {},
- num: 2,
- obj: { str: 'hello' },
- subObj: { str: 'testSubObj' }
-};
http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/lib/ubuntu/exec.js
----------------------------------------------------------------------
diff --git a/lib/ubuntu/exec.js b/lib/ubuntu/exec.js
deleted file mode 100644
index e6e476d..0000000
--- a/lib/ubuntu/exec.js
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-var cordova = require('cordova'),
- utils = require('cordova/utils');
-
-var callbackId = 1;
-cordova.callbacks = [];
-
-cordova.callback = function() {
- var scId = arguments[0];
- var callbackRef = null;
-
- var parameters = [];
- for (var i = 1; i < arguments.length; i++) {
- parameters[i-1] = arguments[i];
- }
- callbackRef = cordova.callbacks[scId];
-
- // Even IDs are success-, odd are error-callbacks - make sure we remove both
- if ((scId % 2) !== 0) {
- scId = scId - 1;
- }
- // Remove both the success as well as the error callback from the stack
- delete cordova.callbacks[scId];
- delete cordova.callbacks[scId + 1];
-
- if (typeof callbackRef == "function") callbackRef.apply(this, parameters);
-};
-
-cordova.callbackWithoutRemove = function() {
- var scId = arguments[0];
- var callbackRef = null;
-
- var parameters = [];
- for (var i = 1; i < arguments.length; i++) {
- parameters[i-1] = arguments[i];
- }
- callbackRef = cordova.callbacks[scId];
-
- if (typeof(callbackRef) == "function") callbackRef.apply(this, parameters);
-};
-
-function ubuntuExec(success, fail, service, action, args) {
- if (callbackId % 2) {
- callbackId++;
- }
-
- var scId = callbackId++;
- var ecId = callbackId++;
- cordova.callbacks[scId] = success;
- cordova.callbacks[ecId] = fail;
-
- args.unshift(ecId);
- args.unshift(scId);
-
- navigator.qt.postMessage(JSON.stringify({messageType: "callPluginFunction", plugin: service, func: action, params: args}));
-}
-module.exports = ubuntuExec;
http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/lib/ubuntu/platform.js
----------------------------------------------------------------------
diff --git a/lib/ubuntu/platform.js b/lib/ubuntu/platform.js
deleted file mode 100644
index 3871545..0000000
--- a/lib/ubuntu/platform.js
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-module.exports = {
- id: "ubuntu",
- bootstrap: function() {
- var channel = require("cordova/channel"),
- cordova = require('cordova'),
- exec = require('cordova/exec'),
- modulemapper = require('cordova/modulemapper');
-
- modulemapper.clobbers('cordova/exec/proxy', 'cordova.commandProxy');
- require('cordova/channel').onNativeReady.fire();
- }
-};
http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/lib/windows8/exec.js
----------------------------------------------------------------------
diff --git a/lib/windows8/exec.js b/lib/windows8/exec.js
deleted file mode 100644
index 6720572..0000000
--- a/lib/windows8/exec.js
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-/*jslint sloppy:true, plusplus:true*/
-/*global require, module, console */
-
-var cordova = require('cordova');
-var execProxy = require('cordova/exec/proxy');
-
-/**
- * Execute a cordova command. It is up to the native side whether this action
- * is synchronous or asynchronous. The native side can return:
- * Synchronous: PluginResult object as a JSON string
- * Asynchronous: Empty string ""
- * If async, the native side will cordova.callbackSuccess or cordova.callbackError,
- * depending upon the result of the action.
- *
- * @param {Function} success The success callback
- * @param {Function} fail The fail callback
- * @param {String} service The name of the service to use
- * @param {String} action Action to be run in cordova
- * @param {String[]} [args] Zero or more arguments to pass to the method
- */
-module.exports = function (success, fail, service, action, args) {
-
- var proxy = execProxy.get(service, action),
- callbackId,
- onSuccess,
- onError;
-
- if (proxy) {
- callbackId = service + cordova.callbackId++;
- // console.log("EXEC:" + service + " : " + action);
- if (typeof success === "function" || typeof fail === "function") {
- cordova.callbacks[callbackId] = {success: success, fail: fail};
- }
- try {
- onSuccess = function (result) {
- cordova.callbackSuccess(callbackId,
- {
- status: cordova.callbackStatus.OK,
- message: result
- });
- };
- onError = function (err) {
- cordova.callbackError(callbackId,
- {
- status: cordova.callbackStatus.ERROR,
- message: err
- });
- };
- proxy(onSuccess, onError, args);
-
- } catch (e) {
- console.log("Exception calling native with command :: " + service + " :: " + action + " ::exception=" + e);
- }
- } else {
- if (typeof fail === "function") {
- fail("Missing Command Error");
- }
- }
-};
http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/lib/windows8/platform.js
----------------------------------------------------------------------
diff --git a/lib/windows8/platform.js b/lib/windows8/platform.js
deleted file mode 100755
index 67a564c..0000000
--- a/lib/windows8/platform.js
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-module.exports = {
- id: 'windows8',
- bootstrap:function() {
- var cordova = require('cordova'),
- exec = require('cordova/exec'),
- channel = cordova.require('cordova/channel'),
- modulemapper = require('cordova/modulemapper');
-
- modulemapper.clobbers('cordova/exec/proxy', 'cordova.commandProxy');
- channel.onNativeReady.fire();
-
- var onWinJSReady = function () {
- var app = WinJS.Application;
- var checkpointHandler = function checkpointHandler() {
- cordova.fireDocumentEvent('pause');
- };
-
- var resumingHandler = function resumingHandler() {
- cordova.fireDocumentEvent('resume');
- };
-
- app.addEventListener("checkpoint", checkpointHandler);
- Windows.UI.WebUI.WebUIApplication.addEventListener("resuming", resumingHandler, false);
- app.start();
-
- };
-
- if (!window.WinJS) {
- // <script src="//Microsoft.WinJS.1.0/js/base.js"></script>
- var scriptElem = document.createElement("script");
- scriptElem.src = "//Microsoft.WinJS.1.0/js/base.js";
- scriptElem.addEventListener("load", onWinJSReady);
- document.head.appendChild(scriptElem);
-
- console.log("added WinJS ... ");
- }
- else {
- onWinJSReady();
- }
- }
-};
http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/lib/windows8/windows8/commandProxy.js
----------------------------------------------------------------------
diff --git a/lib/windows8/windows8/commandProxy.js b/lib/windows8/windows8/commandProxy.js
deleted file mode 100644
index cbdf720..0000000
--- a/lib/windows8/windows8/commandProxy.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-console.log('WARNING: please require cordova/exec/proxy instead');
-module.exports = require('cordova/exec/proxy');
http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/lib/windowsphone/exec.js
----------------------------------------------------------------------
diff --git a/lib/windowsphone/exec.js b/lib/windowsphone/exec.js
deleted file mode 100644
index 96eb306..0000000
--- a/lib/windowsphone/exec.js
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-var cordova = require('cordova');
-
-/**
- * Execute a cordova command. It is up to the native side whether this action
- * is synchronous or asynchronous. The native side can return:
- * Synchronous: PluginResult object as a JSON string
- * Asynchronous: Empty string ""
- * If async, the native side will cordova.callbackSuccess or cordova.callbackError,
- * depending upon the result of the action.
- *
- * @param {Function} success The success callback
- * @param {Function} fail The fail callback
- * @param {String} service The name of the service to use
- * @param {String} action Action to be run in cordova
- * @param {String[]} [args] Zero or more arguments to pass to the method
-
- */
-
-module.exports = function(success, fail, service, action, args) {
-
- var callbackId = service + cordova.callbackId++;
- if (typeof success == "function" || typeof fail == "function") {
- cordova.callbacks[callbackId] = {success:success, fail:fail};
- }
- // generate a new command string, ex. DebugConsole/log/DebugConsole23/["wtf dude?"]
- for(var n = 0; n < args.length; n++)
- {
- if(typeof args[n] !== "string")
- {
- args[n] = JSON.stringify(args[n]);
- }
- }
- var command = service + "/" + action + "/" + callbackId + "/" + JSON.stringify(args);
- // pass it on to Notify
- try {
- if(window.external) {
- window.external.Notify(command);
- }
- else {
- console.log("window.external not available :: command=" + command);
- }
- }
- catch(e) {
- console.log("Exception calling native with command :: " + command + " :: exception=" + e);
- }
-};
-
http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/lib/windowsphone/platform.js
----------------------------------------------------------------------
diff --git a/lib/windowsphone/platform.js b/lib/windowsphone/platform.js
deleted file mode 100644
index 237d4f5..0000000
--- a/lib/windowsphone/platform.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-module.exports = {
- id: 'windowsphone',
- bootstrap: function() {
- var cordova = require('cordova'),
- exec = require('cordova/exec');
-
- // Inject a listener for the backbutton, and tell native to override the flag (true/false) when we have 1 or more, or 0, listeners
- var backButtonChannel = cordova.addDocumentEventHandler('backbutton');
- backButtonChannel.onHasSubscribersChange = function() {
- exec(null, null, "CoreEvents", "overridebackbutton", [this.numHandlers == 1]);
- };
- }
-};
http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/src/amazon-fireos/android/nativeapiprovider.js
----------------------------------------------------------------------
diff --git a/src/amazon-fireos/android/nativeapiprovider.js b/src/amazon-fireos/android/nativeapiprovider.js
new file mode 100644
index 0000000..2e9aa67
--- /dev/null
+++ b/src/amazon-fireos/android/nativeapiprovider.js
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+*/
+
+/**
+ * Exports the ExposedJsApi.java object if available, otherwise exports the PromptBasedNativeApi.
+ */
+
+var nativeApi = this._cordovaNative || require('cordova/android/promptbasednativeapi');
+var currentApi = nativeApi;
+
+module.exports = {
+ get: function() { return currentApi; },
+ setPreferPrompt: function(value) {
+ currentApi = value ? require('cordova/android/promptbasednativeapi') : nativeApi;
+ },
+ // Used only by tests.
+ set: function(value) {
+ currentApi = value;
+ }
+};
http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/src/amazon-fireos/android/promptbasednativeapi.js
----------------------------------------------------------------------
diff --git a/src/amazon-fireos/android/promptbasednativeapi.js b/src/amazon-fireos/android/promptbasednativeapi.js
new file mode 100644
index 0000000..c12f46e
--- /dev/null
+++ b/src/amazon-fireos/android/promptbasednativeapi.js
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+*/
+
+/**
+ * Implements the API of ExposedJsApi.java, but uses prompt() to communicate.
+ * This is used only on the 2.3 simulator, where addJavascriptInterface() is broken.
+ */
+
+module.exports = {
+ exec: function(service, action, callbackId, argsJson) {
+ return prompt(argsJson, 'gap:'+JSON.stringify([service, action, callbackId]));
+ },
+ setNativeToJsBridgeMode: function(value) {
+ prompt(value, 'gap_bridge_mode:');
+ },
+ retrieveJsMessages: function(fromOnlineEvent) {
+ return prompt(+fromOnlineEvent, 'gap_poll:');
+ }
+};
http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/src/amazon-fireos/exec.js
----------------------------------------------------------------------
diff --git a/src/amazon-fireos/exec.js b/src/amazon-fireos/exec.js
new file mode 100644
index 0000000..0d35ff1
--- /dev/null
+++ b/src/amazon-fireos/exec.js
@@ -0,0 +1,252 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+/**
+ * Execute a cordova command. It is up to the native side whether this action
+ * is synchronous or asynchronous. The native side can return:
+ * Synchronous: PluginResult object as a JSON string
+ * Asynchronous: Empty string ""
+ * If async, the native side will cordova.callbackSuccess or cordova.callbackError,
+ * depending upon the result of the action.
+ *
+ * @param {Function} success The success callback
+ * @param {Function} fail The fail callback
+ * @param {String} service The name of the service to use
+ * @param {String} action Action to be run in cordova
+ * @param {String[]} [args] Zero or more arguments to pass to the method
+ */
+var cordova = require('cordova'),
+ nativeApiProvider = require('cordova/android/nativeapiprovider'),
+ utils = require('cordova/utils'),
+ base64 = require('cordova/base64'),
+ jsToNativeModes = {
+ PROMPT: 0,
+ JS_OBJECT: 1,
+ // This mode is currently for benchmarking purposes only. It must be enabled
+ // on the native side through the ENABLE_LOCATION_CHANGE_EXEC_MODE
+ // constant within CordovaWebViewClient.java before it will work.
+ LOCATION_CHANGE: 2
+ },
+ nativeToJsModes = {
+ // Polls for messages using the JS->Native bridge.
+ POLLING: 0,
+ // For LOAD_URL to be viable, it would need to have a work-around for
+ // the bug where the soft-keyboard gets dismissed when a message is sent.
+ LOAD_URL: 1,
+ // For the ONLINE_EVENT to be viable, it would need to intercept all event
+ // listeners (both through addEventListener and window.ononline) as well
+ // as set the navigator property itself.
+ ONLINE_EVENT: 2,
+ // Uses reflection to access private APIs of the WebView that can send JS
+ // to be executed.
+ // Requires Android 3.2.4 or above.
+ PRIVATE_API: 3
+ },
+ jsToNativeBridgeMode, // Set lazily.
+ nativeToJsBridgeMode = nativeToJsModes.ONLINE_EVENT,
+ pollEnabled = false,
+ messagesFromNative = [];
+
+function androidExec(success, fail, service, action, args) {
+ // Set default bridge modes if they have not already been set.
+ // By default, we use the failsafe, since addJavascriptInterface breaks too often
+ if (jsToNativeBridgeMode === undefined) {
+ androidExec.setJsToNativeBridgeMode(jsToNativeModes.JS_OBJECT);
+ }
+
+ // Process any ArrayBuffers in the args into a string.
+ for (var i = 0; i < args.length; i++) {
+ if (utils.typeName(args[i]) == 'ArrayBuffer') {
+ args[i] = base64.fromArrayBuffer(args[i]);
+ }
+ }
+
+ var callbackId = service + cordova.callbackId++,
+ argsJson = JSON.stringify(args);
+
+ if (success || fail) {
+ cordova.callbacks[callbackId] = {success:success, fail:fail};
+ }
+
+ if (jsToNativeBridgeMode == jsToNativeModes.LOCATION_CHANGE) {
+ window.location = 'http://cdv_exec/' + service + '#' + action + '#' + callbackId + '#' + argsJson;
+ } else {
+ var messages = nativeApiProvider.get().exec(service, action, callbackId, argsJson);
+ // If argsJson was received by Java as null, try again with the PROMPT bridge mode.
+ // This happens in rare circumstances, such as when certain Unicode characters are passed over the bridge on a Galaxy S2. See CB-2666.
+ if (jsToNativeBridgeMode == jsToNativeModes.JS_OBJECT && messages === "@Null arguments.") {
+ androidExec.setJsToNativeBridgeMode(jsToNativeModes.PROMPT);
+ androidExec(success, fail, service, action, args);
+ androidExec.setJsToNativeBridgeMode(jsToNativeModes.JS_OBJECT);
+ return;
+ } else {
+ androidExec.processMessages(messages);
+ }
+ }
+}
+
+function pollOnceFromOnlineEvent() {
+ pollOnce(true);
+}
+
+function pollOnce(opt_fromOnlineEvent) {
+ var msg = nativeApiProvider.get().retrieveJsMessages(!!opt_fromOnlineEvent);
+ androidExec.processMessages(msg);
+}
+
+function pollingTimerFunc() {
+ if (pollEnabled) {
+ pollOnce();
+ setTimeout(pollingTimerFunc, 50);
+ }
+}
+
+function hookOnlineApis() {
+ function proxyEvent(e) {
+ cordova.fireWindowEvent(e.type);
+ }
+ // The network module takes care of firing online and offline events.
+ // It currently fires them only on document though, so we bridge them
+ // to window here (while first listening for exec()-releated online/offline
+ // events).
+ window.addEventListener('online', pollOnceFromOnlineEvent, false);
+ window.addEventListener('offline', pollOnceFromOnlineEvent, false);
+ cordova.addWindowEventHandler('online');
+ cordova.addWindowEventHandler('offline');
+ document.addEventListener('online', proxyEvent, false);
+ document.addEventListener('offline', proxyEvent, false);
+}
+
+hookOnlineApis();
+
+androidExec.jsToNativeModes = jsToNativeModes;
+androidExec.nativeToJsModes = nativeToJsModes;
+
+androidExec.setJsToNativeBridgeMode = function(mode) {
+ if (mode == jsToNativeModes.JS_OBJECT && !window._cordovaNative) {
+ console.log('Falling back on PROMPT mode since _cordovaNative is missing. Expected for Android 3.2 and lower only.');
+ mode = jsToNativeModes.PROMPT;
+ }
+ nativeApiProvider.setPreferPrompt(mode == jsToNativeModes.PROMPT);
+ jsToNativeBridgeMode = mode;
+};
+
+androidExec.setNativeToJsBridgeMode = function(mode) {
+ if (mode == nativeToJsBridgeMode) {
+ return;
+ }
+ if (nativeToJsBridgeMode == nativeToJsModes.POLLING) {
+ pollEnabled = false;
+ }
+
+ nativeToJsBridgeMode = mode;
+ // Tell the native side to switch modes.
+ nativeApiProvider.get().setNativeToJsBridgeMode(mode);
+
+ if (mode == nativeToJsModes.POLLING) {
+ pollEnabled = true;
+ setTimeout(pollingTimerFunc, 1);
+ }
+};
+
+// Processes a single message, as encoded by NativeToJsMessageQueue.java.
+function processMessage(message) {
+ try {
+ var firstChar = message.charAt(0);
+ if (firstChar == 'J') {
+ eval(message.slice(1));
+ } else if (firstChar == 'S' || firstChar == 'F') {
+ var success = firstChar == 'S';
+ var keepCallback = message.charAt(1) == '1';
+ var spaceIdx = message.indexOf(' ', 2);
+ var status = +message.slice(2, spaceIdx);
+ var nextSpaceIdx = message.indexOf(' ', spaceIdx + 1);
+ var callbackId = message.slice(spaceIdx + 1, nextSpaceIdx);
+ var payloadKind = message.charAt(nextSpaceIdx + 1);
+ var payload;
+ if (payloadKind == 's') {
+ payload = message.slice(nextSpaceIdx + 2);
+ } else if (payloadKind == 't') {
+ payload = true;
+ } else if (payloadKind == 'f') {
+ payload = false;
+ } else if (payloadKind == 'N') {
+ payload = null;
+ } else if (payloadKind == 'n') {
+ payload = +message.slice(nextSpaceIdx + 2);
+ } else if (payloadKind == 'A') {
+ var data = message.slice(nextSpaceIdx + 2);
+ var bytes = window.atob(data);
+ var arraybuffer = new Uint8Array(bytes.length);
+ for (var i = 0; i < bytes.length; i++) {
+ arraybuffer[i] = bytes.charCodeAt(i);
+ }
+ payload = arraybuffer.buffer;
+ } else if (payloadKind == 'S') {
+ payload = window.atob(message.slice(nextSpaceIdx + 2));
+ } else {
+ payload = JSON.parse(message.slice(nextSpaceIdx + 1));
+ }
+ cordova.callbackFromNative(callbackId, success, status, [payload], keepCallback);
+ } else {
+ console.log("processMessage failed: invalid message:" + message);
+ }
+ } catch (e) {
+ console.log("processMessage failed: Message: " + message);
+ console.log("processMessage failed: Error: " + e);
+ console.log("processMessage failed: Stack: " + e.stack);
+ }
+}
+
+// This is called from the NativeToJsMessageQueue.java.
+androidExec.processMessages = function(messages) {
+ if (messages) {
+ messagesFromNative.push(messages);
+ // Check for the reentrant case, and enqueue the message if that's the case.
+ if (messagesFromNative.length > 1) {
+ return;
+ }
+ while (messagesFromNative.length) {
+ // Don't unshift until the end so that reentrancy can be detected.
+ messages = messagesFromNative[0];
+ // The Java side can send a * message to indicate that it
+ // still has messages waiting to be retrieved.
+ if (messages == '*') {
+ messagesFromNative.shift();
+ window.setTimeout(pollOnce, 0);
+ return;
+ }
+
+ var spaceIdx = messages.indexOf(' ');
+ var msgLen = +messages.slice(0, spaceIdx);
+ var message = messages.substr(spaceIdx + 1, msgLen);
+ messages = messages.slice(spaceIdx + msgLen + 1);
+ processMessage(message);
+ if (messages) {
+ messagesFromNative[0] = messages;
+ } else {
+ messagesFromNative.shift();
+ }
+ }
+ }
+};
+
+module.exports = androidExec;
http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/src/amazon-fireos/platform.js
----------------------------------------------------------------------
diff --git a/src/amazon-fireos/platform.js b/src/amazon-fireos/platform.js
new file mode 100644
index 0000000..768b39b
--- /dev/null
+++ b/src/amazon-fireos/platform.js
@@ -0,0 +1,56 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+module.exports = {
+ id: 'amazon-fireos',
+ bootstrap: function() {
+ var channel = require('cordova/channel'),
+ cordova = require('cordova'),
+ exec = require('cordova/exec'),
+ modulemapper = require('cordova/modulemapper');
+
+ // Tell the native code that a page change has occurred.
+ exec(null, null, 'PluginManager', 'startup', []);
+ // Tell the JS that the native side is ready.
+ channel.onNativeReady.fire();
+
+ // TODO: Extract this as a proper plugin.
+ modulemapper.clobbers('cordova/plugin/android/app', 'navigator.app');
+
+ // Inject a listener for the backbutton on the document.
+ var backButtonChannel = cordova.addDocumentEventHandler('backbutton');
+ backButtonChannel.onHasSubscribersChange = function() {
+ // If we just attached the first handler or detached the last handler,
+ // let native know we need to override the back button.
+ exec(null, null, "App", "overrideBackbutton", [this.numHandlers == 1]);
+ };
+
+ // Add hardware MENU and SEARCH button handlers
+ cordova.addDocumentEventHandler('menubutton');
+ cordova.addDocumentEventHandler('searchbutton');
+
+ // Let native code know we are all done on the JS side.
+ // Native code will then un-hide the WebView.
+ channel.onCordovaReady.subscribe(function() {
+ exec(null, null, "App", "show", []);
+ });
+ }
+};
http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/src/amazon-fireos/plugin/android/app.js
----------------------------------------------------------------------
diff --git a/src/amazon-fireos/plugin/android/app.js b/src/amazon-fireos/plugin/android/app.js
new file mode 100644
index 0000000..c2a4df5
--- /dev/null
+++ b/src/amazon-fireos/plugin/android/app.js
@@ -0,0 +1,92 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+var exec = require('cordova/exec');
+
+module.exports = {
+ /**
+ * Clear the resource cache.
+ */
+ clearCache:function() {
+ exec(null, null, "App", "clearCache", []);
+ },
+
+ /**
+ * Load the url into the webview or into new browser instance.
+ *
+ * @param url The URL to load
+ * @param props Properties that can be passed in to the activity:
+ * wait: int => wait msec before loading URL
+ * loadingDialog: "Title,Message" => display a native loading dialog
+ * loadUrlTimeoutValue: int => time in msec to wait before triggering a timeout error
+ * clearHistory: boolean => clear webview history (default=false)
+ * openExternal: boolean => open in a new browser (default=false)
+ *
+ * Example:
+ * navigator.app.loadUrl("http://server/myapp/index.html", {wait:2000, loadingDialog:"Wait,Loading App", loadUrlTimeoutValue: 60000});
+ */
+ loadUrl:function(url, props) {
+ exec(null, null, "App", "loadUrl", [url, props]);
+ },
+
+ /**
+ * Cancel loadUrl that is waiting to be loaded.
+ */
+ cancelLoadUrl:function() {
+ exec(null, null, "App", "cancelLoadUrl", []);
+ },
+
+ /**
+ * Clear web history in this web view.
+ * Instead of BACK button loading the previous web page, it will exit the app.
+ */
+ clearHistory:function() {
+ exec(null, null, "App", "clearHistory", []);
+ },
+
+ /**
+ * Go to previous page displayed.
+ * This is the same as pressing the backbutton on Android device.
+ */
+ backHistory:function() {
+ exec(null, null, "App", "backHistory", []);
+ },
+
+ /**
+ * Override the default behavior of the Android back button.
+ * If overridden, when the back button is pressed, the "backKeyDown" JavaScript event will be fired.
+ *
+ * Note: The user should not have to call this method. Instead, when the user
+ * registers for the "backbutton" event, this is automatically done.
+ *
+ * @param override T=override, F=cancel override
+ */
+ overrideBackbutton:function(override) {
+ exec(null, null, "App", "overrideBackbutton", [override]);
+ },
+
+ /**
+ * Exit and terminate the application.
+ */
+ exitApp:function() {
+ return exec(null, null, "App", "exitApp", []);
+ }
+};
http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/src/android/android/nativeapiprovider.js
----------------------------------------------------------------------
diff --git a/src/android/android/nativeapiprovider.js b/src/android/android/nativeapiprovider.js
new file mode 100644
index 0000000..2e9aa67
--- /dev/null
+++ b/src/android/android/nativeapiprovider.js
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+*/
+
+/**
+ * Exports the ExposedJsApi.java object if available, otherwise exports the PromptBasedNativeApi.
+ */
+
+var nativeApi = this._cordovaNative || require('cordova/android/promptbasednativeapi');
+var currentApi = nativeApi;
+
+module.exports = {
+ get: function() { return currentApi; },
+ setPreferPrompt: function(value) {
+ currentApi = value ? require('cordova/android/promptbasednativeapi') : nativeApi;
+ },
+ // Used only by tests.
+ set: function(value) {
+ currentApi = value;
+ }
+};
http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/src/android/android/promptbasednativeapi.js
----------------------------------------------------------------------
diff --git a/src/android/android/promptbasednativeapi.js b/src/android/android/promptbasednativeapi.js
new file mode 100644
index 0000000..c12f46e
--- /dev/null
+++ b/src/android/android/promptbasednativeapi.js
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+*/
+
+/**
+ * Implements the API of ExposedJsApi.java, but uses prompt() to communicate.
+ * This is used only on the 2.3 simulator, where addJavascriptInterface() is broken.
+ */
+
+module.exports = {
+ exec: function(service, action, callbackId, argsJson) {
+ return prompt(argsJson, 'gap:'+JSON.stringify([service, action, callbackId]));
+ },
+ setNativeToJsBridgeMode: function(value) {
+ prompt(value, 'gap_bridge_mode:');
+ },
+ retrieveJsMessages: function(fromOnlineEvent) {
+ return prompt(+fromOnlineEvent, 'gap_poll:');
+ }
+};
http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/src/android/exec.js
----------------------------------------------------------------------
diff --git a/src/android/exec.js b/src/android/exec.js
new file mode 100644
index 0000000..0d35ff1
--- /dev/null
+++ b/src/android/exec.js
@@ -0,0 +1,252 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+/**
+ * Execute a cordova command. It is up to the native side whether this action
+ * is synchronous or asynchronous. The native side can return:
+ * Synchronous: PluginResult object as a JSON string
+ * Asynchronous: Empty string ""
+ * If async, the native side will cordova.callbackSuccess or cordova.callbackError,
+ * depending upon the result of the action.
+ *
+ * @param {Function} success The success callback
+ * @param {Function} fail The fail callback
+ * @param {String} service The name of the service to use
+ * @param {String} action Action to be run in cordova
+ * @param {String[]} [args] Zero or more arguments to pass to the method
+ */
+var cordova = require('cordova'),
+ nativeApiProvider = require('cordova/android/nativeapiprovider'),
+ utils = require('cordova/utils'),
+ base64 = require('cordova/base64'),
+ jsToNativeModes = {
+ PROMPT: 0,
+ JS_OBJECT: 1,
+ // This mode is currently for benchmarking purposes only. It must be enabled
+ // on the native side through the ENABLE_LOCATION_CHANGE_EXEC_MODE
+ // constant within CordovaWebViewClient.java before it will work.
+ LOCATION_CHANGE: 2
+ },
+ nativeToJsModes = {
+ // Polls for messages using the JS->Native bridge.
+ POLLING: 0,
+ // For LOAD_URL to be viable, it would need to have a work-around for
+ // the bug where the soft-keyboard gets dismissed when a message is sent.
+ LOAD_URL: 1,
+ // For the ONLINE_EVENT to be viable, it would need to intercept all event
+ // listeners (both through addEventListener and window.ononline) as well
+ // as set the navigator property itself.
+ ONLINE_EVENT: 2,
+ // Uses reflection to access private APIs of the WebView that can send JS
+ // to be executed.
+ // Requires Android 3.2.4 or above.
+ PRIVATE_API: 3
+ },
+ jsToNativeBridgeMode, // Set lazily.
+ nativeToJsBridgeMode = nativeToJsModes.ONLINE_EVENT,
+ pollEnabled = false,
+ messagesFromNative = [];
+
+function androidExec(success, fail, service, action, args) {
+ // Set default bridge modes if they have not already been set.
+ // By default, we use the failsafe, since addJavascriptInterface breaks too often
+ if (jsToNativeBridgeMode === undefined) {
+ androidExec.setJsToNativeBridgeMode(jsToNativeModes.JS_OBJECT);
+ }
+
+ // Process any ArrayBuffers in the args into a string.
+ for (var i = 0; i < args.length; i++) {
+ if (utils.typeName(args[i]) == 'ArrayBuffer') {
+ args[i] = base64.fromArrayBuffer(args[i]);
+ }
+ }
+
+ var callbackId = service + cordova.callbackId++,
+ argsJson = JSON.stringify(args);
+
+ if (success || fail) {
+ cordova.callbacks[callbackId] = {success:success, fail:fail};
+ }
+
+ if (jsToNativeBridgeMode == jsToNativeModes.LOCATION_CHANGE) {
+ window.location = 'http://cdv_exec/' + service + '#' + action + '#' + callbackId + '#' + argsJson;
+ } else {
+ var messages = nativeApiProvider.get().exec(service, action, callbackId, argsJson);
+ // If argsJson was received by Java as null, try again with the PROMPT bridge mode.
+ // This happens in rare circumstances, such as when certain Unicode characters are passed over the bridge on a Galaxy S2. See CB-2666.
+ if (jsToNativeBridgeMode == jsToNativeModes.JS_OBJECT && messages === "@Null arguments.") {
+ androidExec.setJsToNativeBridgeMode(jsToNativeModes.PROMPT);
+ androidExec(success, fail, service, action, args);
+ androidExec.setJsToNativeBridgeMode(jsToNativeModes.JS_OBJECT);
+ return;
+ } else {
+ androidExec.processMessages(messages);
+ }
+ }
+}
+
+function pollOnceFromOnlineEvent() {
+ pollOnce(true);
+}
+
+function pollOnce(opt_fromOnlineEvent) {
+ var msg = nativeApiProvider.get().retrieveJsMessages(!!opt_fromOnlineEvent);
+ androidExec.processMessages(msg);
+}
+
+function pollingTimerFunc() {
+ if (pollEnabled) {
+ pollOnce();
+ setTimeout(pollingTimerFunc, 50);
+ }
+}
+
+function hookOnlineApis() {
+ function proxyEvent(e) {
+ cordova.fireWindowEvent(e.type);
+ }
+ // The network module takes care of firing online and offline events.
+ // It currently fires them only on document though, so we bridge them
+ // to window here (while first listening for exec()-releated online/offline
+ // events).
+ window.addEventListener('online', pollOnceFromOnlineEvent, false);
+ window.addEventListener('offline', pollOnceFromOnlineEvent, false);
+ cordova.addWindowEventHandler('online');
+ cordova.addWindowEventHandler('offline');
+ document.addEventListener('online', proxyEvent, false);
+ document.addEventListener('offline', proxyEvent, false);
+}
+
+hookOnlineApis();
+
+androidExec.jsToNativeModes = jsToNativeModes;
+androidExec.nativeToJsModes = nativeToJsModes;
+
+androidExec.setJsToNativeBridgeMode = function(mode) {
+ if (mode == jsToNativeModes.JS_OBJECT && !window._cordovaNative) {
+ console.log('Falling back on PROMPT mode since _cordovaNative is missing. Expected for Android 3.2 and lower only.');
+ mode = jsToNativeModes.PROMPT;
+ }
+ nativeApiProvider.setPreferPrompt(mode == jsToNativeModes.PROMPT);
+ jsToNativeBridgeMode = mode;
+};
+
+androidExec.setNativeToJsBridgeMode = function(mode) {
+ if (mode == nativeToJsBridgeMode) {
+ return;
+ }
+ if (nativeToJsBridgeMode == nativeToJsModes.POLLING) {
+ pollEnabled = false;
+ }
+
+ nativeToJsBridgeMode = mode;
+ // Tell the native side to switch modes.
+ nativeApiProvider.get().setNativeToJsBridgeMode(mode);
+
+ if (mode == nativeToJsModes.POLLING) {
+ pollEnabled = true;
+ setTimeout(pollingTimerFunc, 1);
+ }
+};
+
+// Processes a single message, as encoded by NativeToJsMessageQueue.java.
+function processMessage(message) {
+ try {
+ var firstChar = message.charAt(0);
+ if (firstChar == 'J') {
+ eval(message.slice(1));
+ } else if (firstChar == 'S' || firstChar == 'F') {
+ var success = firstChar == 'S';
+ var keepCallback = message.charAt(1) == '1';
+ var spaceIdx = message.indexOf(' ', 2);
+ var status = +message.slice(2, spaceIdx);
+ var nextSpaceIdx = message.indexOf(' ', spaceIdx + 1);
+ var callbackId = message.slice(spaceIdx + 1, nextSpaceIdx);
+ var payloadKind = message.charAt(nextSpaceIdx + 1);
+ var payload;
+ if (payloadKind == 's') {
+ payload = message.slice(nextSpaceIdx + 2);
+ } else if (payloadKind == 't') {
+ payload = true;
+ } else if (payloadKind == 'f') {
+ payload = false;
+ } else if (payloadKind == 'N') {
+ payload = null;
+ } else if (payloadKind == 'n') {
+ payload = +message.slice(nextSpaceIdx + 2);
+ } else if (payloadKind == 'A') {
+ var data = message.slice(nextSpaceIdx + 2);
+ var bytes = window.atob(data);
+ var arraybuffer = new Uint8Array(bytes.length);
+ for (var i = 0; i < bytes.length; i++) {
+ arraybuffer[i] = bytes.charCodeAt(i);
+ }
+ payload = arraybuffer.buffer;
+ } else if (payloadKind == 'S') {
+ payload = window.atob(message.slice(nextSpaceIdx + 2));
+ } else {
+ payload = JSON.parse(message.slice(nextSpaceIdx + 1));
+ }
+ cordova.callbackFromNative(callbackId, success, status, [payload], keepCallback);
+ } else {
+ console.log("processMessage failed: invalid message:" + message);
+ }
+ } catch (e) {
+ console.log("processMessage failed: Message: " + message);
+ console.log("processMessage failed: Error: " + e);
+ console.log("processMessage failed: Stack: " + e.stack);
+ }
+}
+
+// This is called from the NativeToJsMessageQueue.java.
+androidExec.processMessages = function(messages) {
+ if (messages) {
+ messagesFromNative.push(messages);
+ // Check for the reentrant case, and enqueue the message if that's the case.
+ if (messagesFromNative.length > 1) {
+ return;
+ }
+ while (messagesFromNative.length) {
+ // Don't unshift until the end so that reentrancy can be detected.
+ messages = messagesFromNative[0];
+ // The Java side can send a * message to indicate that it
+ // still has messages waiting to be retrieved.
+ if (messages == '*') {
+ messagesFromNative.shift();
+ window.setTimeout(pollOnce, 0);
+ return;
+ }
+
+ var spaceIdx = messages.indexOf(' ');
+ var msgLen = +messages.slice(0, spaceIdx);
+ var message = messages.substr(spaceIdx + 1, msgLen);
+ messages = messages.slice(spaceIdx + msgLen + 1);
+ processMessage(message);
+ if (messages) {
+ messagesFromNative[0] = messages;
+ } else {
+ messagesFromNative.shift();
+ }
+ }
+ }
+};
+
+module.exports = androidExec;
http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/src/android/platform.js
----------------------------------------------------------------------
diff --git a/src/android/platform.js b/src/android/platform.js
new file mode 100644
index 0000000..bf966c0
--- /dev/null
+++ b/src/android/platform.js
@@ -0,0 +1,56 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+module.exports = {
+ id: 'android',
+ bootstrap: function() {
+ var channel = require('cordova/channel'),
+ cordova = require('cordova'),
+ exec = require('cordova/exec'),
+ modulemapper = require('cordova/modulemapper');
+
+ // Tell the native code that a page change has occurred.
+ exec(null, null, 'PluginManager', 'startup', []);
+ // Tell the JS that the native side is ready.
+ channel.onNativeReady.fire();
+
+ // TODO: Extract this as a proper plugin.
+ modulemapper.clobbers('cordova/plugin/android/app', 'navigator.app');
+
+ // Inject a listener for the backbutton on the document.
+ var backButtonChannel = cordova.addDocumentEventHandler('backbutton');
+ backButtonChannel.onHasSubscribersChange = function() {
+ // If we just attached the first handler or detached the last handler,
+ // let native know we need to override the back button.
+ exec(null, null, "App", "overrideBackbutton", [this.numHandlers == 1]);
+ };
+
+ // Add hardware MENU and SEARCH button handlers
+ cordova.addDocumentEventHandler('menubutton');
+ cordova.addDocumentEventHandler('searchbutton');
+
+ // Let native code know we are all done on the JS side.
+ // Native code will then un-hide the WebView.
+ channel.onCordovaReady.subscribe(function() {
+ exec(null, null, "App", "show", []);
+ });
+ }
+};
http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/src/android/plugin/android/app.js
----------------------------------------------------------------------
diff --git a/src/android/plugin/android/app.js b/src/android/plugin/android/app.js
new file mode 100644
index 0000000..c2a4df5
--- /dev/null
+++ b/src/android/plugin/android/app.js
@@ -0,0 +1,92 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+var exec = require('cordova/exec');
+
+module.exports = {
+ /**
+ * Clear the resource cache.
+ */
+ clearCache:function() {
+ exec(null, null, "App", "clearCache", []);
+ },
+
+ /**
+ * Load the url into the webview or into new browser instance.
+ *
+ * @param url The URL to load
+ * @param props Properties that can be passed in to the activity:
+ * wait: int => wait msec before loading URL
+ * loadingDialog: "Title,Message" => display a native loading dialog
+ * loadUrlTimeoutValue: int => time in msec to wait before triggering a timeout error
+ * clearHistory: boolean => clear webview history (default=false)
+ * openExternal: boolean => open in a new browser (default=false)
+ *
+ * Example:
+ * navigator.app.loadUrl("http://server/myapp/index.html", {wait:2000, loadingDialog:"Wait,Loading App", loadUrlTimeoutValue: 60000});
+ */
+ loadUrl:function(url, props) {
+ exec(null, null, "App", "loadUrl", [url, props]);
+ },
+
+ /**
+ * Cancel loadUrl that is waiting to be loaded.
+ */
+ cancelLoadUrl:function() {
+ exec(null, null, "App", "cancelLoadUrl", []);
+ },
+
+ /**
+ * Clear web history in this web view.
+ * Instead of BACK button loading the previous web page, it will exit the app.
+ */
+ clearHistory:function() {
+ exec(null, null, "App", "clearHistory", []);
+ },
+
+ /**
+ * Go to previous page displayed.
+ * This is the same as pressing the backbutton on Android device.
+ */
+ backHistory:function() {
+ exec(null, null, "App", "backHistory", []);
+ },
+
+ /**
+ * Override the default behavior of the Android back button.
+ * If overridden, when the back button is pressed, the "backKeyDown" JavaScript event will be fired.
+ *
+ * Note: The user should not have to call this method. Instead, when the user
+ * registers for the "backbutton" event, this is automatically done.
+ *
+ * @param override T=override, F=cancel override
+ */
+ overrideBackbutton:function(override) {
+ exec(null, null, "App", "overrideBackbutton", [override]);
+ },
+
+ /**
+ * Exit and terminate the application.
+ */
+ exitApp:function() {
+ return exec(null, null, "App", "exitApp", []);
+ }
+};
http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/src/blackberry10/exec.js
----------------------------------------------------------------------
diff --git a/src/blackberry10/exec.js b/src/blackberry10/exec.js
new file mode 100644
index 0000000..6e896f4
--- /dev/null
+++ b/src/blackberry10/exec.js
@@ -0,0 +1,103 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+var cordova = require('cordova'),
+ execProxy = require('cordova/exec/proxy');
+
+function RemoteFunctionCall(functionUri) {
+ var params = {};
+
+ function composeUri() {
+ return "http://localhost:8472/" + functionUri;
+ }
+
+ function createXhrRequest(uri, isAsync) {
+ var request = new XMLHttpRequest();
+ request.open("POST", uri, isAsync);
+ request.setRequestHeader("Content-Type", "application/json");
+ return request;
+ }
+
+ this.addParam = function (name, value) {
+ params[name] = encodeURIComponent(JSON.stringify(value));
+ };
+
+ this.makeSyncCall = function () {
+ var requestUri = composeUri(),
+ request = createXhrRequest(requestUri, false),
+ response;
+ request.send(JSON.stringify(params));
+ response = JSON.parse(decodeURIComponent(request.responseText) || "null");
+ return response;
+ };
+
+}
+
+module.exports = function (success, fail, service, action, args) {
+ var uri = service + "/" + action,
+ request = new RemoteFunctionCall(uri),
+ callbackId = service + cordova.callbackId++,
+ proxy,
+ response,
+ name,
+ didSucceed;
+
+ cordova.callbacks[callbackId] = {
+ success: success,
+ fail: fail
+ };
+
+ proxy = execProxy.get(service, action);
+
+ if (proxy) {
+ proxy(success, fail, args);
+ }
+
+ else {
+
+ request.addParam("callbackId", callbackId);
+
+ for (name in args) {
+ if (Object.hasOwnProperty.call(args, name)) {
+ request.addParam(name, args[name]);
+ }
+ }
+
+ response = request.makeSyncCall();
+
+ if (response.code < 0) {
+ if (fail) {
+ fail(response.msg, response);
+ }
+ delete cordova.callbacks[callbackId];
+ } else {
+ didSucceed = response.code === cordova.callbackStatus.OK || response.code === cordova.callbackStatus.NO_RESULT;
+ cordova.callbackFromNative(
+ callbackId,
+ didSucceed,
+ response.code,
+ [ didSucceed ? response.data : response.msg ],
+ !!response.keepCallback
+ );
+ }
+ }
+
+};
http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/src/blackberry10/platform.js
----------------------------------------------------------------------
diff --git a/src/blackberry10/platform.js b/src/blackberry10/platform.js
new file mode 100644
index 0000000..9fcbda0
--- /dev/null
+++ b/src/blackberry10/platform.js
@@ -0,0 +1,57 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+module.exports = {
+
+ id: "blackberry10",
+
+ bootstrap: function() {
+
+ var channel = require('cordova/channel'),
+ addEventListener = document.addEventListener;
+
+ //ready as soon as the plugins are
+ channel.onPluginsReady.subscribe(function () {
+ channel.onNativeReady.fire();
+ });
+
+ //pass document online/offline event listeners to window
+ document.addEventListener = function (type) {
+ if (type === "online" || type === "offline") {
+ window.addEventListener.apply(window, arguments);
+ } else {
+ addEventListener.apply(document, arguments);
+ }
+ };
+
+ //map blackberry.event to document
+ if (!window.blackberry) {
+ window.blackberry = {};
+ }
+ window.blackberry.event =
+ {
+ addEventListener: document.addEventListener,
+ removeEventListener: document.removeEventListener
+ };
+
+ }
+
+};
http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/src/browser/exec.js
----------------------------------------------------------------------
diff --git a/src/browser/exec.js b/src/browser/exec.js
new file mode 100644
index 0000000..130edb9
--- /dev/null
+++ b/src/browser/exec.js
@@ -0,0 +1,48 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+var cordova = require('cordova');
+var execProxy = require('cordova/exec/proxy');
+
+module.exports = function(success, fail, service, action, args) {
+
+ var proxy = execProxy.get(service, action);
+
+ if (proxy) {
+ var callbackId = service + cordova.callbackId++;
+
+ if (typeof success == "function" || typeof fail == "function") {
+ cordova.callbacks[callbackId] = {success:success, fail:fail};
+ }
+
+ try {
+ proxy(success, fail, args);
+ }
+ catch(e) {
+ // TODO throw maybe?
+ var msg = "Exception calling :: " + service + " :: " + action + " ::exception=" + e;
+ console.log(msg);
+ }
+ }
+ else {
+ fail && fail("Missing Command Error");
+ }
+};
http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/src/browser/platform.js
----------------------------------------------------------------------
diff --git a/src/browser/platform.js b/src/browser/platform.js
new file mode 100644
index 0000000..fb30eea
--- /dev/null
+++ b/src/browser/platform.js
@@ -0,0 +1,50 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+module.exports = {
+ id: 'browser',
+ cordovaVersion: '3.4.0',
+
+ bootstrap: function() {
+
+ var moduleMapper = require('cordova/modulemapper');
+ var channel = require('cordova/channel');
+
+ moduleMapper.clobbers('cordova/exec/proxy', 'cordova.commandProxy');
+
+ channel.onPluginsReady.subscribe(function () {
+ channel.onNativeReady.fire();
+ });
+
+ // FIXME is this the right place to clobber pause/resume? I am guessing not
+ // FIXME pause/resume should be deprecated IN CORDOVA for pagevisiblity api
+ document.addEventListener('webkitvisibilitychange', function() {
+ if (document.webkitHidden) {
+ channel.onPause.fire();
+ }
+ else {
+ channel.onResume.fire();
+ }
+ }, false);
+
+ // End of bootstrap
+ }
+};
http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/src/common/argscheck.js
----------------------------------------------------------------------
diff --git a/src/common/argscheck.js b/src/common/argscheck.js
new file mode 100644
index 0000000..104739a
--- /dev/null
+++ b/src/common/argscheck.js
@@ -0,0 +1,81 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+var exec = require('cordova/exec');
+var utils = require('cordova/utils');
+
+var moduleExports = module.exports;
+
+var typeMap = {
+ 'A': 'Array',
+ 'D': 'Date',
+ 'N': 'Number',
+ 'S': 'String',
+ 'F': 'Function',
+ 'O': 'Object'
+};
+
+function extractParamName(callee, argIndex) {
+ return (/.*?\((.*?)\)/).exec(callee)[1].split(', ')[argIndex];
+}
+
+function checkArgs(spec, functionName, args, opt_callee) {
+ if (!moduleExports.enableChecks) {
+ return;
+ }
+ var errMsg = null;
+ var typeName;
+ for (var i = 0; i < spec.length; ++i) {
+ var c = spec.charAt(i),
+ cUpper = c.toUpperCase(),
+ arg = args[i];
+ // Asterix means allow anything.
+ if (c == '*') {
+ continue;
+ }
+ typeName = utils.typeName(arg);
+ if ((arg === null || arg === undefined) && c == cUpper) {
+ continue;
+ }
+ if (typeName != typeMap[cUpper]) {
+ errMsg = 'Expected ' + typeMap[cUpper];
+ break;
+ }
+ }
+ if (errMsg) {
+ errMsg += ', but got ' + typeName + '.';
+ errMsg = 'Wrong type for parameter "' + extractParamName(opt_callee || args.callee, i) + '" of ' + functionName + ': ' + errMsg;
+ // Don't log when running unit tests.
+ if (typeof jasmine == 'undefined') {
+ console.error(errMsg);
+ }
+ throw TypeError(errMsg);
+ }
+}
+
+function getValue(value, defaultValue) {
+ return value === undefined ? defaultValue : value;
+}
+
+moduleExports.checkArgs = checkArgs;
+moduleExports.getValue = getValue;
+moduleExports.enableChecks = true;
+
http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/src/common/base64.js
----------------------------------------------------------------------
diff --git a/src/common/base64.js b/src/common/base64.js
new file mode 100644
index 0000000..be58f38
--- /dev/null
+++ b/src/common/base64.js
@@ -0,0 +1,71 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+var base64 = exports;
+
+base64.fromArrayBuffer = function(arrayBuffer) {
+ var array = new Uint8Array(arrayBuffer);
+ return uint8ToBase64(array);
+};
+
+//------------------------------------------------------------------------------
+
+/* This code is based on the performance tests at http://jsperf.com/b64tests
+ * This 12-bit-at-a-time algorithm was the best performing version on all
+ * platforms tested.
+ */
+
+var b64_6bit = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+var b64_12bit;
+
+var b64_12bitTable = function() {
+ b64_12bit = [];
+ for (var i=0; i<64; i++) {
+ for (var j=0; j<64; j++) {
+ b64_12bit[i*64+j] = b64_6bit[i] + b64_6bit[j];
+ }
+ }
+ b64_12bitTable = function() { return b64_12bit; };
+ return b64_12bit;
+};
+
+function uint8ToBase64(rawData) {
+ var numBytes = rawData.byteLength;
+ var output="";
+ var segment;
+ var table = b64_12bitTable();
+ for (var i=0;i<numBytes-2;i+=3) {
+ segment = (rawData[i] << 16) + (rawData[i+1] << 8) + rawData[i+2];
+ output += table[segment >> 12];
+ output += table[segment & 0xfff];
+ }
+ if (numBytes - i == 2) {
+ segment = (rawData[i] << 16) + (rawData[i+1] << 8);
+ output += table[segment >> 12];
+ output += b64_6bit[(segment & 0xfff) >> 6];
+ output += '=';
+ } else if (numBytes - i == 1) {
+ segment = (rawData[i] << 16);
+ output += table[segment >> 12];
+ output += '==';
+ }
+ return output;
+}
http://git-wip-us.apache.org/repos/asf/cordova-js/blob/d9a3dced/src/common/builder.js
----------------------------------------------------------------------
diff --git a/src/common/builder.js b/src/common/builder.js
new file mode 100644
index 0000000..826820d
--- /dev/null
+++ b/src/common/builder.js
@@ -0,0 +1,128 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+var utils = require('cordova/utils');
+
+function each(objects, func, context) {
+ for (var prop in objects) {
+ if (objects.hasOwnProperty(prop)) {
+ func.apply(context, [objects[prop], prop]);
+ }
+ }
+}
+
+function clobber(obj, key, value) {
+ exports.replaceHookForTesting(obj, key);
+ obj[key] = value;
+ // Getters can only be overridden by getters.
+ if (obj[key] !== value) {
+ utils.defineGetter(obj, key, function() {
+ return value;
+ });
+ }
+}
+
+function assignOrWrapInDeprecateGetter(obj, key, value, message) {
+ if (message) {
+ utils.defineGetter(obj, key, function() {
+ console.log(message);
+ delete obj[key];
+ clobber(obj, key, value);
+ return value;
+ });
+ } else {
+ clobber(obj, key, value);
+ }
+}
+
+function include(parent, objects, clobber, merge) {
+ each(objects, function (obj, key) {
+ try {
+ var result = obj.path ? require(obj.path) : {};
+
+ if (clobber) {
+ // Clobber if it doesn't exist.
+ if (typeof parent[key] === 'undefined') {
+ assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
+ } else if (typeof obj.path !== 'undefined') {
+ // If merging, merge properties onto parent, otherwise, clobber.
+ if (merge) {
+ recursiveMerge(parent[key], result);
+ } else {
+ assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
+ }
+ }
+ result = parent[key];
+ } else {
+ // Overwrite if not currently defined.
+ if (typeof parent[key] == 'undefined') {
+ assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
+ } else {
+ // Set result to what already exists, so we can build children into it if they exist.
+ result = parent[key];
+ }
+ }
+
+ if (obj.children) {
+ include(result, obj.children, clobber, merge);
+ }
+ } catch(e) {
+ utils.alert('Exception building Cordova JS globals: ' + e + ' for key "' + key + '"');
+ }
+ });
+}
+
+/**
+ * Merge properties from one object onto another recursively. Properties from
+ * the src object will overwrite existing target property.
+ *
+ * @param target Object to merge properties into.
+ * @param src Object to merge properties from.
+ */
+function recursiveMerge(target, src) {
+ for (var prop in src) {
+ if (src.hasOwnProperty(prop)) {
+ if (target.prototype && target.prototype.constructor === target) {
+ // If the target object is a constructor override off prototype.
+ clobber(target.prototype, prop, src[prop]);
+ } else {
+ if (typeof src[prop] === 'object' && typeof target[prop] === 'object') {
+ recursiveMerge(target[prop], src[prop]);
+ } else {
+ clobber(target, prop, src[prop]);
+ }
+ }
+ }
+ }
+}
+
+exports.buildIntoButDoNotClobber = function(objects, target) {
+ include(target, objects, false, false);
+};
+exports.buildIntoAndClobber = function(objects, target) {
+ include(target, objects, true, false);
+};
+exports.buildIntoAndMerge = function(objects, target) {
+ include(target, objects, true, true);
+};
+exports.recursiveMerge = recursiveMerge;
+exports.assignOrWrapInDeprecateGetter = assignOrWrapInDeprecateGetter;
+exports.replaceHookForTesting = function() {};