diff --git a/README.md b/README.md index d2d2e99f..a4ebee6d 100755 --- a/README.md +++ b/README.md @@ -29,11 +29,11 @@ Building To create your cordova.jar, copy the commons codec: - mv commons-codec-1.6.jar framework/libs + mv commons-codec-1.7.jar framework/libs then run in the framework directory: - android update project -p . -t android-16 + android update project -p . -t android-17 ant jar diff --git a/VERSION b/VERSION index d2a7ed1f..276cbf9e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.3.0rc1 +2.3.0 diff --git a/bin/create b/bin/create index e01cef98..d1380cbe 100755 --- a/bin/create +++ b/bin/create @@ -23,7 +23,7 @@ # set -e -if [ -n "$1" ] && [ "$1" == "-h" ] +if [ -z "$1" ] || [ "$1" == "-h" ] then echo 'usage: create path package activity' echo "Make sure the Android SDK tools folder is in your PATH!" diff --git a/bin/templates/project/assets/www/index.html b/bin/templates/project/assets/www/index.html index 0f8a50bc..92b61beb 100644 --- a/bin/templates/project/assets/www/index.html +++ b/bin/templates/project/assets/www/index.html @@ -33,7 +33,7 @@

Device is Ready

- + + diff --git a/framework/src/org/apache/cordova/App.java b/framework/src/org/apache/cordova/App.java index dad34a07..afdbf3f2 100755 --- a/framework/src/org/apache/cordova/App.java +++ b/framework/src/org/apache/cordova/App.java @@ -64,7 +64,7 @@ public class App extends CordovaPlugin { this.loadUrl(args.getString(0), args.optJSONObject(1)); } else if (action.equals("cancelLoadUrl")) { - this.cancelLoadUrl(); + //this.cancelLoadUrl(); } else if (action.equals("clearHistory")) { this.clearHistory(); @@ -160,14 +160,6 @@ public class App extends CordovaPlugin { this.webView.showWebPage(url, openExternal, clearHistory, params); } - /** - * Cancel loadUrl before it has been loaded (Only works on a CordovaInterface class) - */ - @Deprecated - public void cancelLoadUrl() { - this.cordova.cancelLoadUrl(); - } - /** * Clear page history for the app. */ diff --git a/framework/src/org/apache/cordova/CameraLauncher.java b/framework/src/org/apache/cordova/CameraLauncher.java index 49a68c03..f9edd10f 100755 --- a/framework/src/org/apache/cordova/CameraLauncher.java +++ b/framework/src/org/apache/cordova/CameraLauncher.java @@ -322,7 +322,8 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect } // If all this is true we shouldn't compress the image. - if (this.targetHeight == -1 && this.targetWidth == -1 && this.mQuality == 100 && rotate == 0) { + if (this.targetHeight == -1 && this.targetWidth == -1 && this.mQuality == 100 && + !this.correctOrientation) { writeUncompressedImage(uri); this.callbackContext.success(uri.toString()); diff --git a/framework/src/org/apache/cordova/ContactAccessorSdk5.java b/framework/src/org/apache/cordova/ContactAccessorSdk5.java index 73d05bc0..3d81648a 100644 --- a/framework/src/org/apache/cordova/ContactAccessorSdk5.java +++ b/framework/src/org/apache/cordova/ContactAccessorSdk5.java @@ -219,6 +219,7 @@ public class ContactAccessorSdk5 extends ContactAccessor { columnsToFetch.add(ContactsContract.CommonDataKinds.Phone.TYPE); } if (isRequired("emails", populate)) { + columnsToFetch.add(ContactsContract.CommonDataKinds.Email._ID); columnsToFetch.add(ContactsContract.CommonDataKinds.Email.DATA); columnsToFetch.add(ContactsContract.CommonDataKinds.Email.TYPE); } @@ -1500,7 +1501,7 @@ public class ContactAccessorSdk5 extends ContactAccessor { .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE) .withValue(ContactsContract.CommonDataKinds.Email.DATA, getJsonString(email, "value")) - .withValue(ContactsContract.CommonDataKinds.Email.TYPE, getPhoneType(getJsonString(email, "type"))) + .withValue(ContactsContract.CommonDataKinds.Email.TYPE, getContactType(getJsonString(email, "type"))) .build()); } diff --git a/framework/src/org/apache/cordova/CordovaChromeClient.java b/framework/src/org/apache/cordova/CordovaChromeClient.java index 44b6bba2..be7c0c19 100755 --- a/framework/src/org/apache/cordova/CordovaChromeClient.java +++ b/framework/src/org/apache/cordova/CordovaChromeClient.java @@ -296,12 +296,17 @@ public class CordovaChromeClient extends WebChromeClient { } // console.log in api level 7: http://developer.android.com/guide/developing/debug-tasks.html + // Expect this to not compile in a future Android release! @SuppressWarnings("deprecation") @Override public void onConsoleMessage(String message, int lineNumber, String sourceID) { - LOG.d(TAG, "%s: Line %d : %s", sourceID, lineNumber, message); - super.onConsoleMessage(message, lineNumber, sourceID); + //This is only for Android 2.1 + if(android.os.Build.VERSION.SDK_INT == android.os.Build.VERSION_CODES.ECLAIR_MR1) + { + LOG.d(TAG, "%s: Line %d : %s", sourceID, lineNumber, message); + super.onConsoleMessage(message, lineNumber, sourceID); + } } @TargetApi(8) diff --git a/framework/src/org/apache/cordova/Device.java b/framework/src/org/apache/cordova/Device.java index 8967bf47..d9a02007 100644 --- a/framework/src/org/apache/cordova/Device.java +++ b/framework/src/org/apache/cordova/Device.java @@ -39,7 +39,7 @@ import android.telephony.TelephonyManager; public class Device extends CordovaPlugin { public static final String TAG = "Device"; - public static String cordovaVersion = "2.3.0rc1"; // Cordova version + public static String cordovaVersion = "2.3.0"; // Cordova version public static String platform = "Android"; // Device OS public static String uuid; // Device UUID @@ -80,7 +80,7 @@ public class Device extends CordovaPlugin { r.put("platform", Device.platform); r.put("name", this.getProductName()); r.put("cordova", Device.cordovaVersion); - r.put("model", this.getProductName()); + r.put("model", this.getModel()); callbackContext.success(r); } else { diff --git a/framework/src/org/apache/cordova/DroidGap.java b/framework/src/org/apache/cordova/DroidGap.java index efa7cb5b..6f16385f 100755 --- a/framework/src/org/apache/cordova/DroidGap.java +++ b/framework/src/org/apache/cordova/DroidGap.java @@ -1037,12 +1037,9 @@ public class DroidGap extends Activity implements CordovaInterface { @Override public boolean onKeyUp(int keyCode, KeyEvent event) { - //Determine if the focus is on the current view or not - if (appView.getHitTestResult() != null && - appView.getHitTestResult().getType() == WebView.HitTestResult.EDIT_TEXT_TYPE && - (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_MENU)) { - return appView.onKeyUp(keyCode, event); - } else if (appView.isCustomViewShowing() && keyCode == KeyEvent.KEYCODE_BACK) { + //Get whatever has focus! + View childView = appView.getFocusedChild(); + if ((appView.isCustomViewShowing() || childView != null ) && keyCode == KeyEvent.KEYCODE_BACK) { return appView.onKeyUp(keyCode, event); } else { return super.onKeyUp(keyCode, event); @@ -1059,10 +1056,10 @@ public class DroidGap extends Activity implements CordovaInterface { @Override public boolean onKeyDown(int keyCode, KeyEvent event) { + //Get whatever has focus! + View childView = appView.getFocusedChild(); //Determine if the focus is on the current view or not - if (appView.getHitTestResult() != null && - appView.getHitTestResult().getType() == WebView.HitTestResult.EDIT_TEXT_TYPE && - keyCode == KeyEvent.KEYCODE_BACK) { + if (childView != null && keyCode == KeyEvent.KEYCODE_BACK) { return appView.onKeyDown(keyCode, event); } else diff --git a/framework/src/org/apache/cordova/FileTransfer.java b/framework/src/org/apache/cordova/FileTransfer.java index fdc9c75d..9bec20c9 100644 --- a/framework/src/org/apache/cordova/FileTransfer.java +++ b/framework/src/org/apache/cordova/FileTransfer.java @@ -676,10 +676,11 @@ public class FileTransfer extends CordovaPlugin { progress.setTotal(connection.getContentLength()); } - FileOutputStream outputStream = new FileOutputStream(file); + FileOutputStream outputStream = null; InputStream inputStream = null; try { + outputStream = new FileOutputStream(file); inputStream = getInputStream(connection); synchronized (context) { if (context.aborted) { diff --git a/framework/src/org/apache/cordova/FileUtils.java b/framework/src/org/apache/cordova/FileUtils.java index 8aff2629..35496e72 100755 --- a/framework/src/org/apache/cordova/FileUtils.java +++ b/framework/src/org/apache/cordova/FileUtils.java @@ -112,11 +112,29 @@ public class FileUtils extends CordovaPlugin { callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, b)); } else if (action.equals("readAsText")) { - String s = this.readAsText(args.getString(0), args.getString(1)); + int start = 0; + int end = Integer.MAX_VALUE; + if (args.length() >= 3) { + start = args.getInt(2); + } + if (args.length() >= 4) { + end = args.getInt(3); + } + + String s = this.readAsText(args.getString(0), args.getString(1), start, end); callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, s)); } else if (action.equals("readAsDataURL")) { - String s = this.readAsDataURL(args.getString(0)); + int start = 0; + int end = Integer.MAX_VALUE; + if (args.length() >= 2) { + start = args.getInt(1); + } + if (args.length() >= 3) { + end = args.getInt(2); + } + + String s = this.readAsDataURL(args.getString(0), start, end); callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, s)); } else if (action.equals("write")) { @@ -932,17 +950,27 @@ public class FileUtils extends CordovaPlugin { * @param filename The name of the file. * @param encoding The encoding to return contents as. Typical value is UTF-8. * (see http://www.iana.org/assignments/character-sets) + * @param start Start position in the file. + * @param end End position to stop at (exclusive). * @return Contents of file. * @throws FileNotFoundException, IOException */ - public String readAsText(String filename, String encoding) throws FileNotFoundException, IOException { + public String readAsText(String filename, String encoding, int start, int end) throws FileNotFoundException, IOException { + int diff = end - start; byte[] bytes = new byte[1000]; BufferedInputStream bis = new BufferedInputStream(getPathFromUri(filename), 1024); ByteArrayOutputStream bos = new ByteArrayOutputStream(); int numRead = 0; - while ((numRead = bis.read(bytes, 0, 1000)) >= 0) { + + if (start > 0) { + bis.skip(start); + } + + while ( diff > 0 && (numRead = bis.read(bytes, 0, Math.min(1000, diff))) >= 0) { + diff -= numRead; bos.write(bytes, 0, numRead); } + return new String(bos.toByteArray(), encoding); } @@ -953,12 +981,19 @@ public class FileUtils extends CordovaPlugin { * @return Contents of file = data:;base64, * @throws FileNotFoundException, IOException */ - public String readAsDataURL(String filename) throws FileNotFoundException, IOException { + public String readAsDataURL(String filename, int start, int end) throws FileNotFoundException, IOException { + int diff = end - start; byte[] bytes = new byte[1000]; BufferedInputStream bis = new BufferedInputStream(getPathFromUri(filename), 1024); ByteArrayOutputStream bos = new ByteArrayOutputStream(); int numRead = 0; - while ((numRead = bis.read(bytes, 0, 1000)) >= 0) { + + if (start > 0) { + bis.skip(start); + } + + while (diff > 0 && (numRead = bis.read(bytes, 0, Math.min(1000, diff))) >= 0) { + diff -= numRead; bos.write(bytes, 0, numRead); } @@ -984,15 +1019,21 @@ public class FileUtils extends CordovaPlugin { * @return a mime type */ public static String getMimeType(String filename) { - // Stupid bug in getFileExtensionFromUrl when the file name has a space - // So we need to replace the space with a url encoded %20 - String url = filename.replace(" ", "%20"); - MimeTypeMap map = MimeTypeMap.getSingleton(); - String extension = MimeTypeMap.getFileExtensionFromUrl(url); - if (extension.toLowerCase().equals("3ga")) { - return "audio/3gpp"; + if (filename != null) { + // Stupid bug in getFileExtensionFromUrl when the file name has a space + // So we need to replace the space with a url encoded %20 + + // CB-2185: Stupid bug not putting JPG extension in the mime-type map + String url = filename.replace(" ", "%20").toLowerCase(); + MimeTypeMap map = MimeTypeMap.getSingleton(); + String extension = MimeTypeMap.getFileExtensionFromUrl(url); + if (extension.toLowerCase().equals("3ga")) { + return "audio/3gpp"; + } else { + return map.getMimeTypeFromExtension(extension); + } } else { - return map.getMimeTypeFromExtension(extension); + return ""; } } diff --git a/framework/src/org/apache/cordova/InAppBrowser.java b/framework/src/org/apache/cordova/InAppBrowser.java index 338d3440..886a95b0 100644 --- a/framework/src/org/apache/cordova/InAppBrowser.java +++ b/framework/src/org/apache/cordova/InAppBrowser.java @@ -18,7 +18,6 @@ */ package org.apache.cordova; -import java.io.InputStream; import java.util.HashMap; import java.util.StringTokenizer; @@ -29,12 +28,12 @@ import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import android.annotation.SuppressLint; import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.graphics.Bitmap; -import android.graphics.BitmapFactory; import android.net.Uri; import android.text.InputType; import android.util.Log; @@ -56,18 +55,18 @@ import android.widget.EditText; import android.widget.LinearLayout; import android.widget.RelativeLayout; +@SuppressLint("SetJavaScriptEnabled") public class InAppBrowser extends CordovaPlugin { private static final String NULL = "null"; protected static final String LOG_TAG = "InAppBrowser"; private static final String SELF = "_self"; private static final String SYSTEM = "_system"; - private static final String BLANK = "_blank"; + // private static final String BLANK = "_blank"; private static final String LOCATION = "location"; - private static int CLOSE_EVENT = 0; - private static int LOCATION_CHANGED_EVENT = 1; - - private String browserCallbackId = null; + private static final String EXIT_EVENT = "exit"; + private static final String LOAD_START_EVENT = "loadstart"; + private static final String LOAD_STOP_EVENT = "loadstop"; private Dialog dialog; private WebView inAppWebView; @@ -128,17 +127,16 @@ public class InAppBrowser extends CordovaPlugin { else if (action.equals("close")) { closeDialog(); - JSONObject obj = new JSONObject(); - obj.put("type", CLOSE_EVENT); - - PluginResult pluginResult = new PluginResult(status, obj); + PluginResult pluginResult = new PluginResult(PluginResult.Status.OK); pluginResult.setKeepCallback(false); this.callbackContext.sendPluginResult(pluginResult); } else { status = PluginResult.Status.INVALID_ACTION; } - this.callbackContext.sendPluginResult(new PluginResult(status, result)); + PluginResult pluginResult = new PluginResult(status, result); + pluginResult.setKeepCallback(true); + this.callbackContext.sendPluginResult(pluginResult); } catch (JSONException e) { this.callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION)); } @@ -208,8 +206,15 @@ public class InAppBrowser extends CordovaPlugin { * Closes the dialog */ private void closeDialog() { - // TODO: fire 'exit' event - this.webView.sendJavascript("cordova.fireWindowEvent('exit');"); + try { + JSONObject obj = new JSONObject(); + obj.put("type", EXIT_EVENT); + + sendUpdate(obj, false); + } catch (JSONException ex) { + Log.d(LOG_TAG, "Should never happen"); + } + if (dialog != null) { dialog.dismiss(); } @@ -301,7 +306,7 @@ public class InAppBrowser extends CordovaPlugin { public void onDismiss(DialogInterface dialog) { try { JSONObject obj = new JSONObject(); - obj.put("type", CLOSE_EVENT); + obj.put("type", EXIT_EVENT); sendUpdate(obj, false); } catch (JSONException e) { @@ -316,7 +321,7 @@ public class InAppBrowser extends CordovaPlugin { // Toolbar layout RelativeLayout toolbar = new RelativeLayout(cordova.getActivity()); - toolbar.setLayoutParams(new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT, this.dpToPixels(44))); + toolbar.setLayoutParams(new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, this.dpToPixels(44))); toolbar.setPadding(this.dpToPixels(2), this.dpToPixels(2), this.dpToPixels(2), this.dpToPixels(2)); toolbar.setHorizontalGravity(Gravity.LEFT); toolbar.setVerticalGravity(Gravity.TOP); @@ -330,7 +335,7 @@ public class InAppBrowser extends CordovaPlugin { // Back button Button back = new Button(cordova.getActivity()); - RelativeLayout.LayoutParams backLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.FILL_PARENT); + RelativeLayout.LayoutParams backLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); backLayoutParams.addRule(RelativeLayout.ALIGN_LEFT); back.setLayoutParams(backLayoutParams); back.setContentDescription("Back Button"); @@ -344,7 +349,7 @@ public class InAppBrowser extends CordovaPlugin { // Forward button Button forward = new Button(cordova.getActivity()); - RelativeLayout.LayoutParams forwardLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.FILL_PARENT); + RelativeLayout.LayoutParams forwardLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); forwardLayoutParams.addRule(RelativeLayout.RIGHT_OF, 2); forward.setLayoutParams(forwardLayoutParams); forward.setContentDescription("Forward Button"); @@ -358,7 +363,7 @@ public class InAppBrowser extends CordovaPlugin { // Edit Text Box edittext = new EditText(cordova.getActivity()); - RelativeLayout.LayoutParams textLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT); + RelativeLayout.LayoutParams textLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); textLayoutParams.addRule(RelativeLayout.RIGHT_OF, 1); textLayoutParams.addRule(RelativeLayout.LEFT_OF, 5); edittext.setLayoutParams(textLayoutParams); @@ -381,7 +386,7 @@ public class InAppBrowser extends CordovaPlugin { // Close button Button close = new Button(cordova.getActivity()); - RelativeLayout.LayoutParams closeLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.FILL_PARENT); + RelativeLayout.LayoutParams closeLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); closeLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); close.setLayoutParams(closeLayoutParams); forward.setContentDescription("Close Button"); @@ -395,7 +400,7 @@ public class InAppBrowser extends CordovaPlugin { // WebView inAppWebView = new WebView(cordova.getActivity()); - inAppWebView.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); + inAppWebView.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); inAppWebView.setWebChromeClient(new WebChromeClient()); WebViewClient client = new InAppBrowserClient(thatWebView, edittext); inAppWebView.setWebViewClient(client); @@ -403,7 +408,15 @@ public class InAppBrowser extends CordovaPlugin { settings.setJavaScriptEnabled(true); settings.setJavaScriptCanOpenWindowsAutomatically(true); settings.setBuiltInZoomControls(true); + /** + * We need to be careful of this line as a future Android release may deprecate it out of existence. + * Can't replace it with the API 8 level call right now as our minimum SDK is 7 until May 2013 + */ + // @TODO: replace with settings.setPluginState(android.webkit.WebSettings.PluginState.ON) settings.setPluginsEnabled(true); + settings.setDatabaseEnabled(true); + String databasePath = cordova.getActivity().getApplicationContext().getDir("inAppBrowserDB", Context.MODE_PRIVATE).getPath(); + settings.setDatabasePath(databasePath); settings.setDomStorageEnabled(true); inAppWebView.loadUrl(url); inAppWebView.setId(6); @@ -432,18 +445,13 @@ public class InAppBrowser extends CordovaPlugin { WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); lp.copyFrom(dialog.getWindow().getAttributes()); - lp.width = WindowManager.LayoutParams.FILL_PARENT; - lp.height = WindowManager.LayoutParams.FILL_PARENT; + lp.width = WindowManager.LayoutParams.MATCH_PARENT; + lp.height = WindowManager.LayoutParams.MATCH_PARENT; dialog.setContentView(main); dialog.show(); dialog.getWindow().setAttributes(lp); } - - private Bitmap loadDrawable(String filename) throws java.io.IOException { - InputStream input = cordova.getActivity().getAssets().open(filename); - return BitmapFactory.decodeStream(input); - } }; this.cordova.getActivity().runOnUiThread(runnable); return ""; @@ -455,11 +463,9 @@ public class InAppBrowser extends CordovaPlugin { * @param obj a JSONObject contain event payload information */ private void sendUpdate(JSONObject obj, boolean keepCallback) { - if (this.browserCallbackId != null) { - PluginResult result = new PluginResult(PluginResult.Status.OK, obj); - result.setKeepCallback(keepCallback); - this.callbackContext.sendPluginResult(result); - } + PluginResult result = new PluginResult(PluginResult.Status.OK, obj); + result.setKeepCallback(keepCallback); + this.callbackContext.sendPluginResult(result); } /** @@ -500,14 +506,29 @@ public class InAppBrowser extends CordovaPlugin { edittext.setText(newloc); } - // TODO: Fire 'loadstart' event only on the InAppBrowser object - this.webView.sendJavascript("cordova.fireWindowEvent('loadstart', '" + url + "');"); + try { + JSONObject obj = new JSONObject(); + obj.put("type", LOAD_START_EVENT); + obj.put("url", newloc); + + sendUpdate(obj, true); + } catch (JSONException ex) { + Log.d(LOG_TAG, "Should never happen"); + } } public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); - // TODO: Fire 'loadstop' event only on the InAppBrowser object - this.webView.sendJavascript("cordova.fireWindowEvent('loadstop', '" + url + "');"); + + try { + JSONObject obj = new JSONObject(); + obj.put("type", LOAD_STOP_EVENT); + obj.put("url", url); + + sendUpdate(obj, true); + } catch (JSONException ex) { + Log.d(LOG_TAG, "Should never happen"); + } } } } \ No newline at end of file diff --git a/framework/src/org/apache/cordova/api/CordovaInterface.java b/framework/src/org/apache/cordova/api/CordovaInterface.java index 6499febe..22e36b64 100755 --- a/framework/src/org/apache/cordova/api/CordovaInterface.java +++ b/framework/src/org/apache/cordova/api/CordovaInterface.java @@ -54,11 +54,6 @@ public interface CordovaInterface { */ public abstract Activity getActivity(); - @Deprecated - public abstract Context getContext(); - - @Deprecated - public abstract void cancelLoadUrl(); /** * Called when a message is sent to plugin. diff --git a/framework/src/org/apache/cordova/api/LegacyContext.java b/framework/src/org/apache/cordova/api/LegacyContext.java index c3030381..fe154f7c 100644 --- a/framework/src/org/apache/cordova/api/LegacyContext.java +++ b/framework/src/org/apache/cordova/api/LegacyContext.java @@ -43,7 +43,6 @@ public class LegacyContext implements CordovaInterface { @Deprecated public void cancelLoadUrl() { Log.i(LOG_TAG, "Replace ctx.cancelLoadUrl() with cordova.cancelLoadUrl()"); - this.cordova.cancelLoadUrl(); } @Deprecated @@ -55,7 +54,7 @@ public class LegacyContext implements CordovaInterface { @Deprecated public Context getContext() { Log.i(LOG_TAG, "Replace ctx.getContext() with cordova.getContext()"); - return this.cordova.getContext(); + return this.cordova.getActivity(); } @Deprecated diff --git a/test/assets/www/cordova.android.js b/test/assets/www/cordova.android.js index b4aa1fec..7655804b 100644 --- a/test/assets/www/cordova.android.js +++ b/test/assets/www/cordova.android.js @@ -1,6 +1,6 @@ -// commit 02b91c5313ff37d74a58f71775170afd360f4a1f +// commit 832eb92dbc908e9544bed202878906fba49667c7 -// File generated at :: Wed Oct 31 2012 10:40:25 GMT-0700 (PDT) +// File generated at :: Fri Nov 30 2012 05:23:45 GMT-0800 (PST) /* Licensed to the Apache Software Foundation (ASF) under one @@ -314,6 +314,65 @@ channel.onDeviceReady = cordova.addStickyDocumentEventHandler('deviceready'); module.exports = cordova; +}); + +// file: lib/common/argscheck.js +define("cordova/argscheck", function(require, exports, module) { + +var exec = require('cordova/exec'); +var moduleExports = module.exports; + +var typeMap = { + 'A': 'Array', + 'D': 'Date', + 'N': 'Number', + 'S': 'String', + 'F': 'Function', + 'O': 'Object' +}; + +function extractParamName(callee, argIndex) { + return (/.*?\((.*?)\)/).exec(callee)[1].split(', ')[argIndex]; +} + +function checkArgs(spec, functionName, args, opt_callee) { + if (!moduleExports.enableChecks) { + return; + } + var errMsg = null; + var type; + for (var i = 0; i < spec.length; ++i) { + var c = spec.charAt(i), + cUpper = c.toUpperCase(), + arg = args[i]; + // Asterix means allow anything. + if (c == '*') { + continue; + } + type = Object.prototype.toString.call(arg).slice(8, -1); + if ((arg === null || arg === undefined) && c == cUpper) { + continue; + } + if (type != typeMap[cUpper]) { + errMsg = 'Expected ' + typeMap[cUpper]; + break; + } + } + if (errMsg) { + errMsg += ', but got ' + type + '.'; + errMsg = 'Wrong type for parameter "' + extractParamName(opt_callee || args.callee, i) + '" of ' + functionName + ': ' + errMsg; + // Don't log when running jake test. + if (typeof jasmine == 'undefined') { + console.error(errMsg); + } + throw TypeError(errMsg); + } +} + +moduleExports.checkArgs = checkArgs; +moduleExports.enableChecks = true; + + }); // file: lib/common/builder.js @@ -329,14 +388,24 @@ function each(objects, func, context) { } } +function clobber(obj, key, value) { + obj[key] = value; + // Getters can only be overridden by getters. + if (obj[key] !== value) { + utils.defineGetter(obj, key, function() { + return value; + }); + } +} + function assignOrWrapInDeprecateGetter(obj, key, value, message) { if (message) { utils.defineGetter(obj, key, function() { - window.console && console.log(message); + console.log(message); return value; }); } else { - obj[key] = value; + clobber(obj, key, value); } } @@ -395,8 +464,11 @@ function recursiveMerge(target, src) { // If the target object is a constructor override off prototype. target.prototype[prop] = src[prop]; } else { - target[prop] = typeof src[prop] === 'object' ? recursiveMerge( - target[prop], src[prop]) : src[prop]; + if (typeof src[prop] === 'object') { + target[prop] = recursiveMerge(target[prop], src[prop]); + } else { + clobber(target, prop, src[prop]); + } } } } @@ -404,18 +476,14 @@ function recursiveMerge(target, src) { } module.exports = { - build: function (objects) { - return { - intoButDoNotClobber: function (target) { - include(target, objects, false, false); - }, - intoAndClobber: function(target) { - include(target, objects, true, false); - }, - intoAndMerge: function(target) { - include(target, objects, true, true); - } - }; + buildIntoButDoNotClobber: function(objects, target) { + include(target, objects, false, false); + }, + buildIntoAndClobber: function(objects, target) { + include(target, objects, true, false); + }, + buildIntoAndMerge: function(objects, target) { + include(target, objects, true, true); } }; @@ -701,7 +769,7 @@ module.exports = { define("cordova/common", function(require, exports, module) { module.exports = { - objects: { + defaults: { cordova: { path: 'cordova', children: { @@ -720,6 +788,9 @@ module.exports = { } } }, + open : { + path: 'cordova/plugin/InAppBrowser' + }, navigator: { children: { notification: { @@ -737,9 +808,6 @@ module.exports = { compass:{ path: 'cordova/plugin/compass' }, - connection: { - path: 'cordova/plugin/network' - }, contacts: { path: 'cordova/plugin/contacts' }, @@ -907,6 +975,15 @@ module.exports = { resolveLocalFileSystemURI:{ path: 'cordova/plugin/resolveLocalFileSystemURI' } + }, + clobbers: { + navigator: { + children: { + connection: { + path: 'cordova/plugin/network' + } + } + } } }; @@ -961,6 +1038,7 @@ var cordova = require('cordova'), function androidExec(success, fail, service, action, args) { // Set default bridge modes if they have not already been set. + // By default, we use the failsafe, since addJavascriptInterface breaks too often if (jsToNativeBridgeMode === undefined) { androidExec.setJsToNativeBridgeMode(jsToNativeModes.JS_OBJECT); } @@ -1199,7 +1277,7 @@ module.exports = { exec(null, null, "App", "show", []); }, [channel.onCordovaReady]); }, - objects: { + clobbers: { navigator: { children: { app:{ @@ -1218,6 +1296,9 @@ module.exports = { }, MediaError: { // exists natively on Android WebView on Android 4.x path: "cordova/plugin/MediaError" + }, + open: { + path: "cordova/plugin/InAppBrowser" } }, merges: { @@ -3235,6 +3316,62 @@ GlobalizationError.PATTERN_ERROR = 3; module.exports = GlobalizationError; +}); + +// file: lib/common/plugin/InAppBrowser.js +define("cordova/plugin/InAppBrowser", function(require, exports, module) { + +var exec = require('cordova/exec'); + +function InAppBrowser() +{ + var _channel = require('cordova/channel'); + this.channels = { + 'loadstart': _channel.create('loadstart'), + 'loadstop' : _channel.create('loadstop'), + 'exit' : _channel.create('exit') + }; +} + +InAppBrowser.prototype._eventHandler = function(event) +{ + if (event.type in this.channels) { + this.channels[event.type].fire(event); + } +} + +InAppBrowser.open = function(strUrl, strWindowName, strWindowFeatures) +{ + var iab = new InAppBrowser(); + var cb = function(eventname) { + iab._eventHandler(eventname); + } + exec(cb, null, "InAppBrowser", "open", [strUrl, strWindowName, strWindowFeatures]); + return iab; +} + +InAppBrowser.prototype.close = function(eventname, f) +{ + exec(null, null, "InAppBrowser", "close", []); +} + +InAppBrowser.prototype.addEventListener = function(eventname, f) +{ + if (eventname in this.channels) { + this.channels[eventname].subscribe(f); + } +} + +InAppBrowser.prototype.removeEventListener = function(eventname, f) +{ + if (eventname in this.channels) { + this.channels[eventname].unsubscribe(f); + } +} + +module.exports = InAppBrowser.open; + + }); // file: lib/common/plugin/LocalFileSystem.js @@ -3673,7 +3810,8 @@ define("cordova/plugin/accelerometer", function(require, exports, module) { * This class provides access to device accelerometer data. * @constructor */ -var utils = require("cordova/utils"), +var argscheck = require('cordova/argscheck'), + utils = require("cordova/utils"), exec = require("cordova/exec"), Acceleration = require('cordova/plugin/Acceleration'); @@ -3737,10 +3875,7 @@ var accelerometer = { * @param {AccelerationOptions} options The options for getting the accelerometer data such as timeout. (OPTIONAL) */ getCurrentAcceleration: function(successCallback, errorCallback, options) { - // successCallback required - if (typeof successCallback !== "function") { - throw "getCurrentAcceleration must be called with at least a success callback function as first parameter."; - } + argscheck.checkArgs('fFO', 'accelerometer.getCurrentAcceleration', arguments); var p; var win = function(a) { @@ -3749,7 +3884,7 @@ var accelerometer = { }; var fail = function(e) { removeListeners(p); - errorCallback(e); + errorCallback && errorCallback(e); }; p = createCallbackPair(win, fail); @@ -3769,20 +3904,16 @@ var accelerometer = { * @return String The watch id that must be passed to #clearWatch to stop watching. */ watchAcceleration: function(successCallback, errorCallback, options) { + argscheck.checkArgs('fFO', 'accelerometer.watchAcceleration', arguments); // Default interval (10 sec) var frequency = (options && options.frequency && typeof options.frequency == 'number') ? options.frequency : 10000; - // successCallback required - if (typeof successCallback !== "function") { - throw "watchAcceleration must be called with at least a success callback function as first parameter."; - } - // Keep reference to watch id, and report accel readings as often as defined in frequency var id = utils.createUUID(); var p = createCallbackPair(function(){}, function(e) { removeListeners(p); - errorCallback(e); + errorCallback && errorCallback(e); }); listeners.push(p); @@ -3798,7 +3929,7 @@ var accelerometer = { if (running) { // If we're already running then immediately invoke the success callback // but only if we have retrieved a value, sample code does not check for null ... - if(accel) { + if (accel) { successCallback(accel); } } else { @@ -4592,7 +4723,8 @@ module.exports = new Capture(); // file: lib/common/plugin/compass.js define("cordova/plugin/compass", function(require, exports, module) { -var exec = require('cordova/exec'), +var argscheck = require('cordova/argscheck'), + exec = require('cordova/exec'), utils = require('cordova/utils'), CompassHeading = require('cordova/plugin/CompassHeading'), CompassError = require('cordova/plugin/CompassError'), @@ -4607,23 +4739,13 @@ var exec = require('cordova/exec'), * @param {CompassOptions} options The options for getting the heading data (not used). */ getCurrentHeading:function(successCallback, errorCallback, options) { - // successCallback required - if (typeof successCallback !== "function") { - console.log("Compass Error: successCallback is not a function"); - return; - } - - // errorCallback optional - if (errorCallback && (typeof errorCallback !== "function")) { - console.log("Compass Error: errorCallback is not a function"); - return; - } + argscheck.checkArgs('fFO', 'compass.getCurrentHeading', arguments); var win = function(result) { var ch = new CompassHeading(result.magneticHeading, result.trueHeading, result.headingAccuracy, result.timestamp); successCallback(ch); }; - var fail = function(code) { + var fail = errorCallback && function(code) { var ce = new CompassError(code); errorCallback(ce); }; @@ -4643,22 +4765,11 @@ var exec = require('cordova/exec'), * specifies to watch via a distance filter rather than time. */ watchHeading:function(successCallback, errorCallback, options) { + argscheck.checkArgs('fFO', 'compass.watchHeading', arguments); // Default interval (100 msec) var frequency = (options !== undefined && options.frequency !== undefined) ? options.frequency : 100; var filter = (options !== undefined && options.filter !== undefined) ? options.filter : 0; - // successCallback required - if (typeof successCallback !== "function") { - console.log("Compass Error: successCallback is not a function"); - return; - } - - // errorCallback optional - if (errorCallback && (typeof errorCallback !== "function")) { - console.log("Compass Error: errorCallback is not a function"); - return; - } - var id = utils.createUUID(); if (filter > 0) { // is an iOS request for watch by filter, no timer needed @@ -4682,8 +4793,8 @@ var exec = require('cordova/exec'), // Stop javascript timer & remove from timer list if (id && timers[id]) { if (timers[id] != "iOS") { - clearInterval(timers[id]); - } else { + clearInterval(timers[id]); + } else { // is iOS watch by filter so call into device to stop exec(null, null, "Compass", "stopHeading", []); } @@ -4871,7 +4982,8 @@ for (var key in console) { // file: lib/common/plugin/contacts.js define("cordova/plugin/contacts", function(require, exports, module) { -var exec = require('cordova/exec'), +var argscheck = require('cordova/argscheck'), + exec = require('cordova/exec'), ContactError = require('cordova/plugin/ContactError'), utils = require('cordova/utils'), Contact = require('cordova/plugin/Contact'); @@ -4890,13 +5002,9 @@ var contacts = { * @return array of Contacts matching search criteria */ find:function(fields, successCB, errorCB, options) { - if (!successCB) { - throw new TypeError("You must specify a success callback for the find command."); - } - if (!fields || (utils.isArray(fields) && fields.length === 0)) { - if (typeof errorCB === "function") { - errorCB(new ContactError(ContactError.INVALID_ARGUMENT_ERROR)); - } + argscheck.checkArgs('afFO', 'contacts.find', arguments); + if (!fields.length) { + errorCB && errorCB(new ContactError(ContactError.INVALID_ARGUMENT_ERROR)); } else { var win = function(result) { var cs = []; @@ -4917,9 +5025,9 @@ var contacts = { * @returns new Contact object */ create:function(properties) { - var i; + argscheck.checkArgs('O', 'contacts.create', arguments); var contact = new Contact(); - for (i in properties) { + for (var i in properties) { if (typeof contact[i] !== 'undefined' && properties.hasOwnProperty(i)) { contact[i] = properties[i]; } @@ -4935,7 +5043,8 @@ module.exports = contacts; // file: lib/common/plugin/device.js define("cordova/plugin/device", function(require, exports, module) { -var channel = require('cordova/channel'), +var argscheck = require('cordova/argscheck'), + channel = require('cordova/channel'), utils = require('cordova/utils'), exec = require('cordova/exec'); @@ -4954,6 +5063,7 @@ function Device() { this.name = null; this.uuid = null; this.cordova = null; + this.model = null; var me = this; @@ -4965,6 +5075,7 @@ function Device() { me.name = info.name; me.uuid = info.uuid; me.cordova = info.cordova; + me.model = info.model; channel.onCordovaInfoReady.fire(); },function(e) { me.available = false; @@ -4980,20 +5091,7 @@ function Device() { * @param {Function} errorCallback The function to call when there is an error getting the heading data. (OPTIONAL) */ Device.prototype.getInfo = function(successCallback, errorCallback) { - - // successCallback required - if (typeof successCallback !== "function") { - console.log("Device Error: successCallback is not a function"); - return; - } - - // errorCallback optional - if (errorCallback && (typeof errorCallback !== "function")) { - console.log("Device Error: errorCallback is not a function"); - return; - } - - // Get info + argscheck.checkArgs('fF', 'Device.getInfo', arguments); exec(successCallback, errorCallback, "Device", "getDeviceInfo", []); }; @@ -5024,7 +5122,8 @@ 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'), +var argscheck = require('cordova/argscheck'), + utils = require('cordova/utils'), exec = require('cordova/exec'), PositionError = require('cordova/plugin/PositionError'), Position = require('cordova/plugin/Position'); @@ -5081,9 +5180,7 @@ var geolocation = { * @param {PositionOptions} options The options for getting the position data. (OPTIONAL) */ getCurrentPosition:function(successCallback, errorCallback, options) { - if (arguments.length === 0) { - throw new Error("getCurrentPosition must be called with at least one argument."); - } + argscheck.checkArgs('fFO', 'geolocation.getCurrentPosition', arguments); options = parseParameters(options); // Timer var that will fire an error callback if no position is retrieved from native @@ -5159,9 +5256,7 @@ var geolocation = { * @return String The watch id that must be passed to #clearWatch to stop watching. */ watchPosition:function(successCallback, errorCallback, options) { - if (arguments.length === 0) { - throw new Error("watchPosition must be called with at least one argument."); - } + argscheck.checkArgs('fFO', 'geolocation.getCurrentPosition', arguments); options = parseParameters(options); var id = utils.createUUID(); @@ -5223,7 +5318,8 @@ module.exports = geolocation; // file: lib/common/plugin/globalization.js define("cordova/plugin/globalization", function(require, exports, module) { -var exec = require('cordova/exec'), +var argscheck = require('cordova/argscheck'), + exec = require('cordova/exec'), GlobalizationError = require('cordova/plugin/GlobalizationError'); var globalization = { @@ -5246,18 +5342,7 @@ var globalization = { * 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; - } - + argscheck.checkArgs('fF', 'Globalization.getPreferredLanguage', arguments); exec(successCB, failureCB, "Globalization","getPreferredLanguage", []); }, @@ -5279,17 +5364,7 @@ getPreferredLanguage:function(successCB, failureCB) { * 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; - } + argscheck.checkArgs('fF', 'Globalization.getLocaleName', arguments); exec(successCB, failureCB, "Globalization","getLocaleName", []); }, @@ -5320,27 +5395,9 @@ getLocaleName:function(successCB, failureCB) { * {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"); - } + argscheck.checkArgs('dfFO', 'Globalization.dateToString', arguments); + var dateValue = date.valueOf(); + exec(successCB, failureCB, "Globalization", "dateToString", [{"date": dateValue, "options": options}]); }, @@ -5380,23 +5437,8 @@ dateToString:function(date, successCB, failureCB, options) { * {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"); - } + argscheck.checkArgs('sfFO', 'Globalization.stringToDate', arguments); + exec(successCB, failureCB, "Globalization", "stringToDate", [{"dateString": dateString, "options": options}]); }, @@ -5433,18 +5475,7 @@ stringToDate:function(dateString, successCB, failureCB, options) { * {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; - } - + argscheck.checkArgs('fFO', 'Globalization.getDatePattern', arguments); exec(successCB, failureCB, "Globalization", "getDatePattern", [{"options": options}]); }, @@ -5475,17 +5506,7 @@ getDatePattern:function(successCB, failureCB, options) { * 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; - } + argscheck.checkArgs('fFO', 'Globalization.getDateNames', arguments); exec(successCB, failureCB, "Globalization", "getDateNames", [{"options": options}]); }, @@ -5510,28 +5531,9 @@ getDateNames:function(successCB, failureCB, options) { * 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"); - } - + argscheck.checkArgs('dfF', 'Globalization.isDayLightSavingsTime', arguments); + var dateValue = date.valueOf(); + exec(successCB, failureCB, "Globalization", "isDayLightSavingsTime", [{"date": dateValue}]); }, /** @@ -5553,18 +5555,7 @@ isDayLightSavingsTime:function(date, successCB, failureCB) { * 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; - } - + argscheck.checkArgs('fF', 'Globalization.getFirstDayOfWeek', arguments); exec(successCB, failureCB, "Globalization", "getFirstDayOfWeek", []); }, @@ -5593,24 +5584,8 @@ getFirstDayOfWeek:function(successCB, failureCB) { * {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"); - } + argscheck.checkArgs('nfFO', 'Globalization.numberToString', arguments); + exec(successCB, failureCB, "Globalization", "numberToString", [{"number": number, "options": options}]); }, /** @@ -5637,24 +5612,8 @@ numberToString:function(number, successCB, failureCB, options) { * 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"); - } + argscheck.checkArgs('sfFO', 'Globalization.stringToNumber', arguments); + exec(successCB, failureCB, "Globalization", "stringToNumber", [{"numberString": numberString, "options": options}]); }, /** @@ -5690,18 +5649,7 @@ stringToNumber:function(numberString, successCB, failureCB, options) { * 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; - } - + argscheck.checkArgs('fFO', 'Globalization.getNumberPattern', arguments); exec(successCB, failureCB, "Globalization", "getNumberPattern", [{"options": options}]); }, @@ -5733,24 +5681,8 @@ getNumberPattern:function(successCB, failureCB, options) { * 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"); - } + argscheck.checkArgs('sfF', 'Globalization.getCurrencyPattern', arguments); + exec(successCB, failureCB, "Globalization", "getCurrencyPattern", [{"currencyCode": currencyCode}]); } }; @@ -6004,49 +5936,9 @@ if (typeof navigator != 'undefined') { }); } -var NetworkConnection = function () { - this.type = null; - this._firstRun = true; - this._timer = null; - this.timeout = 500; - - var me = this; - - channel.onCordovaReady.subscribe(function() { - me.getInfo(function (info) { - me.type = info; - if (info === "none") { - // set a timer if still offline at the end of timer send the offline event - me._timer = setTimeout(function(){ - cordova.fireDocumentEvent("offline"); - me._timer = null; - }, me.timeout); - } else { - // If there is a current offline event pending clear it - if (me._timer !== null) { - clearTimeout(me._timer); - me._timer = null; - } - cordova.fireDocumentEvent("online"); - } - - // should only fire this once - if (me._firstRun) { - me._firstRun = false; - channel.onCordovaConnectionReady.fire(); - } - }, - function (e) { - // If we can't get the network info we should still tell Cordova - // to fire the deviceready event. - if (me._firstRun) { - me._firstRun = false; - channel.onCordovaConnectionReady.fire(); - } - console.log("Error initializing Network Connection: " + e); - }); - }); -}; +function NetworkConnection() { + this.type = 'unknown'; +} /** * Get connection info @@ -6054,12 +5946,48 @@ var NetworkConnection = function () { * @param {Function} successCallback The function to call when the Connection data is available * @param {Function} errorCallback The function to call when there is an error getting the Connection data. (OPTIONAL) */ -NetworkConnection.prototype.getInfo = function (successCallback, errorCallback) { - // Get info +NetworkConnection.prototype.getInfo = function(successCallback, errorCallback) { exec(successCallback, errorCallback, "NetworkStatus", "getConnectionInfo", []); }; -module.exports = new NetworkConnection(); +var me = new NetworkConnection(); +var timerId = null; +var timeout = 500; + +channel.onCordovaReady.subscribe(function() { + me.getInfo(function(info) { + me.type = info; + if (info === "none") { + // set a timer if still offline at the end of timer send the offline event + timerId = setTimeout(function(){ + cordova.fireDocumentEvent("offline"); + timerId = null; + }, timeout); + } else { + // If there is a current offline event pending clear it + if (timerId !== null) { + clearTimeout(timerId); + timerId = null; + } + cordova.fireDocumentEvent("online"); + } + + // should only fire this once + if (channel.onCordovaConnectionReady.state !== 2) { + channel.onCordovaConnectionReady.fire(); + } + }, + function (e) { + // If we can't get the network info we should still tell Cordova + // to fire the deviceready event. + if (channel.onCordovaConnectionReady.state !== 2) { + channel.onCordovaConnectionReady.fire(); + } + console.log("Error initializing Network Connection: " + e); + }); +}); + +module.exports = me; }); @@ -6128,7 +6056,8 @@ module.exports = { // file: lib/common/plugin/requestFileSystem.js define("cordova/plugin/requestFileSystem", function(require, exports, module) { -var FileError = require('cordova/plugin/FileError'), +var argscheck = require('cordova/argscheck'), + FileError = require('cordova/plugin/FileError'), FileSystem = require('cordova/plugin/FileSystem'), exec = require('cordova/exec'); @@ -6140,10 +6069,9 @@ var FileError = require('cordova/plugin/FileError'), * @param errorCallback invoked if error occurs retrieving file system */ var requestFileSystem = function(type, size, successCallback, errorCallback) { + argscheck.checkArgs('nnFF', 'requestFileSystem', arguments); var fail = function(code) { - if (typeof errorCallback === 'function') { - errorCallback(new FileError(code)); - } + errorCallback && errorCallback(new FileError(code)); }; if (type < 0 || type > 3) { @@ -6152,7 +6080,7 @@ var requestFileSystem = function(type, size, successCallback, errorCallback) { // if successful, return a FileSystem object var success = function(file_system) { if (file_system) { - if (typeof successCallback === 'function') { + if (successCallback) { // grab the name and root from the file system object var result = new FileSystem(file_system.name, file_system.root); successCallback(result); @@ -6174,7 +6102,8 @@ module.exports = requestFileSystem; // file: lib/common/plugin/resolveLocalFileSystemURI.js define("cordova/plugin/resolveLocalFileSystemURI", function(require, exports, module) { -var DirectoryEntry = require('cordova/plugin/DirectoryEntry'), +var argscheck = require('cordova/argscheck'), + DirectoryEntry = require('cordova/plugin/DirectoryEntry'), FileEntry = require('cordova/plugin/FileEntry'), FileError = require('cordova/plugin/FileError'), exec = require('cordova/exec'); @@ -6186,11 +6115,10 @@ var DirectoryEntry = require('cordova/plugin/DirectoryEntry'), * @param errorCallback invoked if error occurs retrieving file system entry */ module.exports = function(uri, successCallback, errorCallback) { + argscheck.checkArgs('sFF', 'resolveLocalFileSystemURI', arguments); // error callback var fail = function(error) { - if (typeof errorCallback === 'function') { - errorCallback(new FileError(error)); - } + errorCallback && errorCallback(new FileError(error)); }; // sanity check for 'not:valid:filename' if(!uri || uri.split(":").length > 2) { @@ -6203,15 +6131,10 @@ module.exports = function(uri, successCallback, errorCallback) { var success = function(entry) { var result; if (entry) { - if (typeof successCallback === 'function') { + if (successCallback) { // create appropriate Entry object result = (entry.isDirectory) ? new DirectoryEntry(entry.name, entry.fullPath) : new FileEntry(entry.name, entry.fullPath); - try { - successCallback(result); - } - catch (e) { - console.log('Error invoking callback: ' + e); - } + successCallback(result); } } else { @@ -6259,6 +6182,30 @@ utils.defineGetter = function(obj, key, func) { } }; +utils.arrayIndexOf = function(a, item) { + if (a.indexOf) { + return a.indexOf(item); + } + var len = a.length; + for (var i = 0; i < len; ++i) { + if (a[i] == item) { + return i; + } + } + return -1; +}; + +/** + * Returns whether the item was found in the array. + */ +utils.arrayRemove = function(a, item) { + var index = utils.arrayIndexOf(a, item); + if (index != -1) { + a.splice(index, 1); + } + return index != -1; +}; + /** * Returns an indication of whether the argument is an array or not */ @@ -6454,10 +6401,10 @@ window.cordova = require('cordova'); (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(); + if (context.navigator) { + function CordovaNavigator() {} + CordovaNavigator.prototype = context.navigator; + context.navigator = new CordovaNavigator(); } var channel = require("cordova/channel"), @@ -6472,17 +6419,13 @@ 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).intoButDoNotClobber(window); + builder.buildIntoButDoNotClobber(base.defaults, context); + builder.buildIntoAndMerge(base.merges, context); + builder.buildIntoAndClobber(base.clobbers, context); - // Drop the platform-specific globals into the window object - // and clobber any existing object. - builder.build(platform.objects).intoAndClobber(window); - - // Merge the platform-specific overrides/enhancements into - // the window object. - if (typeof platform.merges !== 'undefined') { - builder.build(platform.merges).intoAndMerge(window); - } + builder.buildIntoButDoNotClobber(platform.defaults, context); + builder.buildIntoAndMerge(platform.merges, context); + builder.buildIntoAndClobber(platform.clobbers, context); // Call the platform-specific initialization platform.initialize();