Update JS snapshot to version 4.1.0-dev (via coho)
Project: http://git-wip-us.apache.org/repos/asf/cordova-osx/repo Commit: http://git-wip-us.apache.org/repos/asf/cordova-osx/commit/3fb50c0a Tree: http://git-wip-us.apache.org/repos/asf/cordova-osx/tree/3fb50c0a Diff: http://git-wip-us.apache.org/repos/asf/cordova-osx/diff/3fb50c0a Branch: refs/heads/master Commit: 3fb50c0ab3ad58e2b59d4245953c4d56dfa5081c Parents: f810d94 Author: Steve Gill <[email protected]> Authored: Thu Feb 11 17:03:57 2016 -0800 Committer: Steve Gill <[email protected]> Committed: Thu Feb 11 17:03:57 2016 -0800 ---------------------------------------------------------------------- CordovaLib/cordova.js | 981 ++++++++++++++++++++++++++++----------------- 1 file changed, 618 insertions(+), 363 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cordova-osx/blob/3fb50c0a/CordovaLib/cordova.js ---------------------------------------------------------------------- diff --git a/CordovaLib/cordova.js b/CordovaLib/cordova.js index f5600ff..346e067 100644 --- a/CordovaLib/cordova.js +++ b/CordovaLib/cordova.js @@ -1,5 +1,5 @@ // Platform: osx -// 4.0.0-dev +// 1b111058631e118dc37da473e30b60214c211d76 /* Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file @@ -19,7 +19,7 @@ under the License. */ ;(function() { -var PLATFORM_VERSION_BUILD_LABEL = '4.0.0-dev'; +var PLATFORM_VERSION_BUILD_LABEL = '4.1.0-dev'; // file: src/scripts/require.js /*jshint -W079 */ @@ -34,7 +34,7 @@ var require, requireStack = [], // Map of module ID -> index into requireStack of modules currently being built. inProgressModules = {}, - SEPERATOR = "."; + SEPARATOR = "."; @@ -44,7 +44,7 @@ var require, 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(SEPERATOR)) + SEPERATOR + id.slice(2); + resultantId = module.id.slice(0, module.id.lastIndexOf(SEPARATOR)) + SEPARATOR + id.slice(2); } return require(resultantId); }; @@ -98,22 +98,19 @@ if (typeof module === "object" && typeof require === "function") { module.exports.define = define; } -// file: lib/cordova.js +// 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'); -/** - * Listen for DOMContentLoaded and notify our channel subscribers. - */ -document.addEventListener('DOMContentLoaded', function() { - channel.onDOMContentLoaded.fire(); -}, false); -if (document.readyState == 'complete' || document.readyState == 'interactive') { - channel.onDOMContentLoaded.fire(); -} /** * Intercept calls to addEventListener + removeEventListener and handle deviceready, @@ -181,17 +178,6 @@ function createEvent(type, data) { return event; } -if(typeof window.console === "undefined") { - window.console = { - log:function(){} - }; -} -// there are places in the framework where we call `warn` also, so we should make sure it exists -if(typeof window.console.warn === "undefined") { - window.console.warn = function(msg) { - this.log("warn: " + msg); - } -} var cordova = { define:define, @@ -234,16 +220,16 @@ var cordova = { var evt = createEvent(type, data); if (typeof documentEventHandlers[type] != 'undefined') { if( bNoDetach ) { - documentEventHandlers[type].fire(evt); + 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); + 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); @@ -284,11 +270,7 @@ var cordova = { * Called by native code when returning successful result from an action. */ callbackSuccess: function(callbackId, args) { - try { - cordova.callbackFromNative(callbackId, true, args.status, [args.message], args.keepCallback); - } catch (e) { - console.log("Error in error callback: " + callbackId + " = "+e); - } + cordova.callbackFromNative(callbackId, true, args.status, [args.message], args.keepCallback); }, /** @@ -297,30 +279,40 @@ var cordova = { callbackError: function(callbackId, args) { // TODO: Deprecate callbackSuccess and callbackError in favour of callbackFromNative. // Derive success from status. - try { - cordova.callbackFromNative(callbackId, false, args.status, [args.message], args.keepCallback); - } catch (e) { - console.log("Error in error callback: " + callbackId + " = "+e); - } + cordova.callbackFromNative(callbackId, false, args.status, [args.message], args.keepCallback); }, /** * Called by native code when returning the result from an action. */ - callbackFromNative: function(callbackId, success, status, args, keepCallback) { - var callback = cordova.callbacks[callbackId]; - if (callback) { - if (success && status == cordova.callbackStatus.OK) { - callback.success && callback.success.apply(null, args); - } else if (!success) { - callback.fail && callback.fail.apply(null, args); - } - - // Clear callback if not expecting any more results - if (!keepCallback) { - delete cordova.callbacks[callbackId]; + 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() { @@ -333,19 +325,14 @@ var cordova = { } }; -// Register pause, resume and deviceready channels as events on document. -channel.onPause = cordova.addDocumentEventHandler('pause'); -channel.onResume = cordova.addDocumentEventHandler('resume'); -channel.onDeviceReady = cordova.addStickyDocumentEventHandler('deviceready'); module.exports = cordova; }); -// file: lib/common/argscheck.js +// file: src/common/argscheck.js define("cordova/argscheck", function(require, exports, module) { -var exec = require('cordova/exec'); var utils = require('cordova/utils'); var moduleExports = module.exports; @@ -360,7 +347,7 @@ var typeMap = { }; function extractParamName(callee, argIndex) { - return (/.*?\((.*?)\)/).exec(callee)[1].split(', ')[argIndex]; + return (/.*?\((.*?)\)/).exec(callee)[1].split(', ')[argIndex]; } function checkArgs(spec, functionName, args, opt_callee) { @@ -408,14 +395,24 @@ moduleExports.enableChecks = true; }); -// file: lib/common/base64.js +// 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); + 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; }; //------------------------------------------------------------------------------ @@ -437,7 +434,7 @@ var b64_12bitTable = function() { } b64_12bitTable = function() { return b64_12bit; }; return b64_12bit; -} +}; function uint8ToBase64(rawData) { var numBytes = rawData.byteLength; @@ -464,7 +461,7 @@ function uint8ToBase64(rawData) { }); -// file: lib/common/builder.js +// file: src/common/builder.js define("cordova/builder", function(require, exports, module) { var utils = require('cordova/utils'); @@ -479,9 +476,14 @@ function each(objects, func, context) { function clobber(obj, key, value) { exports.replaceHookForTesting(obj, key); - obj[key] = value; + var needsProperty = false; + try { + obj[key] = value; + } catch (e) { + needsProperty = true; + } // Getters can only be overridden by getters. - if (obj[key] !== value) { + if (needsProperty || obj[key] !== value) { utils.defineGetter(obj, key, function() { return value; }); @@ -504,36 +506,36 @@ function assignOrWrapInDeprecateGetter(obj, key, value, message) { 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); + 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 { - // Set result to what already exists, so we can build children into it if they exist. - result = parent[key]; + // 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); - } + if (obj.children) { + include(result, obj.children, clobber, merge); + } } catch(e) { - utils.alert('Exception building cordova JS globals: ' + e + ' for key "' + key + '"'); + utils.alert('Exception building Cordova JS globals: ' + e + ' for key "' + key + '"'); } }); } @@ -577,7 +579,7 @@ exports.replaceHookForTesting = function() {}; }); -// file: lib/common/channel.js +// file: src/common/channel.js define("cordova/channel", function(require, exports, module) { var utils = require('cordova/utils'), @@ -596,7 +598,6 @@ var utils = require('cordova/utils'), * 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 - * onDestroy* Internal event fired when app is being destroyed (User should use window.onunload event, not this one). * * 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. @@ -796,6 +797,7 @@ channel.createSticky('onNativeReady'); 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 @@ -807,9 +809,6 @@ channel.create('onResume'); // Event to indicate a pause lifecycle event channel.create('onPause'); -// Event to indicate a destroy lifecycle event -channel.createSticky('onDestroy'); - // Channels that must fire before "deviceready" is fired. channel.waitForInitialization('onCordovaReady'); channel.waitForInitialization('onDOMContentLoaded'); @@ -818,37 +817,7 @@ module.exports = channel; }); -// file: lib/common/commandProxy.js -define("cordova/commandProxy", 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: lib/osx/exec.js +// file: /Users/steveng/repo/cordova/cordova-osx/cordova-js-src/exec.js define("cordova/exec", function(require, exports, module) { /** @@ -857,21 +826,21 @@ define("cordova/exec", function(require, exports, module) { * @private */ var cordova = require('cordova'), - channel = require('cordova/channel'), - utils = require('cordova/utils'), - base64 = require('cordova/base64'); + channel = require('cordova/channel'), + utils = require('cordova/utils'), + base64 = require('cordova/base64'); function massageMessageNativeToJs(message) { if (message.CDVType == 'ArrayBuffer') { - var stringToArrayBuffer = function(str) { + var stringToArrayBuffer = function (str) { var ret = new Uint8Array(str.length); for (var i = 0; i < str.length; i++) { ret[i] = str.charCodeAt(i); } return ret.buffer; }; - var base64ToArrayBuffer = function(b64) { + var base64ToArrayBuffer = function (b64) { return stringToArrayBuffer(atob(b64)); }; message = base64ToArrayBuffer(message.data); @@ -884,7 +853,7 @@ function convertMessageToArgsNativeToJs(message) { if (!message || !message.hasOwnProperty('CDVType')) { args.push(message); } else if (message.CDVType == 'MultiPart') { - message.messages.forEach(function(e) { + message.messages.forEach(function (e) { args.push(massageMessageNativeToJs(e)); }); } else { @@ -895,10 +864,10 @@ function convertMessageToArgsNativeToJs(message) { function massageArgsJsToNative(args) { if (!args || utils.typeName(args) != 'Array') { - return args; + return args; } var ret = []; - args.forEach(function(arg, i) { + args.forEach(function (arg, i) { if (utils.typeName(arg) == 'ArrayBuffer') { ret.push({ 'CDVType': 'ArrayBuffer', @@ -927,10 +896,10 @@ function OSXExec() { if (successCallback || failCallback) { callbackId = service + cordova.callbackId++; cordova.callbacks[callbackId] = - {success:successCallback, fail:failCallback}; + {success: successCallback, fail: failCallback}; } - actionArgs = massageArgsJsToNative(actionArgs); + actionArgs = massageArgsJsToNative(actionArgs); if (window.cordovabridge && window.cordovabridge.exec) { window.cordovabridge.exec(callbackId, service, action, actionArgs); @@ -940,7 +909,7 @@ function OSXExec() { } -OSXExec.nativeCallback = function(callbackId, status, message, keepCallback) { +OSXExec.nativeCallback = function (callbackId, status, message, keepCallback) { var success = status === 0 || status === 1; var args = convertMessageToArgsNativeToJs(message); cordova.callbackFromNative(callbackId, success, status, args, keepCallback); @@ -950,7 +919,290 @@ module.exports = OSXExec; }); -// file: lib/common/modulemapper.js +// 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 5 seconds.'); + logUnfiredChannels(platformInitChannelsArray); + logUnfiredChannels(channel.deviceReadyChannelsArray); + } +}, 5000); + +// 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) { + window.console.warn = function(msg) { + this.log("warn: " + msg); + }; +} + +// Register pause, resume and deviceready channels as events on document. +channel.onPause = cordova.addDocumentEventHandler('pause'); +channel.onResume = cordova.addDocumentEventHandler('resume'); +channel.onActivated = cordova.addDocumentEventHandler('activated'); +channel.onDeviceReady = cordova.addStickyDocumentEventHandler('deviceready'); + +// Listen for DOMContentLoaded and notify our channel subscribers. +if (document.readyState == 'complete' || document.readyState == 'interactive') { + channel.onDOMContentLoaded.fire(); +} else { + document.addEventListener('DOMContentLoaded', function() { + channel.onDOMContentLoaded.fire(); + }, false); +} + +// _nativeReady is global variable that the native side can set +// to signify that the native code is ready. It is a global since +// it may be called before any cordova JS is ready. +if (window._nativeReady) { + channel.onNativeReady.fire(); +} + +modulemapper.clobbers('cordova', 'cordova'); +modulemapper.clobbers('cordova/exec', 'cordova.exec'); +modulemapper.clobbers('cordova/exec', 'Cordova.exec'); + +// Call the platform-specific initialization. +platform.bootstrap && platform.bootstrap(); + +// Wrap in a setTimeout to support the use-case of having plugin JS appended to cordova.js. +// The delay allows the attached modules to be defined before the plugin loader looks for them. +setTimeout(function() { + pluginloader.load(function() { + channel.onPluginsReady.fire(); + }); +}, 0); + +/** + * Create all cordova objects once native side is ready. + */ +channel.join(function() { + modulemapper.mapModules(window); + + platform.initialize && platform.initialize(); + + // Fire event to notify that all objects are created + channel.onCordovaReady.fire(); + + // Fire onDeviceReady event once page has fully loaded, all + // constructors have run and cordova info has been received from native + // side. + channel.join(function() { + require('cordova').fireDocumentEvent('deviceready'); + }, channel.deviceReadyChannelsArray); + +}, platformInitChannelsArray); + + +}); + +// file: src/common/init_b.js +define("cordova/init_b", 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.onDOMContentLoaded, channel.onNativeReady, channel.onPluginsReady]; + +// setting exec +cordova.exec = require('cordova/exec'); + +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 5 seconds.'); + logUnfiredChannels(platformInitChannelsArray); + logUnfiredChannels(channel.deviceReadyChannelsArray); + } +}, 5000); + +// 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) { + window.console.warn = function(msg) { + this.log("warn: " + msg); + }; +} + +// Register pause, resume and deviceready channels as events on document. +channel.onPause = cordova.addDocumentEventHandler('pause'); +channel.onResume = cordova.addDocumentEventHandler('resume'); +channel.onActivated = cordova.addDocumentEventHandler('activated'); +channel.onDeviceReady = cordova.addStickyDocumentEventHandler('deviceready'); + +// Listen for DOMContentLoaded and notify our channel subscribers. +if (document.readyState == 'complete' || document.readyState == 'interactive') { + channel.onDOMContentLoaded.fire(); +} else { + document.addEventListener('DOMContentLoaded', function() { + channel.onDOMContentLoaded.fire(); + }, false); +} + +// _nativeReady is global variable that the native side can set +// to signify that the native code is ready. It is a global since +// it may be called before any cordova JS is ready. +if (window._nativeReady) { + channel.onNativeReady.fire(); +} + +// Call the platform-specific initialization. +platform.bootstrap && platform.bootstrap(); + +// Wrap in a setTimeout to support the use-case of having plugin JS appended to cordova.js. +// The delay allows the attached modules to be defined before the plugin loader looks for them. +setTimeout(function() { + pluginloader.load(function() { + channel.onPluginsReady.fire(); + }); +}, 0); + +/** + * Create all cordova objects once native side is ready. + */ +channel.join(function() { + modulemapper.mapModules(window); + + platform.initialize && platform.initialize(); + + // Fire event to notify that all objects are created + channel.onCordovaReady.fire(); + + // Fire onDeviceReady event once page has fully loaded, all + // constructors have run and cordova info has been received from native + // side. + channel.join(function() { + require('cordova').fireDocumentEvent('deviceready'); + }, channel.deviceReadyChannelsArray); + +}, platformInitChannelsArray); + +}); + +// file: src/common/modulemapper.js define("cordova/modulemapper", function(require, exports, module) { var builder = require('cordova/builder'), @@ -1046,175 +1298,209 @@ exports.getOriginalSymbol = function(context, symbolPath) { return obj; }; -exports.loadMatchingModules = function(matchingRegExp) { - for (var k in moduleMap) { - if (matchingRegExp.exec(k)) { - require(k); - } - } -}; - exports.reset(); }); -// file: lib/osx/platform.js -define("cordova/platform", function(require, exports, module) { +// file: src/common/modulemapper_b.js +define("cordova/modulemapper_b", function(require, exports, module) { -module.exports = { - id: "osx", - initialize:function() { - var modulemapper = require('cordova/modulemapper'); +var builder = require('cordova/builder'), + symbolList = [], + deprecationMap; - modulemapper.loadMatchingModules(/cordova.*\/plugininit$/); +exports.reset = function() { + symbolList = []; + deprecationMap = {}; +}; - modulemapper.loadMatchingModules(/cordova.*\/symbols$/); - modulemapper.mapModules(window); +function addEntry(strategy, moduleName, symbolPath, opt_deprecationMessage) { + symbolList.push(strategy, moduleName, symbolPath); + if (opt_deprecationMessage) { + deprecationMap[symbolPath] = opt_deprecationMessage; } +} + +// Note: Android 2.3 does have Function.bind(). +exports.clobbers = function(moduleName, symbolPath, opt_deprecationMessage) { + addEntry('c', moduleName, symbolPath, opt_deprecationMessage); }; +exports.merges = function(moduleName, symbolPath, opt_deprecationMessage) { + addEntry('m', moduleName, symbolPath, opt_deprecationMessage); +}; -}); +exports.defaults = function(moduleName, symbolPath, opt_deprecationMessage) { + addEntry('d', moduleName, symbolPath, opt_deprecationMessage); +}; -// file: lib/common/plugin/echo.js -define("cordova/plugin/echo", function(require, exports, module) { +exports.runs = function(moduleName) { + addEntry('r', moduleName, null); +}; -var exec = require('cordova/exec'), - utils = require('cordova/utils'); +function prepareNamespace(symbolPath, context) { + if (!symbolPath) { + return context; + } + var parts = symbolPath.split('.'); + var cur = context; + for (var i = 0, part; part = parts[i]; ++i) { + cur = cur[part] = cur[part] || {}; + } + return cur; +} -/** - * Sends the given message through exec() to the Echo plugin, which sends it back to the successCallback. - * @param successCallback invoked with a FileSystem object - * @param errorCallback invoked if error occurs retrieving file system - * @param message The string to be echoed. - * @param forceAsync Whether to force an async return value (for testing native->js bridge). - */ -module.exports = function(successCallback, errorCallback, message, forceAsync) { - var action = 'echo'; - var messageIsMultipart = (utils.typeName(message) == "Array"); - var args = messageIsMultipart ? message : [message]; - - if (utils.typeName(message) == 'ArrayBuffer') { - if (forceAsync) { - console.warn('Cannot echo ArrayBuffer with forced async, falling back to sync.'); +exports.mapModules = function(context) { + var origSymbols = {}; + context.CDV_origSymbols = origSymbols; + for (var i = 0, len = symbolList.length; i < len; i += 3) { + var strategy = symbolList[i]; + var moduleName = symbolList[i + 1]; + var module = require(moduleName); + // <runs/> + if (strategy == 'r') { + continue; } - action += 'ArrayBuffer'; - } else if (messageIsMultipart) { - if (forceAsync) { - console.warn('Cannot echo MultiPart Array with forced async, falling back to sync.'); + var symbolPath = symbolList[i + 2]; + var lastDot = symbolPath.lastIndexOf('.'); + var namespace = symbolPath.substr(0, lastDot); + var lastName = symbolPath.substr(lastDot + 1); + + var deprecationMsg = symbolPath in deprecationMap ? 'Access made to deprecated symbol: ' + symbolPath + '. ' + deprecationMsg : null; + var parentObj = prepareNamespace(namespace, context); + var target = parentObj[lastName]; + + if (strategy == 'm' && target) { + builder.recursiveMerge(target, module); + } else if ((strategy == 'd' && !target) || (strategy != 'd')) { + if (!(symbolPath in origSymbols)) { + origSymbols[symbolPath] = target; + } + builder.assignOrWrapInDeprecateGetter(parentObj, lastName, module, deprecationMsg); } - action += 'MultiPart'; - } else if (forceAsync) { - action += 'Async'; } +}; + +exports.getOriginalSymbol = function(context, symbolPath) { + var origSymbols = context.CDV_origSymbols; + if (origSymbols && (symbolPath in origSymbols)) { + return origSymbols[symbolPath]; + } + var parts = symbolPath.split('.'); + var obj = context; + for (var i = 0; i < parts.length; ++i) { + obj = obj && obj[parts[i]]; + } + return obj; +}; + +exports.reset(); - exec(successCallback, errorCallback, "Echo", action, args); + +}); + +// file: /Users/steveng/repo/cordova/cordova-osx/cordova-js-src/platform.js +define("cordova/platform", function(require, exports, module) { + +module.exports = { + id: "osx", + bootstrap: function() { + require('cordova/channel').onNativeReady.fire(); + } }; }); -// file: lib/common/pluginloader.js +// file: src/common/pluginloader.js define("cordova/pluginloader", function(require, exports, module) { -var channel = require('cordova/channel'); var modulemapper = require('cordova/modulemapper'); +var urlutil = require('cordova/urlutil'); // Helper function to inject a <script> tag. -function injectScript(url, onload, onerror) { +// Exported for testing. +exports.injectScript = function(url, onload, onerror) { var script = document.createElement("script"); // onload fires even when script fails loads with an error. script.onload = onload; - script.onerror = onerror || onload; + // onerror fires for malformed URLs. + script.onerror = onerror; script.src = url; document.head.appendChild(script); +}; + +function injectIfNecessary(id, url, onload, onerror) { + onerror = onerror || onload; + if (id in define.moduleMap) { + onload(); + } else { + exports.injectScript(url, function() { + if (id in define.moduleMap) { + onload(); + } else { + onerror(); + } + }, onerror); + } } -function onScriptLoadingComplete(moduleList) { +function onScriptLoadingComplete(moduleList, finishPluginLoading) { // Loop through all the plugins and then through their clobbers and merges. for (var i = 0, module; module = moduleList[i]; i++) { - if (module) { - try { - if (module.clobbers && module.clobbers.length) { - for (var j = 0; j < module.clobbers.length; j++) { - modulemapper.clobbers(module.id, module.clobbers[j]); - } - } - - if (module.merges && module.merges.length) { - for (var k = 0; k < module.merges.length; k++) { - modulemapper.merges(module.id, module.merges[k]); - } - } - - // Finally, if runs is truthy we want to simply require() the module. - // This can be skipped if it had any merges or clobbers, though, - // since the mapper will already have required the module. - if (module.runs && !(module.clobbers && module.clobbers.length) && !(module.merges && module.merges.length)) { - modulemapper.runs(module.id); - } + if (module.clobbers && module.clobbers.length) { + for (var j = 0; j < module.clobbers.length; j++) { + modulemapper.clobbers(module.id, module.clobbers[j]); } - catch(err) { - // error with module, most likely clobbers, should we continue? + } + + if (module.merges && module.merges.length) { + for (var k = 0; k < module.merges.length; k++) { + modulemapper.merges(module.id, module.merges[k]); } } + + // Finally, if runs is truthy we want to simply require() the module. + if (module.runs) { + modulemapper.runs(module.id); + } } finishPluginLoading(); } -// Called when: -// * There are plugins defined and all plugins are finished loading. -// * There are no plugins to load. -function finishPluginLoading() { - channel.onPluginsReady.fire(); -} - // Handler for the cordova_plugins.js content. // See plugman's plugin_loader.js for the details of this object. // This function is only called if the really is a plugins array that isn't empty. // Otherwise the onerror response handler will just call finishPluginLoading(). -function handlePluginsObject(path, moduleList) { +function handlePluginsObject(path, moduleList, finishPluginLoading) { // Now inject the scripts. var scriptCounter = moduleList.length; if (!scriptCounter) { - onScriptLoadingComplete(); + finishPluginLoading(); return; } function scriptLoadedCallback() { if (!--scriptCounter) { - onScriptLoadingComplete(moduleList); + onScriptLoadingComplete(moduleList, finishPluginLoading); } } for (var i = 0; i < moduleList.length; i++) { - injectScript(path + moduleList[i].file, scriptLoadedCallback); + injectIfNecessary(moduleList[i].id, path + moduleList[i].file, scriptLoadedCallback); } } -function injectPluginScript(pathPrefix) { - injectScript(pathPrefix + 'cordova_plugins.js', function(){ - try { - var moduleList = require("cordova/plugin_list"); - handlePluginsObject(pathPrefix, moduleList); - } catch (e) { - // Error loading cordova_plugins.js, file not found or something - // this is an acceptable error, pre-3.0.0, so we just move on. - finishPluginLoading(); - } - },finishPluginLoading); // also, add script load error handler for file not found -} - function findCordovaPath() { var path = null; var scripts = document.getElementsByTagName('script'); - var term = 'cordova.js'; + var term = '/cordova.js'; for (var n = scripts.length-1; n>-1; n--) { - var src = scripts[n].src; + var src = scripts[n].src.replace(/\?.*$/, ''); // Strip any query param (CB-6007). if (src.indexOf(term) == (src.length - term.length)) { - path = src.substring(0, src.length - term.length); + path = src.substring(0, src.length - term.length) + '/'; break; } } @@ -1224,32 +1510,87 @@ function findCordovaPath() { // Tries to load all plugins' js-modules. // This is an async process, but onDeviceReady is blocked on onPluginsReady. // onPluginsReady is fired when there are no plugins to load, or they are all done. -exports.load = function() { +exports.load = function(callback) { var pathPrefix = findCordovaPath(); if (pathPrefix === null) { console.log('Could not find cordova.js script tag. Plugin loading may fail.'); pathPrefix = ''; } - injectPluginScript(pathPrefix); + injectIfNecessary('cordova/plugin_list', pathPrefix + 'cordova_plugins.js', function() { + var moduleList = require("cordova/plugin_list"); + handlePluginsObject(pathPrefix, moduleList, callback); + }, callback); }; }); -// file: lib/common/symbols.js -define("cordova/symbols", function(require, exports, module) { +// file: src/common/pluginloader_b.js +define("cordova/pluginloader_b", function(require, exports, module) { var modulemapper = require('cordova/modulemapper'); -// Use merges here in case others symbols files depend on this running first, -// but fail to declare the dependency with a require(). -modulemapper.merges('cordova', 'cordova'); -modulemapper.clobbers('cordova/exec', 'cordova.exec'); -modulemapper.clobbers('cordova/exec', 'Cordova.exec'); +// Handler for the cordova_plugins.js content. +// See plugman's plugin_loader.js for the details of this object. +function handlePluginsObject(moduleList) { + // if moduleList is not defined or empty, we've nothing to do + if (!moduleList || !moduleList.length) { + return; + } + + // Loop through all the modules and then through their clobbers and merges. + for (var i = 0, module; module = moduleList[i]; i++) { + if (module.clobbers && module.clobbers.length) { + for (var j = 0; j < module.clobbers.length; j++) { + modulemapper.clobbers(module.id, module.clobbers[j]); + } + } + + if (module.merges && module.merges.length) { + for (var k = 0; k < module.merges.length; k++) { + modulemapper.merges(module.id, module.merges[k]); + } + } + + // Finally, if runs is truthy we want to simply require() the module. + if (module.runs) { + modulemapper.runs(module.id); + } + } +} + +// Loads all plugins' js-modules. Plugin loading is syncronous in browserified bundle +// but the method accepts callback to be compatible with non-browserify flow. +// onDeviceReady is blocked on onPluginsReady. onPluginsReady is fired when there are +// no plugins to load, or they are all done. +exports.load = function(callback) { + var moduleList = require("cordova/plugin_list"); + handlePluginsObject(moduleList); + + callback(); +}; + + +}); + +// file: src/common/urlutil.js +define("cordova/urlutil", function(require, exports, module) { + + +/** + * For already absolute URLs, returns what is passed in. + * For relative URLs, converts them to absolute ones. + */ +exports.makeAbsolute = function makeAbsolute(url) { + var anchorEl = document.createElement('a'); + anchorEl.href = url; + return anchorEl.href; +}; + }); -// file: lib/common/utils.js +// file: src/common/utils.js define("cordova/utils", function(require, exports, module) { var utils = exports; @@ -1311,15 +1652,14 @@ utils.typeName = function(val) { /** * Returns an indication of whether the argument is an array or not */ -utils.isArray = function(a) { - return utils.typeName(a) == 'Array'; -}; +utils.isArray = Array.isArray || + function(a) {return utils.typeName(a) == 'Array';}; /** * Returns an indication of whether the argument is a Date or not */ utils.isDate = function(d) { - return utils.typeName(d) == 'Date'; + return (d instanceof Date); }; /** @@ -1353,17 +1693,25 @@ utils.clone = function(obj) { * Returns a wrapped version of the function */ utils.close = function(context, func, params) { - if (typeof params == 'undefined') { - return function() { - return func.apply(context, arguments); - }; - } else { - return function() { - return func.apply(context, params); - }; - } + return function() { + var args = params || arguments; + return func.apply(context, args); + }; }; +//------------------------------------------------------------------------------ +function UUIDcreatePart(length) { + var uuidpart = ""; + for (var i=0; i<length; i++) { + var uuidchar = parseInt((Math.random() * 256), 10).toString(16); + if (uuidchar.length == 1) { + uuidchar = "0" + uuidchar; + } + uuidpart += uuidchar; + } + return uuidpart; +} + /** * Create a UUID */ @@ -1375,6 +1723,7 @@ utils.createUUID = function() { UUIDcreatePart(6); }; + /** * Extends a child object from a parent object using classical inheritance * pattern. @@ -1384,6 +1733,7 @@ utils.extend = (function() { var F = function() {}; // extend Child from Parent return function(Child, Parent) { + F.prototype = Parent.prototype; Child.prototype = new F(); Child.__super__ = Parent.prototype; @@ -1403,109 +1753,14 @@ utils.alert = function(msg) { }; -//------------------------------------------------------------------------------ -function UUIDcreatePart(length) { - var uuidpart = ""; - for (var i=0; i<length; i++) { - var uuidchar = parseInt((Math.random() * 256), 10).toString(16); - if (uuidchar.length == 1) { - uuidchar = "0" + uuidchar; - } - uuidpart += uuidchar; - } - return uuidpart; -} + }); window.cordova = require('cordova'); -// file: lib/scripts/bootstrap.js +// file: src/scripts/bootstrap.js -(function (context) { - if (context._cordovaJsLoaded) { - throw new Error('cordova.js included multiple times.'); - } - context._cordovaJsLoaded = true; - - var channel = require('cordova/channel'); - var pluginloader = require('cordova/pluginloader'); - - var platformInitChannelsArray = [channel.onNativeReady, channel.onPluginsReady]; - - // setting exec - cordova.exec = require('cordova/exec'); - - 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 5 seconds.'); - logUnfiredChannels(platformInitChannelsArray); - logUnfiredChannels(channel.deviceReadyChannelsArray); - } - }, 5000); - - // 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); - } - } - } - return newNavigator; - } - if (context.navigator) { - context.navigator = replaceNavigator(context.navigator); - } - - // _nativeReady is global variable that the native side can set - // to signify that the native code is ready. It is a global since - // it may be called before any cordova JS is ready. - if (window._nativeReady) { - channel.onNativeReady.fire(); - } - - /** - * Create all cordova objects once native side is ready. - */ - channel.join(function() { - // Call the platform-specific initialization - require('cordova/platform').initialize(); - - // Fire event to notify that all objects are created - channel.onCordovaReady.fire(); - - // Fire onDeviceReady event once page has fully loaded, all - // constructors have run and cordova info has been received from native - // side. - // This join call is deliberately made after platform.initialize() in - // order that plugins may manipulate channel.deviceReadyChannelsArray - // if necessary. - channel.join(function() { - require('cordova').fireDocumentEvent('deviceready'); - }, channel.deviceReadyChannelsArray); - - }, platformInitChannelsArray); - - // Don't attempt to load when running unit tests. - if (typeof XMLHttpRequest != 'undefined') { - pluginloader.load(); - } -}(window)); +require('cordova/init'); })(); \ No newline at end of file --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
