UNPKG

ccos-cli

Version:

This is a command line interface toolkit. It is used for generating and managing example code for CoocaaOS running on Skyworth/Coocaa TV webos API.

1,214 lines (1,084 loc) 87.5 kB
; (function() { var PLATFORM_VERSION_BUILD_LABEL = '5.2.0-dev'; // file: src/scripts/require.js var require, define; (function() { var modules = {}, // Stack of moduleIds currently being built. requireStack = [], // Map of module ID -> index into requireStack of modules currently being built. inProgressModules = {}, SEPARATOR = "."; function build(module) { var factory = module.factory, localRequire = function(id) { var resultantId = id; //Its a relative path, so lop off the last portion and add the id (minus "./") if (id.charAt(0) === ".") { resultantId = module.id.slice(0, module.id.lastIndexOf(SEPARATOR)) + SEPARATOR + id.slice(2); } return require(resultantId); }; module.exports = {}; delete module.factory; factory(localRequire, module.exports, module); return module.exports; } require = function(id) { if (!modules[id]) { throw "module " + id + " not found"; } else if (id in inProgressModules) { var cycle = requireStack.slice(inProgressModules[id]).join('->') + '->' + id; throw "Cycle in require graph: " + cycle; } if (modules[id].factory) { try { inProgressModules[id] = requireStack.length; requireStack.push(id); return build(modules[id]); } finally { delete inProgressModules[id]; requireStack.pop(); } } return modules[id].exports; }; define = function(id, factory) { if (modules[id]) { throw "module " + id + " already defined"; } modules[id] = { id: id, factory: factory }; }; define.remove = function(id) { delete modules[id]; }; define.moduleMap = modules; })(); //Export for use in node if (typeof module === "object" && typeof require === "function") { module.exports.require = require; module.exports.define = define; } // file: src/cordova.js define("cordova", function(require, exports, module) { // Workaround for Windows 10 in hosted environment case // http://www.w3.org/html/wg/drafts/html/master/browsers.html#named-access-on-the-window-object if (window.cordova && !(window.cordova instanceof HTMLElement)) { throw new Error("cordova already defined"); } var channel = require('cordova/channel'); var platform = require('cordova/platform'); /** * Intercept calls to addEventListener + removeEventListener and handle deviceready, * resume, and pause events. */ var m_document_addEventListener = document.addEventListener; var m_document_removeEventListener = document.removeEventListener; var m_window_addEventListener = window.addEventListener; var m_window_removeEventListener = window.removeEventListener; /** * Houses custom event handlers to intercept on document + window event listeners. */ var documentEventHandlers = {}, windowEventHandlers = {}; document.addEventListener = function(evt, handler, capture) { var e = evt.toLowerCase(); if (typeof documentEventHandlers[e] != 'undefined') { documentEventHandlers[e].subscribe(handler); } else { m_document_addEventListener.call(document, evt, handler, capture); } }; window.addEventListener = function(evt, handler, capture) { var e = evt.toLowerCase(); if (typeof windowEventHandlers[e] != 'undefined') { windowEventHandlers[e].subscribe(handler); } else { m_window_addEventListener.call(window, evt, handler, capture); } }; document.removeEventListener = function(evt, handler, capture) { var e = evt.toLowerCase(); // If unsubscribing from an event that is handled by a plugin if (typeof documentEventHandlers[e] != "undefined") { documentEventHandlers[e].unsubscribe(handler); } else { m_document_removeEventListener.call(document, evt, handler, capture); } }; window.removeEventListener = function(evt, handler, capture) { var e = evt.toLowerCase(); // If unsubscribing from an event that is handled by a plugin if (typeof windowEventHandlers[e] != "undefined") { windowEventHandlers[e].unsubscribe(handler); } else { m_window_removeEventListener.call(window, evt, handler, capture); } }; function createEvent(type, data) { var event = document.createEvent('Events'); event.initEvent(type, false, false); if (data) { for (var i in data) { if (data.hasOwnProperty(i)) { event[i] = data[i]; } } } return event; } var cordova = { define: define, require: require, version: PLATFORM_VERSION_BUILD_LABEL, platformVersion: PLATFORM_VERSION_BUILD_LABEL, platformId: platform.id, /** * Methods to add/remove your own addEventListener hijacking on document + window. */ addWindowEventHandler: function(event) { return (windowEventHandlers[event] = channel.create(event)); }, addStickyDocumentEventHandler: function(event) { return (documentEventHandlers[event] = channel.createSticky(event)); }, addDocumentEventHandler: function(event) { return (documentEventHandlers[event] = channel.create(event)); }, removeWindowEventHandler: function(event) { delete windowEventHandlers[event]; }, removeDocumentEventHandler: function(event) { delete documentEventHandlers[event]; }, /** * Retrieve original event handlers that were replaced by Cordova * * @return object */ getOriginalHandlers: function() { return { 'document': { 'addEventListener': m_document_addEventListener, 'removeEventListener': m_document_removeEventListener }, 'window': { 'addEventListener': m_window_addEventListener, 'removeEventListener': m_window_removeEventListener } }; }, /** * Method to fire event from native code * bNoDetach is required for events which cause an exception which needs to be caught in native code */ fireDocumentEvent: function(type, data, bNoDetach) { var evt = createEvent(type, data); if (typeof documentEventHandlers[type] != 'undefined') { if (bNoDetach) { documentEventHandlers[type].fire(evt); } else { setTimeout(function() { // Fire deviceready on listeners that were registered before cordova.js was loaded. if (type == 'deviceready') { document.dispatchEvent(evt); } documentEventHandlers[type].fire(evt); }, 0); } } else { document.dispatchEvent(evt); } }, fireWindowEvent: function(type, data) { var evt = createEvent(type, data); if (typeof windowEventHandlers[type] != 'undefined') { setTimeout(function() { windowEventHandlers[type].fire(evt); }, 0); } else { window.dispatchEvent(evt); } }, /** * Plugin callback mechanism. */ // Randomize the starting callbackId to avoid collisions after refreshing or navigating. // This way, it's very unlikely that any new callback would get the same callbackId as an old callback. callbackId: Math.floor(Math.random() * 2000000000), callbacks: {}, callbackStatus: { NO_RESULT: 0, OK: 1, CLASS_NOT_FOUND_EXCEPTION: 2, ILLEGAL_ACCESS_EXCEPTION: 3, INSTANTIATION_EXCEPTION: 4, MALFORMED_URL_EXCEPTION: 5, IO_EXCEPTION: 6, INVALID_ACTION: 7, JSON_EXCEPTION: 8, ERROR: 9 }, /** * Called by native code when returning successful result from an action. */ callbackSuccess: function(callbackId, args) { cordova.callbackFromNative(callbackId, true, args.status, [args.message], args.keepCallback); }, /** * Called by native code when returning error result from an action. */ callbackError: function(callbackId, args) { // TODO: Deprecate callbackSuccess and callbackError in favour of callbackFromNative. // Derive success from status. cordova.callbackFromNative(callbackId, false, args.status, [args.message], args.keepCallback); }, /** * Called by native code when returning the result from an action. */ callbackFromNative: function(callbackId, isSuccess, status, args, keepCallback) { try { var callback = cordova.callbacks[callbackId]; if (callback) { if (isSuccess && status == cordova.callbackStatus.OK) { callback.success && callback.success.apply(null, args); } else if (!isSuccess) { callback.fail && callback.fail.apply(null, args); } /* else Note, this case is intentionally not caught. this can happen if isSuccess is true, but callbackStatus is NO_RESULT which is used to remove a callback from the list without calling the callbacks typically keepCallback is false in this case */ // Clear callback if not expecting any more results if (!keepCallback) { delete cordova.callbacks[callbackId]; } } } catch (err) { var msg = "Error in " + (isSuccess ? "Success" : "Error") + " callbackId: " + callbackId + " : " + err; console && console.log && console.log(msg); cordova.fireWindowEvent("cordovacallbackerror", { 'message': msg }); throw err; } }, addConstructor: function(func) { channel.onCordovaReady.subscribe(function() { try { func(); } catch (e) { console.log("Failed to run constructor: " + e); } }); } }; module.exports = cordova; }); // file: /Users/steveng/repo/cordova/cordova-android/cordova-js-src/android/nativeapiprovider.js define("cordova/android/nativeapiprovider", function(require, exports, module) { /** * 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; } }; }); // file: /Users/steveng/repo/cordova/cordova-android/cordova-js-src/android/promptbasednativeapi.js define("cordova/android/promptbasednativeapi", function(require, exports, module) { /** * Implements the API of ExposedJsApi.java, but uses prompt() to communicate. * This is used pre-JellyBean, where addJavascriptInterface() is disabled. */ module.exports = { exec: function(bridgeSecret, service, action, callbackId, argsJson) { return prompt(argsJson, 'gap:' + JSON.stringify([bridgeSecret, service, action, callbackId])); }, setNativeToJsBridgeMode: function(bridgeSecret, value) { prompt(value, 'gap_bridge_mode:' + bridgeSecret); }, retrieveJsMessages: function(bridgeSecret, fromOnlineEvent) { return prompt(+fromOnlineEvent, 'gap_poll:' + bridgeSecret); } }; }); // file: src/common/argscheck.js define("cordova/argscheck", function(require, exports, module) { 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; }); // file: src/common/base64.js define("cordova/base64", function(require, exports, module) { var base64 = exports; base64.fromArrayBuffer = function(arrayBuffer) { var array = new Uint8Array(arrayBuffer); return uint8ToBase64(array); }; base64.toArrayBuffer = function(str) { var decodedStr = typeof atob != 'undefined' ? atob(str) : new Buffer(str, 'base64').toString('binary'); var arrayBuffer = new ArrayBuffer(decodedStr.length); var array = new Uint8Array(arrayBuffer); for (var i = 0, len = decodedStr.length; i < len; i++) { array[i] = decodedStr.charCodeAt(i); } return arrayBuffer; }; //------------------------------------------------------------------------------ /* 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; } }); // file: src/common/builder.js define("cordova/builder", function(require, exports, module) { 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); var needsProperty = false; try { obj[key] = value; } catch (e) { needsProperty = true; } // Getters can only be overridden by getters. if (needsProperty || 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() {}; }); // file: src/common/channel.js define("cordova/channel", function(require, exports, module) { var utils = require('cordova/utils'), nextGuid = 1; /** * Custom pub-sub "channel" that can have functions subscribed to it * This object is used to define and control firing of events for * cordova initialization, as well as for custom events thereafter. * * The order of events during page load and Cordova startup is as follows: * * onDOMContentLoaded* Internal event that is received when the web page is loaded and parsed. * onNativeReady* Internal event that indicates the Cordova native side is ready. * onCordovaReady* Internal event fired when all Cordova JavaScript objects have been created. * onDeviceReady* User event fired to indicate that Cordova is ready * onResume User event fired to indicate a start/resume lifecycle event * onPause User event fired to indicate a pause lifecycle event * * The events marked with an * are sticky. Once they have fired, they will stay in the fired state. * All listeners that subscribe after the event is fired will be executed right away. * * The only Cordova events that user code should register for are: * deviceready Cordova native code is initialized and Cordova APIs can be called from JavaScript * pause App has moved to background * resume App has returned to foreground * * Listeners can be registered as: * document.addEventListener("deviceready", myDeviceReadyListener, false); * document.addEventListener("resume", myResumeListener, false); * document.addEventListener("pause", myPauseListener, false); * * The DOM lifecycle events should be used for saving and restoring state * window.onload * window.onunload * */ /** * Channel * @constructor * @param type String the channel name */ var Channel = function(type, sticky) { this.type = type; // Map of guid -> function. this.handlers = {}; // 0 = Non-sticky, 1 = Sticky non-fired, 2 = Sticky fired. this.state = sticky ? 1 : 0; // Used in sticky mode to remember args passed to fire(). this.fireArgs = null; // Used by onHasSubscribersChange to know if there are any listeners. this.numHandlers = 0; // Function that is called when the first listener is subscribed, or when // the last listener is unsubscribed. this.onHasSubscribersChange = null; }, channel = { /** * Calls the provided function only after all of the channels specified * have been fired. All channels must be sticky channels. */ join: function(h, c) { var len = c.length, i = len, f = function() { if (!(--i)) h(); }; for (var j = 0; j < len; j++) { if (c[j].state === 0) { throw Error('Can only use join with sticky channels.'); } c[j].subscribe(f); } if (!len) h(); }, create: function(type) { return channel[type] = new Channel(type, false); }, createSticky: function(type) { return channel[type] = new Channel(type, true); }, /** * cordova Channels that must fire before "deviceready" is fired. */ deviceReadyChannelsArray: [], deviceReadyChannelsMap: {}, /** * Indicate that a feature needs to be initialized before it is ready to be used. * This holds up Cordova's "deviceready" event until the feature has been initialized * and Cordova.initComplete(feature) is called. * * @param feature {String} The unique feature name */ waitForInitialization: function(feature) { if (feature) { var c = channel[feature] || this.createSticky(feature); this.deviceReadyChannelsMap[feature] = c; this.deviceReadyChannelsArray.push(c); } }, /** * Indicate that initialization code has completed and the feature is ready to be used. * * @param feature {String} The unique feature name */ initializationComplete: function(feature) { var c = this.deviceReadyChannelsMap[feature]; if (c) { c.fire(); } } }; function forceFunction(f) { if (typeof f != 'function') throw "Function required as first argument!"; } /** * Subscribes the given function to the channel. Any time that * Channel.fire is called so too will the function. * Optionally specify an execution context for the function * and a guid that can be used to stop subscribing to the channel. * Returns the guid. */ Channel.prototype.subscribe = function(f, c) { // need a function to call forceFunction(f); if (this.state == 2) { f.apply(c || this, this.fireArgs); return; } var func = f, guid = f.observer_guid; if (typeof c == "object") { func = utils.close(c, f); } if (!guid) { // first time any channel has seen this subscriber guid = '' + nextGuid++; } func.observer_guid = guid; f.observer_guid = guid; // Don't add the same handler more than once. if (!this.handlers[guid]) { this.handlers[guid] = func; this.numHandlers++; if (this.numHandlers == 1) { this.onHasSubscribersChange && this.onHasSubscribersChange(); } } }; /** * Unsubscribes the function with the given guid from the channel. */ Channel.prototype.unsubscribe = function(f) { // need a function to unsubscribe forceFunction(f); var guid = f.observer_guid, handler = this.handlers[guid]; if (handler) { delete this.handlers[guid]; this.numHandlers--; if (this.numHandlers === 0) { this.onHasSubscribersChange && this.onHasSubscribersChange(); } } }; /** * Calls all functions subscribed to this channel. */ Channel.prototype.fire = function(e) { var fail = false, fireArgs = Array.prototype.slice.call(arguments); // Apply stickiness. if (this.state == 1) { this.state = 2; this.fireArgs = fireArgs; } if (this.numHandlers) { // Copy the values first so that it is safe to modify it from within // callbacks. var toCall = []; for (var item in this.handlers) { toCall.push(this.handlers[item]); } for (var i = 0; i < toCall.length; ++i) { toCall[i].apply(this, fireArgs); } if (this.state == 2 && this.numHandlers) { this.numHandlers = 0; this.handlers = {}; this.onHasSubscribersChange && this.onHasSubscribersChange(); } } }; // defining them here so they are ready super fast! // DOM event that is received when the web page is loaded and parsed. channel.createSticky('onDOMContentLoaded'); // Event to indicate the Cordova native side is ready. channel.createSticky('onNativeReady'); // Event to indicate that all Cordova JavaScript objects have been created // and it's time to run plugin constructors. channel.createSticky('onCordovaReady'); // Event to indicate that all automatically loaded JS plugins are loaded and ready. // FIXME remove this channel.createSticky('onPluginsReady'); // Event to indicate that Cordova is ready channel.createSticky('onDeviceReady'); // Event to indicate a resume lifecycle event channel.create('onResume'); // Event to indicate a pause lifecycle event channel.create('onPause'); // Channels that must fire before "deviceready" is fired. channel.waitForInitialization('onCordovaReady'); channel.waitForInitialization('onDOMContentLoaded'); module.exports = channel; }); // file: /Users/steveng/repo/cordova/cordova-android/cordova-js-src/exec.js define("cordova/exec", function(require, exports, module) { /** * 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'), channel = require('cordova/channel'), jsToNativeModes = { PROMPT: 0, JS_OBJECT: 1 }, 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 }, jsToNativeBridgeMode, // Set lazily. nativeToJsBridgeMode = nativeToJsModes.ONLINE_EVENT, pollEnabled = false, bridgeSecret = -1; var messagesFromNative = []; var isProcessing = false; var resolvedPromise = typeof Promise == 'undefined' ? null : Promise.resolve(); var nextTick = resolvedPromise ? function(fn) { resolvedPromise.then(fn); } : function(fn) { setTimeout(fn); }; function androidExec(success, fail, service, action, args) { if (bridgeSecret < 0) { // If we ever catch this firing, we'll need to queue up exec()s // and fire them once we get a secret. For now, I don't think // it's possible for exec() to be called since plugins are parsed but // not run until until after onNativeReady. throw new Error('exec() called without bridgeSecret'); } // 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 }; } var msgs = nativeApiProvider.get().exec(bridgeSecret, 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 && msgs === "@Null arguments.") { androidExec.setJsToNativeBridgeMode(jsToNativeModes.PROMPT); androidExec(success, fail, service, action, args); androidExec.setJsToNativeBridgeMode(jsToNativeModes.JS_OBJECT); } else if (msgs) { messagesFromNative.push(msgs); // Always process async to avoid exceptions messing up stack. nextTick(processMessages); } } androidExec.init = function() { bridgeSecret = +prompt('', 'gap_init:' + nativeToJsBridgeMode); channel.onNativeReady.fire(); }; function pollOnceFromOnlineEvent() { pollOnce(true); } function pollOnce(opt_fromOnlineEvent) { if (bridgeSecret < 0) { // This can happen when the NativeToJsMessageQueue resets the online state on page transitions. // We know there's nothing to retrieve, so no need to poll. return; } var msgs = nativeApiProvider.get().retrieveJsMessages(bridgeSecret, !!opt_fromOnlineEvent); if (msgs) { messagesFromNative.push(msgs); // Process sync since we know we're already top-of-stack. processMessages(); } } 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) { 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. // Otherwise, it will be set by androidExec.init() if (bridgeSecret >= 0) { nativeApiProvider.get().setNativeToJsBridgeMode(bridgeSecret, mode); } if (mode == nativeToJsModes.POLLING) { pollEnabled = true; setTimeout(pollingTimerFunc, 1); } }; function buildPayload(payload, message) { var payloadKind = message.charAt(0); if (payloadKind == 's') { payload.push(message.slice(1)); } else if (payloadKind == 't') { payload.push(true); } else if (payloadKind == 'f') { payload.push(false); } else if (payloadKind == 'N') { payload.push(null); } else if (payloadKind == 'n') { payload.push(+message.slice(1)); } else if (payloadKind == 'A') { var data = message.slice(1); payload.push(base64.toArrayBuffer(data)); } else if (payloadKind == 'S') { payload.push(window.atob(message.slice(1))); } else if (payloadKind == 'M') { var multipartMessages = message.slice(1); while (multipartMessages !== "") { var spaceIdx = multipartMessages.indexOf(' '); var msgLen = +multipartMessages.slice(0, spaceIdx); var multipartMessage = multipartMessages.substr(spaceIdx + 1, msgLen); multipartMessages = multipartMessages.slice(spaceIdx + msgLen + 1); buildPayload(payload, multipartMessage); } } else { payload.push(JSON.parse(message)); } } // Processes a single message, as encoded by NativeToJsMessageQueue.java. function processMessage(message) { var firstChar = message.charAt(0); if (firstChar == 'J') { // This is deprecated on the .java side. It doesn't work with CSP enabled. 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 payloadMessage = message.slice(nextSpaceIdx + 1); var payload = []; buildPayload(payload, payloadMessage); cordova.callbackFromNative(callbackId, success, status, payload, keepCallback); } else { console.log("processMessage failed: invalid message: " + JSON.stringify(message)); } } function processMessages() { // Check for the reentrant case. if (isProcessing) { return; } if (messagesFromNative.length === 0) { return; } isProcessing = true; try { var msg = popMessageFromQueue(); // The Java side can send a * message to indicate that it // still has messages waiting to be retrieved. if (msg == '*' && messagesFromNative.length === 0) { nextTick(pollOnce); return; } processMessage(msg); } finally { isProcessing = false; if (messagesFromNative.length > 0) { nextTick(processMessages); } } } function popMessageFromQueue() { var messageBatch = messagesFromNative.shift(); if (messageBatch == '*') { return '*'; } var spaceIdx = messageBatch.indexOf(' '); var msgLen = +messageBatch.slice(0, spaceIdx); var message = messageBatch.substr(spaceIdx + 1, msgLen); messageBatch = messageBatch.slice(spaceIdx + msgLen + 1); if (messageBatch) { messagesFromNative.unshift(messageBatch); } return message; } module.exports = androidExec; }); // file: src/common/exec/proxy.js define("cordova/exec/proxy", function(require, exports, module) { // internal map of proxy function var CommandProxyMap = {}; module.exports = { // example: cordova.commandProxy.add("Accelerometer",{getCurrentAcceleration: function(successCallback, errorCallback, options) {...},...); add: function(id, proxyObj) { console.log("adding proxy for " + id); CommandProxyMap[id] = proxyObj; return proxyObj; }, // cordova.commandProxy.remove("Accelerometer"); remove: function(id) { var proxy = CommandProxyMap[id]; delete CommandProxyMap[id]; CommandProxyMap[id] = null; return proxy; }, get: function(service, action) { return (CommandProxyMap[service] ? CommandProxyMap[service][action] : null); } }; }); // file: src/common/init.js define("cordova/init", function(require, exports, module) { var channel = require('cordova/channel'); var cordova = require('cordova'); var modulemapper = require('cordova/modulemapper'); var platform = require('cordova/platform'); var pluginloader = require('cordova/pluginloader'); var utils = require('cordova/utils'); var platformInitChannelsArray = [channel.onNativeReady, channel.onPluginsReady]; function logUnfiredChannels(arr) { for (var i = 0; i < arr.length; ++i) { if (arr[i].state != 2) { console.log('Channel not fired: ' + arr[i].type); } } } window.setTimeout(function() { if (channel.onDeviceReady.state != 2) { console.log('deviceready has not fired after 50 seconds.'); logUnfiredChannels(platformInitChannelsArray); logUnfiredChannels(channel.deviceReadyChannelsArray); } }, 50000); // Replace navigator before any modules are required(), to ensure it happens as soon as possible. // We replace it so that properties that can't be clobbered can instead be overridden. function replaceNavigator(origNavigator) { var CordovaNavigator = function() {}; CordovaNavigator.prototype = origNavigator; var newNavigator = new CordovaNavigator(); // This work-around really only applies to new APIs that are newer than Function.bind. // Without it, APIs such as getGamepads() break. if (CordovaNavigator.bind) { for (var key in origNavigator) { if (typeof origNavigator[key] == 'function') { newNavigator[key] = origNavigator[key].bind(origNavigator); } else { (function(k) { utils.defineGetterSetter(newNavigator, key, function() { return origNavigator[k]; }); })(key); } } } return newNavigator; } if (window.navigator) { window.navigator = replaceNavigator(window.navigator); } if (!window.console) { window.console = { log: function() {} }; } if (!window.console.warn) {