Update cordova.js -- includes new Binary bridge, supporting Android 4.0

This commit is contained in:
Ian Clelland 2013-07-09 16:45:25 -04:00
parent 99341bce29
commit f7014f14df

View File

@ -1,5 +1,5 @@
// Platform: android // Platform: android
// 2.7.0rc1-154-g98a62ff // 2.7.0rc1-161-g0c80083
/* /*
Licensed to the Apache Software Foundation (ASF) under one Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file or more contributor license agreements. See the NOTICE file
@ -19,7 +19,7 @@
under the License. under the License.
*/ */
;(function() { ;(function() {
var CORDOVA_JS_BUILD_LABEL = '2.7.0rc1-154-g98a62ff'; var CORDOVA_JS_BUILD_LABEL = '2.7.0rc1-161-g0c80083';
// file: lib/scripts/require.js // file: lib/scripts/require.js
var require, var require,
@ -393,6 +393,62 @@ moduleExports.getValue = getValue;
moduleExports.enableChecks = true; 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 // file: lib/common/builder.js
@ -799,6 +855,7 @@ define("cordova/exec", function(require, exports, module) {
var cordova = require('cordova'), var cordova = require('cordova'),
nativeApiProvider = require('cordova/plugin/android/nativeapiprovider'), nativeApiProvider = require('cordova/plugin/android/nativeapiprovider'),
utils = require('cordova/utils'), utils = require('cordova/utils'),
base64 = require('cordova/base64'),
jsToNativeModes = { jsToNativeModes = {
PROMPT: 0, PROMPT: 0,
JS_OBJECT: 1, JS_OBJECT: 1,
@ -837,7 +894,7 @@ function androidExec(success, fail, service, action, args) {
// Process any ArrayBuffers in the args into a string. // Process any ArrayBuffers in the args into a string.
for (var i = 0; i < args.length; i++) { for (var i = 0; i < args.length; i++) {
if (utils.typeName(args[i]) == 'ArrayBuffer') { if (utils.typeName(args[i]) == 'ArrayBuffer') {
args[i] = window.btoa(String.fromCharCode.apply(null, new Uint8Array(args[i]))); args[i] = base64.fromArrayBuffer(args[i]);
} }
} }
@ -1047,6 +1104,10 @@ exports.defaults = function(moduleName, symbolPath, opt_deprecationMessage) {
addEntry('d', moduleName, symbolPath, opt_deprecationMessage); addEntry('d', moduleName, symbolPath, opt_deprecationMessage);
}; };
exports.runs = function(moduleName) {
addEntry('r', moduleName, null);
};
function prepareNamespace(symbolPath, context) { function prepareNamespace(symbolPath, context) {
if (!symbolPath) { if (!symbolPath) {
return context; return context;
@ -1065,12 +1126,16 @@ exports.mapModules = function(context) {
for (var i = 0, len = symbolList.length; i < len; i += 3) { for (var i = 0, len = symbolList.length; i < len; i += 3) {
var strategy = symbolList[i]; var strategy = symbolList[i];
var moduleName = symbolList[i + 1]; var moduleName = symbolList[i + 1];
var module = require(moduleName);
// <runs/>
if (strategy == 'r') {
continue;
}
var symbolPath = symbolList[i + 2]; var symbolPath = symbolList[i + 2];
var lastDot = symbolPath.lastIndexOf('.'); var lastDot = symbolPath.lastIndexOf('.');
var namespace = symbolPath.substr(0, lastDot); var namespace = symbolPath.substr(0, lastDot);
var lastName = symbolPath.substr(lastDot + 1); var lastName = symbolPath.substr(lastDot + 1);
var module = require(moduleName);
var deprecationMsg = symbolPath in deprecationMap ? 'Access made to deprecated symbol: ' + symbolPath + '. ' + deprecationMsg : null; var deprecationMsg = symbolPath in deprecationMap ? 'Access made to deprecated symbol: ' + symbolPath + '. ' + deprecationMsg : null;
var parentObj = prepareNamespace(namespace, context); var parentObj = prepareNamespace(namespace, context);
var target = parentObj[lastName]; var target = parentObj[lastName];
@ -2160,6 +2225,155 @@ var modulemapper = require('cordova/modulemapper');
modulemapper.clobbers('cordova/plugin/logger', 'cordova.logger'); modulemapper.clobbers('cordova/plugin/logger', 'cordova.logger');
});
// file: lib/common/pluginloader.js
define("cordova/pluginloader", function(require, exports, module) {
var channel = require('cordova/channel');
var modulemapper = require('cordova/modulemapper');
var scriptCounter = 0;
var moduleList = null;
function scriptLoadedCallback() {
scriptCounter--;
if (scriptCounter === 0) {
onScriptLoadingComplete();
}
}
// Helper function to inject a <script> tag.
function injectScript(url, onload) {
scriptCounter++;
var script = document.createElement("script");
// onload fires even when script fails loads with an error.
script.onload = onload;
script.src = url;
document.head.appendChild(script);
}
function onScriptLoadingComplete() {
// Loop through all the plugins and then through their clobbers and merges.
for (var i = 0; i < moduleList.length; i++) {
var module = moduleList[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) {
// Now inject the scripts.
for (var i = 0; i < moduleList.length; i++) {
injectScript(path + moduleList[i].file, scriptLoadedCallback);
}
}
function injectPluginScript(pathPrefix) {
injectScript(pathPrefix + 'cordova_plugins.js', function(){
try {
moduleList = require("cordova/plugin_list");
handlePluginsObject(pathPrefix);
} 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();
}
});
}
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.warn('Could not find cordova.js script tag. Plugin loading may fail.');
pathPrefix = '';
}
// 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) {
moduleList = obj;
handlePluginsObject(pathPrefix);
} else {
finishPluginLoading();
}
};
xhr.onerror = function() {
// 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
injectPluginScript(pathPrefix);
};
try {
xhr.open('GET', pathPrefix + 'cordova_plugins.json', true); // Async
xhr.send();
} catch(err){
injectPluginScript(pathPrefix);
}
};
}); });
// file: lib/common/symbols.js // file: lib/common/symbols.js
@ -2355,6 +2569,8 @@ window.cordova = require('cordova');
context._cordovaJsLoaded = true; context._cordovaJsLoaded = true;
var channel = require('cordova/channel'); var channel = require('cordova/channel');
var pluginloader = require('cordova/pluginloader');
var platformInitChannelsArray = [channel.onNativeReady, channel.onPluginsReady]; var platformInitChannelsArray = [channel.onNativeReady, channel.onPluginsReady];
function logUnfiredChannels(arr) { function logUnfiredChannels(arr) {
@ -2423,6 +2639,10 @@ window.cordova = require('cordova');
}, platformInitChannelsArray); }, platformInitChannelsArray);
// Don't attempt to load when running unit tests.
if (typeof XMLHttpRequest != 'undefined') {
pluginloader.load();
}
}(window)); }(window));
// file: lib/scripts/bootstrap-android.js // file: lib/scripts/bootstrap-android.js
@ -2431,164 +2651,4 @@ window.cordova = require('cordova');
require('cordova/exec')(null, null, 'PluginManager', 'startup', []); require('cordova/exec')(null, null, 'PluginManager', 'startup', []);
require('cordova/channel').onNativeReady.fire(); 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));
})(); })();