diff options
-rw-r--r-- | Android/.classpath | 2 | ||||
-rw-r--r-- | Android/libs/cordova-2.1.0.jar | bin | 191253 -> 0 bytes | |||
-rwxr-xr-x[-rw-r--r--] | Android/res/xml/config.xml | 4 | ||||
-rw-r--r-- | iPhone/FixMyStreet.xcodeproj/project.pbxproj | 2 | ||||
-rw-r--r-- | iPhone/FixMyStreet/Classes/MainViewController.m | 76 | ||||
-rwxr-xr-x | www/cordova-android-2.2.0.js (renamed from www/cordova-android-2.1.0.js) | 1702 | ||||
-rw-r--r-- | www/cordova-independent.js | 4 | ||||
-rwxr-xr-x | www/cordova-ios-2.2.0.js (renamed from www/cordova-ios-2.1.0.js) | 1463 |
8 files changed, 2379 insertions, 874 deletions
diff --git a/Android/.classpath b/Android/.classpath index e088a5d..bc7a6b5 100644 --- a/Android/.classpath +++ b/Android/.classpath @@ -4,6 +4,6 @@ <classpathentry kind="src" path="gen"/> <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/> <classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/> - <classpathentry kind="lib" path="libs/cordova-2.1.0.jar"/> + <classpathentry kind="lib" path="libs/cordova-2.2.0.jar"/> <classpathentry kind="output" path="bin/classes"/> </classpath> diff --git a/Android/libs/cordova-2.1.0.jar b/Android/libs/cordova-2.1.0.jar Binary files differdeleted file mode 100644 index d3eecaa..0000000 --- a/Android/libs/cordova-2.1.0.jar +++ /dev/null diff --git a/Android/res/xml/config.xml b/Android/res/xml/config.xml index 4a6fffc..da9c1f4 100644..100755 --- a/Android/res/xml/config.xml +++ b/Android/res/xml/config.xml @@ -30,7 +30,7 @@ <access origin=".*"/> <log level="DEBUG"/> - <preference name="useBrowserHistory" value="false" /> + <preference name="useBrowserHistory" value="true" /> <preference name="exit-on-suspend" value="false" /> <plugins> <plugin name="App" value="org.apache.cordova.App"/> @@ -45,12 +45,12 @@ <plugin name="NetworkStatus" value="org.apache.cordova.NetworkManager"/> <plugin name="Notification" value="org.apache.cordova.Notification"/> <plugin name="Storage" value="org.apache.cordova.Storage"/> - <plugin name="Temperature" value="org.apache.cordova.TempListener"/> <plugin name="FileTransfer" value="org.apache.cordova.FileTransfer"/> <plugin name="Capture" value="org.apache.cordova.Capture"/> <plugin name="Battery" value="org.apache.cordova.BatteryListener"/> <plugin name="SplashScreen" value="org.apache.cordova.SplashScreen"/> <plugin name="Echo" value="org.apache.cordova.Echo" /> + <plugin name="Globalization" value="org.apache.cordova.Globalization"/> </plugins> </cordova> diff --git a/iPhone/FixMyStreet.xcodeproj/project.pbxproj b/iPhone/FixMyStreet.xcodeproj/project.pbxproj index b985cab..99c2e21 100644 --- a/iPhone/FixMyStreet.xcodeproj/project.pbxproj +++ b/iPhone/FixMyStreet.xcodeproj/project.pbxproj @@ -63,7 +63,7 @@ /* Begin PBXFileReference section */ 24065F8C162C7721004574A1 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = "<group>"; }; - 240FE2E9162D6E4D00250E2D /* CordovaLib.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = CordovaLib.xcodeproj; path = ../../../../../libs/cordova_2.1/lib/ios/CordovaLib/CordovaLib.xcodeproj; sourceTree = "<group>"; }; + 240FE2E9162D6E4D00250E2D /* CordovaLib.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = CordovaLib.xcodeproj; path = ../../../../../libs/cordova_2.2/CordovaLib/CordovaLib.xcodeproj; sourceTree = "<group>"; }; 249ED5EA162D82AD000076A1 /* cordova */ = {isa = PBXFileReference; lastKnownFileType = folder; path = cordova; sourceTree = "<group>"; }; 24C01C771664F30600417E3D /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = "<group>"; }; 24C01C781664F30600417E3D /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon@2x.png"; sourceTree = "<group>"; }; diff --git a/iPhone/FixMyStreet/Classes/MainViewController.m b/iPhone/FixMyStreet/Classes/MainViewController.m index 289da35..0df74a0 100644 --- a/iPhone/FixMyStreet/Classes/MainViewController.m +++ b/iPhone/FixMyStreet/Classes/MainViewController.m @@ -6,9 +6,9 @@ to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - + http://www.apache.org/licenses/LICENSE-2.0 - + Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -19,17 +19,17 @@ // // MainViewController.h -// cordova1.8.0 +// cordova-2.2 // -// Created by Struan Donald on 08/06/2012. -// Copyright __MyCompanyName__ 2012. All rights reserved. +// Created by ___FULLUSERNAME___ on ___DATE___. +// Copyright ___ORGANIZATIONNAME___ ___YEAR___. All rights reserved. // #import "MainViewController.h" @implementation MainViewController -- (id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil +- (id)initWithNibName:(NSString*)nibNameOrNil bundle:(NSBundle*)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { @@ -38,36 +38,52 @@ return self; } -- (void) didReceiveMemoryWarning +- (void)didReceiveMemoryWarning { // Releases the view if it doesn't have a superview. [super didReceiveMemoryWarning]; - + // Release any cached data, images, etc that aren't in use. } #pragma mark - View lifecycle -- (void) viewDidLoad +- (void)viewWillAppear:(BOOL)animated +{ + // Set the main view to utilize the entire application frame space of the device. + // Change this to suit your view's UI footprint needs in your application. + + UIView* rootView = [[[[UIApplication sharedApplication] keyWindow] rootViewController] view]; + CGRect webViewFrame = [[[rootView subviews] objectAtIndex:0] frame]; // first subview is the UIWebView + + if (CGRectEqualToRect(webViewFrame, CGRectZero)) { // UIWebView is sized according to its parent, here it hasn't been sized yet + self.view.frame = [[UIScreen mainScreen] applicationFrame]; // size UIWebView's parent according to application frame, which will in turn resize the UIWebView + } + + [super viewWillAppear:animated]; +} + +- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view from its nib. } -- (void) viewDidUnload +- (void)viewDidUnload { [super viewDidUnload]; // Release any retained subviews of the main view. // e.g. self.myOutlet = nil; } -- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { // Return YES for supported orientations return [super shouldAutorotateToInterfaceOrientation:interfaceOrientation]; } /* Comment out the block below to over-ride */ + /* - (CDVCordovaView*) newCordovaViewWithFrame:(CGRect)bounds { @@ -76,24 +92,25 @@ */ /* Comment out the block below to over-ride */ + /* #pragma CDVCommandDelegate implementation - (id) getCommandInstance:(NSString*)className { - return [super getCommandInstance:className]; + return [super getCommandInstance:className]; } - (BOOL) execute:(CDVInvokedUrlCommand*)command { - return [super execute:command]; + return [super execute:command]; } - (NSString*) pathForResource:(NSString*)resourcepath; { - return [super pathForResource:resourcepath]; + return [super pathForResource:resourcepath]; } - + - (void) registerPlugin:(CDVPlugin*)plugin withClassName:(NSString*)className { return [super registerPlugin:plugin withClassName:className]; @@ -102,38 +119,39 @@ #pragma UIWebDelegate implementation -- (void) webViewDidFinishLoad:(UIWebView*) theWebView +- (void)webViewDidFinishLoad:(UIWebView*)theWebView { - // only valid if ___PROJECTNAME__-Info.plist specifies a protocol to handle - if (self.invokeString) - { + // only valid if ___PROJECTNAME__-Info.plist specifies a protocol to handle + if (self.invokeString) { // this is passed before the deviceready event is fired, so you can access it in js when you receive deviceready + NSLog(@"DEPRECATED: window.invokeString - use the window.handleOpenURL(url) function instead, which is always called when the app is launched through a custom scheme url."); NSString* jsString = [NSString stringWithFormat:@"var invokeString = \"%@\";", self.invokeString]; [theWebView stringByEvaluatingJavaScriptFromString:jsString]; - } - - // Black base color for background matches the native apps - theWebView.backgroundColor = [UIColor blackColor]; + } - return [super webViewDidFinishLoad:theWebView]; + // Black base color for background matches the native apps + theWebView.backgroundColor = [UIColor blackColor]; + + return [super webViewDidFinishLoad:theWebView]; } /* Comment out the block below to over-ride */ + /* -- (void) webViewDidStartLoad:(UIWebView*)theWebView +- (void) webViewDidStartLoad:(UIWebView*)theWebView { - return [super webViewDidStartLoad:theWebView]; + return [super webViewDidStartLoad:theWebView]; } -- (void) webView:(UIWebView*)theWebView didFailLoadWithError:(NSError*)error +- (void) webView:(UIWebView*)theWebView didFailLoadWithError:(NSError*)error { - return [super webView:theWebView didFailLoadWithError:error]; + return [super webView:theWebView didFailLoadWithError:error]; } - (BOOL) webView:(UIWebView*)theWebView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType { - return [super webView:theWebView shouldStartLoadWithRequest:request navigationType:navigationType]; + return [super webView:theWebView shouldStartLoadWithRequest:request navigationType:navigationType]; } */ diff --git a/www/cordova-android-2.1.0.js b/www/cordova-android-2.2.0.js index 9e7fa8e..9f8f783 100755 --- a/www/cordova-android-2.1.0.js +++ b/www/cordova-android-2.2.0.js @@ -1,6 +1,6 @@ -// commit 143f5221a6251c9cbccdedc57005c61551b97f12 +// commit 02b91c5313ff37d74a58f71775170afd360f4a1f -// File generated at :: Wed Sep 12 2012 12:51:58 GMT-0700 (PDT) +// File generated at :: Wed Oct 31 2012 10:40:25 GMT-0700 (PDT) /* Licensed to the Apache Software Foundation (ASF) under one @@ -24,11 +24,16 @@ ;(function() { // file: lib/scripts/require.js + var require, define; (function () { var modules = {}; + // Stack of moduleIds currently being built. + var requireStack = []; + // Map of module ID -> index into requireStack of modules currently being built. + var inProgressModules = {}; function build(module) { var factory = module.factory; @@ -41,8 +46,21 @@ var require, 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; } - return modules[id].factory ? build(modules[id]) : modules[id].exports; + 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) { @@ -67,8 +85,11 @@ if (typeof module === "object" && typeof require === "function") { module.exports.require = require; module.exports.define = define; } + // file: lib/cordova.js define("cordova", function(require, exports, module) { + + var channel = require('cordova/channel'); /** @@ -99,11 +120,7 @@ var documentEventHandlers = {}, document.addEventListener = function(evt, handler, capture) { var e = evt.toLowerCase(); if (typeof documentEventHandlers[e] != 'undefined') { - if (evt === 'deviceready') { - documentEventHandlers[e].subscribeOnce(handler); - } else { - documentEventHandlers[e].subscribe(handler); - } + documentEventHandlers[e].subscribe(handler); } else { m_document_addEventListener.call(document, evt, handler, capture); } @@ -120,7 +137,7 @@ window.addEventListener = function(evt, handler, capture) { document.removeEventListener = function(evt, handler, capture) { var e = evt.toLowerCase(); - // If unsubcribing from an event that is handled by a plugin + // If unsubscribing from an event that is handled by a plugin if (typeof documentEventHandlers[e] != "undefined") { documentEventHandlers[e].unsubscribe(handler); } else { @@ -130,7 +147,7 @@ document.removeEventListener = function(evt, handler, capture) { window.removeEventListener = function(evt, handler, capture) { var e = evt.toLowerCase(); - // If unsubcribing from an event that is handled by a plugin + // If unsubscribing from an event that is handled by a plugin if (typeof windowEventHandlers[e] != "undefined") { windowEventHandlers[e].unsubscribe(handler); } else { @@ -163,11 +180,14 @@ var cordova = { /** * Methods to add/remove your own addEventListener hijacking on document + window. */ - addWindowEventHandler:function(event, opts) { - return (windowEventHandlers[event] = channel.create(event, opts)); + addWindowEventHandler:function(event) { + return (windowEventHandlers[event] = channel.create(event)); }, - addDocumentEventHandler:function(event, opts) { - return (documentEventHandlers[event] = channel.create(event, opts)); + addStickyDocumentEventHandler:function(event) { + return (documentEventHandlers[event] = channel.createSticky(event)); + }, + addDocumentEventHandler:function(event) { + return (documentEventHandlers[event] = channel.create(event)); }, removeWindowEventHandler:function(event) { delete windowEventHandlers[event]; @@ -176,7 +196,7 @@ var cordova = { delete documentEventHandlers[event]; }, /** - * Retreive original event handlers that were replaced by Cordova + * Retrieve original event handlers that were replaced by Cordova * * @return object */ @@ -186,7 +206,7 @@ var cordova = { }, /** * Method to fire event from native code - * bNoDetach is required for events which cause an exception which needs to be caught in 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); @@ -214,18 +234,12 @@ var cordova = { } }, - // TODO: iOS only - // This queue holds the currently executing command and all pending - // commands executed with cordova.exec(). - commandQueue:[], - // Indicates if we're currently in the middle of flushing the command - // queue on the native side. - commandQueueFlushing:false, - // END TODO /** * Plugin callback mechanism. */ - callbackId: 0, + // 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, @@ -242,57 +256,48 @@ var cordova = { /** * Called by native code when returning successful result from an action. - * - * @param callbackId - * @param args */ callbackSuccess: function(callbackId, args) { - if (cordova.callbacks[callbackId]) { - - // If result is to be sent to callback - if (args.status == cordova.callbackStatus.OK) { - try { - if (cordova.callbacks[callbackId].success) { - cordova.callbacks[callbackId].success(args.message); - } - } - catch (e) { - console.log("Error in success callback: "+callbackId+" = "+e); - } - } - - // Clear callback if not expecting any more results - if (!args.keepCallback) { - delete cordova.callbacks[callbackId]; - } + try { + cordova.callbackFromNative(callbackId, true, args.status, args.message, args.keepCallback); + } catch (e) { + console.log("Error in error callback: " + callbackId + " = "+e); } }, /** * Called by native code when returning error result from an action. - * - * @param callbackId - * @param args */ callbackError: function(callbackId, args) { - if (cordova.callbacks[callbackId]) { - try { - if (cordova.callbacks[callbackId].fail) { - cordova.callbacks[callbackId].fail(args.message); - } - } - catch (e) { - console.log("Error in error callback: "+callbackId+" = "+e); + // 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); + } + }, + + /** + * Called by native code when returning the result from an action. + */ + callbackFromNative: function(callbackId, success, status, message, keepCallback) { + var callback = cordova.callbacks[callbackId]; + if (callback) { + if (success && status == cordova.callbackStatus.OK) { + callback.success && callback.success(message); + } else if (!success) { + callback.fail && callback.fail(message); } // Clear callback if not expecting any more results - if (!args.keepCallback) { + if (!keepCallback) { delete cordova.callbacks[callbackId]; } } }, addConstructor: function(func) { - channel.onCordovaReady.subscribeOnce(function() { + channel.onCordovaReady.subscribe(function() { try { func(); } catch(e) { @@ -305,7 +310,7 @@ 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.addDocumentEventHandler('deviceready'); +channel.onDeviceReady = cordova.addStickyDocumentEventHandler('deviceready'); module.exports = cordova; @@ -313,6 +318,7 @@ module.exports = cordova; // file: lib/common/builder.js define("cordova/builder", function(require, exports, module) { + var utils = require('cordova/utils'); function each(objects, func, context) { @@ -323,6 +329,17 @@ function each(objects, func, context) { } } +function assignOrWrapInDeprecateGetter(obj, key, value, message) { + if (message) { + utils.defineGetter(obj, key, function() { + window.console && console.log(message); + return value; + }); + } else { + obj[key] = value; + } +} + function include(parent, objects, clobber, merge) { each(objects, function (obj, key) { try { @@ -331,20 +348,20 @@ function include(parent, objects, clobber, merge) { if (clobber) { // Clobber if it doesn't exist. if (typeof parent[key] === 'undefined') { - parent[key] = result; + 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 { - parent[key] = result; + assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated); } } result = parent[key]; } else { // Overwrite if not currently defined. if (typeof parent[key] == 'undefined') { - parent[key] = result; + assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated); } else if (merge && typeof obj.path !== 'undefined') { // If merging, merge parent onto result recursiveMerge(result, parent[key]); @@ -389,7 +406,7 @@ function recursiveMerge(target, src) { module.exports = { build: function (objects) { return { - intoButDontClobber: function (target) { + intoButDoNotClobber: function (target) { include(target, objects, false, false); }, intoAndClobber: function(target) { @@ -406,25 +423,29 @@ module.exports = { // file: lib/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. + * 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. - * onCordovaInfoReady Internal event fired when device properties are available. - * onCordovaConnectionReady Internal event fired when the connection property has been set. - * 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). + * 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. + * onCordovaInfoReady* Internal event fired when device properties are available. + * onCordovaConnectionReady* Internal event fired when the connection property has been set. + * 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. * * 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 @@ -446,49 +467,45 @@ var utils = require('cordova/utils'), * Channel * @constructor * @param type String the channel name - * @param opts Object options to pass into the channel, currently - * supports: - * onSubscribe: callback that fires when - * something subscribes to the Channel. Sets - * context to the Channel. - * onUnsubscribe: callback that fires when - * something unsubscribes to the Channel. Sets - * context to the Channel. - */ -var Channel = function(type, opts) { + */ +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; - this.fired = false; - this.enabled = true; - this.events = { - onSubscribe:null, - onUnsubscribe:null - }; - if (opts) { - if (opts.onSubscribe) this.events.onSubscribe = opts.onSubscribe; - if (opts.onUnsubscribe) this.events.onUnsubscribe = opts.onUnsubscribe; - } + // 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. + * have been fired. All channels must be sticky channels. */ - join: function (h, c) { - var i = c.length; - var len = i; - var f = function() { - if (!(--i)) h(); - }; + join: function(h, c) { + var len = c.length, + i = len, + f = function() { + if (!(--i)) h(); + }; for (var j=0; j<len; j++) { - !c[j].fired?c[j].subscribeOnce(f):i--; + if (c[j].state === 0) { + throw Error('Can only use join with sticky channels.'); + } + c[j].subscribe(f); } - if (!i) h(); + if (!len) h(); }, - create: function (type, opts) { - channel[type] = new Channel(type, opts); - return channel[type]; + create: function(type) { + return channel[type] = new Channel(type, false); + }, + createSticky: function(type) { + return channel[type] = new Channel(type, true); }, /** @@ -506,13 +523,7 @@ var Channel = function(type, opts) { */ waitForInitialization: function(feature) { if (feature) { - var c = null; - if (this[feature]) { - c = this[feature]; - } - else { - c = this.create(feature); - } + var c = channel[feature] || this.createSticky(feature); this.deviceReadyChannelsMap[feature] = c; this.deviceReadyChannelsArray.push(c); } @@ -532,7 +543,7 @@ var Channel = function(type, opts) { }; function forceFunction(f) { - if (f === null || f === undefined || typeof f != 'function') throw "Function required as first argument!"; + if (typeof f != 'function') throw "Function required as first argument!"; } /** @@ -542,67 +553,50 @@ function forceFunction(f) { * and a guid that can be used to stop subscribing to the channel. * Returns the guid. */ -Channel.prototype.subscribe = function(f, c, g) { +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; + var func = f, + guid = f.observer_guid; if (typeof c == "object") { func = utils.close(c, f); } - g = g || func.observer_guid || f.observer_guid; - if (!g) { + if (!guid) { // first time any channel has seen this subscriber - g = nextGuid++; + guid = '' + nextGuid++; } - func.observer_guid = g; - f.observer_guid = g; + func.observer_guid = guid; + f.observer_guid = guid; // Don't add the same handler more than once. - if (!this.handlers[g]) { - this.handlers[g] = func; + if (!this.handlers[guid]) { + this.handlers[guid] = func; this.numHandlers++; - if (this.events.onSubscribe) this.events.onSubscribe.call(this); - if (this.fired) func.apply(this, this.fireArgs); - } - return g; -}; - -/** - * Like subscribe but the function is only called once and then it - * auto-unsubscribes itself. - */ -Channel.prototype.subscribeOnce = function(f, c) { - // need a function to call - forceFunction(f); - - var g = null; - var _this = this; - if (this.fired) { - f.apply(c || null, this.fireArgs); - } else { - g = this.subscribe(function() { - _this.unsubscribe(g); - f.apply(c || null, arguments); - }); - f.observer_guid = g; + if (this.numHandlers == 1) { + this.onHasSubscribersChange && this.onHasSubscribersChange(); + } } - return g; }; /** * Unsubscribes the function with the given guid from the channel. */ -Channel.prototype.unsubscribe = function(g) { +Channel.prototype.unsubscribe = function(f) { // need a function to unsubscribe - if (g === null || g === undefined) { throw "You must pass _something_ into Channel.unsubscribe"; } + forceFunction(f); - if (typeof g == 'function') { g = g.observer_guid; } - var handler = this.handlers[g]; + var guid = f.observer_guid, + handler = this.handlers[guid]; if (handler) { - if (handler.observer_guid) handler.observer_guid=null; - delete this.handlers[g]; + delete this.handlers[guid]; this.numHandlers--; - if (this.events.onUnsubscribe) this.events.onUnsubscribe.call(this); + if (this.numHandlers === 0) { + this.onHasSubscribersChange && this.onHasSubscribersChange(); + } } }; @@ -610,10 +604,14 @@ Channel.prototype.unsubscribe = function(g) { * Calls all functions subscribed to this channel. */ Channel.prototype.fire = function(e) { - if (this.enabled) { - var fail = false; - this.fired = true; - this.fireArgs = arguments; + 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 = []; @@ -621,33 +619,36 @@ Channel.prototype.fire = function(e) { toCall.push(this.handlers[item]); } for (var i = 0; i < toCall.length; ++i) { - var rv = (toCall[i].apply(this, arguments)===false); - fail = fail || rv; + toCall[i].apply(this, fireArgs); + } + if (this.state == 2 && this.numHandlers) { + this.numHandlers = 0; + this.handlers = {}; + this.onHasSubscribersChange && this.onHasSubscribersChange(); } - return !fail; } - return true; }; + // defining them here so they are ready super fast! // DOM event that is received when the web page is loaded and parsed. -channel.create('onDOMContentLoaded'); +channel.createSticky('onDOMContentLoaded'); // Event to indicate the Cordova native side is ready. -channel.create('onNativeReady'); +channel.createSticky('onNativeReady'); // Event to indicate that all Cordova JavaScript objects have been created // and it's time to run plugin constructors. -channel.create('onCordovaReady'); +channel.createSticky('onCordovaReady'); // Event to indicate that device properties are available -channel.create('onCordovaInfoReady'); +channel.createSticky('onCordovaInfoReady'); // Event to indicate that the connection property has been set. -channel.create('onCordovaConnectionReady'); +channel.createSticky('onCordovaConnectionReady'); // Event to indicate that Cordova is ready -channel.create('onDeviceReady'); +channel.createSticky('onDeviceReady'); // Event to indicate a resume lifecycle event channel.create('onResume'); @@ -656,7 +657,7 @@ channel.create('onResume'); channel.create('onPause'); // Event to indicate a destroy lifecycle event -channel.create('onDestroy'); +channel.createSticky('onDestroy'); // Channels that must fire before "deviceready" is fired. channel.waitForInitialization('onCordovaReady'); @@ -666,8 +667,39 @@ 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/common/common.js define("cordova/common", function(require, exports, module) { + module.exports = { objects: { cordova: { @@ -705,6 +737,9 @@ module.exports = { compass:{ path: 'cordova/plugin/compass' }, + connection: { + path: 'cordova/plugin/network' + }, contacts: { path: 'cordova/plugin/contacts' }, @@ -718,10 +753,14 @@ module.exports = { geolocation: { path: 'cordova/plugin/geolocation' }, + globalization: { + path: 'cordova/plugin/globalization' + }, network: { children: { connection: { - path: 'cordova/plugin/network' + path: 'cordova/plugin/network', + deprecated: 'navigator.network.connection is deprecated. Use navigator.connection instead.' } } }, @@ -832,6 +871,9 @@ module.exports = { Flags: { path: 'cordova/plugin/Flags' }, + GlobalizationError: { + path: 'cordova/plugin/GlobalizationError' + }, LocalFileSystem: { path: 'cordova/plugin/LocalFileSystem' }, @@ -872,11 +914,12 @@ module.exports = { // file: lib/android/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 - * Asynchrounous: Empty string "" + * Asynchronous: Empty string "" * If async, the native side will cordova.callbackSuccess or cordova.callbackError, * depending upon the result of the action. * @@ -887,10 +930,7 @@ define("cordova/exec", function(require, exports, module) { * @param {String[]} [args] Zero or more arguments to pass to the method */ var cordova = require('cordova'), - callback = require('cordova/plugin/android/callback'), - polling = require('cordova/plugin/android/polling'), - jsToNativeBridgeMode, - nativeToJsBridgeMode, + nativeApiProvider = require('cordova/plugin/android/nativeapiprovider'), jsToNativeModes = { PROMPT: 0, JS_OBJECT: 1, @@ -900,124 +940,99 @@ var cordova = require('cordova'), LOCATION_CHANGE: 2 }, nativeToJsModes = { - // Polls for messages using the prompt() bridge. + // Polls for messages using the JS->Native bridge. POLLING: 0, - // Does an XHR to a local server, which will send back messages. This is - // broken on ICS when a proxy server is configured. - HANGING_GET: 1, // 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: 2, + 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: 3, + ONLINE_EVENT: 2, // Uses reflection to access private APIs of the WebView that can send JS // to be executed. // Requires Android 3.2.4 or above. - PRIVATE_API: 4 - }; + PRIVATE_API: 3 + }, + jsToNativeBridgeMode, // Set lazily. + nativeToJsBridgeMode = nativeToJsModes.ONLINE_EVENT, + pollEnabled = false, + messagesFromNative = []; function androidExec(success, fail, service, action, args) { // Set default bridge modes if they have not already been set. if (jsToNativeBridgeMode === undefined) { - androidExec.setJsToNativeBridgeMode(jsToNativeModes.PROMPT); - } - if (nativeToJsBridgeMode === undefined) { - if (callback.isAvailable()) { - androidExec.setNativeToJsBridgeMode(nativeToJsModes.HANGING_GET); - } else { - androidExec.setNativeToJsBridgeMode(nativeToJsModes.POLLING); - } + androidExec.setJsToNativeBridgeMode(jsToNativeModes.JS_OBJECT); } - try { - var callbackId = service + cordova.callbackId++, - argsJson = JSON.stringify(args), - result; - if (success || fail) { - cordova.callbacks[callbackId] = {success:success, fail:fail}; - } - - if (jsToNativeBridgeMode == jsToNativeModes.LOCATION_CHANGE) { - window.location = 'http://cdv_exec/' + service + '#' + action + '#' + callbackId + '#' + argsJson; - } else if (jsToNativeBridgeMode == jsToNativeModes.JS_OBJECT) { - // Explicit cast to string is required on Android 2.1 to convert from - // a Java string to a JS string. - result = '' + _cordovaExec.exec(service, action, callbackId, argsJson); - } else { - result = prompt(argsJson, "gap:"+JSON.stringify([service, action, callbackId, true])); - } - // If a result was returned - if (result) { - var v = JSON.parse(result); - - // If status is OK, then return value back to caller - if (v.status === cordova.callbackStatus.OK) { - - // If there is a success callback, then call it now with - // returned value - if (success) { - try { - success(v.message); - } catch (e) { - console.log("Error in success callback: " + callbackId + " = " + e); - } + var callbackId = service + cordova.callbackId++, + argsJson = JSON.stringify(args), + returnValue; - // Clear callback if not expecting any more results - if (!v.keepCallback) { - delete cordova.callbacks[callbackId]; - } - } - return v.message; - } + // TODO: Returning the payload of a synchronous call was deprecated in 2.2.0. + // Remove it after 6 months. + function captureReturnValue(value) { + returnValue = value; + success && success(value); + } - // If no result - else if (v.status === cordova.callbackStatus.NO_RESULT) { - // Clear callback if not expecting any more results - if (!v.keepCallback) { - delete cordova.callbacks[callbackId]; - } - } + cordova.callbacks[callbackId] = {success:captureReturnValue, fail:fail}; - // If error, then display error - else { - console.log("Error: Status="+v.status+" Message="+v.message); + if (jsToNativeBridgeMode == jsToNativeModes.LOCATION_CHANGE) { + window.location = 'http://cdv_exec/' + service + '#' + action + '#' + callbackId + '#' + argsJson; + } else { + var messages = nativeApiProvider.get().exec(service, action, callbackId, argsJson); + androidExec.processMessages(messages); + } + if (cordova.callbacks[callbackId]) { + if (success || fail) { + cordova.callbacks[callbackId].success = success; + } else { + delete cordova.callbacks[callbackId]; + } + } + return returnValue; +} - // If there is a fail callback, then call it now with returned value - if (fail) { - try { - fail(v.message); - } - catch (e1) { - console.log("Error in error callback: "+callbackId+" = "+e1); - } +function pollOnce() { + var msg = nativeApiProvider.get().retrieveJsMessages(); + androidExec.processMessages(msg); +} - // Clear callback if not expecting any more results - if (!v.keepCallback) { - delete cordova.callbacks[callbackId]; - } - } - return null; - } - } - } catch (e2) { - console.log("Error: "+e2); +function pollingTimerFunc() { + if (pollEnabled) { + pollOnce(); + setTimeout(pollingTimerFunc, 50); } } -function onOnLineEvent(e) { - while (polling.pollOnce()); +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', pollOnce, false); + window.addEventListener('offline', pollOnce, 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._cordovaExec) { - console.log('Falling back on PROMPT mode since _cordovaExec is missing.'); + if (mode == jsToNativeModes.JS_OBJECT && !window._cordovaNative) { + console.log('Falling back on PROMPT mode since _cordovaNative is missing.'); mode = jsToNativeModes.PROMPT; } + nativeApiProvider.setPreferPrompt(mode == jsToNativeModes.PROMPT); jsToNativeBridgeMode = mode; }; @@ -1026,25 +1041,88 @@ androidExec.setNativeToJsBridgeMode = function(mode) { return; } if (nativeToJsBridgeMode == nativeToJsModes.POLLING) { - polling.stop(); - } else if (nativeToJsBridgeMode == nativeToJsModes.HANGING_GET) { - callback.stop(); - } else if (nativeToJsBridgeMode == nativeToJsModes.ONLINE_EVENT) { - window.removeEventListener('online', onOnLineEvent, false); - window.removeEventListener('offline', onOnLineEvent, false); + pollEnabled = false; } nativeToJsBridgeMode = mode; // Tell the native side to switch modes. - prompt(mode, "gap_bridge_mode:"); + nativeApiProvider.get().setNativeToJsBridgeMode(mode); if (mode == nativeToJsModes.POLLING) { - polling.start(); - } else if (mode == nativeToJsModes.HANGING_GET) { - callback.start(); - } else if (mode == nativeToJsModes.ONLINE_EVENT) { - window.addEventListener('online', onOnLineEvent, false); - window.addEventListener('offline', onOnLineEvent, false); + pollEnabled = true; + setTimeout(pollingTimerFunc, 1); + } +}; + +// Processes a single message, as encoded by NativeToJsMessageQueue.java. +function processMessage(message) { + try { + var firstChar = message.charAt(0); + if (firstChar == 'J') { + eval(message.slice(1)); + } else if (firstChar == 'S' || firstChar == 'F') { + var success = firstChar == 'S'; + var keepCallback = message.charAt(1) == '1'; + var spaceIdx = message.indexOf(' ', 2); + var status = +message.slice(2, spaceIdx); + var nextSpaceIdx = message.indexOf(' ', spaceIdx + 1); + var callbackId = message.slice(spaceIdx + 1, nextSpaceIdx); + var payloadKind = message.charAt(nextSpaceIdx + 1); + var payload; + if (payloadKind == 's') { + payload = message.slice(nextSpaceIdx + 2); + } else if (payloadKind == 't') { + payload = true; + } else if (payloadKind == 'f') { + payload = false; + } else if (payloadKind == 'N') { + payload = null; + } else if (payloadKind == 'n') { + payload = +message.slice(nextSpaceIdx + 2); + } else { + payload = JSON.parse(message.slice(nextSpaceIdx + 1)); + } + cordova.callbackFromNative(callbackId, success, status, payload, keepCallback); + } else { + console.log("processMessage failed: invalid message:" + message); + } + } catch (e) { + console.log("processMessage failed: Message: " + message); + console.log("processMessage failed: Error: " + e); + console.log("processMessage failed: Stack: " + e.stack); + } +} + +// This is called from the NativeToJsMessageQueue.java. +androidExec.processMessages = function(messages) { + if (messages) { + messagesFromNative.push(messages); + while (messagesFromNative.length) { + messages = messagesFromNative.shift(); + // The Java side can send a * message to indicate that it + // still has messages waiting to be retrieved. + // TODO(agrieve): This is currently disabled on the Java side + // since it breaks returning the result in exec of synchronous + // plugins. Once we remove this ability, we can remove this comment. + if (messages == '*') { + window.setTimeout(pollOnce, 0); + continue; + } + + var spaceIdx = messages.indexOf(' '); + var msgLen = +messages.slice(0, spaceIdx); + var message = messages.substr(spaceIdx + 1, msgLen); + messages = messages.slice(spaceIdx + msgLen + 1); + // Put the remaining messages back into queue in case an exec() + // is made by the callback. + if (messages) { + messagesFromNative.unshift(messages); + } + + if (message) { + processMessage(message); + } + } } }; @@ -1054,6 +1132,7 @@ module.exports = androidExec; // file: lib/android/platform.js define("cordova/platform", function(require, exports, module) { + module.exports = { id: "android", initialize:function() { @@ -1062,20 +1141,12 @@ module.exports = { exec = require('cordova/exec'); // Inject a listener for the backbutton on the document. - var backButtonChannel = cordova.addDocumentEventHandler('backbutton', { - onSubscribe:function() { - // If we just attached the first handler, let native know we need to override the back button. - if (this.numHandlers === 1) { - exec(null, null, "App", "overrideBackbutton", [true]); - } - }, - onUnsubscribe:function() { - // If we just detached the last handler, let native know we no longer override the back button. - if (this.numHandlers === 0) { - exec(null, null, "App", "overrideBackbutton", [false]); - } - } - }); + var backButtonChannel = cordova.addDocumentEventHandler('backbutton'); + backButtonChannel.onHasSubscribersChange = function() { + // If we just attached the first handler or detached the last handler, + // let native know we need to override the back button. + exec(null, null, "App", "overrideBackbutton", [this.numHandlers == 1]); + }; // Add hardware MENU and SEARCH button handlers cordova.addDocumentEventHandler('menubutton'); @@ -1129,16 +1200,6 @@ module.exports = { }, [channel.onCordovaReady]); }, objects: { - cordova: { - children: { - JSCallback:{ - path:"cordova/plugin/android/callback" - }, - JSCallbackPolling:{ - path:"cordova/plugin/android/polling" - } - } - }, navigator: { children: { app:{ @@ -1177,6 +1238,7 @@ module.exports = { // file: lib/common/plugin/Acceleration.js define("cordova/plugin/Acceleration", function(require, exports, module) { + var Acceleration = function(x, y, z, timestamp) { this.x = x; this.y = y; @@ -1190,6 +1252,7 @@ module.exports = Acceleration; // file: lib/common/plugin/Camera.js define("cordova/plugin/Camera", function(require, exports, module) { + var exec = require('cordova/exec'), Camera = require('cordova/plugin/CameraConstants'); @@ -1211,6 +1274,7 @@ for (var key in Camera) { * @param {Object} options */ cameraExport.getPicture = function(successCallback, errorCallback, options) { + options = options || {}; // successCallback required if (typeof successCallback != "function") { console.log("Camera Error: successCallback is not a function"); @@ -1224,9 +1288,9 @@ cameraExport.getPicture = function(successCallback, errorCallback, options) { } var quality = 50; - if (options && typeof options.quality == "number") { + if (typeof options.quality == "number") { quality = options.quality; - } else if (options && typeof options.quality == "string") { + } else if (typeof options.quality == "string") { var qlity = parseInt(options.quality, 10); if (isNaN(qlity) === false) { quality = qlity.valueOf(); @@ -1306,10 +1370,12 @@ cameraExport.cleanup = function(successCallback, errorCallback) { }; module.exports = cameraExport; + }); // file: lib/common/plugin/CameraConstants.js define("cordova/plugin/CameraConstants", function(require, exports, module) { + module.exports = { DestinationType:{ DATA_URL: 0, // Return base64 encoded string @@ -1337,10 +1403,12 @@ module.exports = { ARROW_ANY : 15 } }; + }); // file: lib/common/plugin/CameraPopoverOptions.js define("cordova/plugin/CameraPopoverOptions", function(require, exports, module) { + var Camera = require('cordova/plugin/CameraConstants'); /** @@ -1357,10 +1425,12 @@ var CameraPopoverOptions = function(x,y,width,height,arrowDir){ }; module.exports = CameraPopoverOptions; + }); // file: lib/common/plugin/CaptureAudioOptions.js define("cordova/plugin/CaptureAudioOptions", function(require, exports, module) { + /** * Encapsulates all audio capture operation configuration options. */ @@ -1374,10 +1444,12 @@ var CaptureAudioOptions = function(){ }; module.exports = CaptureAudioOptions; + }); // file: lib/common/plugin/CaptureError.js define("cordova/plugin/CaptureError", function(require, exports, module) { + /** * The CaptureError interface encapsulates all errors in the Capture API. */ @@ -1397,10 +1469,12 @@ CaptureError.CAPTURE_NO_MEDIA_FILES = 3; CaptureError.CAPTURE_NOT_SUPPORTED = 20; module.exports = CaptureError; + }); // file: lib/common/plugin/CaptureImageOptions.js define("cordova/plugin/CaptureImageOptions", function(require, exports, module) { + /** * Encapsulates all image capture operation configuration options. */ @@ -1412,10 +1486,12 @@ var CaptureImageOptions = function(){ }; module.exports = CaptureImageOptions; + }); // file: lib/common/plugin/CaptureVideoOptions.js define("cordova/plugin/CaptureVideoOptions", function(require, exports, module) { + /** * Encapsulates all video capture operation configuration options. */ @@ -1429,13 +1505,15 @@ var CaptureVideoOptions = function(){ }; module.exports = CaptureVideoOptions; + }); // file: lib/common/plugin/CompassError.js define("cordova/plugin/CompassError", function(require, exports, module) { + /** * CompassError. - * An error code assigned by an implementation when an error has occured + * An error code assigned by an implementation when an error has occurred * @constructor */ var CompassError = function(err) { @@ -1446,10 +1524,12 @@ CompassError.COMPASS_INTERNAL_ERR = 0; CompassError.COMPASS_NOT_SUPPORTED = 20; module.exports = CompassError; + }); // file: lib/common/plugin/CompassHeading.js define("cordova/plugin/CompassHeading", function(require, exports, module) { + var CompassHeading = function(magneticHeading, trueHeading, headingAccuracy, timestamp) { this.magneticHeading = (magneticHeading !== undefined ? magneticHeading : null); this.trueHeading = (trueHeading !== undefined ? trueHeading : null); @@ -1458,10 +1538,12 @@ var CompassHeading = function(magneticHeading, trueHeading, headingAccuracy, tim }; module.exports = CompassHeading; + }); // file: lib/common/plugin/ConfigurationData.js define("cordova/plugin/ConfigurationData", function(require, exports, module) { + /** * Encapsulates a set of parameters that the capture device supports. */ @@ -1477,10 +1559,12 @@ function ConfigurationData() { } module.exports = ConfigurationData; + }); // file: lib/common/plugin/Connection.js define("cordova/plugin/Connection", function(require, exports, module) { + /** * Network status */ @@ -1493,10 +1577,12 @@ module.exports = { CELL_4G: "4g", NONE: "none" }; + }); // file: lib/common/plugin/Contact.js define("cordova/plugin/Contact", function(require, exports, module) { + var exec = require('cordova/exec'), ContactError = require('cordova/plugin/ContactError'), utils = require('cordova/utils'); @@ -1679,6 +1765,7 @@ module.exports = Contact; // file: lib/common/plugin/ContactAddress.js define("cordova/plugin/ContactAddress", function(require, exports, module) { + /** * Contact address. * @constructor @@ -1704,13 +1791,15 @@ var ContactAddress = function(pref, type, formatted, streetAddress, locality, re }; module.exports = ContactAddress; + }); // file: lib/common/plugin/ContactError.js define("cordova/plugin/ContactError", function(require, exports, module) { + /** * ContactError. - * An error code assigned by an implementation when an error has occured + * An error code assigned by an implementation when an error has occurred * @constructor */ var ContactError = function(err) { @@ -1729,10 +1818,12 @@ ContactError.NOT_SUPPORTED_ERROR = 5; ContactError.PERMISSION_DENIED_ERROR = 20; module.exports = ContactError; + }); // file: lib/common/plugin/ContactField.js define("cordova/plugin/ContactField", function(require, exports, module) { + /** * Generic contact field. * @constructor @@ -1749,10 +1840,12 @@ var ContactField = function(type, value, pref) { }; module.exports = ContactField; + }); // file: lib/common/plugin/ContactFindOptions.js define("cordova/plugin/ContactFindOptions", function(require, exports, module) { + /** * ContactFindOptions. * @constructor @@ -1766,10 +1859,12 @@ var ContactFindOptions = function(filter, multiple) { }; module.exports = ContactFindOptions; + }); // file: lib/common/plugin/ContactName.js define("cordova/plugin/ContactName", function(require, exports, module) { + /** * Contact name. * @constructor @@ -1790,10 +1885,12 @@ var ContactName = function(formatted, familyName, givenName, middle, prefix, suf }; module.exports = ContactName; + }); // file: lib/common/plugin/ContactOrganization.js define("cordova/plugin/ContactOrganization", function(require, exports, module) { + /** * Contact organization. * @constructor @@ -1817,10 +1914,12 @@ var ContactOrganization = function(pref, type, name, dept, title) { }; module.exports = ContactOrganization; + }); // file: lib/common/plugin/Coordinates.js define("cordova/plugin/Coordinates", function(require, exports, module) { + /** * This class contains position information. * @param {Object} lat @@ -1874,6 +1973,7 @@ module.exports = Coordinates; // file: lib/common/plugin/DirectoryEntry.js define("cordova/plugin/DirectoryEntry", function(require, exports, module) { + var utils = require('cordova/utils'), exec = require('cordova/exec'), Entry = require('cordova/plugin/Entry'), @@ -1906,7 +2006,7 @@ DirectoryEntry.prototype.createReader = function() { * Creates or looks up a directory * * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a directory - * @param {Flags} options to create or excluively create the directory + * @param {Flags} options to create or exclusively create the directory * @param {Function} successCallback is called with the new entry * @param {Function} errorCallback is called with a FileError */ @@ -1938,7 +2038,7 @@ DirectoryEntry.prototype.removeRecursively = function(successCallback, errorCall * Creates or looks up a file * * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a file - * @param {Flags} options to create or excluively create the file + * @param {Flags} options to create or exclusively create the file * @param {Function} successCallback is called with the new entry * @param {Function} errorCallback is called with a FileError */ @@ -1960,6 +2060,7 @@ module.exports = DirectoryEntry; // file: lib/common/plugin/DirectoryReader.js define("cordova/plugin/DirectoryReader", function(require, exports, module) { + var exec = require('cordova/exec'), FileError = require('cordova/plugin/FileError') ; @@ -2007,6 +2108,7 @@ module.exports = DirectoryReader; // file: lib/common/plugin/Entry.js define("cordova/plugin/Entry", function(require, exports, module) { + var exec = require('cordova/exec'), FileError = require('cordova/plugin/FileError'), Metadata = require('cordova/plugin/Metadata'); @@ -2225,10 +2327,12 @@ Entry.prototype.getParent = function(successCallback, errorCallback) { }; module.exports = Entry; + }); // file: lib/common/plugin/File.js define("cordova/plugin/File", function(require, exports, module) { + /** * Constructor. * name {DOMString} name of the file, without path information @@ -2247,10 +2351,12 @@ var File = function(name, fullPath, type, lastModifiedDate, size){ }; module.exports = File; + }); // file: lib/common/plugin/FileEntry.js define("cordova/plugin/FileEntry", function(require, exports, module) { + var utils = require('cordova/utils'), exec = require('cordova/exec'), Entry = require('cordova/plugin/Entry'), @@ -2314,10 +2420,12 @@ FileEntry.prototype.file = function(successCallback, errorCallback) { module.exports = FileEntry; + }); // file: lib/common/plugin/FileError.js define("cordova/plugin/FileError", function(require, exports, module) { + /** * FileError */ @@ -2343,10 +2451,12 @@ FileError.TYPE_MISMATCH_ERR = 11; FileError.PATH_EXISTS_ERR = 12; module.exports = FileError; + }); // file: lib/common/plugin/FileReader.js define("cordova/plugin/FileReader", function(require, exports, module) { + var exec = require('cordova/exec'), FileError = require('cordova/plugin/FileError'), ProgressEvent = require('cordova/plugin/ProgressEvent'); @@ -2372,7 +2482,7 @@ var FileReader = function() { // Event handlers this.onloadstart = null; // When the read starts. - this.onprogress = null; // While reading (and decoding) file or fileBlob data, and reporting partial file data (progess.loaded/progress.total) + this.onprogress = null; // While reading (and decoding) file or fileBlob data, and reporting partial file data (progress.loaded/progress.total) this.onload = null; // When the read has successfully completed. this.onerror = null; // When the read has failed (see errors). this.onloadend = null; // When the request has completed (either in success or failure). @@ -2596,10 +2706,12 @@ FileReader.prototype.readAsArrayBuffer = function(file) { }; module.exports = FileReader; + }); // file: lib/common/plugin/FileSystem.js define("cordova/plugin/FileSystem", function(require, exports, module) { + var DirectoryEntry = require('cordova/plugin/DirectoryEntry'); /** @@ -2622,14 +2734,29 @@ module.exports = FileSystem; // file: lib/common/plugin/FileTransfer.js define("cordova/plugin/FileTransfer", function(require, exports, module) { + var exec = require('cordova/exec'), - FileTransferError = require('cordova/plugin/FileTransferError'); + FileTransferError = require('cordova/plugin/FileTransferError'), + ProgressEvent = require('cordova/plugin/ProgressEvent'); + +function newProgressEvent(result) { + var pe = new ProgressEvent(); + pe.lengthComputable = result.lengthComputable; + pe.loaded = result.loaded; + pe.total = result.total; + return pe; +} + +var idCounter = 0; /** * FileTransfer uploads a file to a remote server. * @constructor */ -var FileTransfer = function() {}; +var FileTransfer = function() { + this._id = ++idCounter; + this.onprogress = null; // optional callback +}; /** * Given an absolute file path, uploads a file on the device to a remote server @@ -2672,7 +2799,17 @@ FileTransfer.prototype.upload = function(filePath, server, successCallback, erro errorCallback(error); }; - exec(successCallback, fail, 'FileTransfer', 'upload', [filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode, headers]); + var self = this; + var win = function(result) { + if (typeof result.lengthComputable != "undefined") { + if (self.onprogress) { + return self.onprogress(newProgressEvent(result)); + } + } else { + return successCallback(result); + } + }; + exec(win, fail, 'FileTransfer', 'upload', [filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode, headers, this._id]); }; /** @@ -2681,23 +2818,31 @@ FileTransfer.prototype.upload = function(filePath, server, successCallback, erro * @param target {String} Full path of the file on the device * @param successCallback (Function} Callback to be invoked when upload has completed * @param errorCallback {Function} Callback to be invoked upon error + * @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false */ -FileTransfer.prototype.download = function(source, target, successCallback, errorCallback) { +FileTransfer.prototype.download = function(source, target, successCallback, errorCallback, trustAllHosts) { // sanity parameter checking if (!source || !target) throw new Error("FileTransfer.download requires source URI and target URI parameters at the minimum."); + var self = this; var win = function(result) { - var entry = null; - if (result.isDirectory) { - entry = new (require('cordova/plugin/DirectoryEntry'))(); - } - else if (result.isFile) { - entry = new (require('cordova/plugin/FileEntry'))(); + if (typeof result.lengthComputable != "undefined") { + if (self.onprogress) { + return self.onprogress(newProgressEvent(result)); + } + } else { + var entry = null; + if (result.isDirectory) { + entry = new (require('cordova/plugin/DirectoryEntry'))(); + } + else if (result.isFile) { + entry = new (require('cordova/plugin/FileEntry'))(); + } + entry.isDirectory = result.isDirectory; + entry.isFile = result.isFile; + entry.name = result.name; + entry.fullPath = result.fullPath; + successCallback(entry); } - entry.isDirectory = result.isDirectory; - entry.isFile = result.isFile; - entry.name = result.name; - entry.fullPath = result.fullPath; - successCallback(entry); }; var fail = function(e) { @@ -2705,7 +2850,16 @@ FileTransfer.prototype.download = function(source, target, successCallback, erro errorCallback(error); }; - exec(win, errorCallback, 'FileTransfer', 'download', [source, target]); + exec(win, fail, 'FileTransfer', 'download', [source, target, trustAllHosts, this._id]); +}; + +/** + * Aborts the ongoing file transfer on this object + * @param successCallback {Function} Callback to be invoked upon success + * @param errorCallback {Function} Callback to be invoked upon error + */ +FileTransfer.prototype.abort = function(successCallback, errorCallback) { + exec(successCallback, errorCallback, 'FileTransfer', 'abort', [this._id]); }; module.exports = FileTransfer; @@ -2714,6 +2868,7 @@ module.exports = FileTransfer; // file: lib/common/plugin/FileTransferError.js define("cordova/plugin/FileTransferError", function(require, exports, module) { + /** * FileTransferError * @constructor @@ -2728,6 +2883,7 @@ var FileTransferError = function(code, source, target, status) { FileTransferError.FILE_NOT_FOUND_ERR = 1; FileTransferError.INVALID_URL_ERR = 2; FileTransferError.CONNECTION_ERR = 3; +FileTransferError.ABORT_ERR = 4; module.exports = FileTransferError; @@ -2735,6 +2891,7 @@ module.exports = FileTransferError; // file: lib/common/plugin/FileUploadOptions.js define("cordova/plugin/FileUploadOptions", function(require, exports, module) { + /** * Options to customize the HTTP request used to upload files. * @constructor @@ -2759,6 +2916,7 @@ module.exports = FileUploadOptions; // file: lib/common/plugin/FileUploadResult.js define("cordova/plugin/FileUploadResult", function(require, exports, module) { + /** * FileUploadResult * @constructor @@ -2770,10 +2928,12 @@ var FileUploadResult = function() { }; module.exports = FileUploadResult; + }); // file: lib/common/plugin/FileWriter.js define("cordova/plugin/FileWriter", function(require, exports, module) { + var exec = require('cordova/exec'), FileError = require('cordova/plugin/FileError'), ProgressEvent = require('cordova/plugin/ProgressEvent'); @@ -3032,6 +3192,7 @@ module.exports = FileWriter; // file: lib/common/plugin/Flags.js define("cordova/plugin/Flags", function(require, exports, module) { + /** * Supplies arguments to methods that lookup or create files and directories. * @@ -3047,10 +3208,38 @@ function Flags(create, exclusive) { } module.exports = Flags; + +}); + +// file: lib/common/plugin/GlobalizationError.js +define("cordova/plugin/GlobalizationError", function(require, exports, module) { + + +/** + * Globalization error object + * + * @constructor + * @param code + * @param message + */ +var GlobalizationError = function(code, message) { + this.code = code || null; + this.message = message || ''; +}; + +// Globalization error codes +GlobalizationError.UNKNOWN_ERROR = 0; +GlobalizationError.FORMATTING_ERROR = 1; +GlobalizationError.PARSING_ERROR = 2; +GlobalizationError.PATTERN_ERROR = 3; + +module.exports = GlobalizationError; + }); // file: lib/common/plugin/LocalFileSystem.js define("cordova/plugin/LocalFileSystem", function(require, exports, module) { + var exec = require('cordova/exec'); /** @@ -3064,10 +3253,12 @@ LocalFileSystem.TEMPORARY = 0; //temporary, with no guarantee of persistence LocalFileSystem.PERSISTENT = 1; //persistent module.exports = LocalFileSystem; + }); // file: lib/common/plugin/Media.js define("cordova/plugin/Media", function(require, exports, module) { + var utils = require('cordova/utils'), exec = require('cordova/exec'); @@ -3242,13 +3433,13 @@ Media.onStatus = function(id, msgType, value) { media._duration = value; break; case Media.MEDIA_ERROR : - media.errorCallback && media.errorCallback(value); + media.errorCallback && media.errorCallback(value); break; case Media.MEDIA_POSITION : media._position = Number(value); break; default : - console && console.error && console.error("Unhandled Media.onStatus :: " + msgType); + console && console.error && console.error("Unhandled Media.onStatus :: " + msgType); break; } } @@ -3259,10 +3450,12 @@ Media.onStatus = function(id, msgType, value) { }; module.exports = Media; + }); // file: lib/common/plugin/MediaError.js define("cordova/plugin/MediaError", function(require, exports, module) { + /** * This class contains information about any Media errors. */ @@ -3277,28 +3470,32 @@ we should simply use a literal : errorCallbackFunction( {'code':3} ); */ -if(!MediaError) { - var MediaError = function(code, msg) { + var _MediaError = window.MediaError; + + +if(!_MediaError) { + window.MediaError = _MediaError = function(code, msg) { this.code = (typeof code != 'undefined') ? code : null; this.message = msg || ""; // message is NON-standard! do not use! }; } -MediaError.MEDIA_ERR_NONE_ACTIVE = MediaError.MEDIA_ERR_NONE_ACTIVE || 0; -MediaError.MEDIA_ERR_ABORTED = MediaError.MEDIA_ERR_ABORTED || 1; -MediaError.MEDIA_ERR_NETWORK = MediaError.MEDIA_ERR_NETWORK || 2; -MediaError.MEDIA_ERR_DECODE = MediaError.MEDIA_ERR_DECODE || 3; -MediaError.MEDIA_ERR_NONE_SUPPORTED = MediaError.MEDIA_ERR_NONE_SUPPORTED || 4; -// TODO: MediaError.MEDIA_ERR_NONE_SUPPORTED is legacy, the W3 spec now defines it as below. +_MediaError.MEDIA_ERR_NONE_ACTIVE = _MediaError.MEDIA_ERR_NONE_ACTIVE || 0; +_MediaError.MEDIA_ERR_ABORTED = _MediaError.MEDIA_ERR_ABORTED || 1; +_MediaError.MEDIA_ERR_NETWORK = _MediaError.MEDIA_ERR_NETWORK || 2; +_MediaError.MEDIA_ERR_DECODE = _MediaError.MEDIA_ERR_DECODE || 3; +_MediaError.MEDIA_ERR_NONE_SUPPORTED = _MediaError.MEDIA_ERR_NONE_SUPPORTED || 4; +// TODO: MediaError.MEDIA_ERR_NONE_SUPPORTED is legacy, the W3 spec now defines it as below. // as defined by http://dev.w3.org/html5/spec-author-view/video.html#error-codes -MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED = MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED || 4; +_MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED = _MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED || 4; -module.exports = MediaError; +module.exports = _MediaError; }); // file: lib/common/plugin/MediaFile.js define("cordova/plugin/MediaFile", function(require, exports, module) { + var utils = require('cordova/utils'), exec = require('cordova/exec'), File = require('cordova/plugin/File'), @@ -3338,6 +3535,7 @@ module.exports = MediaFile; // file: lib/common/plugin/MediaFileData.js define("cordova/plugin/MediaFileData", function(require, exports, module) { + /** * MediaFileData encapsulates format information of a media file. * @@ -3356,10 +3554,12 @@ var MediaFileData = function(codecs, bitrate, height, width, duration){ }; module.exports = MediaFileData; + }); // file: lib/common/plugin/Metadata.js define("cordova/plugin/Metadata", function(require, exports, module) { + /** * Information about the state of the file or directory * @@ -3370,10 +3570,12 @@ var Metadata = function(time) { }; module.exports = Metadata; + }); // file: lib/common/plugin/Position.js define("cordova/plugin/Position", function(require, exports, module) { + var Coordinates = require('cordova/plugin/Coordinates'); var Position = function(coords, timestamp) { @@ -3391,6 +3593,7 @@ module.exports = Position; // file: lib/common/plugin/PositionError.js define("cordova/plugin/PositionError", function(require, exports, module) { + /** * Position error object * @@ -3408,10 +3611,12 @@ PositionError.POSITION_UNAVAILABLE = 2; PositionError.TIMEOUT = 3; module.exports = PositionError; + }); // file: lib/common/plugin/ProgressEvent.js define("cordova/plugin/ProgressEvent", function(require, exports, module) { + // If ProgressEvent exists in global context, use it already, otherwise use our own polyfill // Feature test: See if we can instantiate a native ProgressEvent; // if so, use that approach, @@ -3458,10 +3663,12 @@ var ProgressEvent = (function() { })(); module.exports = ProgressEvent; + }); // file: lib/common/plugin/accelerometer.js define("cordova/plugin/accelerometer", function(require, exports, module) { + /** * This class provides access to device accelerometer data. * @constructor @@ -3523,7 +3730,7 @@ function removeListeners(l) { var accelerometer = { /** - * Asynchronously aquires the current acceleration. + * Asynchronously acquires the current acceleration. * * @param {Function} successCallback The function to call when the acceleration data is available * @param {Function} errorCallback The function to call when there is an error getting the acceleration data. (OPTIONAL) @@ -3554,7 +3761,7 @@ var accelerometer = { }, /** - * Asynchronously aquires the acceleration repeatedly at a given interval. + * Asynchronously acquires the acceleration repeatedly at a given interval. * * @param {Function} successCallback The function to call each time the acceleration data is available * @param {Function} errorCallback The function to call when there is an error getting the acceleration data. (OPTIONAL) @@ -3622,6 +3829,7 @@ module.exports = accelerometer; // file: lib/android/plugin/android/app.js define("cordova/plugin/android/app", function(require, exports, module) { + var exec = require('cordova/exec'); module.exports = { @@ -3693,92 +3901,12 @@ module.exports = { return exec(null, null, "App", "exitApp", []); } }; -}); - -// file: lib/android/plugin/android/callback.js -define("cordova/plugin/android/callback", function(require, exports, module) { -var port = null, - token = null, - xmlhttp; - -function startXhr() { - // cordova/exec depends on this module, so we can't require cordova/exec on the module level. - var exec = require('cordova/exec'), - xmlhttp = new XMLHttpRequest(); - - // Callback function when XMLHttpRequest is ready - xmlhttp.onreadystatechange=function(){ - if (!xmlhttp) { - return; - } - if (xmlhttp.readyState === 4){ - // If callback has JavaScript statement to execute - if (xmlhttp.status === 200) { - - // Need to url decode the response - var msg = decodeURIComponent(xmlhttp.responseText); - setTimeout(function() { - try { - var t = eval(msg); - } - catch (e) { - // If we're getting an error here, seeing the message will help in debugging - console.log("JSCallback: Message from Server: " + msg); - console.log("JSCallback Error: "+e); - } - }, 1); - setTimeout(startXhr, 1); - } - - // If callback ping (used to keep XHR request from timing out) - else if (xmlhttp.status === 404) { - setTimeout(startXhr, 10); - } - - // 0 == Page is unloading. - // 400 == Bad request. - // 403 == invalid token. - // 503 == server stopped. - else { - console.log("JSCallback Error: Request failed with status " + xmlhttp.status); - exec.setNativeToJsBridgeMode(exec.nativeToJsModes.POLLING); - } - } - }; - - if (port === null) { - port = prompt("getPort", "gap_callbackServer:"); - } - if (token === null) { - token = prompt("getToken", "gap_callbackServer:"); - } - xmlhttp.open("GET", "http://127.0.0.1:"+port+"/"+token , true); - xmlhttp.send(); -} - -module.exports = { - start: function() { - startXhr(); - }, - - stop: function() { - if (xmlhttp) { - var tmp = xmlhttp; - xmlhttp = null; - tmp.abort(); - } - }, - - isAvailable: function() { - return ("true" != prompt("usePolling", "gap_callbackServer:")); - } -}; - }); // file: lib/android/plugin/android/device.js define("cordova/plugin/android/device", function(require, exports, module) { + var channel = require('cordova/channel'), utils = require('cordova/utils'), exec = require('cordova/exec'), @@ -3800,7 +3928,7 @@ module.exports = { * DEPRECATED * This is only for Android. * - * This resets the back button to the default behaviour + * This resets the back button to the default behavior */ resetBackButton:function() { console.log("Device.resetBackButton() is deprecated. Use App.overrideBackbutton(false)."); @@ -3821,8 +3949,28 @@ module.exports = { }); +// file: lib/android/plugin/android/nativeapiprovider.js +define("cordova/plugin/android/nativeapiprovider", function(require, exports, module) { + +var nativeApi = this._cordovaNative || require('cordova/plugin/android/promptbasednativeapi'); +var currentApi = nativeApi; + +module.exports = { + get: function() { return currentApi; }, + setPreferPrompt: function(value) { + currentApi = value ? require('cordova/plugin/android/promptbasednativeapi') : nativeApi; + }, + // Used only by tests. + set: function(value) { + currentApi = value; + } +}; + +}); + // file: lib/android/plugin/android/notification.js define("cordova/plugin/android/notification", function(require, exports, module) { + var exec = require('cordova/exec'); /** @@ -3876,56 +4024,29 @@ module.exports = { exec(null, null, 'Notification', 'progressValue', [ value ]); } }; -}); - -// file: lib/android/plugin/android/polling.js -define("cordova/plugin/android/polling", function(require, exports, module) { -var cordova = require('cordova'), - POLL_INTERVAL = 50, - enabled = false; -function pollOnce() { - var msg = prompt("", "gap_poll:"); - if (msg) { - try { - eval(""+msg); - } - catch (e) { - console.log("JSCallbackPolling: Message from Server: " + msg); - console.log("JSCallbackPolling Error: "+e); - } - return true; - } - return false; -} +}); -function doPoll() { - if (!enabled) { - return; - } - var nextDelay = POLL_INTERVAL; - if (pollOnce()) { - nextDelay = 0; - } - setTimeout(doPoll, nextDelay); -} +// file: lib/android/plugin/android/promptbasednativeapi.js +define("cordova/plugin/android/promptbasednativeapi", function(require, exports, module) { module.exports = { - start: function() { - enabled = true; - setTimeout(doPoll, 1); + exec: function(service, action, callbackId, argsJson) { + return prompt(argsJson, 'gap:'+JSON.stringify([service, action, callbackId])); }, - stop: function() { - enabled = false; + setNativeToJsBridgeMode: function(value) { + prompt(value, 'gap_bridge_mode:'); }, - pollOnce: pollOnce + retrieveJsMessages: function() { + return prompt('', 'gap_poll:'); + } }; - }); // file: lib/android/plugin/android/storage.js define("cordova/plugin/android/storage", function(require, exports, module) { + var utils = require('cordova/utils'), exec = require('cordova/exec'), channel = require('cordova/channel'); @@ -4308,6 +4429,7 @@ module.exports = { // file: lib/common/plugin/battery.js define("cordova/plugin/battery", function(require, exports, module) { + /** * This class contains information about the current battery status. * @constructor @@ -4325,34 +4447,25 @@ var Battery = function() { this._level = null; this._isPlugged = null; // Create new event handlers on the window (returns a channel instance) - var subscriptionEvents = { - onSubscribe:this.onSubscribe, - onUnsubscribe:this.onUnsubscribe - }; this.channels = { - batterystatus:cordova.addWindowEventHandler("batterystatus", subscriptionEvents), - batterylow:cordova.addWindowEventHandler("batterylow", subscriptionEvents), - batterycritical:cordova.addWindowEventHandler("batterycritical", subscriptionEvents) + batterystatus:cordova.addWindowEventHandler("batterystatus"), + batterylow:cordova.addWindowEventHandler("batterylow"), + batterycritical:cordova.addWindowEventHandler("batterycritical") }; + for (var key in this.channels) { + this.channels[key].onHasSubscribersChange = Battery.onHasSubscribersChange; + } }; /** * Event handlers for when callbacks get registered for the battery. * Keep track of how many handlers we have so we can start and stop the native battery listener * appropriately (and hopefully save on battery life!). */ -Battery.prototype.onSubscribe = function() { - var me = battery; +Battery.onHasSubscribersChange = function() { // If we just registered the first handler, make sure native listener is started. - if (handlers() === 1) { - exec(me._status, me._error, "Battery", "start", []); - } -}; - -Battery.prototype.onUnsubscribe = function() { - var me = battery; - - // If we just unregistered the last handler, make sure native listener is stopped. - if (handlers() === 0) { + if (this.numHandlers === 1 && handlers() === 1) { + exec(battery._status, battery._error, "Battery", "start", []); + } else if (handlers() === 0) { exec(null, null, "Battery", "stop", []); } }; @@ -4395,10 +4508,12 @@ Battery.prototype._error = function(e) { var battery = new Battery(); module.exports = battery; + }); // file: lib/common/plugin/capture.js define("cordova/plugin/capture", function(require, exports, module) { + var exec = require('cordova/exec'), MediaFile = require('cordova/plugin/MediaFile'); @@ -4476,6 +4591,7 @@ module.exports = new Capture(); // file: lib/common/plugin/compass.js define("cordova/plugin/compass", function(require, exports, module) { + var exec = require('cordova/exec'), utils = require('cordova/utils'), CompassHeading = require('cordova/plugin/CompassHeading'), @@ -4577,10 +4693,12 @@ var exec = require('cordova/exec'), }; module.exports = compass; + }); // file: lib/common/plugin/console-via-logger.js define("cordova/plugin/console-via-logger", function(require, exports, module) { + //------------------------------------------------------------------------------ var logger = require("cordova/plugin/logger"); @@ -4729,7 +4847,7 @@ console.table = function(data, columns) { //------------------------------------------------------------------------------ // return a new function that calls both functions passed as args //------------------------------------------------------------------------------ -function wrapperedOrigCall(orgFunc, newFunc) { +function wrappedOrigCall(orgFunc, newFunc) { return function() { var args = [].slice.call(arguments); try { orgFunc.apply(WinConsole, args); } catch (e) {} @@ -4744,7 +4862,7 @@ function wrapperedOrigCall(orgFunc, newFunc) { //------------------------------------------------------------------------------ for (var key in console) { if (typeof WinConsole[key] == "function") { - console[key] = wrapperedOrigCall(WinConsole[key], console[key]); + console[key] = wrappedOrigCall(WinConsole[key], console[key]); } } @@ -4752,6 +4870,7 @@ for (var key in console) { // file: lib/common/plugin/contacts.js define("cordova/plugin/contacts", function(require, exports, module) { + var exec = require('cordova/exec'), ContactError = require('cordova/plugin/ContactError'), utils = require('cordova/utils'), @@ -4815,6 +4934,7 @@ module.exports = contacts; // file: lib/common/plugin/device.js define("cordova/plugin/device", function(require, exports, module) { + var channel = require('cordova/channel'), utils = require('cordova/utils'), exec = require('cordova/exec'); @@ -4837,7 +4957,7 @@ function Device() { var me = this; - channel.onCordovaReady.subscribeOnce(function() { + channel.onCordovaReady.subscribe(function() { me.getInfo(function(info) { me.available = true; me.platform = info.platform; @@ -4883,10 +5003,11 @@ module.exports = new Device(); // file: lib/common/plugin/echo.js define("cordova/plugin/echo", function(require, exports, module) { + var exec = require('cordova/exec'); /** - * Sends the given message through exec() to the Echo plugink, which sends it back to the successCallback. + * 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. @@ -4902,6 +5023,7 @@ module.exports = function(successCallback, errorCallback, message, forceAsync) { // file: lib/common/plugin/geolocation.js define("cordova/plugin/geolocation", function(require, exports, module) { + var utils = require('cordova/utils'), exec = require('cordova/exec'), PositionError = require('cordova/plugin/PositionError'), @@ -4952,7 +5074,7 @@ function createTimeout(errorCallback, timeout) { var geolocation = { lastPosition:null, // reference to last known (cached) position returned /** - * Asynchronously aquires the current position. + * Asynchronously acquires the current position. * * @param {Function} successCallback The function to call when the position data is available * @param {Function} errorCallback The function to call when there is an error getting the heading position. (OPTIONAL) @@ -4966,11 +5088,11 @@ var geolocation = { // Timer var that will fire an error callback if no position is retrieved from native // before the "timeout" param provided expires - var timeoutTimer = null; + var timeoutTimer = {timer:null}; var win = function(p) { - clearTimeout(timeoutTimer); - if (!timeoutTimer) { + clearTimeout(timeoutTimer.timer); + if (!(timeoutTimer.timer)) { // Timeout already happened, or native fired error callback for // this geo request. // Don't continue with success callback. @@ -4992,8 +5114,8 @@ var geolocation = { successCallback(pos); }; var fail = function(e) { - clearTimeout(timeoutTimer); - timeoutTimer = null; + clearTimeout(timeoutTimer.timer); + timeoutTimer.timer = null; var err = new PositionError(e.code, e.message); if (errorCallback) { errorCallback(err); @@ -5016,12 +5138,12 @@ var geolocation = { // If the timeout value was not set to Infinity (default), then // set up a timeout function that will fire the error callback // if no successful position was retrieved before timeout expired. - timeoutTimer = createTimeout(fail, options.timeout); + timeoutTimer.timer = createTimeout(fail, options.timeout); } else { // This is here so the check in the win function doesn't mess stuff up // may seem weird but this guarantees timeoutTimer is // always truthy before we call into native - timeoutTimer = true; + timeoutTimer.timer = true; } exec(win, fail, "Geolocation", "getLocation", [options.enableHighAccuracy, options.maximumAge]); } @@ -5048,7 +5170,7 @@ var geolocation = { timers[id] = geolocation.getCurrentPosition(successCallback, errorCallback, options); var fail = function(e) { - clearTimeout(timers[id]); + clearTimeout(timers[id].timer); var err = new PositionError(e.code, e.message); if (errorCallback) { errorCallback(err); @@ -5056,9 +5178,9 @@ var geolocation = { }; var win = function(p) { - clearTimeout(timers[id]); + clearTimeout(timers[id].timer); if (options.timeout !== Infinity) { - timers[id] = createTimeout(fail, options.timeout); + timers[id].timer = createTimeout(fail, options.timeout); } var pos = new Position( { @@ -5087,8 +5209,8 @@ var geolocation = { */ clearWatch:function(id) { if (id && timers[id] !== undefined) { - clearTimeout(timers[id]); - delete timers[id]; + clearTimeout(timers[id].timer); + timers[id].timer = false; exec(null, null, "Geolocation", "clearWatch", [id]); } } @@ -5098,8 +5220,548 @@ module.exports = geolocation; }); +// file: lib/common/plugin/globalization.js +define("cordova/plugin/globalization", function(require, exports, module) { + +var exec = require('cordova/exec'), + GlobalizationError = require('cordova/plugin/GlobalizationError'); + +var globalization = { + +/** +* Returns the string identifier for the client's current language. +* It returns the language identifier string to the successCB callback with a +* properties object as a parameter. If there is an error getting the language, +* then the errorCB callback is invoked. +* +* @param {Function} successCB +* @param {Function} errorCB +* +* @return Object.value {String}: The language identifier +* +* @error GlobalizationError.UNKNOWN_ERROR +* +* Example +* globalization.getPreferredLanguage(function (language) {alert('language:' + language.value + '\n');}, +* function () {}); +*/ +getPreferredLanguage:function(successCB, failureCB) { + // successCallback required + if (typeof successCB != "function") { + console.log("Globalization.getPreferredLanguage Error: successCB is not a function"); + return; + } + + // errorCallback required + if (typeof failureCB != "function") { + console.log("Globalization.getPreferredLanguage Error: failureCB is not a function"); + return; + } + + exec(successCB, failureCB, "Globalization","getPreferredLanguage", []); +}, + +/** +* Returns the string identifier for the client's current locale setting. +* It returns the locale identifier string to the successCB callback with a +* properties object as a parameter. If there is an error getting the locale, +* then the errorCB callback is invoked. +* +* @param {Function} successCB +* @param {Function} errorCB +* +* @return Object.value {String}: The locale identifier +* +* @error GlobalizationError.UNKNOWN_ERROR +* +* Example +* globalization.getLocaleName(function (locale) {alert('locale:' + locale.value + '\n');}, +* function () {}); +*/ +getLocaleName:function(successCB, failureCB) { + // successCallback required + if (typeof successCB != "function") { + console.log("Globalization.getLocaleName Error: successCB is not a function"); + return; + } + + // errorCallback required + if (typeof failureCB != "function") { + console.log("Globalization.getLocaleName Error: failureCB is not a function"); + return; + } + exec(successCB, failureCB, "Globalization","getLocaleName", []); +}, + + +/** +* Returns a date formatted as a string according to the client's user preferences and +* calendar using the time zone of the client. It returns the formatted date string to the +* successCB callback with a properties object as a parameter. If there is an error +* formatting the date, then the errorCB callback is invoked. +* +* The defaults are: formatLenght="short" and selector="date and time" +* +* @param {Date} date +* @param {Function} successCB +* @param {Function} errorCB +* @param {Object} options {optional} +* formatLength {String}: 'short', 'medium', 'long', or 'full' +* selector {String}: 'date', 'time', or 'date and time' +* +* @return Object.value {String}: The localized date string +* +* @error GlobalizationError.FORMATTING_ERROR +* +* Example +* globalization.dateToString(new Date(), +* function (date) {alert('date:' + date.value + '\n');}, +* function (errorCode) {alert(errorCode);}, +* {formatLength:'short'}); +*/ +dateToString:function(date, successCB, failureCB, options) { + // successCallback required + if (typeof successCB != "function") { + console.log("Globalization.dateToString Error: successCB is not a function"); + return; + } + + // errorCallback required + if (typeof failureCB != "function") { + console.log("Globalization.dateToString Error: failureCB is not a function"); + return; + } + + + if (date instanceof Date){ + var dateValue; + dateValue = date.valueOf(); + exec(successCB, failureCB, "Globalization", "dateToString", [{"date": dateValue, "options": options}]); + } + else { + console.log("Globalization.dateToString Error: date is not a Date object"); + } +}, + + +/** +* Parses a date formatted as a string according to the client's user +* preferences and calendar using the time zone of the client and returns +* the corresponding date object. It returns the date to the successCB +* callback with a properties object as a parameter. If there is an error +* parsing the date string, then the errorCB callback is invoked. +* +* The defaults are: formatLength="short" and selector="date and time" +* +* @param {String} dateString +* @param {Function} successCB +* @param {Function} errorCB +* @param {Object} options {optional} +* formatLength {String}: 'short', 'medium', 'long', or 'full' +* selector {String}: 'date', 'time', or 'date and time' +* +* @return Object.year {Number}: The four digit year +* Object.month {Number}: The month from (0 - 11) +* Object.day {Number}: The day from (1 - 31) +* Object.hour {Number}: The hour from (0 - 23) +* Object.minute {Number}: The minute from (0 - 59) +* Object.second {Number}: The second from (0 - 59) +* Object.millisecond {Number}: The milliseconds (from 0 - 999), +* not available on all platforms +* +* @error GlobalizationError.PARSING_ERROR +* +* Example +* globalization.stringToDate('4/11/2011', +* function (date) { alert('Month:' + date.month + '\n' + +* 'Day:' + date.day + '\n' + +* 'Year:' + date.year + '\n');}, +* function (errorCode) {alert(errorCode);}, +* {selector:'date'}); +*/ +stringToDate:function(dateString, successCB, failureCB, options) { + // successCallback required + if (typeof successCB != "function") { + console.log("Globalization.stringToDate Error: successCB is not a function"); + return; + } + + // errorCallback required + if (typeof failureCB != "function") { + console.log("Globalization.stringToDate Error: failureCB is not a function"); + return; + } + if (typeof dateString == "string"){ + exec(successCB, failureCB, "Globalization", "stringToDate", [{"dateString": dateString, "options": options}]); + } + else { + console.log("Globalization.stringToDate Error: dateString is not a string"); + } +}, + + +/** +* Returns a pattern string for formatting and parsing dates according to the client's +* user preferences. It returns the pattern to the successCB callback with a +* properties object as a parameter. If there is an error obtaining the pattern, +* then the errorCB callback is invoked. +* +* The defaults are: formatLength="short" and selector="date and time" +* +* @param {Function} successCB +* @param {Function} errorCB +* @param {Object} options {optional} +* formatLength {String}: 'short', 'medium', 'long', or 'full' +* selector {String}: 'date', 'time', or 'date and time' +* +* @return Object.pattern {String}: The date and time pattern for formatting and parsing dates. +* The patterns follow Unicode Technical Standard #35 +* http://unicode.org/reports/tr35/tr35-4.html +* Object.timezone {String}: The abbreviated name of the time zone on the client +* Object.utc_offset {Number}: The current difference in seconds between the client's +* time zone and coordinated universal time. +* Object.dst_offset {Number}: The current daylight saving time offset in seconds +* between the client's non-daylight saving's time zone +* and the client's daylight saving's time zone. +* +* @error GlobalizationError.PATTERN_ERROR +* +* Example +* globalization.getDatePattern( +* function (date) {alert('pattern:' + date.pattern + '\n');}, +* function () {}, +* {formatLength:'short'}); +*/ +getDatePattern:function(successCB, failureCB, options) { + // successCallback required + if (typeof successCB != "function") { + console.log("Globalization.getDatePattern Error: successCB is not a function"); + return; + } + + // errorCallback required + if (typeof failureCB != "function") { + console.log("Globalization.getDatePattern Error: failureCB is not a function"); + return; + } + + exec(successCB, failureCB, "Globalization", "getDatePattern", [{"options": options}]); +}, + + +/** +* Returns an array of either the names of the months or days of the week +* according to the client's user preferences and calendar. It returns the array of names to the +* successCB callback with a properties object as a parameter. If there is an error obtaining the +* names, then the errorCB callback is invoked. +* +* The defaults are: type="wide" and item="months" +* +* @param {Function} successCB +* @param {Function} errorCB +* @param {Object} options {optional} +* type {String}: 'narrow' or 'wide' +* item {String}: 'months', or 'days' +* +* @return Object.value {Array{String}}: The array of names starting from either +* the first month in the year or the +* first day of the week. +* @error GlobalizationError.UNKNOWN_ERROR +* +* Example +* globalization.getDateNames(function (names) { +* for(var i = 0; i < names.value.length; i++) { +* alert('Month:' + names.value[i] + '\n');}}, +* function () {}); +*/ +getDateNames:function(successCB, failureCB, options) { + // successCallback required + if (typeof successCB != "function") { + console.log("Globalization.getDateNames Error: successCB is not a function"); + return; + } + + // errorCallback required + if (typeof failureCB != "function") { + console.log("Globalization.getDateNames Error: failureCB is not a function"); + return; + } + exec(successCB, failureCB, "Globalization", "getDateNames", [{"options": options}]); +}, + +/** +* Returns whether daylight savings time is in effect for a given date using the client's +* time zone and calendar. It returns whether or not daylight savings time is in effect +* to the successCB callback with a properties object as a parameter. If there is an error +* reading the date, then the errorCB callback is invoked. +* +* @param {Date} date +* @param {Function} successCB +* @param {Function} errorCB +* +* @return Object.dst {Boolean}: The value "true" indicates that daylight savings time is +* in effect for the given date and "false" indicate that it is not. +* +* @error GlobalizationError.UNKNOWN_ERROR +* +* Example +* globalization.isDayLightSavingsTime(new Date(), +* function (date) {alert('dst:' + date.dst + '\n');} +* function () {}); +*/ +isDayLightSavingsTime:function(date, successCB, failureCB) { + // successCallback required + if (typeof successCB != "function") { + console.log("Globalization.isDayLightSavingsTime Error: successCB is not a function"); + return; + } + + // errorCallback required + if (typeof failureCB != "function") { + console.log("Globalization.isDayLightSavingsTime Error: failureCB is not a function"); + return; + } + + + if (date instanceof Date){ + var dateValue; + dateValue = date.valueOf(); + exec(successCB, failureCB, "Globalization", "isDayLightSavingsTime", [{"date": dateValue}]); + } + else { + console.log("Globalization.isDayLightSavingsTime Error: date is not a Date object"); + } + +}, + +/** +* Returns the first day of the week according to the client's user preferences and calendar. +* The days of the week are numbered starting from 1 where 1 is considered to be Sunday. +* It returns the day to the successCB callback with a properties object as a parameter. +* If there is an error obtaining the pattern, then the errorCB callback is invoked. +* +* @param {Function} successCB +* @param {Function} errorCB +* +* @return Object.value {Number}: The number of the first day of the week. +* +* @error GlobalizationError.UNKNOWN_ERROR +* +* Example +* globalization.getFirstDayOfWeek(function (day) +* { alert('Day:' + day.value + '\n');}, +* function () {}); +*/ +getFirstDayOfWeek:function(successCB, failureCB) { + // successCallback required + if (typeof successCB != "function") { + console.log("Globalization.getFirstDayOfWeek Error: successCB is not a function"); + return; + } + + // errorCallback required + if (typeof failureCB != "function") { + console.log("Globalization.getFirstDayOfWeek Error: failureCB is not a function"); + return; + } + + exec(successCB, failureCB, "Globalization", "getFirstDayOfWeek", []); +}, + + +/** +* Returns a number formatted as a string according to the client's user preferences. +* It returns the formatted number string to the successCB callback with a properties object as a +* parameter. If there is an error formatting the number, then the errorCB callback is invoked. +* +* The defaults are: type="decimal" +* +* @param {Number} number +* @param {Function} successCB +* @param {Function} errorCB +* @param {Object} options {optional} +* type {String}: 'decimal', "percent", or 'currency' +* +* @return Object.value {String}: The formatted number string. +* +* @error GlobalizationError.FORMATTING_ERROR +* +* Example +* globalization.numberToString(3.25, +* function (number) {alert('number:' + number.value + '\n');}, +* function () {}, +* {type:'decimal'}); +*/ +numberToString:function(number, successCB, failureCB, options) { + // successCallback required + if (typeof successCB != "function") { + console.log("Globalization.numberToString Error: successCB is not a function"); + return; + } + + // errorCallback required + if (typeof failureCB != "function") { + console.log("Globalization.numberToString Error: failureCB is not a function"); + return; + } + + if(typeof number == "number") { + exec(successCB, failureCB, "Globalization", "numberToString", [{"number": number, "options": options}]); + } + else { + console.log("Globalization.numberToString Error: number is not a number"); + } +}, + +/** +* Parses a number formatted as a string according to the client's user preferences and +* returns the corresponding number. It returns the number to the successCB callback with a +* properties object as a parameter. If there is an error parsing the number string, then +* the errorCB callback is invoked. +* +* The defaults are: type="decimal" +* +* @param {String} numberString +* @param {Function} successCB +* @param {Function} errorCB +* @param {Object} options {optional} +* type {String}: 'decimal', "percent", or 'currency' +* +* @return Object.value {Number}: The parsed number. +* +* @error GlobalizationError.PARSING_ERROR +* +* Example +* globalization.stringToNumber('1234.56', +* function (number) {alert('Number:' + number.value + '\n');}, +* function () { alert('Error parsing number');}); +*/ +stringToNumber:function(numberString, successCB, failureCB, options) { + // successCallback required + if (typeof successCB != "function") { + console.log("Globalization.stringToNumber Error: successCB is not a function"); + return; + } + + // errorCallback required + if (typeof failureCB != "function") { + console.log("Globalization.stringToNumber Error: failureCB is not a function"); + return; + } + + if(typeof numberString == "string") { + exec(successCB, failureCB, "Globalization", "stringToNumber", [{"numberString": numberString, "options": options}]); + } + else { + console.log("Globalization.stringToNumber Error: numberString is not a string"); + } +}, + +/** +* Returns a pattern string for formatting and parsing numbers according to the client's user +* preferences. It returns the pattern to the successCB callback with a properties object as a +* parameter. If there is an error obtaining the pattern, then the errorCB callback is invoked. +* +* The defaults are: type="decimal" +* +* @param {Function} successCB +* @param {Function} errorCB +* @param {Object} options {optional} +* type {String}: 'decimal', "percent", or 'currency' +* +* @return Object.pattern {String}: The number pattern for formatting and parsing numbers. +* The patterns follow Unicode Technical Standard #35. +* http://unicode.org/reports/tr35/tr35-4.html +* Object.symbol {String}: The symbol to be used when formatting and parsing +* e.g., percent or currency symbol. +* Object.fraction {Number}: The number of fractional digits to use when parsing and +* formatting numbers. +* Object.rounding {Number}: The rounding increment to use when parsing and formatting. +* Object.positive {String}: The symbol to use for positive numbers when parsing and formatting. +* Object.negative: {String}: The symbol to use for negative numbers when parsing and formatting. +* Object.decimal: {String}: The decimal symbol to use for parsing and formatting. +* Object.grouping: {String}: The grouping symbol to use for parsing and formatting. +* +* @error GlobalizationError.PATTERN_ERROR +* +* Example +* globalization.getNumberPattern( +* function (pattern) {alert('Pattern:' + pattern.pattern + '\n');}, +* function () {}); +*/ +getNumberPattern:function(successCB, failureCB, options) { + // successCallback required + if (typeof successCB != "function") { + console.log("Globalization.getNumberPattern Error: successCB is not a function"); + return; + } + + // errorCallback required + if (typeof failureCB != "function") { + console.log("Globalization.getNumberPattern Error: failureCB is not a function"); + return; + } + + exec(successCB, failureCB, "Globalization", "getNumberPattern", [{"options": options}]); +}, + +/** +* Returns a pattern string for formatting and parsing currency values according to the client's +* user preferences and ISO 4217 currency code. It returns the pattern to the successCB callback with a +* properties object as a parameter. If there is an error obtaining the pattern, then the errorCB +* callback is invoked. +* +* @param {String} currencyCode +* @param {Function} successCB +* @param {Function} errorCB +* +* @return Object.pattern {String}: The currency pattern for formatting and parsing currency values. +* The patterns follow Unicode Technical Standard #35 +* http://unicode.org/reports/tr35/tr35-4.html +* Object.code {String}: The ISO 4217 currency code for the pattern. +* Object.fraction {Number}: The number of fractional digits to use when parsing and +* formatting currency. +* Object.rounding {Number}: The rounding increment to use when parsing and formatting. +* Object.decimal: {String}: The decimal symbol to use for parsing and formatting. +* Object.grouping: {String}: The grouping symbol to use for parsing and formatting. +* +* @error GlobalizationError.FORMATTING_ERROR +* +* Example +* globalization.getCurrencyPattern('EUR', +* function (currency) {alert('Pattern:' + currency.pattern + '\n');} +* function () {}); +*/ +getCurrencyPattern:function(currencyCode, successCB, failureCB) { + // successCallback required + if (typeof successCB != "function") { + console.log("Globalization.getCurrencyPattern Error: successCB is not a function"); + return; + } + + // errorCallback required + if (typeof failureCB != "function") { + console.log("Globalization.getCurrencyPattern Error: failureCB is not a function"); + return; + } + + if(typeof currencyCode == "string") { + exec(successCB, failureCB, "Globalization", "getCurrencyPattern", [{"currencyCode": currencyCode}]); + } + else { + console.log("Globalization.getCurrencyPattern Error: currencyCode is not a currency code"); + } +} + +}; + +module.exports = globalization; + +}); + // file: lib/common/plugin/logger.js define("cordova/plugin/logger", function(require, exports, module) { + //------------------------------------------------------------------------------ // The logger module exports the following properties/functions: // @@ -5327,9 +5989,20 @@ document.addEventListener("deviceready", logger.__onDeviceReady, false); // file: lib/common/plugin/network.js define("cordova/plugin/network", function(require, exports, module) { + var exec = require('cordova/exec'), cordova = require('cordova'), - channel = require('cordova/channel'); + channel = require('cordova/channel'), + utils = require('cordova/utils'); + +// Link the onLine property with the Cordova-supplied network info. +// This works because we clobber the naviagtor object with our own +// object in bootstrap.js. +if (typeof navigator != 'undefined') { + utils.defineGetter(navigator, 'onLine', function() { + return this.connection.type != 'none'; + }); +} var NetworkConnection = function () { this.type = null; @@ -5339,7 +6012,7 @@ var NetworkConnection = function () { var me = this; - channel.onCordovaReady.subscribeOnce(function() { + channel.onCordovaReady.subscribe(function() { me.getInfo(function (info) { me.type = info; if (info === "none") { @@ -5387,10 +6060,12 @@ NetworkConnection.prototype.getInfo = function (successCallback, errorCallback) }; module.exports = new NetworkConnection(); + }); // file: lib/common/plugin/notification.js define("cordova/plugin/notification", function(require, exports, module) { + var exec = require('cordova/exec'); /** @@ -5447,10 +6122,12 @@ module.exports = { exec(null, null, "Notification", "beep", [count]); } }; + }); // file: lib/common/plugin/requestFileSystem.js define("cordova/plugin/requestFileSystem", function(require, exports, module) { + var FileError = require('cordova/plugin/FileError'), FileSystem = require('cordova/plugin/FileSystem'), exec = require('cordova/exec'); @@ -5491,10 +6168,12 @@ var requestFileSystem = function(type, size, successCallback, errorCallback) { }; module.exports = requestFileSystem; + }); // file: lib/common/plugin/resolveLocalFileSystemURI.js define("cordova/plugin/resolveLocalFileSystemURI", function(require, exports, module) { + var DirectoryEntry = require('cordova/plugin/DirectoryEntry'), FileEntry = require('cordova/plugin/FileEntry'), FileError = require('cordova/plugin/FileError'), @@ -5548,6 +6227,7 @@ module.exports = function(uri, successCallback, errorCallback) { // file: lib/common/plugin/splashscreen.js define("cordova/plugin/splashscreen", function(require, exports, module) { + var exec = require('cordova/exec'); var splashscreen = { @@ -5560,13 +6240,26 @@ var splashscreen = { }; module.exports = splashscreen; + }); // file: lib/common/utils.js define("cordova/utils", function(require, exports, module) { + var utils = exports; /** + * Defines a property getter for obj[key]. + */ +utils.defineGetter = function(obj, key, func) { + if (Object.defineProperty) { + Object.defineProperty(obj, key, { get: func }); + } else { + obj.__defineGetter__(key, func); + } +}; + +/** * Returns an indication of whether the argument is an array or not */ utils.isArray = function(a) { @@ -5608,7 +6301,7 @@ utils.clone = function(obj) { }; /** - * Returns a wrappered version of the function + * Returns a wrapped version of the function */ utils.close = function(context, func, params) { if (typeof params == 'undefined') { @@ -5653,8 +6346,8 @@ utils.extend = (function() { * Alerts a message in any available way: alert or console.log. */ utils.alert = function(msg) { - if (alert) { - alert(msg); + if (window.alert) { + window.alert(msg); } else if (console && console.log) { console.log(msg); } @@ -5757,7 +6450,16 @@ function formatted(object, formatChar) { window.cordova = require('cordova'); // file: lib/scripts/bootstrap.js + (function (context) { + // 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. + if (typeof navigator != 'undefined') { + var CordovaNavigator = function () {}; + CordovaNavigator.prototype = navigator; + navigator = new CordovaNavigator(); + } + var channel = require("cordova/channel"), _self = { boot: function () { @@ -5770,7 +6472,7 @@ window.cordova = require('cordova'); platform = require('cordova/platform'); // Drop the common globals into the window object, but be nice and don't overwrite anything. - builder.build(base.objects).intoButDontClobber(window); + builder.build(base.objects).intoButDoNotClobber(window); // Drop the platform-specific globals into the window object // and clobber any existing object. @@ -5799,7 +6501,7 @@ window.cordova = require('cordova'); }; // boot up once native side is ready - channel.onNativeReady.subscribeOnce(_self.boot); + channel.onNativeReady.subscribe(_self.boot); // _nativeReady is global variable that the native side can set // to signify that the native code is ready. It is a global since diff --git a/www/cordova-independent.js b/www/cordova-independent.js index f56a8f0..05fd645 100644 --- a/www/cordova-independent.js +++ b/www/cordova-independent.js @@ -2,9 +2,9 @@ var scriptElement = document.createElement("script"); scriptElement.type = "text/javascript"; if (navigator.userAgent.match(/(iPhone|iPod|iPad)/)) { - scriptElement.src = 'cordova-ios-2.1.0.js'; + scriptElement.src = 'cordova-ios-2.2.0.js'; } else if (navigator.userAgent.match(/Android/)) { - scriptElement.src = 'cordova-android-2.1.0.js'; + scriptElement.src = 'cordova-android-2.2.0.js'; } else { alert("Unknown platform - userAgent is: " + navigator.userAgent); } diff --git a/www/cordova-ios-2.1.0.js b/www/cordova-ios-2.2.0.js index db81edf..b63d517 100755 --- a/www/cordova-ios-2.1.0.js +++ b/www/cordova-ios-2.2.0.js @@ -1,6 +1,6 @@ -// commit 143f5221a6251c9cbccdedc57005c61551b97f12 +// commit 02b91c5313ff37d74a58f71775170afd360f4a1f -// File generated at :: Wed Sep 12 2012 15:26:58 GMT-0700 (PDT) +// File generated at :: Wed Oct 31 2012 14:34:26 GMT-0700 (PDT) /* Licensed to the Apache Software Foundation (ASF) under one @@ -24,11 +24,16 @@ ;(function() { // file: lib/scripts/require.js + var require, define; (function () { var modules = {}; + // Stack of moduleIds currently being built. + var requireStack = []; + // Map of module ID -> index into requireStack of modules currently being built. + var inProgressModules = {}; function build(module) { var factory = module.factory; @@ -41,8 +46,21 @@ var require, 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].factory ? build(modules[id]) : modules[id].exports; + return modules[id].exports; }; define = function (id, factory) { @@ -67,8 +85,11 @@ if (typeof module === "object" && typeof require === "function") { module.exports.require = require; module.exports.define = define; } + // file: lib/cordova.js define("cordova", function(require, exports, module) { + + var channel = require('cordova/channel'); /** @@ -99,11 +120,7 @@ var documentEventHandlers = {}, document.addEventListener = function(evt, handler, capture) { var e = evt.toLowerCase(); if (typeof documentEventHandlers[e] != 'undefined') { - if (evt === 'deviceready') { - documentEventHandlers[e].subscribeOnce(handler); - } else { - documentEventHandlers[e].subscribe(handler); - } + documentEventHandlers[e].subscribe(handler); } else { m_document_addEventListener.call(document, evt, handler, capture); } @@ -120,7 +137,7 @@ window.addEventListener = function(evt, handler, capture) { document.removeEventListener = function(evt, handler, capture) { var e = evt.toLowerCase(); - // If unsubcribing from an event that is handled by a plugin + // If unsubscribing from an event that is handled by a plugin if (typeof documentEventHandlers[e] != "undefined") { documentEventHandlers[e].unsubscribe(handler); } else { @@ -130,7 +147,7 @@ document.removeEventListener = function(evt, handler, capture) { window.removeEventListener = function(evt, handler, capture) { var e = evt.toLowerCase(); - // If unsubcribing from an event that is handled by a plugin + // If unsubscribing from an event that is handled by a plugin if (typeof windowEventHandlers[e] != "undefined") { windowEventHandlers[e].unsubscribe(handler); } else { @@ -163,11 +180,14 @@ var cordova = { /** * Methods to add/remove your own addEventListener hijacking on document + window. */ - addWindowEventHandler:function(event, opts) { - return (windowEventHandlers[event] = channel.create(event, opts)); + addWindowEventHandler:function(event) { + return (windowEventHandlers[event] = channel.create(event)); + }, + addStickyDocumentEventHandler:function(event) { + return (documentEventHandlers[event] = channel.createSticky(event)); }, - addDocumentEventHandler:function(event, opts) { - return (documentEventHandlers[event] = channel.create(event, opts)); + addDocumentEventHandler:function(event) { + return (documentEventHandlers[event] = channel.create(event)); }, removeWindowEventHandler:function(event) { delete windowEventHandlers[event]; @@ -176,7 +196,7 @@ var cordova = { delete documentEventHandlers[event]; }, /** - * Retreive original event handlers that were replaced by Cordova + * Retrieve original event handlers that were replaced by Cordova * * @return object */ @@ -186,7 +206,7 @@ var cordova = { }, /** * Method to fire event from native code - * bNoDetach is required for events which cause an exception which needs to be caught in 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); @@ -214,18 +234,12 @@ var cordova = { } }, - // TODO: iOS only - // This queue holds the currently executing command and all pending - // commands executed with cordova.exec(). - commandQueue:[], - // Indicates if we're currently in the middle of flushing the command - // queue on the native side. - commandQueueFlushing:false, - // END TODO /** * Plugin callback mechanism. */ - callbackId: 0, + // 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, @@ -242,57 +256,48 @@ var cordova = { /** * Called by native code when returning successful result from an action. - * - * @param callbackId - * @param args */ callbackSuccess: function(callbackId, args) { - if (cordova.callbacks[callbackId]) { - - // If result is to be sent to callback - if (args.status == cordova.callbackStatus.OK) { - try { - if (cordova.callbacks[callbackId].success) { - cordova.callbacks[callbackId].success(args.message); - } - } - catch (e) { - console.log("Error in success callback: "+callbackId+" = "+e); - } - } - - // Clear callback if not expecting any more results - if (!args.keepCallback) { - delete cordova.callbacks[callbackId]; - } + try { + cordova.callbackFromNative(callbackId, true, args.status, args.message, args.keepCallback); + } catch (e) { + console.log("Error in error callback: " + callbackId + " = "+e); } }, /** * Called by native code when returning error result from an action. - * - * @param callbackId - * @param args */ callbackError: function(callbackId, args) { - if (cordova.callbacks[callbackId]) { - try { - if (cordova.callbacks[callbackId].fail) { - cordova.callbacks[callbackId].fail(args.message); - } - } - catch (e) { - console.log("Error in error callback: "+callbackId+" = "+e); + // 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); + } + }, + + /** + * Called by native code when returning the result from an action. + */ + callbackFromNative: function(callbackId, success, status, message, keepCallback) { + var callback = cordova.callbacks[callbackId]; + if (callback) { + if (success && status == cordova.callbackStatus.OK) { + callback.success && callback.success(message); + } else if (!success) { + callback.fail && callback.fail(message); } // Clear callback if not expecting any more results - if (!args.keepCallback) { + if (!keepCallback) { delete cordova.callbacks[callbackId]; } } }, addConstructor: function(func) { - channel.onCordovaReady.subscribeOnce(function() { + channel.onCordovaReady.subscribe(function() { try { func(); } catch(e) { @@ -305,7 +310,7 @@ 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.addDocumentEventHandler('deviceready'); +channel.onDeviceReady = cordova.addStickyDocumentEventHandler('deviceready'); module.exports = cordova; @@ -313,6 +318,7 @@ module.exports = cordova; // file: lib/common/builder.js define("cordova/builder", function(require, exports, module) { + var utils = require('cordova/utils'); function each(objects, func, context) { @@ -323,6 +329,17 @@ function each(objects, func, context) { } } +function assignOrWrapInDeprecateGetter(obj, key, value, message) { + if (message) { + utils.defineGetter(obj, key, function() { + window.console && console.log(message); + return value; + }); + } else { + obj[key] = value; + } +} + function include(parent, objects, clobber, merge) { each(objects, function (obj, key) { try { @@ -331,20 +348,20 @@ function include(parent, objects, clobber, merge) { if (clobber) { // Clobber if it doesn't exist. if (typeof parent[key] === 'undefined') { - parent[key] = result; + 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 { - parent[key] = result; + assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated); } } result = parent[key]; } else { // Overwrite if not currently defined. if (typeof parent[key] == 'undefined') { - parent[key] = result; + assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated); } else if (merge && typeof obj.path !== 'undefined') { // If merging, merge parent onto result recursiveMerge(result, parent[key]); @@ -389,7 +406,7 @@ function recursiveMerge(target, src) { module.exports = { build: function (objects) { return { - intoButDontClobber: function (target) { + intoButDoNotClobber: function (target) { include(target, objects, false, false); }, intoAndClobber: function(target) { @@ -406,25 +423,29 @@ module.exports = { // file: lib/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. + * 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. - * onCordovaInfoReady Internal event fired when device properties are available. - * onCordovaConnectionReady Internal event fired when the connection property has been set. - * 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). + * 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. + * onCordovaInfoReady* Internal event fired when device properties are available. + * onCordovaConnectionReady* Internal event fired when the connection property has been set. + * 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. * * 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 @@ -446,49 +467,45 @@ var utils = require('cordova/utils'), * Channel * @constructor * @param type String the channel name - * @param opts Object options to pass into the channel, currently - * supports: - * onSubscribe: callback that fires when - * something subscribes to the Channel. Sets - * context to the Channel. - * onUnsubscribe: callback that fires when - * something unsubscribes to the Channel. Sets - * context to the Channel. */ -var Channel = function(type, opts) { +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; - this.fired = false; - this.enabled = true; - this.events = { - onSubscribe:null, - onUnsubscribe:null - }; - if (opts) { - if (opts.onSubscribe) this.events.onSubscribe = opts.onSubscribe; - if (opts.onUnsubscribe) this.events.onUnsubscribe = opts.onUnsubscribe; - } + // 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. + * have been fired. All channels must be sticky channels. */ - join: function (h, c) { - var i = c.length; - var len = i; - var f = function() { - if (!(--i)) h(); - }; + join: function(h, c) { + var len = c.length, + i = len, + f = function() { + if (!(--i)) h(); + }; for (var j=0; j<len; j++) { - !c[j].fired?c[j].subscribeOnce(f):i--; + if (c[j].state === 0) { + throw Error('Can only use join with sticky channels.'); + } + c[j].subscribe(f); } - if (!i) h(); + if (!len) h(); }, - create: function (type, opts) { - channel[type] = new Channel(type, opts); - return channel[type]; + create: function(type) { + return channel[type] = new Channel(type, false); + }, + createSticky: function(type) { + return channel[type] = new Channel(type, true); }, /** @@ -506,13 +523,7 @@ var Channel = function(type, opts) { */ waitForInitialization: function(feature) { if (feature) { - var c = null; - if (this[feature]) { - c = this[feature]; - } - else { - c = this.create(feature); - } + var c = channel[feature] || this.createSticky(feature); this.deviceReadyChannelsMap[feature] = c; this.deviceReadyChannelsArray.push(c); } @@ -532,7 +543,7 @@ var Channel = function(type, opts) { }; function forceFunction(f) { - if (f === null || f === undefined || typeof f != 'function') throw "Function required as first argument!"; + if (typeof f != 'function') throw "Function required as first argument!"; } /** @@ -542,67 +553,50 @@ function forceFunction(f) { * and a guid that can be used to stop subscribing to the channel. * Returns the guid. */ -Channel.prototype.subscribe = function(f, c, g) { +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; + var func = f, + guid = f.observer_guid; if (typeof c == "object") { func = utils.close(c, f); } - g = g || func.observer_guid || f.observer_guid; - if (!g) { + if (!guid) { // first time any channel has seen this subscriber - g = nextGuid++; + guid = '' + nextGuid++; } - func.observer_guid = g; - f.observer_guid = g; + func.observer_guid = guid; + f.observer_guid = guid; // Don't add the same handler more than once. - if (!this.handlers[g]) { - this.handlers[g] = func; + if (!this.handlers[guid]) { + this.handlers[guid] = func; this.numHandlers++; - if (this.events.onSubscribe) this.events.onSubscribe.call(this); - if (this.fired) func.apply(this, this.fireArgs); - } - return g; -}; - -/** - * Like subscribe but the function is only called once and then it - * auto-unsubscribes itself. - */ -Channel.prototype.subscribeOnce = function(f, c) { - // need a function to call - forceFunction(f); - - var g = null; - var _this = this; - if (this.fired) { - f.apply(c || null, this.fireArgs); - } else { - g = this.subscribe(function() { - _this.unsubscribe(g); - f.apply(c || null, arguments); - }); - f.observer_guid = g; + if (this.numHandlers == 1) { + this.onHasSubscribersChange && this.onHasSubscribersChange(); + } } - return g; }; /** * Unsubscribes the function with the given guid from the channel. */ -Channel.prototype.unsubscribe = function(g) { +Channel.prototype.unsubscribe = function(f) { // need a function to unsubscribe - if (g === null || g === undefined) { throw "You must pass _something_ into Channel.unsubscribe"; } + forceFunction(f); - if (typeof g == 'function') { g = g.observer_guid; } - var handler = this.handlers[g]; + var guid = f.observer_guid, + handler = this.handlers[guid]; if (handler) { - if (handler.observer_guid) handler.observer_guid=null; - delete this.handlers[g]; + delete this.handlers[guid]; this.numHandlers--; - if (this.events.onUnsubscribe) this.events.onUnsubscribe.call(this); + if (this.numHandlers === 0) { + this.onHasSubscribersChange && this.onHasSubscribersChange(); + } } }; @@ -610,10 +604,14 @@ Channel.prototype.unsubscribe = function(g) { * Calls all functions subscribed to this channel. */ Channel.prototype.fire = function(e) { - if (this.enabled) { - var fail = false; - this.fired = true; - this.fireArgs = arguments; + 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 = []; @@ -621,33 +619,36 @@ Channel.prototype.fire = function(e) { toCall.push(this.handlers[item]); } for (var i = 0; i < toCall.length; ++i) { - var rv = (toCall[i].apply(this, arguments)===false); - fail = fail || rv; + toCall[i].apply(this, fireArgs); + } + if (this.state == 2 && this.numHandlers) { + this.numHandlers = 0; + this.handlers = {}; + this.onHasSubscribersChange && this.onHasSubscribersChange(); } - return !fail; } - return true; }; + // defining them here so they are ready super fast! // DOM event that is received when the web page is loaded and parsed. -channel.create('onDOMContentLoaded'); +channel.createSticky('onDOMContentLoaded'); // Event to indicate the Cordova native side is ready. -channel.create('onNativeReady'); +channel.createSticky('onNativeReady'); // Event to indicate that all Cordova JavaScript objects have been created // and it's time to run plugin constructors. -channel.create('onCordovaReady'); +channel.createSticky('onCordovaReady'); // Event to indicate that device properties are available -channel.create('onCordovaInfoReady'); +channel.createSticky('onCordovaInfoReady'); // Event to indicate that the connection property has been set. -channel.create('onCordovaConnectionReady'); +channel.createSticky('onCordovaConnectionReady'); // Event to indicate that Cordova is ready -channel.create('onDeviceReady'); +channel.createSticky('onDeviceReady'); // Event to indicate a resume lifecycle event channel.create('onResume'); @@ -656,7 +657,7 @@ channel.create('onResume'); channel.create('onPause'); // Event to indicate a destroy lifecycle event -channel.create('onDestroy'); +channel.createSticky('onDestroy'); // Channels that must fire before "deviceready" is fired. channel.waitForInitialization('onCordovaReady'); @@ -666,8 +667,39 @@ 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/common/common.js define("cordova/common", function(require, exports, module) { + module.exports = { objects: { cordova: { @@ -705,6 +737,9 @@ module.exports = { compass:{ path: 'cordova/plugin/compass' }, + connection: { + path: 'cordova/plugin/network' + }, contacts: { path: 'cordova/plugin/contacts' }, @@ -718,10 +753,14 @@ module.exports = { geolocation: { path: 'cordova/plugin/geolocation' }, + globalization: { + path: 'cordova/plugin/globalization' + }, network: { children: { connection: { - path: 'cordova/plugin/network' + path: 'cordova/plugin/network', + deprecated: 'navigator.network.connection is deprecated. Use navigator.connection instead.' } } }, @@ -832,6 +871,9 @@ module.exports = { Flags: { path: 'cordova/plugin/Flags' }, + GlobalizationError: { + path: 'cordova/plugin/GlobalizationError' + }, LocalFileSystem: { path: 'cordova/plugin/LocalFileSystem' }, @@ -872,6 +914,7 @@ module.exports = { // file: lib/ios/exec.js define("cordova/exec", function(require, exports, module) { + /** * Creates a gap bridge iframe used to notify the native code about queued * commands. @@ -880,7 +923,6 @@ define("cordova/exec", function(require, exports, module) { */ var cordova = require('cordova'), channel = require('cordova/channel'), - nativecomm = require('cordova/plugin/ios/nativecomm'), utils = require('cordova/utils'), jsToNativeModes = { IFRAME_NAV: 0, @@ -889,11 +931,14 @@ var cordova = require('cordova'), XHR_OPTIONAL_PAYLOAD: 3 }, // XHR mode does not work on iOS 4.2, so default to IFRAME_NAV for such devices. - // XHR mode's main advantage is working around a bug in -webkit-scroll, which + // XHR mode's main advantage is working around a bug in -webkit-scroll, which // doesn't exist in 4.X devices anyways. bridgeMode = navigator.userAgent.indexOf(' 4_') == -1 ? jsToNativeModes.XHR_NO_PAYLOAD : jsToNativeModes.IFRAME_NAV, execIframe, - execXhr; + execXhr, + requestCount = 0, + commandQueue = [], // Contains pending JS->Native messages. + isInContextOfEvalJs = 0; function createExecIframe() { var iframe = document.createElement("iframe"); @@ -903,13 +948,13 @@ function createExecIframe() { } function shouldBundleCommandJson() { - if (bridgeMode == 2) { + if (bridgeMode == jsToNativeModes.XHR_WITH_PAYLOAD) { return true; } - if (bridgeMode == 3) { + if (bridgeMode == jsToNativeModes.XHR_OPTIONAL_PAYLOAD) { var payloadLength = 0; - for (var i = 0; i < cordova.commandQueue.length; ++i) { - payloadLength += cordova.commandQueue[i].length; + for (var i = 0; i < commandQueue.length; ++i) { + payloadLength += commandQueue[i].length; } // The value here was determined using the benchmark within CordovaLibApp on an iPad 3. return payloadLength < 4500; @@ -918,7 +963,7 @@ function shouldBundleCommandJson() { } function iOSExec() { - if (!channel.onCordovaReady.fired) { + if (channel.onCordovaReady.state != 2) { utils.alert("ERROR: Attempting to call cordova.exec()" + " before 'deviceready'. Ignoring."); return; @@ -960,21 +1005,26 @@ function iOSExec() { // Stringify and queue the command. We stringify to command now to // effectively clone the command arguments in case they are mutated before // the command is executed. - cordova.commandQueue.push(JSON.stringify(command)); - - // If the queue length is 1, then that means it was empty before we queued - // the given command, so let the native side know that we have some - // commands to execute, unless the queue is currently being flushed, in - // which case the command will be picked up without notification. - if (cordova.commandQueue.length == 1 && !cordova.commandQueueFlushing) { - if (bridgeMode) { + commandQueue.push(JSON.stringify(command)); + + if (!isInContextOfEvalJs) { + if (bridgeMode != jsToNativeModes.IFRAME_NAV) { + // Re-using the XHR improves exec() performance by about 10%. + // It is possible for a native stringByEvaluatingJavascriptFromString call + // to cause us to reach this point when a request is already in progress, + // so we check the readyState to guard agains re-using an inprogress XHR. + // Refer to CB-1404. + if (execXhr && execXhr.readyState != 4) { + execXhr = null; + } execXhr = execXhr || new XMLHttpRequest(); - // Changeing this to a GET will make the XHR reach the URIProtocol on 4.2. + // Changing this to a GET will make the XHR reach the URIProtocol on 4.2. // For some reason it still doesn't work though... - execXhr.open('HEAD', "file:///!gap_exec", true); + execXhr.open('HEAD', "/!gap_exec", true); execXhr.setRequestHeader('vc', cordova.iOSVCAddr); + execXhr.setRequestHeader('rc', ++requestCount); if (shouldBundleCommandJson()) { - execXhr.setRequestHeader('cmds', nativecomm()); + execXhr.setRequestHeader('cmds', iOSExec.nativeFetchMessages()); } execXhr.send(null); } else { @@ -997,12 +1047,41 @@ iOSExec.setJsToNativeBridgeMode = function(mode) { bridgeMode = mode; }; +iOSExec.nativeFetchMessages = function() { + // Each entry in commandQueue is a JSON string already. + if (!commandQueue.length) { + return ''; + } + var json = '[' + commandQueue.join(',') + ']'; + commandQueue.length = 0; + return json; +}; + +iOSExec.nativeCallback = function(callbackId, status, payload, keepCallback) { + return iOSExec.nativeEvalAndFetch(function() { + var success = status == 0 || status == 1; + cordova.callbackFromNative(callbackId, success, status, payload, keepCallback); + }); +}; + +iOSExec.nativeEvalAndFetch = function(func) { + // This shouldn't be nested, but better to be safe. + isInContextOfEvalJs++; + try { + func(); + return iOSExec.nativeFetchMessages(); + } finally { + isInContextOfEvalJs--; + } +}; + module.exports = iOSExec; }); // file: lib/ios/platform.js define("cordova/platform", function(require, exports, module) { + module.exports = { id: "ios", initialize:function() { @@ -1059,6 +1138,7 @@ logger.useConsole(false); // file: lib/common/plugin/Acceleration.js define("cordova/plugin/Acceleration", function(require, exports, module) { + var Acceleration = function(x, y, z, timestamp) { this.x = x; this.y = y; @@ -1072,6 +1152,7 @@ module.exports = Acceleration; // file: lib/common/plugin/Camera.js define("cordova/plugin/Camera", function(require, exports, module) { + var exec = require('cordova/exec'), Camera = require('cordova/plugin/CameraConstants'); @@ -1093,6 +1174,7 @@ for (var key in Camera) { * @param {Object} options */ cameraExport.getPicture = function(successCallback, errorCallback, options) { + options = options || {}; // successCallback required if (typeof successCallback != "function") { console.log("Camera Error: successCallback is not a function"); @@ -1106,9 +1188,9 @@ cameraExport.getPicture = function(successCallback, errorCallback, options) { } var quality = 50; - if (options && typeof options.quality == "number") { + if (typeof options.quality == "number") { quality = options.quality; - } else if (options && typeof options.quality == "string") { + } else if (typeof options.quality == "string") { var qlity = parseInt(options.quality, 10); if (isNaN(qlity) === false) { quality = qlity.valueOf(); @@ -1188,10 +1270,12 @@ cameraExport.cleanup = function(successCallback, errorCallback) { }; module.exports = cameraExport; + }); // file: lib/common/plugin/CameraConstants.js define("cordova/plugin/CameraConstants", function(require, exports, module) { + module.exports = { DestinationType:{ DATA_URL: 0, // Return base64 encoded string @@ -1219,10 +1303,12 @@ module.exports = { ARROW_ANY : 15 } }; + }); // file: lib/common/plugin/CameraPopoverOptions.js define("cordova/plugin/CameraPopoverOptions", function(require, exports, module) { + var Camera = require('cordova/plugin/CameraConstants'); /** @@ -1239,10 +1325,12 @@ var CameraPopoverOptions = function(x,y,width,height,arrowDir){ }; module.exports = CameraPopoverOptions; + }); // file: lib/common/plugin/CaptureAudioOptions.js define("cordova/plugin/CaptureAudioOptions", function(require, exports, module) { + /** * Encapsulates all audio capture operation configuration options. */ @@ -1256,10 +1344,12 @@ var CaptureAudioOptions = function(){ }; module.exports = CaptureAudioOptions; + }); // file: lib/common/plugin/CaptureError.js define("cordova/plugin/CaptureError", function(require, exports, module) { + /** * The CaptureError interface encapsulates all errors in the Capture API. */ @@ -1279,10 +1369,12 @@ CaptureError.CAPTURE_NO_MEDIA_FILES = 3; CaptureError.CAPTURE_NOT_SUPPORTED = 20; module.exports = CaptureError; + }); // file: lib/common/plugin/CaptureImageOptions.js define("cordova/plugin/CaptureImageOptions", function(require, exports, module) { + /** * Encapsulates all image capture operation configuration options. */ @@ -1294,10 +1386,12 @@ var CaptureImageOptions = function(){ }; module.exports = CaptureImageOptions; + }); // file: lib/common/plugin/CaptureVideoOptions.js define("cordova/plugin/CaptureVideoOptions", function(require, exports, module) { + /** * Encapsulates all video capture operation configuration options. */ @@ -1311,13 +1405,15 @@ var CaptureVideoOptions = function(){ }; module.exports = CaptureVideoOptions; + }); // file: lib/common/plugin/CompassError.js define("cordova/plugin/CompassError", function(require, exports, module) { + /** * CompassError. - * An error code assigned by an implementation when an error has occured + * An error code assigned by an implementation when an error has occurred * @constructor */ var CompassError = function(err) { @@ -1328,10 +1424,12 @@ CompassError.COMPASS_INTERNAL_ERR = 0; CompassError.COMPASS_NOT_SUPPORTED = 20; module.exports = CompassError; + }); // file: lib/common/plugin/CompassHeading.js define("cordova/plugin/CompassHeading", function(require, exports, module) { + var CompassHeading = function(magneticHeading, trueHeading, headingAccuracy, timestamp) { this.magneticHeading = (magneticHeading !== undefined ? magneticHeading : null); this.trueHeading = (trueHeading !== undefined ? trueHeading : null); @@ -1340,10 +1438,12 @@ var CompassHeading = function(magneticHeading, trueHeading, headingAccuracy, tim }; module.exports = CompassHeading; + }); // file: lib/common/plugin/ConfigurationData.js define("cordova/plugin/ConfigurationData", function(require, exports, module) { + /** * Encapsulates a set of parameters that the capture device supports. */ @@ -1359,10 +1459,12 @@ function ConfigurationData() { } module.exports = ConfigurationData; + }); // file: lib/common/plugin/Connection.js define("cordova/plugin/Connection", function(require, exports, module) { + /** * Network status */ @@ -1375,10 +1477,12 @@ module.exports = { CELL_4G: "4g", NONE: "none" }; + }); // file: lib/common/plugin/Contact.js define("cordova/plugin/Contact", function(require, exports, module) { + var exec = require('cordova/exec'), ContactError = require('cordova/plugin/ContactError'), utils = require('cordova/utils'); @@ -1561,6 +1665,7 @@ module.exports = Contact; // file: lib/common/plugin/ContactAddress.js define("cordova/plugin/ContactAddress", function(require, exports, module) { + /** * Contact address. * @constructor @@ -1586,13 +1691,15 @@ var ContactAddress = function(pref, type, formatted, streetAddress, locality, re }; module.exports = ContactAddress; + }); // file: lib/common/plugin/ContactError.js define("cordova/plugin/ContactError", function(require, exports, module) { + /** * ContactError. - * An error code assigned by an implementation when an error has occured + * An error code assigned by an implementation when an error has occurred * @constructor */ var ContactError = function(err) { @@ -1611,10 +1718,12 @@ ContactError.NOT_SUPPORTED_ERROR = 5; ContactError.PERMISSION_DENIED_ERROR = 20; module.exports = ContactError; + }); // file: lib/common/plugin/ContactField.js define("cordova/plugin/ContactField", function(require, exports, module) { + /** * Generic contact field. * @constructor @@ -1631,10 +1740,12 @@ var ContactField = function(type, value, pref) { }; module.exports = ContactField; + }); // file: lib/common/plugin/ContactFindOptions.js define("cordova/plugin/ContactFindOptions", function(require, exports, module) { + /** * ContactFindOptions. * @constructor @@ -1648,10 +1759,12 @@ var ContactFindOptions = function(filter, multiple) { }; module.exports = ContactFindOptions; + }); // file: lib/common/plugin/ContactName.js define("cordova/plugin/ContactName", function(require, exports, module) { + /** * Contact name. * @constructor @@ -1672,10 +1785,12 @@ var ContactName = function(formatted, familyName, givenName, middle, prefix, suf }; module.exports = ContactName; + }); // file: lib/common/plugin/ContactOrganization.js define("cordova/plugin/ContactOrganization", function(require, exports, module) { + /** * Contact organization. * @constructor @@ -1699,10 +1814,12 @@ var ContactOrganization = function(pref, type, name, dept, title) { }; module.exports = ContactOrganization; + }); // file: lib/common/plugin/Coordinates.js define("cordova/plugin/Coordinates", function(require, exports, module) { + /** * This class contains position information. * @param {Object} lat @@ -1756,6 +1873,7 @@ module.exports = Coordinates; // file: lib/common/plugin/DirectoryEntry.js define("cordova/plugin/DirectoryEntry", function(require, exports, module) { + var utils = require('cordova/utils'), exec = require('cordova/exec'), Entry = require('cordova/plugin/Entry'), @@ -1788,7 +1906,7 @@ DirectoryEntry.prototype.createReader = function() { * Creates or looks up a directory * * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a directory - * @param {Flags} options to create or excluively create the directory + * @param {Flags} options to create or exclusively create the directory * @param {Function} successCallback is called with the new entry * @param {Function} errorCallback is called with a FileError */ @@ -1820,7 +1938,7 @@ DirectoryEntry.prototype.removeRecursively = function(successCallback, errorCall * Creates or looks up a file * * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a file - * @param {Flags} options to create or excluively create the file + * @param {Flags} options to create or exclusively create the file * @param {Function} successCallback is called with the new entry * @param {Function} errorCallback is called with a FileError */ @@ -1842,6 +1960,7 @@ module.exports = DirectoryEntry; // file: lib/common/plugin/DirectoryReader.js define("cordova/plugin/DirectoryReader", function(require, exports, module) { + var exec = require('cordova/exec'), FileError = require('cordova/plugin/FileError') ; @@ -1889,6 +2008,7 @@ module.exports = DirectoryReader; // file: lib/common/plugin/Entry.js define("cordova/plugin/Entry", function(require, exports, module) { + var exec = require('cordova/exec'), FileError = require('cordova/plugin/FileError'), Metadata = require('cordova/plugin/Metadata'); @@ -2107,10 +2227,12 @@ Entry.prototype.getParent = function(successCallback, errorCallback) { }; module.exports = Entry; + }); // file: lib/common/plugin/File.js define("cordova/plugin/File", function(require, exports, module) { + /** * Constructor. * name {DOMString} name of the file, without path information @@ -2129,10 +2251,12 @@ var File = function(name, fullPath, type, lastModifiedDate, size){ }; module.exports = File; + }); // file: lib/common/plugin/FileEntry.js define("cordova/plugin/FileEntry", function(require, exports, module) { + var utils = require('cordova/utils'), exec = require('cordova/exec'), Entry = require('cordova/plugin/Entry'), @@ -2196,10 +2320,12 @@ FileEntry.prototype.file = function(successCallback, errorCallback) { module.exports = FileEntry; + }); // file: lib/common/plugin/FileError.js define("cordova/plugin/FileError", function(require, exports, module) { + /** * FileError */ @@ -2225,10 +2351,12 @@ FileError.TYPE_MISMATCH_ERR = 11; FileError.PATH_EXISTS_ERR = 12; module.exports = FileError; + }); // file: lib/common/plugin/FileReader.js define("cordova/plugin/FileReader", function(require, exports, module) { + var exec = require('cordova/exec'), FileError = require('cordova/plugin/FileError'), ProgressEvent = require('cordova/plugin/ProgressEvent'); @@ -2254,7 +2382,7 @@ var FileReader = function() { // Event handlers this.onloadstart = null; // When the read starts. - this.onprogress = null; // While reading (and decoding) file or fileBlob data, and reporting partial file data (progess.loaded/progress.total) + this.onprogress = null; // While reading (and decoding) file or fileBlob data, and reporting partial file data (progress.loaded/progress.total) this.onload = null; // When the read has successfully completed. this.onerror = null; // When the read has failed (see errors). this.onloadend = null; // When the request has completed (either in success or failure). @@ -2478,10 +2606,12 @@ FileReader.prototype.readAsArrayBuffer = function(file) { }; module.exports = FileReader; + }); // file: lib/common/plugin/FileSystem.js define("cordova/plugin/FileSystem", function(require, exports, module) { + var DirectoryEntry = require('cordova/plugin/DirectoryEntry'); /** @@ -2504,14 +2634,29 @@ module.exports = FileSystem; // file: lib/common/plugin/FileTransfer.js define("cordova/plugin/FileTransfer", function(require, exports, module) { + var exec = require('cordova/exec'), - FileTransferError = require('cordova/plugin/FileTransferError'); + FileTransferError = require('cordova/plugin/FileTransferError'), + ProgressEvent = require('cordova/plugin/ProgressEvent'); + +function newProgressEvent(result) { + var pe = new ProgressEvent(); + pe.lengthComputable = result.lengthComputable; + pe.loaded = result.loaded; + pe.total = result.total; + return pe; +} + +var idCounter = 0; /** * FileTransfer uploads a file to a remote server. * @constructor */ -var FileTransfer = function() {}; +var FileTransfer = function() { + this._id = ++idCounter; + this.onprogress = null; // optional callback +}; /** * Given an absolute file path, uploads a file on the device to a remote server @@ -2554,7 +2699,17 @@ FileTransfer.prototype.upload = function(filePath, server, successCallback, erro errorCallback(error); }; - exec(successCallback, fail, 'FileTransfer', 'upload', [filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode, headers]); + var self = this; + var win = function(result) { + if (typeof result.lengthComputable != "undefined") { + if (self.onprogress) { + return self.onprogress(newProgressEvent(result)); + } + } else { + return successCallback(result); + } + }; + exec(win, fail, 'FileTransfer', 'upload', [filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode, headers, this._id]); }; /** @@ -2563,23 +2718,31 @@ FileTransfer.prototype.upload = function(filePath, server, successCallback, erro * @param target {String} Full path of the file on the device * @param successCallback (Function} Callback to be invoked when upload has completed * @param errorCallback {Function} Callback to be invoked upon error + * @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false */ -FileTransfer.prototype.download = function(source, target, successCallback, errorCallback) { +FileTransfer.prototype.download = function(source, target, successCallback, errorCallback, trustAllHosts) { // sanity parameter checking if (!source || !target) throw new Error("FileTransfer.download requires source URI and target URI parameters at the minimum."); + var self = this; var win = function(result) { - var entry = null; - if (result.isDirectory) { - entry = new (require('cordova/plugin/DirectoryEntry'))(); - } - else if (result.isFile) { - entry = new (require('cordova/plugin/FileEntry'))(); + if (typeof result.lengthComputable != "undefined") { + if (self.onprogress) { + return self.onprogress(newProgressEvent(result)); + } + } else { + var entry = null; + if (result.isDirectory) { + entry = new (require('cordova/plugin/DirectoryEntry'))(); + } + else if (result.isFile) { + entry = new (require('cordova/plugin/FileEntry'))(); + } + entry.isDirectory = result.isDirectory; + entry.isFile = result.isFile; + entry.name = result.name; + entry.fullPath = result.fullPath; + successCallback(entry); } - entry.isDirectory = result.isDirectory; - entry.isFile = result.isFile; - entry.name = result.name; - entry.fullPath = result.fullPath; - successCallback(entry); }; var fail = function(e) { @@ -2587,7 +2750,16 @@ FileTransfer.prototype.download = function(source, target, successCallback, erro errorCallback(error); }; - exec(win, errorCallback, 'FileTransfer', 'download', [source, target]); + exec(win, fail, 'FileTransfer', 'download', [source, target, trustAllHosts, this._id]); +}; + +/** + * Aborts the ongoing file transfer on this object + * @param successCallback {Function} Callback to be invoked upon success + * @param errorCallback {Function} Callback to be invoked upon error + */ +FileTransfer.prototype.abort = function(successCallback, errorCallback) { + exec(successCallback, errorCallback, 'FileTransfer', 'abort', [this._id]); }; module.exports = FileTransfer; @@ -2596,6 +2768,7 @@ module.exports = FileTransfer; // file: lib/common/plugin/FileTransferError.js define("cordova/plugin/FileTransferError", function(require, exports, module) { + /** * FileTransferError * @constructor @@ -2610,6 +2783,7 @@ var FileTransferError = function(code, source, target, status) { FileTransferError.FILE_NOT_FOUND_ERR = 1; FileTransferError.INVALID_URL_ERR = 2; FileTransferError.CONNECTION_ERR = 3; +FileTransferError.ABORT_ERR = 4; module.exports = FileTransferError; @@ -2617,6 +2791,7 @@ module.exports = FileTransferError; // file: lib/common/plugin/FileUploadOptions.js define("cordova/plugin/FileUploadOptions", function(require, exports, module) { + /** * Options to customize the HTTP request used to upload files. * @constructor @@ -2641,6 +2816,7 @@ module.exports = FileUploadOptions; // file: lib/common/plugin/FileUploadResult.js define("cordova/plugin/FileUploadResult", function(require, exports, module) { + /** * FileUploadResult * @constructor @@ -2652,10 +2828,12 @@ var FileUploadResult = function() { }; module.exports = FileUploadResult; + }); // file: lib/common/plugin/FileWriter.js define("cordova/plugin/FileWriter", function(require, exports, module) { + var exec = require('cordova/exec'), FileError = require('cordova/plugin/FileError'), ProgressEvent = require('cordova/plugin/ProgressEvent'); @@ -2914,6 +3092,7 @@ module.exports = FileWriter; // file: lib/common/plugin/Flags.js define("cordova/plugin/Flags", function(require, exports, module) { + /** * Supplies arguments to methods that lookup or create files and directories. * @@ -2929,10 +3108,38 @@ function Flags(create, exclusive) { } module.exports = Flags; + +}); + +// file: lib/common/plugin/GlobalizationError.js +define("cordova/plugin/GlobalizationError", function(require, exports, module) { + + +/** + * Globalization error object + * + * @constructor + * @param code + * @param message + */ +var GlobalizationError = function(code, message) { + this.code = code || null; + this.message = message || ''; +}; + +// Globalization error codes +GlobalizationError.UNKNOWN_ERROR = 0; +GlobalizationError.FORMATTING_ERROR = 1; +GlobalizationError.PARSING_ERROR = 2; +GlobalizationError.PATTERN_ERROR = 3; + +module.exports = GlobalizationError; + }); // file: lib/common/plugin/LocalFileSystem.js define("cordova/plugin/LocalFileSystem", function(require, exports, module) { + var exec = require('cordova/exec'); /** @@ -2946,10 +3153,12 @@ LocalFileSystem.TEMPORARY = 0; //temporary, with no guarantee of persistence LocalFileSystem.PERSISTENT = 1; //persistent module.exports = LocalFileSystem; + }); // file: lib/common/plugin/Media.js define("cordova/plugin/Media", function(require, exports, module) { + var utils = require('cordova/utils'), exec = require('cordova/exec'); @@ -3124,13 +3333,13 @@ Media.onStatus = function(id, msgType, value) { media._duration = value; break; case Media.MEDIA_ERROR : - media.errorCallback && media.errorCallback(value); + media.errorCallback && media.errorCallback(value); break; case Media.MEDIA_POSITION : media._position = Number(value); break; default : - console && console.error && console.error("Unhandled Media.onStatus :: " + msgType); + console && console.error && console.error("Unhandled Media.onStatus :: " + msgType); break; } } @@ -3141,10 +3350,12 @@ Media.onStatus = function(id, msgType, value) { }; module.exports = Media; + }); // file: lib/common/plugin/MediaError.js define("cordova/plugin/MediaError", function(require, exports, module) { + /** * This class contains information about any Media errors. */ @@ -3159,28 +3370,32 @@ we should simply use a literal : errorCallbackFunction( {'code':3} ); */ -if(!MediaError) { - var MediaError = function(code, msg) { + var _MediaError = window.MediaError; + + +if(!_MediaError) { + window.MediaError = _MediaError = function(code, msg) { this.code = (typeof code != 'undefined') ? code : null; this.message = msg || ""; // message is NON-standard! do not use! }; } -MediaError.MEDIA_ERR_NONE_ACTIVE = MediaError.MEDIA_ERR_NONE_ACTIVE || 0; -MediaError.MEDIA_ERR_ABORTED = MediaError.MEDIA_ERR_ABORTED || 1; -MediaError.MEDIA_ERR_NETWORK = MediaError.MEDIA_ERR_NETWORK || 2; -MediaError.MEDIA_ERR_DECODE = MediaError.MEDIA_ERR_DECODE || 3; -MediaError.MEDIA_ERR_NONE_SUPPORTED = MediaError.MEDIA_ERR_NONE_SUPPORTED || 4; -// TODO: MediaError.MEDIA_ERR_NONE_SUPPORTED is legacy, the W3 spec now defines it as below. +_MediaError.MEDIA_ERR_NONE_ACTIVE = _MediaError.MEDIA_ERR_NONE_ACTIVE || 0; +_MediaError.MEDIA_ERR_ABORTED = _MediaError.MEDIA_ERR_ABORTED || 1; +_MediaError.MEDIA_ERR_NETWORK = _MediaError.MEDIA_ERR_NETWORK || 2; +_MediaError.MEDIA_ERR_DECODE = _MediaError.MEDIA_ERR_DECODE || 3; +_MediaError.MEDIA_ERR_NONE_SUPPORTED = _MediaError.MEDIA_ERR_NONE_SUPPORTED || 4; +// TODO: MediaError.MEDIA_ERR_NONE_SUPPORTED is legacy, the W3 spec now defines it as below. // as defined by http://dev.w3.org/html5/spec-author-view/video.html#error-codes -MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED = MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED || 4; +_MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED = _MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED || 4; -module.exports = MediaError; +module.exports = _MediaError; }); // file: lib/common/plugin/MediaFile.js define("cordova/plugin/MediaFile", function(require, exports, module) { + var utils = require('cordova/utils'), exec = require('cordova/exec'), File = require('cordova/plugin/File'), @@ -3220,6 +3435,7 @@ module.exports = MediaFile; // file: lib/common/plugin/MediaFileData.js define("cordova/plugin/MediaFileData", function(require, exports, module) { + /** * MediaFileData encapsulates format information of a media file. * @@ -3238,10 +3454,12 @@ var MediaFileData = function(codecs, bitrate, height, width, duration){ }; module.exports = MediaFileData; + }); // file: lib/common/plugin/Metadata.js define("cordova/plugin/Metadata", function(require, exports, module) { + /** * Information about the state of the file or directory * @@ -3252,10 +3470,12 @@ var Metadata = function(time) { }; module.exports = Metadata; + }); // file: lib/common/plugin/Position.js define("cordova/plugin/Position", function(require, exports, module) { + var Coordinates = require('cordova/plugin/Coordinates'); var Position = function(coords, timestamp) { @@ -3273,6 +3493,7 @@ module.exports = Position; // file: lib/common/plugin/PositionError.js define("cordova/plugin/PositionError", function(require, exports, module) { + /** * Position error object * @@ -3290,10 +3511,12 @@ PositionError.POSITION_UNAVAILABLE = 2; PositionError.TIMEOUT = 3; module.exports = PositionError; + }); // file: lib/common/plugin/ProgressEvent.js define("cordova/plugin/ProgressEvent", function(require, exports, module) { + // If ProgressEvent exists in global context, use it already, otherwise use our own polyfill // Feature test: See if we can instantiate a native ProgressEvent; // if so, use that approach, @@ -3340,10 +3563,12 @@ var ProgressEvent = (function() { })(); module.exports = ProgressEvent; + }); // file: lib/common/plugin/accelerometer.js define("cordova/plugin/accelerometer", function(require, exports, module) { + /** * This class provides access to device accelerometer data. * @constructor @@ -3405,7 +3630,7 @@ function removeListeners(l) { var accelerometer = { /** - * Asynchronously aquires the current acceleration. + * Asynchronously acquires the current acceleration. * * @param {Function} successCallback The function to call when the acceleration data is available * @param {Function} errorCallback The function to call when there is an error getting the acceleration data. (OPTIONAL) @@ -3436,7 +3661,7 @@ var accelerometer = { }, /** - * Asynchronously aquires the acceleration repeatedly at a given interval. + * Asynchronously acquires the acceleration repeatedly at a given interval. * * @param {Function} successCallback The function to call each time the acceleration data is available * @param {Function} errorCallback The function to call when there is an error getting the acceleration data. (OPTIONAL) @@ -3504,6 +3729,7 @@ module.exports = accelerometer; // file: lib/common/plugin/battery.js define("cordova/plugin/battery", function(require, exports, module) { + /** * This class contains information about the current battery status. * @constructor @@ -3521,34 +3747,25 @@ var Battery = function() { this._level = null; this._isPlugged = null; // Create new event handlers on the window (returns a channel instance) - var subscriptionEvents = { - onSubscribe:this.onSubscribe, - onUnsubscribe:this.onUnsubscribe - }; this.channels = { - batterystatus:cordova.addWindowEventHandler("batterystatus", subscriptionEvents), - batterylow:cordova.addWindowEventHandler("batterylow", subscriptionEvents), - batterycritical:cordova.addWindowEventHandler("batterycritical", subscriptionEvents) + batterystatus:cordova.addWindowEventHandler("batterystatus"), + batterylow:cordova.addWindowEventHandler("batterylow"), + batterycritical:cordova.addWindowEventHandler("batterycritical") }; + for (var key in this.channels) { + this.channels[key].onHasSubscribersChange = Battery.onHasSubscribersChange; + } }; /** * Event handlers for when callbacks get registered for the battery. * Keep track of how many handlers we have so we can start and stop the native battery listener * appropriately (and hopefully save on battery life!). */ -Battery.prototype.onSubscribe = function() { - var me = battery; +Battery.onHasSubscribersChange = function() { // If we just registered the first handler, make sure native listener is started. - if (handlers() === 1) { - exec(me._status, me._error, "Battery", "start", []); - } -}; - -Battery.prototype.onUnsubscribe = function() { - var me = battery; - - // If we just unregistered the last handler, make sure native listener is stopped. - if (handlers() === 0) { + if (this.numHandlers === 1 && handlers() === 1) { + exec(battery._status, battery._error, "Battery", "start", []); + } else if (handlers() === 0) { exec(null, null, "Battery", "stop", []); } }; @@ -3591,10 +3808,12 @@ Battery.prototype._error = function(e) { var battery = new Battery(); module.exports = battery; + }); // file: lib/common/plugin/capture.js define("cordova/plugin/capture", function(require, exports, module) { + var exec = require('cordova/exec'), MediaFile = require('cordova/plugin/MediaFile'); @@ -3672,6 +3891,7 @@ module.exports = new Capture(); // file: lib/common/plugin/compass.js define("cordova/plugin/compass", function(require, exports, module) { + var exec = require('cordova/exec'), utils = require('cordova/utils'), CompassHeading = require('cordova/plugin/CompassHeading'), @@ -3773,10 +3993,12 @@ var exec = require('cordova/exec'), }; module.exports = compass; + }); // file: lib/common/plugin/console-via-logger.js define("cordova/plugin/console-via-logger", function(require, exports, module) { + //------------------------------------------------------------------------------ var logger = require("cordova/plugin/logger"); @@ -3925,7 +4147,7 @@ console.table = function(data, columns) { //------------------------------------------------------------------------------ // return a new function that calls both functions passed as args //------------------------------------------------------------------------------ -function wrapperedOrigCall(orgFunc, newFunc) { +function wrappedOrigCall(orgFunc, newFunc) { return function() { var args = [].slice.call(arguments); try { orgFunc.apply(WinConsole, args); } catch (e) {} @@ -3940,7 +4162,7 @@ function wrapperedOrigCall(orgFunc, newFunc) { //------------------------------------------------------------------------------ for (var key in console) { if (typeof WinConsole[key] == "function") { - console[key] = wrapperedOrigCall(WinConsole[key], console[key]); + console[key] = wrappedOrigCall(WinConsole[key], console[key]); } } @@ -3948,6 +4170,7 @@ for (var key in console) { // file: lib/common/plugin/contacts.js define("cordova/plugin/contacts", function(require, exports, module) { + var exec = require('cordova/exec'), ContactError = require('cordova/plugin/ContactError'), utils = require('cordova/utils'), @@ -4011,6 +4234,7 @@ module.exports = contacts; // file: lib/common/plugin/device.js define("cordova/plugin/device", function(require, exports, module) { + var channel = require('cordova/channel'), utils = require('cordova/utils'), exec = require('cordova/exec'); @@ -4033,7 +4257,7 @@ function Device() { var me = this; - channel.onCordovaReady.subscribeOnce(function() { + channel.onCordovaReady.subscribe(function() { me.getInfo(function(info) { me.available = true; me.platform = info.platform; @@ -4079,10 +4303,11 @@ module.exports = new Device(); // file: lib/common/plugin/echo.js define("cordova/plugin/echo", function(require, exports, module) { + var exec = require('cordova/exec'); /** - * Sends the given message through exec() to the Echo plugink, which sends it back to the successCallback. + * 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. @@ -4098,6 +4323,7 @@ module.exports = function(successCallback, errorCallback, message, forceAsync) { // file: lib/common/plugin/geolocation.js define("cordova/plugin/geolocation", function(require, exports, module) { + var utils = require('cordova/utils'), exec = require('cordova/exec'), PositionError = require('cordova/plugin/PositionError'), @@ -4148,7 +4374,7 @@ function createTimeout(errorCallback, timeout) { var geolocation = { lastPosition:null, // reference to last known (cached) position returned /** - * Asynchronously aquires the current position. + * Asynchronously acquires the current position. * * @param {Function} successCallback The function to call when the position data is available * @param {Function} errorCallback The function to call when there is an error getting the heading position. (OPTIONAL) @@ -4162,11 +4388,11 @@ var geolocation = { // Timer var that will fire an error callback if no position is retrieved from native // before the "timeout" param provided expires - var timeoutTimer = null; + var timeoutTimer = {timer:null}; var win = function(p) { - clearTimeout(timeoutTimer); - if (!timeoutTimer) { + clearTimeout(timeoutTimer.timer); + if (!(timeoutTimer.timer)) { // Timeout already happened, or native fired error callback for // this geo request. // Don't continue with success callback. @@ -4188,8 +4414,8 @@ var geolocation = { successCallback(pos); }; var fail = function(e) { - clearTimeout(timeoutTimer); - timeoutTimer = null; + clearTimeout(timeoutTimer.timer); + timeoutTimer.timer = null; var err = new PositionError(e.code, e.message); if (errorCallback) { errorCallback(err); @@ -4212,12 +4438,12 @@ var geolocation = { // If the timeout value was not set to Infinity (default), then // set up a timeout function that will fire the error callback // if no successful position was retrieved before timeout expired. - timeoutTimer = createTimeout(fail, options.timeout); + timeoutTimer.timer = createTimeout(fail, options.timeout); } else { // This is here so the check in the win function doesn't mess stuff up // may seem weird but this guarantees timeoutTimer is // always truthy before we call into native - timeoutTimer = true; + timeoutTimer.timer = true; } exec(win, fail, "Geolocation", "getLocation", [options.enableHighAccuracy, options.maximumAge]); } @@ -4244,7 +4470,7 @@ var geolocation = { timers[id] = geolocation.getCurrentPosition(successCallback, errorCallback, options); var fail = function(e) { - clearTimeout(timers[id]); + clearTimeout(timers[id].timer); var err = new PositionError(e.code, e.message); if (errorCallback) { errorCallback(err); @@ -4252,9 +4478,9 @@ var geolocation = { }; var win = function(p) { - clearTimeout(timers[id]); + clearTimeout(timers[id].timer); if (options.timeout !== Infinity) { - timers[id] = createTimeout(fail, options.timeout); + timers[id].timer = createTimeout(fail, options.timeout); } var pos = new Position( { @@ -4283,8 +4509,8 @@ var geolocation = { */ clearWatch:function(id) { if (id && timers[id] !== undefined) { - clearTimeout(timers[id]); - delete timers[id]; + clearTimeout(timers[id].timer); + timers[id].timer = false; exec(null, null, "Geolocation", "clearWatch", [id]); } } @@ -4294,8 +4520,548 @@ module.exports = geolocation; }); +// file: lib/common/plugin/globalization.js +define("cordova/plugin/globalization", function(require, exports, module) { + +var exec = require('cordova/exec'), + GlobalizationError = require('cordova/plugin/GlobalizationError'); + +var globalization = { + +/** +* Returns the string identifier for the client's current language. +* It returns the language identifier string to the successCB callback with a +* properties object as a parameter. If there is an error getting the language, +* then the errorCB callback is invoked. +* +* @param {Function} successCB +* @param {Function} errorCB +* +* @return Object.value {String}: The language identifier +* +* @error GlobalizationError.UNKNOWN_ERROR +* +* Example +* globalization.getPreferredLanguage(function (language) {alert('language:' + language.value + '\n');}, +* function () {}); +*/ +getPreferredLanguage:function(successCB, failureCB) { + // successCallback required + if (typeof successCB != "function") { + console.log("Globalization.getPreferredLanguage Error: successCB is not a function"); + return; + } + + // errorCallback required + if (typeof failureCB != "function") { + console.log("Globalization.getPreferredLanguage Error: failureCB is not a function"); + return; + } + + exec(successCB, failureCB, "Globalization","getPreferredLanguage", []); +}, + +/** +* Returns the string identifier for the client's current locale setting. +* It returns the locale identifier string to the successCB callback with a +* properties object as a parameter. If there is an error getting the locale, +* then the errorCB callback is invoked. +* +* @param {Function} successCB +* @param {Function} errorCB +* +* @return Object.value {String}: The locale identifier +* +* @error GlobalizationError.UNKNOWN_ERROR +* +* Example +* globalization.getLocaleName(function (locale) {alert('locale:' + locale.value + '\n');}, +* function () {}); +*/ +getLocaleName:function(successCB, failureCB) { + // successCallback required + if (typeof successCB != "function") { + console.log("Globalization.getLocaleName Error: successCB is not a function"); + return; + } + + // errorCallback required + if (typeof failureCB != "function") { + console.log("Globalization.getLocaleName Error: failureCB is not a function"); + return; + } + exec(successCB, failureCB, "Globalization","getLocaleName", []); +}, + + +/** +* Returns a date formatted as a string according to the client's user preferences and +* calendar using the time zone of the client. It returns the formatted date string to the +* successCB callback with a properties object as a parameter. If there is an error +* formatting the date, then the errorCB callback is invoked. +* +* The defaults are: formatLenght="short" and selector="date and time" +* +* @param {Date} date +* @param {Function} successCB +* @param {Function} errorCB +* @param {Object} options {optional} +* formatLength {String}: 'short', 'medium', 'long', or 'full' +* selector {String}: 'date', 'time', or 'date and time' +* +* @return Object.value {String}: The localized date string +* +* @error GlobalizationError.FORMATTING_ERROR +* +* Example +* globalization.dateToString(new Date(), +* function (date) {alert('date:' + date.value + '\n');}, +* function (errorCode) {alert(errorCode);}, +* {formatLength:'short'}); +*/ +dateToString:function(date, successCB, failureCB, options) { + // successCallback required + if (typeof successCB != "function") { + console.log("Globalization.dateToString Error: successCB is not a function"); + return; + } + + // errorCallback required + if (typeof failureCB != "function") { + console.log("Globalization.dateToString Error: failureCB is not a function"); + return; + } + + + if (date instanceof Date){ + var dateValue; + dateValue = date.valueOf(); + exec(successCB, failureCB, "Globalization", "dateToString", [{"date": dateValue, "options": options}]); + } + else { + console.log("Globalization.dateToString Error: date is not a Date object"); + } +}, + + +/** +* Parses a date formatted as a string according to the client's user +* preferences and calendar using the time zone of the client and returns +* the corresponding date object. It returns the date to the successCB +* callback with a properties object as a parameter. If there is an error +* parsing the date string, then the errorCB callback is invoked. +* +* The defaults are: formatLength="short" and selector="date and time" +* +* @param {String} dateString +* @param {Function} successCB +* @param {Function} errorCB +* @param {Object} options {optional} +* formatLength {String}: 'short', 'medium', 'long', or 'full' +* selector {String}: 'date', 'time', or 'date and time' +* +* @return Object.year {Number}: The four digit year +* Object.month {Number}: The month from (0 - 11) +* Object.day {Number}: The day from (1 - 31) +* Object.hour {Number}: The hour from (0 - 23) +* Object.minute {Number}: The minute from (0 - 59) +* Object.second {Number}: The second from (0 - 59) +* Object.millisecond {Number}: The milliseconds (from 0 - 999), +* not available on all platforms +* +* @error GlobalizationError.PARSING_ERROR +* +* Example +* globalization.stringToDate('4/11/2011', +* function (date) { alert('Month:' + date.month + '\n' + +* 'Day:' + date.day + '\n' + +* 'Year:' + date.year + '\n');}, +* function (errorCode) {alert(errorCode);}, +* {selector:'date'}); +*/ +stringToDate:function(dateString, successCB, failureCB, options) { + // successCallback required + if (typeof successCB != "function") { + console.log("Globalization.stringToDate Error: successCB is not a function"); + return; + } + + // errorCallback required + if (typeof failureCB != "function") { + console.log("Globalization.stringToDate Error: failureCB is not a function"); + return; + } + if (typeof dateString == "string"){ + exec(successCB, failureCB, "Globalization", "stringToDate", [{"dateString": dateString, "options": options}]); + } + else { + console.log("Globalization.stringToDate Error: dateString is not a string"); + } +}, + + +/** +* Returns a pattern string for formatting and parsing dates according to the client's +* user preferences. It returns the pattern to the successCB callback with a +* properties object as a parameter. If there is an error obtaining the pattern, +* then the errorCB callback is invoked. +* +* The defaults are: formatLength="short" and selector="date and time" +* +* @param {Function} successCB +* @param {Function} errorCB +* @param {Object} options {optional} +* formatLength {String}: 'short', 'medium', 'long', or 'full' +* selector {String}: 'date', 'time', or 'date and time' +* +* @return Object.pattern {String}: The date and time pattern for formatting and parsing dates. +* The patterns follow Unicode Technical Standard #35 +* http://unicode.org/reports/tr35/tr35-4.html +* Object.timezone {String}: The abbreviated name of the time zone on the client +* Object.utc_offset {Number}: The current difference in seconds between the client's +* time zone and coordinated universal time. +* Object.dst_offset {Number}: The current daylight saving time offset in seconds +* between the client's non-daylight saving's time zone +* and the client's daylight saving's time zone. +* +* @error GlobalizationError.PATTERN_ERROR +* +* Example +* globalization.getDatePattern( +* function (date) {alert('pattern:' + date.pattern + '\n');}, +* function () {}, +* {formatLength:'short'}); +*/ +getDatePattern:function(successCB, failureCB, options) { + // successCallback required + if (typeof successCB != "function") { + console.log("Globalization.getDatePattern Error: successCB is not a function"); + return; + } + + // errorCallback required + if (typeof failureCB != "function") { + console.log("Globalization.getDatePattern Error: failureCB is not a function"); + return; + } + + exec(successCB, failureCB, "Globalization", "getDatePattern", [{"options": options}]); +}, + + +/** +* Returns an array of either the names of the months or days of the week +* according to the client's user preferences and calendar. It returns the array of names to the +* successCB callback with a properties object as a parameter. If there is an error obtaining the +* names, then the errorCB callback is invoked. +* +* The defaults are: type="wide" and item="months" +* +* @param {Function} successCB +* @param {Function} errorCB +* @param {Object} options {optional} +* type {String}: 'narrow' or 'wide' +* item {String}: 'months', or 'days' +* +* @return Object.value {Array{String}}: The array of names starting from either +* the first month in the year or the +* first day of the week. +* @error GlobalizationError.UNKNOWN_ERROR +* +* Example +* globalization.getDateNames(function (names) { +* for(var i = 0; i < names.value.length; i++) { +* alert('Month:' + names.value[i] + '\n');}}, +* function () {}); +*/ +getDateNames:function(successCB, failureCB, options) { + // successCallback required + if (typeof successCB != "function") { + console.log("Globalization.getDateNames Error: successCB is not a function"); + return; + } + + // errorCallback required + if (typeof failureCB != "function") { + console.log("Globalization.getDateNames Error: failureCB is not a function"); + return; + } + exec(successCB, failureCB, "Globalization", "getDateNames", [{"options": options}]); +}, + +/** +* Returns whether daylight savings time is in effect for a given date using the client's +* time zone and calendar. It returns whether or not daylight savings time is in effect +* to the successCB callback with a properties object as a parameter. If there is an error +* reading the date, then the errorCB callback is invoked. +* +* @param {Date} date +* @param {Function} successCB +* @param {Function} errorCB +* +* @return Object.dst {Boolean}: The value "true" indicates that daylight savings time is +* in effect for the given date and "false" indicate that it is not. +* +* @error GlobalizationError.UNKNOWN_ERROR +* +* Example +* globalization.isDayLightSavingsTime(new Date(), +* function (date) {alert('dst:' + date.dst + '\n');} +* function () {}); +*/ +isDayLightSavingsTime:function(date, successCB, failureCB) { + // successCallback required + if (typeof successCB != "function") { + console.log("Globalization.isDayLightSavingsTime Error: successCB is not a function"); + return; + } + + // errorCallback required + if (typeof failureCB != "function") { + console.log("Globalization.isDayLightSavingsTime Error: failureCB is not a function"); + return; + } + + + if (date instanceof Date){ + var dateValue; + dateValue = date.valueOf(); + exec(successCB, failureCB, "Globalization", "isDayLightSavingsTime", [{"date": dateValue}]); + } + else { + console.log("Globalization.isDayLightSavingsTime Error: date is not a Date object"); + } + +}, + +/** +* Returns the first day of the week according to the client's user preferences and calendar. +* The days of the week are numbered starting from 1 where 1 is considered to be Sunday. +* It returns the day to the successCB callback with a properties object as a parameter. +* If there is an error obtaining the pattern, then the errorCB callback is invoked. +* +* @param {Function} successCB +* @param {Function} errorCB +* +* @return Object.value {Number}: The number of the first day of the week. +* +* @error GlobalizationError.UNKNOWN_ERROR +* +* Example +* globalization.getFirstDayOfWeek(function (day) +* { alert('Day:' + day.value + '\n');}, +* function () {}); +*/ +getFirstDayOfWeek:function(successCB, failureCB) { + // successCallback required + if (typeof successCB != "function") { + console.log("Globalization.getFirstDayOfWeek Error: successCB is not a function"); + return; + } + + // errorCallback required + if (typeof failureCB != "function") { + console.log("Globalization.getFirstDayOfWeek Error: failureCB is not a function"); + return; + } + + exec(successCB, failureCB, "Globalization", "getFirstDayOfWeek", []); +}, + + +/** +* Returns a number formatted as a string according to the client's user preferences. +* It returns the formatted number string to the successCB callback with a properties object as a +* parameter. If there is an error formatting the number, then the errorCB callback is invoked. +* +* The defaults are: type="decimal" +* +* @param {Number} number +* @param {Function} successCB +* @param {Function} errorCB +* @param {Object} options {optional} +* type {String}: 'decimal', "percent", or 'currency' +* +* @return Object.value {String}: The formatted number string. +* +* @error GlobalizationError.FORMATTING_ERROR +* +* Example +* globalization.numberToString(3.25, +* function (number) {alert('number:' + number.value + '\n');}, +* function () {}, +* {type:'decimal'}); +*/ +numberToString:function(number, successCB, failureCB, options) { + // successCallback required + if (typeof successCB != "function") { + console.log("Globalization.numberToString Error: successCB is not a function"); + return; + } + + // errorCallback required + if (typeof failureCB != "function") { + console.log("Globalization.numberToString Error: failureCB is not a function"); + return; + } + + if(typeof number == "number") { + exec(successCB, failureCB, "Globalization", "numberToString", [{"number": number, "options": options}]); + } + else { + console.log("Globalization.numberToString Error: number is not a number"); + } +}, + +/** +* Parses a number formatted as a string according to the client's user preferences and +* returns the corresponding number. It returns the number to the successCB callback with a +* properties object as a parameter. If there is an error parsing the number string, then +* the errorCB callback is invoked. +* +* The defaults are: type="decimal" +* +* @param {String} numberString +* @param {Function} successCB +* @param {Function} errorCB +* @param {Object} options {optional} +* type {String}: 'decimal', "percent", or 'currency' +* +* @return Object.value {Number}: The parsed number. +* +* @error GlobalizationError.PARSING_ERROR +* +* Example +* globalization.stringToNumber('1234.56', +* function (number) {alert('Number:' + number.value + '\n');}, +* function () { alert('Error parsing number');}); +*/ +stringToNumber:function(numberString, successCB, failureCB, options) { + // successCallback required + if (typeof successCB != "function") { + console.log("Globalization.stringToNumber Error: successCB is not a function"); + return; + } + + // errorCallback required + if (typeof failureCB != "function") { + console.log("Globalization.stringToNumber Error: failureCB is not a function"); + return; + } + + if(typeof numberString == "string") { + exec(successCB, failureCB, "Globalization", "stringToNumber", [{"numberString": numberString, "options": options}]); + } + else { + console.log("Globalization.stringToNumber Error: numberString is not a string"); + } +}, + +/** +* Returns a pattern string for formatting and parsing numbers according to the client's user +* preferences. It returns the pattern to the successCB callback with a properties object as a +* parameter. If there is an error obtaining the pattern, then the errorCB callback is invoked. +* +* The defaults are: type="decimal" +* +* @param {Function} successCB +* @param {Function} errorCB +* @param {Object} options {optional} +* type {String}: 'decimal', "percent", or 'currency' +* +* @return Object.pattern {String}: The number pattern for formatting and parsing numbers. +* The patterns follow Unicode Technical Standard #35. +* http://unicode.org/reports/tr35/tr35-4.html +* Object.symbol {String}: The symbol to be used when formatting and parsing +* e.g., percent or currency symbol. +* Object.fraction {Number}: The number of fractional digits to use when parsing and +* formatting numbers. +* Object.rounding {Number}: The rounding increment to use when parsing and formatting. +* Object.positive {String}: The symbol to use for positive numbers when parsing and formatting. +* Object.negative: {String}: The symbol to use for negative numbers when parsing and formatting. +* Object.decimal: {String}: The decimal symbol to use for parsing and formatting. +* Object.grouping: {String}: The grouping symbol to use for parsing and formatting. +* +* @error GlobalizationError.PATTERN_ERROR +* +* Example +* globalization.getNumberPattern( +* function (pattern) {alert('Pattern:' + pattern.pattern + '\n');}, +* function () {}); +*/ +getNumberPattern:function(successCB, failureCB, options) { + // successCallback required + if (typeof successCB != "function") { + console.log("Globalization.getNumberPattern Error: successCB is not a function"); + return; + } + + // errorCallback required + if (typeof failureCB != "function") { + console.log("Globalization.getNumberPattern Error: failureCB is not a function"); + return; + } + + exec(successCB, failureCB, "Globalization", "getNumberPattern", [{"options": options}]); +}, + +/** +* Returns a pattern string for formatting and parsing currency values according to the client's +* user preferences and ISO 4217 currency code. It returns the pattern to the successCB callback with a +* properties object as a parameter. If there is an error obtaining the pattern, then the errorCB +* callback is invoked. +* +* @param {String} currencyCode +* @param {Function} successCB +* @param {Function} errorCB +* +* @return Object.pattern {String}: The currency pattern for formatting and parsing currency values. +* The patterns follow Unicode Technical Standard #35 +* http://unicode.org/reports/tr35/tr35-4.html +* Object.code {String}: The ISO 4217 currency code for the pattern. +* Object.fraction {Number}: The number of fractional digits to use when parsing and +* formatting currency. +* Object.rounding {Number}: The rounding increment to use when parsing and formatting. +* Object.decimal: {String}: The decimal symbol to use for parsing and formatting. +* Object.grouping: {String}: The grouping symbol to use for parsing and formatting. +* +* @error GlobalizationError.FORMATTING_ERROR +* +* Example +* globalization.getCurrencyPattern('EUR', +* function (currency) {alert('Pattern:' + currency.pattern + '\n');} +* function () {}); +*/ +getCurrencyPattern:function(currencyCode, successCB, failureCB) { + // successCallback required + if (typeof successCB != "function") { + console.log("Globalization.getCurrencyPattern Error: successCB is not a function"); + return; + } + + // errorCallback required + if (typeof failureCB != "function") { + console.log("Globalization.getCurrencyPattern Error: failureCB is not a function"); + return; + } + + if(typeof currencyCode == "string") { + exec(successCB, failureCB, "Globalization", "getCurrencyPattern", [{"currencyCode": currencyCode}]); + } + else { + console.log("Globalization.getCurrencyPattern Error: currencyCode is not a currency code"); + } +} + +}; + +module.exports = globalization; + +}); + // file: lib/ios/plugin/ios/Contact.js define("cordova/plugin/ios/Contact", function(require, exports, module) { + var exec = require('cordova/exec'), ContactError = require('cordova/plugin/ContactError'); @@ -4326,10 +5092,12 @@ module.exports = { } } }; + }); // file: lib/ios/plugin/ios/Entry.js define("cordova/plugin/ios/Entry", function(require, exports, module) { + module.exports = { toURL:function() { // TODO: refactor path in a cross-platform way so we can eliminate @@ -4341,10 +5109,12 @@ module.exports = { return "file://localhost" + this.fullPath; } }; + }); // file: lib/ios/plugin/ios/FileReader.js define("cordova/plugin/ios/FileReader", function(require, exports, module) { + var exec = require('cordova/exec'), FileError = require('cordova/plugin/FileError'), FileReader = require('cordova/plugin/FileReader'), @@ -4432,33 +5202,18 @@ module.exports = { "File", "readAsText", [this.fileName, enc]); } }; + }); // file: lib/ios/plugin/ios/console.js define("cordova/plugin/ios/console", function(require, exports, module) { + var exec = require('cordova/exec'); /** - * This class provides access to the debugging console. - * @constructor + * create a nice string for an object */ -var DebugConsole = function() { - this.winConsole = window.console; - this.logLevel = DebugConsole.INFO_LEVEL; -}; - -// from most verbose, to least verbose -DebugConsole.ALL_LEVEL = 1; // same as first level -DebugConsole.INFO_LEVEL = 1; -DebugConsole.WARN_LEVEL = 2; -DebugConsole.ERROR_LEVEL = 4; -DebugConsole.NONE_LEVEL = 8; - -DebugConsole.prototype.setLevel = function(level) { - this.logLevel = level; -}; - -var stringify = function(message) { +function stringify(message) { try { if (typeof message === "object" && JSON && JSON.stringify) { try { @@ -4473,52 +5228,54 @@ var stringify = function(message) { } catch (e) { return e.toString(); } -}; +} /** - * Print a normal log message to the console - * @param {Object|String} message Message or object to print to the console + * Wrapper one of the console logging methods, so that + * the Cordova logging native is called, then the original. */ -DebugConsole.prototype.log = function(message) { - if (this.logLevel <= DebugConsole.INFO_LEVEL) { - exec(null, null, 'Debug Console', 'log', [ stringify(message), { logLevel: 'INFO' } ]); - } - else if (this.winConsole && this.winConsole.log) { - this.winConsole.log(message); - } -}; +function wrappedMethod(console, method) { + var origMethod = console[method]; -/** - * Print a warning message to the console - * @param {Object|String} message Message or object to print to the console - */ -DebugConsole.prototype.warn = function(message) { - if (this.logLevel <= DebugConsole.WARN_LEVEL) { - exec(null, null, 'Debug Console', 'log', [ stringify(message), { logLevel: 'WARN' } ]); - } - else if (this.winConsole && this.winConsole.warn) { - this.winConsole.warn(message); - } -}; + return function(message) { + exec(null, null, + 'Debug Console', 'log', + [ stringify(message), { logLevel: method.toUpperCase() } ] + ); -/** - * Print an error message to the console - * @param {Object|String} message Message or object to print to the console - */ -DebugConsole.prototype.error = function(message) { - if (this.logLevel <= DebugConsole.ERROR_LEVEL) { - exec(null, null, 'Debug Console', 'log', [ stringify(message), { logLevel: 'ERROR' } ]); - } - else if (this.winConsole && this.winConsole.error){ - this.winConsole.error(message); - } -}; + if (!origMethod) return; + + origMethod.apply(console, arguments); + }; +} + +var console = window.console || {}; + +// 2012-10-06 pmuellr - marking setLevel() method and logLevel property +// on console as deprecated; +// it didn't do anything useful, since the level constants weren't accessible +// to anyone + +console.setLevel = function() {}; +console.logLevel = 0; + +// wrapper the logging messages + +var methods = ["log", "debug", "info", "warn", "error"]; + +for (var i=0; i<methods.length; i++) { + var method = methods[i]; + + console[method] = wrappedMethod(console, method); +} + +module.exports = console; -module.exports = new DebugConsole(); }); // file: lib/ios/plugin/ios/contacts.js define("cordova/plugin/ios/contacts", function(require, exports, module) { + var exec = require('cordova/exec'); /** @@ -4560,26 +5317,12 @@ module.exports = { exec(win, null, "Contacts","chooseContact", [options]); } }; -}); - -// file: lib/ios/plugin/ios/nativecomm.js -define("cordova/plugin/ios/nativecomm", function(require, exports, module) { -var cordova = require('cordova'); - -/** - * Called by native code to retrieve all queued commands and clear the queue. - */ -module.exports = function() { - // Each entry in commandQueue is a JSON string already. - var json = '[' + cordova.commandQueue.join(',') + ']'; - cordova.commandQueue.length = 0; - return json; -}; }); // file: lib/ios/plugin/ios/notification.js define("cordova/plugin/ios/notification", function(require, exports, module) { + var Media = require('cordova/plugin/Media'); module.exports = { @@ -4587,10 +5330,12 @@ module.exports = { (new Media('beep.wav')).play(); } }; + }); // file: lib/common/plugin/logger.js define("cordova/plugin/logger", function(require, exports, module) { + //------------------------------------------------------------------------------ // The logger module exports the following properties/functions: // @@ -4818,9 +5563,20 @@ document.addEventListener("deviceready", logger.__onDeviceReady, false); // file: lib/common/plugin/network.js define("cordova/plugin/network", function(require, exports, module) { + var exec = require('cordova/exec'), cordova = require('cordova'), - channel = require('cordova/channel'); + channel = require('cordova/channel'), + utils = require('cordova/utils'); + +// Link the onLine property with the Cordova-supplied network info. +// This works because we clobber the naviagtor object with our own +// object in bootstrap.js. +if (typeof navigator != 'undefined') { + utils.defineGetter(navigator, 'onLine', function() { + return this.connection.type != 'none'; + }); +} var NetworkConnection = function () { this.type = null; @@ -4830,7 +5586,7 @@ var NetworkConnection = function () { var me = this; - channel.onCordovaReady.subscribeOnce(function() { + channel.onCordovaReady.subscribe(function() { me.getInfo(function (info) { me.type = info; if (info === "none") { @@ -4878,10 +5634,12 @@ NetworkConnection.prototype.getInfo = function (successCallback, errorCallback) }; module.exports = new NetworkConnection(); + }); // file: lib/common/plugin/notification.js define("cordova/plugin/notification", function(require, exports, module) { + var exec = require('cordova/exec'); /** @@ -4938,10 +5696,12 @@ module.exports = { exec(null, null, "Notification", "beep", [count]); } }; + }); // file: lib/common/plugin/requestFileSystem.js define("cordova/plugin/requestFileSystem", function(require, exports, module) { + var FileError = require('cordova/plugin/FileError'), FileSystem = require('cordova/plugin/FileSystem'), exec = require('cordova/exec'); @@ -4982,10 +5742,12 @@ var requestFileSystem = function(type, size, successCallback, errorCallback) { }; module.exports = requestFileSystem; + }); // file: lib/common/plugin/resolveLocalFileSystemURI.js define("cordova/plugin/resolveLocalFileSystemURI", function(require, exports, module) { + var DirectoryEntry = require('cordova/plugin/DirectoryEntry'), FileEntry = require('cordova/plugin/FileEntry'), FileError = require('cordova/plugin/FileError'), @@ -5039,6 +5801,7 @@ module.exports = function(uri, successCallback, errorCallback) { // file: lib/common/plugin/splashscreen.js define("cordova/plugin/splashscreen", function(require, exports, module) { + var exec = require('cordova/exec'); var splashscreen = { @@ -5051,13 +5814,26 @@ var splashscreen = { }; module.exports = splashscreen; + }); // file: lib/common/utils.js define("cordova/utils", function(require, exports, module) { + var utils = exports; /** + * Defines a property getter for obj[key]. + */ +utils.defineGetter = function(obj, key, func) { + if (Object.defineProperty) { + Object.defineProperty(obj, key, { get: func }); + } else { + obj.__defineGetter__(key, func); + } +}; + +/** * Returns an indication of whether the argument is an array or not */ utils.isArray = function(a) { @@ -5099,7 +5875,7 @@ utils.clone = function(obj) { }; /** - * Returns a wrappered version of the function + * Returns a wrapped version of the function */ utils.close = function(context, func, params) { if (typeof params == 'undefined') { @@ -5144,8 +5920,8 @@ utils.extend = (function() { * Alerts a message in any available way: alert or console.log. */ utils.alert = function(msg) { - if (alert) { - alert(msg); + if (window.alert) { + window.alert(msg); } else if (console && console.log) { console.log(msg); } @@ -5248,7 +6024,16 @@ function formatted(object, formatChar) { window.cordova = require('cordova'); // file: lib/scripts/bootstrap.js + (function (context) { + // 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. + if (typeof navigator != 'undefined') { + var CordovaNavigator = function () {}; + CordovaNavigator.prototype = navigator; + navigator = new CordovaNavigator(); + } + var channel = require("cordova/channel"), _self = { boot: function () { @@ -5261,7 +6046,7 @@ window.cordova = require('cordova'); platform = require('cordova/platform'); // Drop the common globals into the window object, but be nice and don't overwrite anything. - builder.build(base.objects).intoButDontClobber(window); + builder.build(base.objects).intoButDoNotClobber(window); // Drop the platform-specific globals into the window object // and clobber any existing object. @@ -5290,7 +6075,7 @@ window.cordova = require('cordova'); }; // boot up once native side is ready - channel.onNativeReady.subscribeOnce(_self.boot); + channel.onNativeReady.subscribe(_self.boot); // _nativeReady is global variable that the native side can set // to signify that the native code is ready. It is a global since |