Update JS snapshot and VERSION to 2.9.1-dev
Project: http://git-wip-us.apache.org/repos/asf/cordova-android/repo Commit: http://git-wip-us.apache.org/repos/asf/cordova-android/commit/bdecdea5 Tree: http://git-wip-us.apache.org/repos/asf/cordova-android/tree/bdecdea5 Diff: http://git-wip-us.apache.org/repos/asf/cordova-android/diff/bdecdea5 Branch: refs/heads/2.9.x Commit: bdecdea568f6bada0a68c8fb333b8bdc2f50ace8 Parents: a88b8de Author: Andrew Grieve <[email protected]> Authored: Tue Oct 22 15:45:38 2013 -0400 Committer: Andrew Grieve <[email protected]> Committed: Tue Oct 22 16:42:56 2013 -0400 ---------------------------------------------------------------------- VERSION | 2 +- framework/assets/www/cordova.js | 663 ++++++++++++---------- framework/src/org/apache/cordova/Device.java | 2 +- 3 files changed, 373 insertions(+), 294 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cordova-android/blob/bdecdea5/VERSION ---------------------------------------------------------------------- diff --git a/VERSION b/VERSION index c8e38b6..ee57e1e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.9.0 +2.9.1-dev http://git-wip-us.apache.org/repos/asf/cordova-android/blob/bdecdea5/framework/assets/www/cordova.js ---------------------------------------------------------------------- diff --git a/framework/assets/www/cordova.js b/framework/assets/www/cordova.js index 873c068..05a64e0 100644 --- a/framework/assets/www/cordova.js +++ b/framework/assets/www/cordova.js @@ -1,5 +1,5 @@ // Platform: android -// 2.9.0-0-g83dc4bd +// 2.9.1-dev-af4bcf4 /* 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 CORDOVA_JS_BUILD_LABEL = '2.9.0-0-g83dc4bd'; +var CORDOVA_JS_BUILD_LABEL = '2.9.1-dev-af4bcf4'; // file: lib/scripts/require.js var require, @@ -100,6 +100,7 @@ define("cordova", function(require, exports, module) { var channel = require('cordova/channel'); +var platform = require('cordova/platform'); /** * Listen for DOMContentLoaded and notify our channel subscribers. @@ -182,10 +183,18 @@ if(typeof window.console === "undefined") { 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, require:require, + version:CORDOVA_JS_BUILD_LABEL, + platformId:platform.id, /** * Methods to add/remove your own addEventListener hijacking on document + window. */ @@ -221,16 +230,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); @@ -347,7 +356,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) { @@ -376,7 +385,7 @@ function checkArgs(spec, functionName, args, opt_callee) { 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 jake test. + // Don't log when running unit tests. if (typeof jasmine == 'undefined') { console.error(errMsg); } @@ -395,6 +404,62 @@ moduleExports.enableChecks = true; }); +// file: lib/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); +}; + +//------------------------------------------------------------------------------ + +/* 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: lib/common/builder.js define("cordova/builder", function(require, exports, module) { @@ -435,36 +500,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 + '"'); } }); } @@ -808,6 +873,7 @@ define("cordova/exec", function(require, exports, module) { var cordova = require('cordova'), nativeApiProvider = require('cordova/plugin/android/nativeapiprovider'), utils = require('cordova/utils'), + base64 = require('cordova/base64'), jsToNativeModes = { PROMPT: 0, JS_OBJECT: 1, @@ -846,7 +912,7 @@ function androidExec(success, fail, service, action, args) { // 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] = window.btoa(String.fromCharCode.apply(null, new Uint8Array(args[i]))); + args[i] = base64.fromArrayBuffer(args[i]); } } @@ -874,8 +940,12 @@ function androidExec(success, fail, service, action, args) { } } -function pollOnce() { - var msg = nativeApiProvider.get().retrieveJsMessages(); +function pollOnceFromOnlineEvent() { + pollOnce(true); +} + +function pollOnce(opt_fromOnlineEvent) { + var msg = nativeApiProvider.get().retrieveJsMessages(!!opt_fromOnlineEvent); androidExec.processMessages(msg); } @@ -894,8 +964,8 @@ function hookOnlineApis() { // 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', pollOnce, false); - window.addEventListener('offline', pollOnce, false); + window.addEventListener('online', pollOnceFromOnlineEvent, false); + window.addEventListener('offline', pollOnceFromOnlineEvent, false); cordova.addWindowEventHandler('online'); cordova.addWindowEventHandler('offline'); document.addEventListener('online', proxyEvent, false); @@ -1056,6 +1126,10 @@ exports.defaults = function(moduleName, symbolPath, opt_deprecationMessage) { addEntry('d', moduleName, symbolPath, opt_deprecationMessage); }; +exports.runs = function(moduleName) { + addEntry('r', moduleName, null); +}; + function prepareNamespace(symbolPath, context) { if (!symbolPath) { return context; @@ -1074,12 +1148,16 @@ exports.mapModules = function(context) { 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; + } var symbolPath = symbolList[i + 2]; var lastDot = symbolPath.lastIndexOf('.'); var namespace = symbolPath.substr(0, lastDot); var lastName = symbolPath.substr(lastDot + 1); - var module = require(moduleName); var deprecationMsg = symbolPath in deprecationMap ? 'Access made to deprecated symbol: ' + symbolPath + '. ' + deprecationMsg : null; var parentObj = prepareNamespace(namespace, context); var target = parentObj[lastName]; @@ -1928,6 +2006,7 @@ var exec = require('cordova/exec'), */ function DirectoryReader(path) { this.path = path || null; + this.hasReadEntries = false; } /** @@ -1937,6 +2016,12 @@ function DirectoryReader(path) { * @param {Function} errorCallback is called with a FileError */ DirectoryReader.prototype.readEntries = function(successCallback, errorCallback) { + // If we've already read and passed on this directory's entries, return an empty list. + if (this.hasReadEntries) { + successCallback([]); + return; + } + var reader = this; var win = typeof successCallback !== 'function' ? null : function(result) { var retVal = []; for (var i=0; i<result.length; i++) { @@ -1953,6 +2038,7 @@ DirectoryReader.prototype.readEntries = function(successCallback, errorCallback) entry.fullPath = result[i].fullPath; retVal.push(entry); } + reader.hasReadEntries = true; successCallback(retVal); }; var fail = typeof errorCallback !== 'function' ? null : function(code) { @@ -3063,27 +3149,28 @@ FileWriter.prototype.abort = function() { */ FileWriter.prototype.write = function(data) { - var isBinary = false; + var that=this; + var supportsBinary = (typeof window.Blob !== 'undefined' && typeof window.ArrayBuffer !== 'undefined'); + var isBinary; - // If we don't have Blob or ArrayBuffer support, don't bother. - if (typeof window.Blob !== 'undefined' && typeof window.ArrayBuffer !== 'undefined') { - - // Check to see if the incoming data is a blob - if (data instanceof Blob) { - var that=this; - var fileReader = new FileReader(); - fileReader.onload = function() { - // Call this method again, with the arraybuffer as argument - FileWriter.prototype.write.call(that, this.result); - }; + // Check to see if the incoming data is a blob + if (data instanceof File || (supportsBinary && data instanceof Blob)) { + var fileReader = new FileReader(); + fileReader.onload = function() { + // Call this method again, with the arraybuffer as argument + FileWriter.prototype.write.call(that, this.result); + }; + if (supportsBinary) { fileReader.readAsArrayBuffer(data); - return; + } else { + fileReader.readAsText(data); } - - // Mark data type for safer transport over the binary bridge - isBinary = (data instanceof ArrayBuffer); + return; } + // Mark data type for safer transport over the binary bridge + isBinary = supportsBinary && (data instanceof ArrayBuffer); + // Throw an exception if we are already writing a file if (this.readyState === FileWriter.WRITING) { throw new FileError(FileError.INVALID_STATE_ERR); @@ -3316,6 +3403,7 @@ define("cordova/plugin/InAppBrowser", function(require, exports, module) { var exec = require('cordova/exec'); var channel = require('cordova/channel'); var modulemapper = require('cordova/modulemapper'); +var urlutil = require('cordova/urlutil'); function InAppBrowser() { this.channels = { @@ -3324,6 +3412,7 @@ function InAppBrowser() { 'loaderror' : channel.create('loaderror'), 'exit' : channel.create('exit') }; + this._alive = true; } InAppBrowser.prototype = { @@ -3333,7 +3422,10 @@ InAppBrowser.prototype = { } }, close: function (eventname) { - exec(null, null, "InAppBrowser", "close", []); + if (this._alive) { + this._alive = false; + exec(null, null, "InAppBrowser", "close", []); + } }, show: function (eventname) { exec(null, null, "InAppBrowser", "show", []); @@ -3371,17 +3463,18 @@ InAppBrowser.prototype = { }; module.exports = function(strUrl, strWindowName, strWindowFeatures) { - var iab = new InAppBrowser(); - var cb = function(eventname) { - iab._eventHandler(eventname); - }; - // Don't catch calls that write to existing frames (e.g. named iframes). if (window.frames && window.frames[strWindowName]) { var origOpenFunc = modulemapper.getOriginalSymbol(window, 'open'); return origOpenFunc.apply(window, arguments); } + strUrl = urlutil.makeAbsolute(strUrl); + var iab = new InAppBrowser(); + var cb = function(eventname) { + iab._eventHandler(eventname); + }; + exec(cb, cb, "InAppBrowser", "open", [strUrl, strWindowName, strWindowFeatures]); return iab; }; @@ -3973,73 +4066,73 @@ define("cordova/plugin/android/app", function(require, exports, module) { var exec = require('cordova/exec'); module.exports = { - /** - * Clear the resource cache. - */ - clearCache:function() { - exec(null, null, "App", "clearCache", []); - }, + /** + * 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]); - }, + /** + * 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", []); - }, + /** + * 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", []); - }, + /** + * 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", []); - }, + /** + * 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]); - }, + /** + * 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", []); - } + /** + * Exit and terminate the application. + */ + exitApp:function() { + return exec(null, null, "App", "exitApp", []); + } }; }); @@ -4186,8 +4279,8 @@ module.exports = { setNativeToJsBridgeMode: function(value) { prompt(value, 'gap_bridge_mode:'); }, - retrieveJsMessages: function() { - return prompt('', 'gap_poll:'); + retrieveJsMessages: function(fromOnlineEvent) { + return prompt(+fromOnlineEvent, 'gap_poll:'); } }; @@ -4482,9 +4575,9 @@ var DroidDB_openDatabase = function(name, version, display_name, size) { module.exports = { - openDatabase:DroidDB_openDatabase, - failQuery:failQuery, - completeQuery:completeQuery + openDatabase:DroidDB_openDatabase, + failQuery:failQuery, + completeQuery:completeQuery }; }); @@ -6517,6 +6610,127 @@ modulemapper.clobbers('cordova/plugin/splashscreen', 'navigator.splashscreen'); }); +// file: lib/common/pluginloader.js +define("cordova/pluginloader", function(require, exports, module) { + +var channel = require('cordova/channel'); +var modulemapper = require('cordova/modulemapper'); + +// Helper function to inject a <script> tag. +function injectScript(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; + script.src = url; + document.head.appendChild(script); +} + +function onScriptLoadingComplete(moduleList) { + // 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); + } + } + catch(err) { + // error with module, most likely clobbers, should we continue? + } + } + } + + 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) { + // Now inject the scripts. + var scriptCounter = moduleList.length; + + if (!scriptCounter) { + finishPluginLoading(); + return; + } + function scriptLoadedCallback() { + if (!--scriptCounter) { + onScriptLoadingComplete(moduleList); + } + } + + for (var i = 0; i < moduleList.length; i++) { + injectScript(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'; + for (var n = scripts.length-1; n>-1; n--) { + var src = scripts[n].src; + if (src.indexOf(term) == (src.length - term.length)) { + path = src.substring(0, src.length - term.length); + break; + } + } + return path; +} + +// 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() { + var pathPrefix = findCordovaPath(); + if (pathPrefix === null) { + console.log('Could not find cordova.js script tag. Plugin loading may fail.'); + pathPrefix = ''; + } + injectPluginScript(pathPrefix); +}; + + +}); + // file: lib/common/symbols.js define("cordova/symbols", function(require, exports, module) { @@ -6530,6 +6744,23 @@ modulemapper.clobbers('cordova/exec', 'Cordova.exec'); }); +// file: lib/common/urlutil.js +define("cordova/urlutil", function(require, exports, module) { + +var urlutil = exports; +var anchorEl = document.createElement('a'); + +/** + * For already absolute URLs, returns what is passed in. + * For relative URLs, converts them to absolute ones. + */ +urlutil.makeAbsolute = function(url) { + anchorEl.href = url; + return anchorEl.href; +}; + +}); + // file: lib/common/utils.js define("cordova/utils", function(require, exports, module) { @@ -6710,6 +6941,8 @@ window.cordova = require('cordova'); context._cordovaJsLoaded = true; var channel = require('cordova/channel'); + var pluginloader = require('cordova/pluginloader'); + var platformInitChannelsArray = [channel.onNativeReady, channel.onPluginsReady]; function logUnfiredChannels(arr) { @@ -6778,170 +7011,16 @@ window.cordova = require('cordova'); }, platformInitChannelsArray); + // Don't attempt to load when running unit tests. + if (typeof XMLHttpRequest != 'undefined') { + pluginloader.load(); + } }(window)); // file: lib/scripts/bootstrap-android.js +// Tell the native code that a page change has occurred. +require('cordova/exec')(null, null, 'PluginManager', 'startup', []); require('cordova/channel').onNativeReady.fire(); -// file: lib/scripts/plugin_loader.js - -// 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. -(function (context) { - // To be populated with the handler by handlePluginsObject. - var onScriptLoadingComplete; - - var scriptCounter = 0; - function scriptLoadedCallback() { - scriptCounter--; - if (scriptCounter === 0) { - onScriptLoadingComplete && onScriptLoadingComplete(); - } - } - - function scriptErrorCallback(err) { - // Open Question: If a script path specified in cordova_plugins.js does not exist, do we fail for all? - // this is currently just continuing. - scriptCounter--; - if (scriptCounter === 0) { - onScriptLoadingComplete && onScriptLoadingComplete(); - } - } - - // Helper function to inject a <script> tag. - function injectScript(path) { - scriptCounter++; - var script = document.createElement("script"); - script.onload = scriptLoadedCallback; - script.onerror = scriptErrorCallback; - script.src = path; - document.head.appendChild(script); - } - - // Called when: - // * There are plugins defined and all plugins are finished loading. - // * There are no plugins to load. - function finishPluginLoading() { - context.cordova.require('cordova/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(modules, path) { - // First create the callback for when all plugins are loaded. - var mapper = context.cordova.require('cordova/modulemapper'); - onScriptLoadingComplete = function() { - // Loop through all the plugins and then through their clobbers and merges. - for (var i = 0; i < modules.length; i++) { - var module = modules[i]; - if (module) { - try { - if (module.clobbers && module.clobbers.length) { - for (var j = 0; j < module.clobbers.length; j++) { - mapper.clobbers(module.id, module.clobbers[j]); - } - } - - if (module.merges && module.merges.length) { - for (var k = 0; k < module.merges.length; k++) { - mapper.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)) { - context.cordova.require(module.id); - } - } - catch(err) { - // error with module, most likely clobbers, should we continue? - } - } - } - - finishPluginLoading(); - }; - - // Now inject the scripts. - for (var i = 0; i < modules.length; i++) { - injectScript(path + modules[i].file); - } - } - - // Find the root of the app - var path = ''; - var scripts = document.getElementsByTagName('script'); - var term = 'cordova.js'; - for (var n = scripts.length-1; n>-1; n--) { - var src = scripts[n].src; - if (src.indexOf(term) == (src.length - term.length)) { - path = src.substring(0, src.length - term.length); - break; - } - } - - var plugins_json = path + 'cordova_plugins.json'; - var plugins_js = path + 'cordova_plugins.js'; - - // One some phones (Windows) this xhr.open throws an Access Denied exception - // So lets keep trying, but with a script tag injection technique instead of XHR - var injectPluginScript = function injectPluginScript() { - try { - var script = document.createElement("script"); - script.onload = function(){ - var list = cordova.require("cordova/plugin_list"); - handlePluginsObject(list,path); - }; - script.onerror = function() { - // 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(); - }; - script.src = plugins_js; - document.head.appendChild(script); - - } catch(err){ - finishPluginLoading(); - } - } - - - // Try to XHR the cordova_plugins.json file asynchronously. - var xhr = new XMLHttpRequest(); - xhr.onload = function() { - // If the response is a JSON string which composes an array, call handlePluginsObject. - // If the request fails, or the response is not a JSON array, just call finishPluginLoading. - var obj; - try { - obj = (this.status == 0 || this.status == 200) && this.responseText && JSON.parse(this.responseText); - } catch (err) { - // obj will be undefined. - } - if (Array.isArray(obj) && obj.length > 0) { - handlePluginsObject(obj, path); - } else { - finishPluginLoading(); - } - }; - xhr.onerror = function() { - // In this case, the json file was not present, but XHR was allowed, - // so we should still try the script injection technique with the js file - // in case that is there. - injectPluginScript(); - }; - try { // we commented we were going to try, so let us actually try and catch - xhr.open('GET', plugins_json, true); // Async - xhr.send(); - } catch(err){ - injectPluginScript(); - } -}(window)); - - })(); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cordova-android/blob/bdecdea5/framework/src/org/apache/cordova/Device.java ---------------------------------------------------------------------- diff --git a/framework/src/org/apache/cordova/Device.java b/framework/src/org/apache/cordova/Device.java index 66b3393..fcda087 100644 --- a/framework/src/org/apache/cordova/Device.java +++ b/framework/src/org/apache/cordova/Device.java @@ -38,7 +38,7 @@ import android.telephony.TelephonyManager; public class Device extends CordovaPlugin { public static final String TAG = "Device"; - public static String cordovaVersion = "2.9.0"; // Cordova version + public static String cordovaVersion = "2.9.1-dev"; // Cordova version public static String platform = "Android"; // Device OS public static String uuid; // Device UUID
