aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Android/.classpath2
-rwxr-xr-xAndroid/cordova/appinfo.jarbin0 -> 1574 bytes
-rwxr-xr-xAndroid/cordova/build39
-rwxr-xr-xAndroid/cordova/clean22
-rwxr-xr-xAndroid/cordova/lib/cordova386
-rwxr-xr-xAndroid/cordova/lib/install-device49
-rwxr-xr-xAndroid/cordova/lib/install-emulator50
-rwxr-xr-xAndroid/cordova/lib/list-devices30
-rwxr-xr-xAndroid/cordova/lib/list-emulator-images32
-rwxr-xr-xAndroid/cordova/lib/list-started-emulators32
-rwxr-xr-xAndroid/cordova/lib/start-emulator91
-rwxr-xr-xAndroid/cordova/log20
-rwxr-xr-xAndroid/cordova/run81
-rwxr-xr-xAndroid/libs/cordova-2.5.0.jarbin240800 -> 0 bytes
-rwxr-xr-xAndroid/libs/cordova-2.9.0.jarbin0 -> 446253 bytes
-rwxr-xr-xAndroid/res/xml/config.xml164
-rwxr-xr-xwww/cordova-android-2.9.0.js (renamed from www/cordova-android-2.5.0.js)959
-rw-r--r--www/cordova-independent.js2
-rw-r--r--www/index.html1
19 files changed, 1666 insertions, 294 deletions
diff --git a/Android/.classpath b/Android/.classpath
index 18a533a..373a2e7 100644
--- a/Android/.classpath
+++ b/Android/.classpath
@@ -2,9 +2,9 @@
<classpath>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
- <classpathentry kind="lib" path="libs/cordova-2.5.0.jar"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
+ <classpathentry exported="true" kind="lib" path="libs/cordova-2.9.0.jar"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>
diff --git a/Android/cordova/appinfo.jar b/Android/cordova/appinfo.jar
new file mode 100755
index 0000000..2faa20e
--- /dev/null
+++ b/Android/cordova/appinfo.jar
Binary files differ
diff --git a/Android/cordova/build b/Android/cordova/build
new file mode 100755
index 0000000..5ba36c0
--- /dev/null
+++ b/Android/cordova/build
@@ -0,0 +1,39 @@
+#!/bin/bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# 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
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+PROJECT_PATH=$( cd "$DIR/.." && pwd )
+
+if [[ "$#" -eq 1 ]] ; then
+ if [[ $1 == "--debug" ]] ; then
+ $DIR/clean
+ ant debug -f "$PROJECT_PATH"/build.xml
+ elif [[ $1 == "--release" ]] ; then
+ $DIR/clean
+ ant release -f "$PROJECT_PATH"/build.xml
+ elif [[ $1 == "--nobuild" ]] ; then
+ echo "Skipping build..."
+ else
+ echo "Error : Build command '$1' not recognized."
+ exit 2
+ fi
+else
+ echo "Warning : [ --debug | --release | --nobuild ] not specified, defaulting to --debug"
+ $DIR/clean
+ ant debug -f "$PROJECT_PATH"/build.xml
+fi
diff --git a/Android/cordova/clean b/Android/cordova/clean
new file mode 100755
index 0000000..b943b47
--- /dev/null
+++ b/Android/cordova/clean
@@ -0,0 +1,22 @@
+#!/bin/bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# 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
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+PROJECT_PATH=$( cd "$DIR/.." && pwd )
+echo "Cleaning project..."
+ant -f "$PROJECT_PATH/build.xml" clean
diff --git a/Android/cordova/lib/cordova b/Android/cordova/lib/cordova
new file mode 100755
index 0000000..294df49
--- /dev/null
+++ b/Android/cordova/lib/cordova
@@ -0,0 +1,386 @@
+#!/bin/bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# 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
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+PROJECT_PATH=$( cd "$( dirname "$0" )/../.." && pwd )
+
+function list_devices {
+ IFS=$'\n'
+ devices=`adb devices | awk '/List of devices attached/ { while(getline > 0) { print }}' | grep 'device' | grep -v 'emulator'`
+ device_list=($devices)
+ if [[ ${#device_list[@]} > 0 ]] ; then
+ for i in ${devices[@]}
+ do
+ # remove space and 'device'
+ echo ${i/[^a-zA-Z0-9._]device/}
+ done
+ else
+ echo "No devices found."
+ exit 2
+ fi
+}
+
+function list_started_emulators {
+ IFS=$'\n'
+ devices=`adb devices | awk '/List of devices attached/ { while(getline > 0) { print }}' | grep 'device' | grep 'emulator'`
+ emulator_list=($devices)
+ if [[ ${#emulator_list[@]} > 0 ]] ; then
+ for i in ${emulator_list[@]}
+ do
+ # remove space and 'device'
+ echo ${i/[^a-zA-Z0-9._]device/}
+ done
+ else
+ echo "No started emulators found, you can start an emulator by using the command"
+ echo " 'cordova/lib/start-emulator'"
+ exit 2
+ fi
+}
+
+function list_emulator_images {
+ emulator_images=`android list avds | grep "Name:" | cut -f 2 -d ":"`
+ emulator_list=($emulator_images)
+ if [[ ${#emulator_list[@]} > 0 ]] ; then
+ for i in ${emulator_list[@]}
+ do
+ echo ${i/[^a-zA-Z0-9._]/}
+ done
+ else
+ echo "No emulators found, if you would like to create an emulator follow the instructions"
+ echo " provided here : http://developer.android.com/tools/devices/index.html"
+ echo " Or run 'android create avd --name <name> --target <targetID>' in on the command line."
+ exit 2
+ fi
+}
+
+function start_emulator {
+ emulator_images=`android list avds | grep "Name:" | cut -f 2 -d ":"`
+ # if target emulator is provided
+ if [[ "$#" -eq 1 ]] ; then
+ # check that it exists
+ if [[ $emulator_images =~ $1 ]] ; then
+ #xterm -e emulator -avd $1 &
+ emulator -avd $1 1> /dev/null 2>&1 &
+ else
+ echo "Could not find the provided emulator, make sure the emulator exists"
+ echo " by checking 'cordova/lib/list-emulator-images'"
+ exit 2
+ fi
+ else
+ # start first emulator
+ emulator_list=($emulator_images)
+ if [[ ${#emulator_list[@]} > 0 ]] ; then
+ #xterm -e emulator -avd ${emulator_list[0]} &
+ emulator -avd ${emulator_list[0]/[^a-zA-Z0-9._]/} 1> /dev/null 2>&1 &
+ else
+ echo "No emulators found, if you would like to create an emulator follow the instructions"
+ echo " provided here : http://developer.android.com/tools/devices/index.html"
+ echo " Or run 'android create avd --name <name> --target <targetID>' in on the command line."
+ exit 2
+ fi
+ fi
+}
+
+function install_device {
+ IFS=$'\n'
+ devices=`adb devices | awk '/List of devices attached/ { while(getline > 0) { print }}' | grep 'device' | grep -v 'emulator'`
+ device_list=($devices)
+ if [[ ${#device_list[@]} > 0 ]] ; then
+ apks=`find $PROJECT_PATH/bin -type f -maxdepth 1 | egrep '\.apk$'`
+ apk_list=($apks)
+ if [[ ${#apk_list[@]} > 0 ]] ; then
+ local target
+ # handle target emulator
+ if [[ "$#" -eq 1 ]] ; then
+ # deploy to given target
+ target=${1/--target=/}
+ else
+ # delete trailing space and 'device' after device ID
+ target=${device_list[0]/[^a-zA-Z0-9._]device/}
+ fi
+ echo "Installing ${apk_list[0]} onto device $target..."
+ adb -s $target install -r ${apk_list[0]};
+ echo "Launching application..."
+ local launch_str=$(java -jar "$PROJECT_PATH"/cordova/appinfo.jar "$PROJECT_PATH"/AndroidManifest.xml)
+ adb -s $target shell am start -W -a android.intent.action.MAIN -n $launch_str
+ else
+ echo "Application package not found, could not install to device"
+ echo " make sure your application is built before deploying."
+ exit 2
+ fi
+ else
+ echo "No devices found to deploy to. Please make sure your device is connected"
+ echo " and you can view it using the 'cordova/lib/list-devices' command."
+ exit 2
+ fi
+}
+
+function install_emulator {
+ IFS=$'\n'
+ # check that there is an emulator to deploy to
+ emulator_string=`adb devices | awk '/List of devices attached/ { while(getline > 0) { print }}' | grep 'emulator'`
+ emulator_list=($emulator_string)
+ if [[ ${#emulator_list[@]} > 0 ]] ; then
+ apks=`find $PROJECT_PATH/bin -type f -maxdepth 1 | egrep '\.apk$'`
+ apk_list=($apks)
+ if [[ ${#apk_list[@]} > 0 ]] ; then
+ local target
+ # handle target emulator
+ if [[ "$#" -eq 1 ]] ; then
+ # deploy to given target
+ target=${1/--target=/}
+ else
+ # delete trailing space and 'device' after emulator ID
+ target=${emulator_list[0]/[^a-zA-Z0-9._]device/}
+ fi
+ echo "Installing ${apk_list[0]} onto $target..."
+ adb -s $target install -r ${apk_list[0]};
+ echo "Launching application..."
+ local launch_str=$(java -jar "$PROJECT_PATH"/cordova/appinfo.jar "$PROJECT_PATH"/AndroidManifest.xml)
+ adb -s $target shell am start -W -a android.intent.action.MAIN -n $launch_str
+
+ else
+ echo "Application package not found, could not install to device"
+ echo " make sure your application is built before deploying."
+ exit 2
+ fi
+ else
+ echo "No emulators found to deploy to. Please make sure your emulator is started"
+ echo " and you can view it using the 'cordova/lib/list-started-emulators' command."
+ exit 2
+ fi
+}
+
+# cleans the project
+function clean {
+ echo "Cleaning project..."
+ ant clean
+}
+
+# has to be used independently and not in conjunction with other commands
+function log {
+ # filter out nativeGetEnabledTags spam from latest sdk bug.
+ adb logcat | grep -v nativeGetEnabledTags
+}
+
+
+function build {
+ if [[ "$#" -eq 1 ]] ; then
+ if [[ $1 == "--debug" ]] ; then
+ clean
+ ant debug -f "$PROJECT_PATH"/build.xml
+ elif [[ $1 == "--release" ]] ; then
+ clean
+ ant release -f "$PROJECT_PATH"/build.xml
+ elif [[ $1 == "--nobuild" ]] ; then
+ echo "Skipping build..."
+ else
+ echo "Error : Build command '$1' not recognized."
+ exit 2
+ fi
+ else
+ echo "Warning : [ --debug | --release | --nobuild ] not specified, defaulting to --debug"
+ clean
+ ant debug -f "$PROJECT_PATH"/build.xml
+ fi
+}
+
+
+function wait_for_emulator {
+ emulator_string=`adb devices | awk '/List of devices attached/ { while(getline > 0) { print }}' | grep 'device' | grep 'emulator'`
+ old_started=($emulator_string)
+ local new_started
+ local new_emulator_name
+ local i="0"
+ echo -n "Waiting for emulator..."
+ while [ $i -lt 300 ]
+ do
+ emulator_string=`adb devices | awk '/List of devices attached/ { while(getline > 0) { print }}' | grep 'device' | grep 'emulator'`
+ new_started=($emulator_string)
+ if [[ ${#new_started[@]} > ${#old_started[@]} && -z "$new_emulator_name" ]] ; then
+ # get the name of the started emulator
+ local count="0"
+ if [[ ${#old_started[@]} == 0 ]] ; then
+ new_emulator_name=${new_started[$count]/[^a-zA-Z0-9._]device/}
+ else
+ for count in {0...${#old_started[@]}}
+ do
+ if [[ ! ${new_started[$count]} == ${old_started[$count]} ]] ; then
+ new_emulator_name=${new_started[$count]/[^a-zA-Z0-9._]device/}
+ fi
+ done
+ if [[ -z "$new_emulator_name" ]] ; then
+ count=$[count+1]
+ new_emulator_name=${new_started[$count]/[^a-zA-Z0-9._]device/}
+ fi
+ fi
+ elif [[ "$new_emulator_name" ]] ; then
+ boot_anim=`adb -s $new_emulator_name shell getprop init.svc.bootanim`
+ if [[ $boot_anim =~ "stopped" ]] ; then
+ break
+ else
+ sleep 1
+ i=$[i+1]
+ echo -n "."
+ fi
+ else
+ sleep 1
+ i=$[i+1]
+ echo -n "."
+ fi
+ done
+ # Device timeout: emulator has not started in time
+ if [ $i -eq 300 ]
+ then
+ echo "emulator timeout!"
+ exit 69
+ else
+ echo "connected!"
+ fi
+}
+
+function run {
+ IFS=$'\n'
+ if [[ "$#" -eq 2 ]] ; then
+ build $2
+ if [[ $1 == "--device" ]] ; then
+ install_device
+ elif [[ $1 == "--emulator" ]] ; then
+ install_emulator
+ elif [[ $1 =~ "--target=" ]]; then
+ install_device $1
+ else
+ echo "Error : '$1' is not recognized as an install option"
+ fi
+ elif [[ "$#" -eq 1 ]] ; then
+ if [[ $1 == "--debug" || $1 == "--release" || $1 == "--nobuild" ]] ; then
+ build $1
+ elif [[ $1 == "--device" ]] ; then
+ install_device
+ elif [[ $1 == "--emulator" ]] ; then
+ install_emulator
+ elif [[ $1 =~ "--target=" ]]; then
+ install_device $1
+ else
+ echo "Error : '$1' is not recognized as an install option"
+ fi
+ else
+ echo "Warning : [ --device | --emulate | --target=<targetID> ] not specified, using defaults."
+ build
+ devices=`adb devices | awk '/List of devices attached/ { while(getline > 0) { print }}' | grep 'device' | grep -v 'emulator'`
+ device_list=($devices)
+ emulator_string=`adb devices | awk '/List of devices attached/ { while(getline > 0) { print }}' | grep 'device' | grep 'emulator'`
+ emulator_list=($emulator_string)
+ if [[ ${#device_list[@]} > 0 ]] ; then
+ install_device
+ elif [[ ${#emulator_list[@]} > 0 ]] ; then
+ install_emulator
+ else
+ emulator_images=`android list avds | grep "Name:" | cut -f 2 -d ":"`
+ echo $emulator_images
+ emulator_image_list=($emulator_images)
+ if [[ ${#emulator_image_list[@]} > 0 ]] ; then
+ echo "Starting emulator : ${emulator_image_list[0]}"
+ emulator -avd ${emulator_image_list[0]/[^.\w]/} 1> /dev/null 2>&1 &
+ wait_for_emulator
+ install_emulator
+ else
+ # TODO : look for emulator images and start one if it's availible
+ echo "Error : there are no availible devices or emulators to deploy to."
+ echo " create an emulator or connect your device to run this command."
+ echo "If you would like to create an emulator follow the instructions"
+ echo " provided here : http://developer.android.com/tools/devices/index.html"
+ echo " Or run 'android create avd --name <name> --target <targetID>' in on the command line."
+ exit 2
+ fi
+ fi
+ fi
+}
+
+# parse command line arguments
+
+if [[ $# > 3 ]] ; then
+ echo "Error : too many arguments."
+ exit 2
+elif [[ $# == 3 ]] ; then
+ if [[ $1 == "run" ]] ; then
+ run $2 $3
+ else
+ echo "Error : too many arguments for '$1'"
+ exit 2
+ fi
+elif [[ $# == 2 ]] ; then
+ if [[ $1 == "run" ]] ; then
+ if [[ $2 == "--emulator" || $2 == "--device" || $2 =~ "--target=" ]] ; then
+ run $2 ''
+ elif [[ $2 == "--debug" || $2 == "--release" || $2 == "--nobuild" ]] ; then
+ run '' $2
+ else
+ echo "Error : '$2' is not recognized as a run option."
+ exit 2
+ fi
+ elif [[ $1 == "build" ]] ; then
+ build $2
+ elif [[ $1 == "start-emulator" ]] ; then
+ start_emulator $2
+ elif [[ $1 == "install-device" ]] ; then
+ if [[ $2 =~ "--target=" ]] ; then
+ install_device $2
+ else
+ echo "Error : '$2' is not recognized as an install option"
+ exit 2
+ fi
+ elif [[ $1 == "install-emulator" ]] ; then
+ if [[ $2 =~ "--target=" ]] ; then
+ install_emulator $2
+ else
+ echo "Error : '$2' is not recognized as an install option"
+ exit 2
+ fi
+ else
+ echo "Error : '$1' is not recognized as an option that takes arguments"
+ exit 2
+ fi
+elif [[ $# == 1 ]] ; then
+ if [[ $1 == "run" ]] ; then
+ run
+ elif [[ $1 == "build" ]]; then
+ build
+ elif [[ $1 == "clean" ]]; then
+ clean
+ elif [[ $1 == "log" ]]; then
+ log
+ elif [[ $1 == "list-devices" ]]; then
+ list_devices
+ elif [[ $1 == "list-emulator-images" ]]; then
+ list_emulator_images
+ elif [[ $1 == "list-started-emulators" ]]; then
+ list_started_emulators
+ elif [[ $1 == "install-device" ]]; then
+ install_device
+ elif [[ $1 == "install-emulator" ]]; then
+ install_emulator
+ elif [[ $1 == "start-emulator" ]]; then
+ start_emulator
+ else
+ echo "Error : '$1' is not recognized as a tooling command."
+ exit 2
+ fi
+else
+ echo "Error : No command recieved, exiting..."
+ exit 2
+fi \ No newline at end of file
diff --git a/Android/cordova/lib/install-device b/Android/cordova/lib/install-device
new file mode 100755
index 0000000..e70bef7
--- /dev/null
+++ b/Android/cordova/lib/install-device
@@ -0,0 +1,49 @@
+#!/bin/bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# 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
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+PROJECT_PATH=$( cd "$DIR/../.." && pwd )
+device_list=$("$DIR/list-devices")
+if [ $? != 0 ]; then
+ echo "No devices found to deploy to. Please make sure your device is connected"
+ echo " and you can view it using the 'cordova/lib/list-devices' command."
+ exit 2
+fi
+
+apks=`find $PROJECT_PATH/bin -type f -maxdepth 1 | egrep '\.apk$'`
+apk_list=($apks)
+if [[ ${#apk_list[@]} > 0 ]] ; then
+ # handle target
+ read -ra device_array <<< "$device_list"
+ if [[ "$#" -eq 1 ]] ; then
+ # deploy to given target
+ target=${1/--target=/}
+ else
+ # delete trailing space and 'device' after device ID
+ target=${device_array[0]}
+ fi
+ echo "Installing ${apk_list[0]} onto device $target..."
+ adb -s $target install -r ${apk_list[0]};
+ echo "Launching application..."
+ launch_str=$(java -jar "$PROJECT_PATH"/cordova/appinfo.jar "$PROJECT_PATH"/AndroidManifest.xml)
+ adb -s $target shell am start -W -a android.intent.action.MAIN -n $launch_str
+else
+ echo "Application package not found, could not install to device"
+ echo " make sure your application is built before deploying."
+ exit 2
+fi
diff --git a/Android/cordova/lib/install-emulator b/Android/cordova/lib/install-emulator
new file mode 100755
index 0000000..d4bffa4
--- /dev/null
+++ b/Android/cordova/lib/install-emulator
@@ -0,0 +1,50 @@
+#!/bin/bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# 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
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+PROJECT_PATH=$( cd "$DIR/../.." && pwd )
+emulator_list=$("$DIR/list-started-emulators")
+if [ $? != 0 ]; then
+ echo "No emulators found to deploy to. Please make sure your emulator is started"
+ echo " You can view it using the 'cordova/lib/list-started-emulators' command."
+ echo " You can view created emulator images using the 'cordova/lib/list-emulator-images' command."
+ echo " You can start an emulator image using the 'cordova/lib/start-emulator' command."
+ exit 2
+fi
+
+apks=`find $PROJECT_PATH/bin -type f -maxdepth 1 | egrep '\.apk$'`
+apk_list=($apks)
+if [[ ${#apk_list[@]} > 0 ]] ; then
+ # handle target emulator
+ if [[ "$#" -eq 1 ]] ; then
+ # deploy to given target
+ target=${1/--target=/}
+ else
+ # delete trailing space and 'device' after emulator ID
+ target=${emulator_list[0]}
+ fi
+ echo "Installing ${apk_list[0]} onto emulator $target..."
+ adb -s $target install -r ${apk_list[0]};
+ echo "Launching application..."
+ launch_str=$(java -jar "$PROJECT_PATH"/cordova/appinfo.jar "$PROJECT_PATH"/AndroidManifest.xml)
+ adb -s $target shell am start -W -a android.intent.action.MAIN -n $launch_str
+else
+ echo "Application package not found, could not install to device"
+ echo " make sure your application is built before deploying."
+ exit 2
+fi
diff --git a/Android/cordova/lib/list-devices b/Android/cordova/lib/list-devices
new file mode 100755
index 0000000..86d0054
--- /dev/null
+++ b/Android/cordova/lib/list-devices
@@ -0,0 +1,30 @@
+#!/bin/bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# 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
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+devices=`adb devices | awk '/List of devices attached/ { while(getline > 0) { print }}' | grep 'device' | grep -v 'emulator' | awk '{ print $1; }'`
+device_list=($devices)
+if [[ ${#device_list[@]} > 0 ]] ; then
+ for i in ${devices[@]}
+ do
+ echo $i
+ done
+ exit 0
+else
+ echo "No devices found."
+ exit 2
+fi
diff --git a/Android/cordova/lib/list-emulator-images b/Android/cordova/lib/list-emulator-images
new file mode 100755
index 0000000..202d0e5
--- /dev/null
+++ b/Android/cordova/lib/list-emulator-images
@@ -0,0 +1,32 @@
+#!/bin/bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# 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
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+emulator_images=`android list avds | grep "Name:" | cut -f 2 -d ":"`
+emulator_list=($emulator_images)
+if [[ ${#emulator_list[@]} > 0 ]] ; then
+ for i in ${emulator_list[@]}
+ do
+ echo $i
+ done
+ exit 0
+else
+ echo "No emulators found, if you would like to create an emulator follow the instructions"
+ echo " provided here : http://developer.android.com/tools/devices/index.html"
+ echo " Or run 'android create avd --name <name> --target <targetID>' in on the command line."
+ exit 2
+fi
diff --git a/Android/cordova/lib/list-started-emulators b/Android/cordova/lib/list-started-emulators
new file mode 100755
index 0000000..2aa6e99
--- /dev/null
+++ b/Android/cordova/lib/list-started-emulators
@@ -0,0 +1,32 @@
+#!/bin/bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# 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
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+devices=`adb devices | awk '/List of devices attached/ { while(getline > 0) { print $1;}}' | grep 'emulator' | grep -v 'offline'`
+read -ra emulator_list <<< "$devices"
+if [[ ${#emulator_list[@]} > 0 ]] ; then
+ for i in ${emulator_list[@]}
+ do
+ # remove space and 'device'
+ echo $i
+ done
+ exit 0
+else
+ echo "No started emulators found (it may still be booting up), you can start an emulator by using the command"
+ echo " 'cordova/lib/start-emulator'"
+ exit 2
+fi
diff --git a/Android/cordova/lib/start-emulator b/Android/cordova/lib/start-emulator
new file mode 100755
index 0000000..10e73ce
--- /dev/null
+++ b/Android/cordova/lib/start-emulator
@@ -0,0 +1,91 @@
+#!/bin/bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# 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
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+PROJECT_PATH=$( cd "$( dirname "$0" )/../.." && pwd )
+
+function dot {
+ sleep 1
+ echo -n "."
+}
+
+function wait_for_emulator {
+ local i="0"
+ echo -n "Waiting for emulator"
+ emulator_string=$($DIR/list-started-emulators)
+ while [ $? != 0 ]
+ do
+ dot
+ i=$[i+1]
+ emulator_string=$($DIR/list-started-emulators)
+ done
+ read -ra target <<< "$emulator_string"
+ echo ""
+ echo -n "Waiting for it to boot up (this can take a while)"
+ while [ $i -lt 300 ]
+ do
+ boot_anim=$(adb -s $target shell getprop init.svc.bootanim 2>&1)
+ if [[ "$boot_anim" =~ "stopped" ]] ; then
+ break
+ else
+ i=$[i+1]
+ dot
+ fi
+ done
+ # Device timeout: emulator has not started in time
+ if [ $i -eq 300 ]
+ then
+ echo ""
+ echo "Emulator timeout!"
+ exit 69
+ else
+ echo ""
+ echo "Connected!"
+ fi
+ # Unlock the device
+ adb -s $target shell input keyevent 82
+ exit 0
+}
+
+emulator_images=$("$DIR/list-emulator-images")
+if [ $? != 0 ]; then
+ echo "No emulators found, if you would like to create an emulator follow the instructions"
+ echo " provided here : http://developer.android.com/tools/devices/index.html"
+ echo " Or run 'android create avd --name <name> --target <targetID>' in on the command line."
+ exit 2
+fi
+
+# if target emulator is provided
+if [[ "$#" -eq 1 ]] ; then
+ # check that it exists
+ if [[ $emulator_images =~ $1 ]] ; then
+ #xterm -e emulator -avd $1 &
+ emulator -avd $1 1> /dev/null 2>&1 &
+ else
+ echo "Could not find the provided emulator '$1', make sure the emulator exists"
+ echo " by checking 'cordova/lib/list-emulator-images'"
+ exit 2
+ fi
+else
+ # start first emulator
+ read -ra emulator_list <<< "$emulator_images"
+ #xterm -e emulator -avd ${emulator_list[0]} &
+ emulator -avd ${emulator_list[0]} 1> /dev/null 2>&1 &
+fi
+
+wait_for_emulator
diff --git a/Android/cordova/log b/Android/cordova/log
new file mode 100755
index 0000000..f8df9cc
--- /dev/null
+++ b/Android/cordova/log
@@ -0,0 +1,20 @@
+#!/bin/bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# 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
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# filter out nativeGetEnabledTags spam from latest sdk bug.
+adb logcat | grep -v nativeGetEnabledTags
diff --git a/Android/cordova/run b/Android/cordova/run
new file mode 100755
index 0000000..4772058
--- /dev/null
+++ b/Android/cordova/run
@@ -0,0 +1,81 @@
+#!/bin/bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# 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
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+PROJECT_PATH=$( cd "$DIR/.." && pwd )
+
+function run_on_device_or_emulator {
+ devices=`$DIR/lib/list-devices`
+ if [ $? = 0 ]; then
+ $DIR/lib/install-device
+ else
+ run_on_emulator
+ fi
+}
+
+function run_on_emulator {
+ emulators=`$DIR/lib/list-started-emulators`
+ if [ $? = 0 ] ; then
+ $DIR/lib/install-emulator
+ else
+ images=`$DIR/lib/list-emulator-images`
+ if [ $? = 0 ] ; then
+ $DIR/lib/start-emulator
+ $DIR/lib/install-emulator
+ else
+ echo "No devices/emulators started nor images available to start. How are we supposed to do this, then?"
+ exit 2
+ fi
+ fi
+}
+
+
+
+if [[ "$#" -eq 2 ]] ; then
+ # TODO: the order of arguments here may be reversed from the assumption below
+ $DIR/build $2
+ if [[ $1 == "--device" ]] ; then
+ $DIR/lib/install-device
+ elif [[ $1 == "--emulator" ]] ; then
+ run_on_emulator
+ elif [[ $1 =~ "--target=" ]]; then
+ $DIR/lib/install-device $1
+ else
+ echo "Error : '$1' is not recognized as an install option"
+ fi
+elif [[ "$#" -eq 1 ]] ; then
+ if [[ $1 == "--debug" || $1 == "--release" || $1 == "--nobuild" ]] ; then
+ $DIR/build $1
+ run_on_device_or_emulator
+ elif [[ $1 == "--device" ]] ; then
+ $DIR/build
+ $DIR/lib/install-device
+ elif [[ $1 == "--emulator" ]] ; then
+ $DIR/build
+ run_on_emulator
+ elif [[ $1 =~ "--target=" ]]; then
+ $DIR/build
+ $DIR/lib/install-device $1
+ else
+ echo "Error : '$1' is not recognized as an install option"
+ fi
+else
+ echo "Warning : [ --device | --emulate | --target=<targetID> ] not specified, using defaults."
+ $DIR/build
+ run_on_device_or_emulator
+fi
diff --git a/Android/libs/cordova-2.5.0.jar b/Android/libs/cordova-2.5.0.jar
deleted file mode 100755
index 1c3b9f0..0000000
--- a/Android/libs/cordova-2.5.0.jar
+++ /dev/null
Binary files differ
diff --git a/Android/libs/cordova-2.9.0.jar b/Android/libs/cordova-2.9.0.jar
new file mode 100755
index 0000000..ce7c1e8
--- /dev/null
+++ b/Android/libs/cordova-2.9.0.jar
Binary files differ
diff --git a/Android/res/xml/config.xml b/Android/res/xml/config.xml
index bacafc9..9b70ae2 100755
--- a/Android/res/xml/config.xml
+++ b/Android/res/xml/config.xml
@@ -1,59 +1,113 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- 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
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ 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
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
-->
-<cordova>
+<widget xmlns = "http://www.w3.org/ns/widgets"
+ id = "io.cordova.helloCordova"
+ version = "2.0.0">
+ <name>Hello Cordova</name>
+
+ <description>
+ A sample Apache Cordova application that responds to the deviceready event.
+ </description>
+
+ <author href="http://cordova.io" email="dev@cordova.apache.org">
+ Apache Cordova Team
+ </author>
+
+ <access origin="*.tile.openstreetmap.org"/>
+ <access origin="*.tilma.mysociety.org"/>
+ <access origin="*.virtualearth.net"/>
+ <access origin="mapit.mysociety.org"/>
+ <access origin="struan.fixmystreet.dev.mysociety.org"/>
+ <access origin="192.168.1.13"/>
+ <access origin="debug.phonegap.com"/>
+
+ <!-- <content src="http://mysite.com/myapp.html" /> for external pages -->
+ <content src="index.html" />
+
+ <preference name="loglevel" value="DEBUG" />
<!--
- access elements control the Android whitelist.
- Domains are assumed blocked unless set otherwise
- -->
-
- <access origin="http://127.0.0.1*"/> <!-- allow local pages -->
-
- <!-- <access origin="https://example.com" /> allow any secure requests to example.com -->
- <!-- <access origin="https://example.com" subdomains="true" /> such as above, but including subdomains, such as www -->
- <access origin=".*"/>
-
- <content src="index.html"/>
-
- <log level="DEBUG"/>
- <preference name="useBrowserHistory" value="true" />
- <preference name="exit-on-suspend" value="false" />
-<plugins>
- <plugin name="App" value="org.apache.cordova.App"/>
- <plugin name="Geolocation" value="org.apache.cordova.GeoBroker"/>
- <plugin name="Device" value="org.apache.cordova.Device"/>
- <plugin name="Accelerometer" value="org.apache.cordova.AccelListener"/>
- <plugin name="Compass" value="org.apache.cordova.CompassListener"/>
- <plugin name="Media" value="org.apache.cordova.AudioHandler"/>
- <plugin name="Camera" value="org.apache.cordova.CameraLauncher"/>
- <plugin name="Contacts" value="org.apache.cordova.ContactManager"/>
- <plugin name="File" value="org.apache.cordova.FileUtils"/>
- <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="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"/>
- <plugin name="InAppBrowser" value="org.apache.cordova.InAppBrowser"/>
-</plugins>
-</cordova>
+ <preference name="splashscreen" value="resourceName" />
+ <preference name="backgroundColor" value="0xFFF" />
+ <preference name="loadUrlTimeoutValue" value="20000" />
+ <preference name="InAppBrowserStorageEnabled" value="true" />
+ <preference name="disallowOverscroll" value="true" />
+ -->
+ <feature name="App">
+ <param name="android-package" value="org.apache.cordova.App"/>
+ </feature>
+ <feature name="Geolocation">
+ <param name="android-package" value="org.apache.cordova.GeoBroker"/>
+ </feature>
+ <feature name="Device">
+ <param name="android-package" value="org.apache.cordova.Device"/>
+ </feature>
+ <feature name="Accelerometer">
+ <param name="android-package" value="org.apache.cordova.AccelListener"/>
+ </feature>
+ <feature name="Compass">
+ <param name="android-package" value="org.apache.cordova.CompassListener"/>
+ </feature>
+ <feature name="Media">
+ <param name="android-package" value="org.apache.cordova.AudioHandler"/>
+ </feature>
+ <feature name="Camera">
+ <param name="android-package" value="org.apache.cordova.CameraLauncher"/>
+ </feature>
+ <feature name="Contacts">
+ <param name="android-package" value="org.apache.cordova.ContactManager"/>
+ </feature>
+ <feature name="File">
+ <param name="android-package" value="org.apache.cordova.FileUtils"/>
+ </feature>
+ <feature name="NetworkStatus">
+ <param name="android-package" value="org.apache.cordova.NetworkManager"/>
+ </feature>
+ <feature name="Notification">
+ <param name="android-package" value="org.apache.cordova.Notification"/>
+ </feature>
+ <feature name="Storage">
+ <param name="android-package" value="org.apache.cordova.Storage"/>
+ </feature>
+ <feature name="FileTransfer">
+ <param name="android-package" value="org.apache.cordova.FileTransfer"/>
+ </feature>
+ <feature name="Capture">
+ <param name="android-package" value="org.apache.cordova.Capture"/>
+ </feature>
+ <feature name="Battery">
+ <param name="android-package" value="org.apache.cordova.BatteryListener"/>
+ </feature>
+ <feature name="SplashScreen">
+ <param name="android-package" value="org.apache.cordova.SplashScreen"/>
+ </feature>
+ <feature name="Echo">
+ <param name="android-package" value="org.apache.cordova.Echo"/>
+ </feature>
+ <feature name="Globalization">
+ <param name="android-package" value="org.apache.cordova.Globalization"/>
+ </feature>
+ <feature name="InAppBrowser">
+ <param name="android-package" value="org.apache.cordova.InAppBrowser"/>
+ </feature>
+ <!-- Deprecated plugins element. Remove in 3.0 -->
+ <plugins>
+ </plugins>
+</widget>
diff --git a/www/cordova-android-2.5.0.js b/www/cordova-android-2.9.0.js
index e4b9ea2..8454775 100755
--- a/www/cordova-android-2.5.0.js
+++ b/www/cordova-android-2.9.0.js
@@ -1,9 +1,5 @@
// Platform: android
-
-// commit f50d20a87431c79a54572263729461883f611a53
-
-// File generated at :: Tue Feb 26 2013 13:37:51 GMT-0800 (PST)
-
+// 2.9.0-0-g83dc4bd
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
@@ -22,26 +18,36 @@
specific language governing permissions and limitations
under the License.
*/
-
;(function() {
-
+var CORDOVA_JS_BUILD_LABEL = '2.9.0-0-g83dc4bd';
// file: lib/scripts/require.js
var require,
define;
(function () {
- var modules = {};
+ var modules = {},
// Stack of moduleIds currently being built.
- var requireStack = [];
+ requireStack = [],
// Map of module ID -> index into requireStack of modules currently being built.
- var inProgressModules = {};
+ inProgressModules = {},
+ SEPERATOR = ".";
+
+
function build(module) {
- var factory = module.factory;
+ var factory = module.factory,
+ localRequire = function (id) {
+ var resultantId = id;
+ //Its a relative path, so lop off the last portion and add the id (minus "./")
+ if (id.charAt(0) === ".") {
+ resultantId = module.id.slice(0, module.id.lastIndexOf(SEPERATOR)) + SEPERATOR + id.slice(2);
+ }
+ return require(resultantId);
+ };
module.exports = {};
delete module.factory;
- factory(require, module.exports, module);
+ factory(localRequire, module.exports, module);
return module.exports;
}
@@ -219,6 +225,10 @@ var cordova = {
}
else {
setTimeout(function() {
+ // Fire deviceready on listeners that were registered before cordova.js was loaded.
+ if (type == 'deviceready') {
+ document.dispatchEvent(evt);
+ }
documentEventHandlers[type].fire(evt);
}, 0);
}
@@ -262,7 +272,7 @@ var cordova = {
*/
callbackSuccess: function(callbackId, args) {
try {
- cordova.callbackFromNative(callbackId, true, args.status, args.message, args.keepCallback);
+ cordova.callbackFromNative(callbackId, true, args.status, [args.message], args.keepCallback);
} catch (e) {
console.log("Error in error callback: " + callbackId + " = "+e);
}
@@ -275,7 +285,7 @@ var cordova = {
// TODO: Deprecate callbackSuccess and callbackError in favour of callbackFromNative.
// Derive success from status.
try {
- cordova.callbackFromNative(callbackId, false, args.status, args.message, args.keepCallback);
+ cordova.callbackFromNative(callbackId, false, args.status, [args.message], args.keepCallback);
} catch (e) {
console.log("Error in error callback: " + callbackId + " = "+e);
}
@@ -284,13 +294,13 @@ var cordova = {
/**
* Called by native code when returning the result from an action.
*/
- callbackFromNative: function(callbackId, success, status, message, keepCallback) {
+ callbackFromNative: function(callbackId, success, status, args, keepCallback) {
var callback = cordova.callbacks[callbackId];
if (callback) {
if (success && status == cordova.callbackStatus.OK) {
- callback.success && callback.success(message);
+ callback.success && callback.success.apply(null, args);
} else if (!success) {
- callback.fail && callback.fail(message);
+ callback.fail && callback.fail.apply(null, args);
}
// Clear callback if not expecting any more results
@@ -724,6 +734,9 @@ channel.createSticky('onCordovaInfoReady');
// Event to indicate that the connection property has been set.
channel.createSticky('onCordovaConnectionReady');
+// Event to indicate that all automatically loaded JS plugins are loaded and ready.
+channel.createSticky('onPluginsReady');
+
// Event to indicate that Cordova is ready
channel.createSticky('onDeviceReady');
@@ -739,6 +752,7 @@ channel.createSticky('onDestroy');
// Channels that must fire before "deviceready" is fired.
channel.waitForInitialization('onCordovaReady');
channel.waitForInitialization('onCordovaConnectionReady');
+channel.waitForInitialization('onDOMContentLoaded');
module.exports = channel;
@@ -837,32 +851,27 @@ function androidExec(success, fail, service, action, args) {
}
var callbackId = service + cordova.callbackId++,
- argsJson = JSON.stringify(args),
- returnValue;
+ argsJson = JSON.stringify(args);
- // 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 (success || fail) {
+ cordova.callbacks[callbackId] = {success:success, fail:fail};
}
- cordova.callbacks[callbackId] = {success:captureReturnValue, fail:fail};
-
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;
+ // If argsJson was received by Java as null, try again with the PROMPT bridge mode.
+ // This happens in rare circumstances, such as when certain Unicode characters are passed over the bridge on a Galaxy S2. See CB-2666.
+ if (jsToNativeBridgeMode == jsToNativeModes.JS_OBJECT && messages === "@Null arguments.") {
+ androidExec.setJsToNativeBridgeMode(jsToNativeModes.PROMPT);
+ androidExec(success, fail, service, action, args);
+ androidExec.setJsToNativeBridgeMode(jsToNativeModes.JS_OBJECT);
+ return;
} else {
- delete cordova.callbacks[callbackId];
+ androidExec.processMessages(messages);
}
}
- return returnValue;
}
function pollOnce() {
@@ -900,7 +909,7 @@ androidExec.nativeToJsModes = nativeToJsModes;
androidExec.setJsToNativeBridgeMode = function(mode) {
if (mode == jsToNativeModes.JS_OBJECT && !window._cordovaNative) {
- console.log('Falling back on PROMPT mode since _cordovaNative is missing.');
+ console.log('Falling back on PROMPT mode since _cordovaNative is missing. Expected for Android 3.2 and lower only.');
mode = jsToNativeModes.PROMPT;
}
nativeApiProvider.setPreferPrompt(mode == jsToNativeModes.PROMPT);
@@ -958,10 +967,12 @@ function processMessage(message) {
arraybuffer[i] = bytes.charCodeAt(i);
}
payload = arraybuffer.buffer;
+ } else if (payloadKind == 'S') {
+ payload = window.atob(message.slice(nextSpaceIdx + 2));
} else {
payload = JSON.parse(message.slice(nextSpaceIdx + 1));
}
- cordova.callbackFromNative(callbackId, success, status, payload, keepCallback);
+ cordova.callbackFromNative(callbackId, success, status, [payload], keepCallback);
} else {
console.log("processMessage failed: invalid message:" + message);
}
@@ -976,30 +987,30 @@ function processMessage(message) {
androidExec.processMessages = function(messages) {
if (messages) {
messagesFromNative.push(messages);
+ // Check for the reentrant case, and enqueue the message if that's the case.
+ if (messagesFromNative.length > 1) {
+ return;
+ }
while (messagesFromNative.length) {
- messages = messagesFromNative.shift();
+ // Don't unshift until the end so that reentrancy can be detected.
+ messages = messagesFromNative[0];
// 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 == '*') {
+ messagesFromNative.shift();
window.setTimeout(pollOnce, 0);
- continue;
+ return;
}
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.
+ processMessage(message);
if (messages) {
- messagesFromNative.unshift(messages);
- }
-
- if (message) {
- processMessage(message);
+ messagesFromNative[0] = messages;
+ } else {
+ messagesFromNative.shift();
}
}
}
@@ -1203,9 +1214,10 @@ cameraExport.getPicture = function(successCallback, errorCallback, options) {
var correctOrientation = !!options.correctOrientation;
var saveToPhotoAlbum = !!options.saveToPhotoAlbum;
var popoverOptions = getValue(options.popoverOptions, null);
+ var cameraDirection = getValue(options.cameraDirection, Camera.Direction.BACK);
var args = [quality, destinationType, sourceType, targetWidth, targetHeight, encodingType,
- mediaType, allowEdit, correctOrientation, saveToPhotoAlbum, popoverOptions];
+ mediaType, allowEdit, correctOrientation, saveToPhotoAlbum, popoverOptions, cameraDirection];
exec(successCallback, errorCallback, "Camera", "takePicture", args);
return new CameraPopoverHandle();
@@ -1248,6 +1260,10 @@ module.exports = {
ARROW_LEFT : 4,
ARROW_RIGHT : 8,
ARROW_ANY : 15
+ },
+ Direction:{
+ BACK: 0,
+ FRONT: 1
}
};
@@ -1304,8 +1320,6 @@ var CaptureAudioOptions = function(){
this.limit = 1;
// Maximum duration of a single sound clip in seconds.
this.duration = 0;
- // The selected audio mode. Must match with one of the elements in supportedAudioModes array.
- this.mode = null;
};
module.exports = CaptureAudioOptions;
@@ -1346,8 +1360,6 @@ define("cordova/plugin/CaptureImageOptions", function(require, exports, module)
var CaptureImageOptions = function(){
// Upper limit of images user can take. Value must be equal or greater than 1.
this.limit = 1;
- // The selected image mode. Must match with one of the elements in supportedImageModes array.
- this.mode = null;
};
module.exports = CaptureImageOptions;
@@ -1365,8 +1377,6 @@ var CaptureVideoOptions = function(){
this.limit = 1;
// Maximum duration of a single video clip in seconds.
this.duration = 0;
- // The selected video mode. Must match with one of the elements in supportedVideoModes array.
- this.mode = null;
};
module.exports = CaptureVideoOptions;
@@ -2386,11 +2396,7 @@ function initRead(reader, file) {
reader._error = null;
reader._readyState = FileReader.LOADING;
- if (typeof file == 'string') {
- // Deprecated in Cordova 2.4.
- console.warning('Using a string argument with FileReader.readAs functions is deprecated.');
- reader._fileName = file;
- } else if (typeof file.fullPath == 'string') {
+ if (typeof file.fullPath == 'string') {
reader._fileName = file.fullPath;
} else {
reader._fileName = '';
@@ -2439,14 +2445,7 @@ FileReader.prototype.readAsText = function(file, encoding) {
// Default encoding is UTF-8
var enc = encoding ? encoding : "UTF-8";
var me = this;
- var execArgs = [this._fileName, enc];
-
- // Maybe add slice parameters.
- if (file.end < file.size) {
- execArgs.push(file.start, file.end);
- } else if (file.start > 0) {
- execArgs.push(file.start);
- }
+ var execArgs = [this._fileName, enc, file.start, file.end];
// Read file
exec(
@@ -2515,14 +2514,7 @@ FileReader.prototype.readAsDataURL = function(file) {
}
var me = this;
- var execArgs = [this._fileName];
-
- // Maybe add slice parameters.
- if (file.end < file.size) {
- execArgs.push(file.start, file.end);
- } else if (file.start > 0) {
- execArgs.push(file.start);
- }
+ var execArgs = [this._fileName, file.start, file.end];
// Read file
exec(
@@ -2585,9 +2577,59 @@ FileReader.prototype.readAsBinaryString = function(file) {
if (initRead(this, file)) {
return this._realReader.readAsBinaryString(file);
}
- // TODO - Can't return binary data to browser.
- console.log('method "readAsBinaryString" is not supported at this time.');
- this.abort();
+
+ var me = this;
+ var execArgs = [this._fileName, file.start, file.end];
+
+ // Read file
+ exec(
+ // Success callback
+ function(r) {
+ // If DONE (cancelled), then don't do anything
+ if (me._readyState === FileReader.DONE) {
+ return;
+ }
+
+ // DONE state
+ me._readyState = FileReader.DONE;
+
+ me._result = r;
+
+ // If onload callback
+ if (typeof me.onload === "function") {
+ me.onload(new ProgressEvent("load", {target:me}));
+ }
+
+ // If onloadend callback
+ if (typeof me.onloadend === "function") {
+ me.onloadend(new ProgressEvent("loadend", {target:me}));
+ }
+ },
+ // Error callback
+ function(e) {
+ // If DONE (cancelled), then don't do anything
+ if (me._readyState === FileReader.DONE) {
+ return;
+ }
+
+ // DONE state
+ me._readyState = FileReader.DONE;
+
+ me._result = null;
+
+ // Save error
+ me._error = new FileError(e);
+
+ // If onerror callback
+ if (typeof me.onerror === "function") {
+ me.onerror(new ProgressEvent("error", {target:me}));
+ }
+
+ // If onloadend callback
+ if (typeof me.onloadend === "function") {
+ me.onloadend(new ProgressEvent("loadend", {target:me}));
+ }
+ }, "File", "readAsBinaryString", execArgs);
};
/**
@@ -2599,9 +2641,59 @@ FileReader.prototype.readAsArrayBuffer = function(file) {
if (initRead(this, file)) {
return this._realReader.readAsArrayBuffer(file);
}
- // TODO - Can't return binary data to browser.
- console.log('This method is not supported at this time.');
- this.abort();
+
+ var me = this;
+ var execArgs = [this._fileName, file.start, file.end];
+
+ // Read file
+ exec(
+ // Success callback
+ function(r) {
+ // If DONE (cancelled), then don't do anything
+ if (me._readyState === FileReader.DONE) {
+ return;
+ }
+
+ // DONE state
+ me._readyState = FileReader.DONE;
+
+ me._result = r;
+
+ // If onload callback
+ if (typeof me.onload === "function") {
+ me.onload(new ProgressEvent("load", {target:me}));
+ }
+
+ // If onloadend callback
+ if (typeof me.onloadend === "function") {
+ me.onloadend(new ProgressEvent("loadend", {target:me}));
+ }
+ },
+ // Error callback
+ function(e) {
+ // If DONE (cancelled), then don't do anything
+ if (me._readyState === FileReader.DONE) {
+ return;
+ }
+
+ // DONE state
+ me._readyState = FileReader.DONE;
+
+ me._result = null;
+
+ // Save error
+ me._error = new FileError(e);
+
+ // If onerror callback
+ if (typeof me.onerror === "function") {
+ me.onerror(new ProgressEvent("error", {target:me}));
+ }
+
+ // If onloadend callback
+ if (typeof me.onloadend === "function") {
+ me.onloadend(new ProgressEvent("loadend", {target:me}));
+ }
+ }, "File", "readAsArrayBuffer", execArgs);
};
module.exports = FileReader;
@@ -2647,6 +2739,38 @@ function newProgressEvent(result) {
return pe;
}
+function getBasicAuthHeader(urlString) {
+ var header = null;
+
+ if (window.btoa) {
+ // parse the url using the Location object
+ var url = document.createElement('a');
+ url.href = urlString;
+
+ var credentials = null;
+ var protocol = url.protocol + "//";
+ var origin = protocol + url.host;
+
+ // check whether there are the username:password credentials in the url
+ if (url.href.indexOf(origin) !== 0) { // credentials found
+ var atIndex = url.href.indexOf("@");
+ credentials = url.href.substring(protocol.length, atIndex);
+ }
+
+ if (credentials) {
+ var authHeader = "Authorization";
+ var authHeaderValue = "Basic " + window.btoa(credentials);
+
+ header = {
+ name : authHeader,
+ value : authHeaderValue
+ };
+ }
+ }
+
+ return header;
+}
+
var idCounter = 0;
/**
@@ -2677,11 +2801,25 @@ FileTransfer.prototype.upload = function(filePath, server, successCallback, erro
var params = null;
var chunkedMode = true;
var headers = null;
+ var httpMethod = null;
+ var basicAuthHeader = getBasicAuthHeader(server);
+ if (basicAuthHeader) {
+ options = options || {};
+ options.headers = options.headers || {};
+ options.headers[basicAuthHeader.name] = basicAuthHeader.value;
+ }
+
if (options) {
fileKey = options.fileKey;
fileName = options.fileName;
mimeType = options.mimeType;
headers = options.headers;
+ httpMethod = options.httpMethod || "POST";
+ if (httpMethod.toUpperCase() == "PUT"){
+ httpMethod = "PUT";
+ } else {
+ httpMethod = "POST";
+ }
if (options.chunkedMode !== null || typeof options.chunkedMode != "undefined") {
chunkedMode = options.chunkedMode;
}
@@ -2694,7 +2832,7 @@ FileTransfer.prototype.upload = function(filePath, server, successCallback, erro
}
var fail = errorCallback && function(e) {
- var error = new FileTransferError(e.code, e.source, e.target, e.http_status);
+ var error = new FileTransferError(e.code, e.source, e.target, e.http_status, e.body);
errorCallback(error);
};
@@ -2708,7 +2846,7 @@ FileTransfer.prototype.upload = function(filePath, server, successCallback, erro
successCallback && successCallback(result);
}
};
- exec(win, fail, 'FileTransfer', 'upload', [filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode, headers, this._id]);
+ exec(win, fail, 'FileTransfer', 'upload', [filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode, headers, this._id, httpMethod]);
};
/**
@@ -2718,10 +2856,24 @@ FileTransfer.prototype.upload = function(filePath, server, successCallback, erro
* @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
+ * @param options {FileDownloadOptions} Optional parameters such as headers
*/
-FileTransfer.prototype.download = function(source, target, successCallback, errorCallback, trustAllHosts) {
+FileTransfer.prototype.download = function(source, target, successCallback, errorCallback, trustAllHosts, options) {
argscheck.checkArgs('ssFF*', 'FileTransfer.download', arguments);
var self = this;
+
+ var basicAuthHeader = getBasicAuthHeader(source);
+ if (basicAuthHeader) {
+ options = options || {};
+ options.headers = options.headers || {};
+ options.headers[basicAuthHeader.name] = basicAuthHeader.value;
+ }
+
+ var headers = null;
+ if (options) {
+ headers = options.headers || null;
+ }
+
var win = function(result) {
if (typeof result.lengthComputable != "undefined") {
if (self.onprogress) {
@@ -2744,20 +2896,19 @@ FileTransfer.prototype.download = function(source, target, successCallback, erro
};
var fail = errorCallback && function(e) {
- var error = new FileTransferError(e.code, e.source, e.target, e.http_status);
+ var error = new FileTransferError(e.code, e.source, e.target, e.http_status, e.body);
errorCallback(error);
};
- exec(win, fail, 'FileTransfer', 'download', [source, target, trustAllHosts, this._id]);
+ exec(win, fail, 'FileTransfer', 'download', [source, target, trustAllHosts, this._id, headers]);
};
/**
- * 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
+ * Aborts the ongoing file transfer on this object. The original error
+ * callback for the file transfer will be called if necessary.
*/
-FileTransfer.prototype.abort = function(successCallback, errorCallback) {
- exec(successCallback, errorCallback, 'FileTransfer', 'abort', [this._id]);
+FileTransfer.prototype.abort = function() {
+ exec(null, null, 'FileTransfer', 'abort', [this._id]);
};
module.exports = FileTransfer;
@@ -2801,12 +2952,13 @@ define("cordova/plugin/FileUploadOptions", function(require, exports, module) {
* @param headers {Object} Keys are header names, values are header values. Multiple
* headers of the same name are not supported.
*/
-var FileUploadOptions = function(fileKey, fileName, mimeType, params, headers) {
+var FileUploadOptions = function(fileKey, fileName, mimeType, params, headers, httpMethod) {
this.fileKey = fileKey || null;
this.fileName = fileName || null;
this.mimeType = mimeType || null;
this.params = params || null;
this.headers = headers || null;
+ this.httpMethod = httpMethod || null;
};
module.exports = FileUploadOptions;
@@ -2907,9 +3059,31 @@ FileWriter.prototype.abort = function() {
/**
* Writes data to the file
*
- * @param text to be written
+ * @param data text or blob to be written
*/
-FileWriter.prototype.write = function(text) {
+FileWriter.prototype.write = function(data) {
+
+ var isBinary = false;
+
+ // If we don't have Blob or ArrayBuffer support, don't bother.
+ if (typeof window.Blob !== 'undefined' && typeof window.ArrayBuffer !== 'undefined') {
+
+ // Check to see if the incoming data is a blob
+ if (data instanceof Blob) {
+ var that=this;
+ var fileReader = new FileReader();
+ fileReader.onload = function() {
+ // Call this method again, with the arraybuffer as argument
+ FileWriter.prototype.write.call(that, this.result);
+ };
+ fileReader.readAsArrayBuffer(data);
+ return;
+ }
+
+ // Mark data type for safer transport over the binary bridge
+ isBinary = (data instanceof ArrayBuffer);
+ }
+
// Throw an exception if we are already writing a file
if (this.readyState === FileWriter.WRITING) {
throw new FileError(FileError.INVALID_STATE_ERR);
@@ -2975,7 +3149,7 @@ FileWriter.prototype.write = function(text) {
if (typeof me.onwriteend === "function") {
me.onwriteend(new ProgressEvent("writeend", {"target":me}));
}
- }, "File", "write", [this.fileName, text, this.position]);
+ }, "File", "write", [this.fileName, data, this.position, isBinary]);
};
/**
@@ -3141,11 +3315,13 @@ define("cordova/plugin/InAppBrowser", function(require, exports, module) {
var exec = require('cordova/exec');
var channel = require('cordova/channel');
+var modulemapper = require('cordova/modulemapper');
function InAppBrowser() {
this.channels = {
'loadstart': channel.create('loadstart'),
'loadstop' : channel.create('loadstop'),
+ 'loaderror' : channel.create('loaderror'),
'exit' : channel.create('exit')
};
}
@@ -3159,6 +3335,9 @@ InAppBrowser.prototype = {
close: function (eventname) {
exec(null, null, "InAppBrowser", "close", []);
},
+ show: function (eventname) {
+ exec(null, null, "InAppBrowser", "show", []);
+ },
addEventListener: function (eventname,f) {
if (eventname in this.channels) {
this.channels[eventname].subscribe(f);
@@ -3168,6 +3347,26 @@ InAppBrowser.prototype = {
if (eventname in this.channels) {
this.channels[eventname].unsubscribe(f);
}
+ },
+
+ executeScript: function(injectDetails, cb) {
+ if (injectDetails.code) {
+ exec(cb, null, "InAppBrowser", "injectScriptCode", [injectDetails.code, !!cb]);
+ } else if (injectDetails.file) {
+ exec(cb, null, "InAppBrowser", "injectScriptFile", [injectDetails.file, !!cb]);
+ } else {
+ throw new Error('executeScript requires exactly one of code or file to be specified');
+ }
+ },
+
+ insertCSS: function(injectDetails, cb) {
+ if (injectDetails.code) {
+ exec(cb, null, "InAppBrowser", "injectStyleCode", [injectDetails.code, !!cb]);
+ } else if (injectDetails.file) {
+ exec(cb, null, "InAppBrowser", "injectStyleFile", [injectDetails.file, !!cb]);
+ } else {
+ throw new Error('insertCSS requires exactly one of code or file to be specified');
+ }
}
};
@@ -3176,7 +3375,14 @@ module.exports = function(strUrl, strWindowName, strWindowFeatures) {
var cb = function(eventname) {
iab._eventHandler(eventname);
};
- exec(cb, null, "InAppBrowser", "open", [strUrl, strWindowName, strWindowFeatures]);
+
+ // Don't catch calls that write to existing frames (e.g. named iframes).
+ if (window.frames && window.frames[strWindowName]) {
+ var origOpenFunc = modulemapper.getOriginalSymbol(window, 'open');
+ return origOpenFunc.apply(window, arguments);
+ }
+
+ exec(cb, cb, "InAppBrowser", "open", [strUrl, strWindowName, strWindowFeatures]);
return iab;
};
@@ -3886,6 +4092,10 @@ module.exports = {
// file: lib/android/plugin/android/nativeapiprovider.js
define("cordova/plugin/android/nativeapiprovider", function(require, exports, module) {
+/**
+ * Exports the ExposedJsApi.java object if available, otherwise exports the PromptBasedNativeApi.
+ */
+
var nativeApi = this._cordovaNative || require('cordova/plugin/android/promptbasednativeapi');
var currentApi = nativeApi;
@@ -3964,6 +4174,11 @@ module.exports = {
// file: lib/android/plugin/android/promptbasednativeapi.js
define("cordova/plugin/android/promptbasednativeapi", function(require, exports, module) {
+/**
+ * Implements the API of ExposedJsApi.java, but uses prompt() to communicate.
+ * This is used only on the 2.3 simulator, where addJavascriptInterface() is broken.
+ */
+
module.exports = {
exec: function(service, action, callbackId, argsJson) {
return prompt(argsJson, 'gap:'+JSON.stringify([service, action, callbackId]));
@@ -4699,7 +4914,7 @@ console.debug = function() {
console.assert = function(expression) {
if (expression) return;
- var message = utils.vformat(arguments[1], [].slice.call(arguments, 2));
+ var message = logger.format.apply(logger.format, [].slice.call(arguments, 1));
console.log("ASSERT: " + message);
};
@@ -4887,7 +5102,6 @@ function Device() {
this.available = false;
this.platform = null;
this.version = null;
- this.name = null;
this.uuid = null;
this.cordova = null;
this.model = null;
@@ -4896,12 +5110,15 @@ function Device() {
channel.onCordovaReady.subscribe(function() {
me.getInfo(function(info) {
+ var buildLabel = info.cordova;
+ if (buildLabel != CORDOVA_JS_BUILD_LABEL) {
+ buildLabel += ' JS=' + CORDOVA_JS_BUILD_LABEL;
+ }
me.available = true;
me.platform = info.platform;
me.version = info.version;
- me.name = info.name;
me.uuid = info.uuid;
- me.cordova = info.cordova;
+ me.cordova = buildLabel;
me.model = info.model;
channel.onCordovaInfoReady.fire();
},function(e) {
@@ -4940,7 +5157,8 @@ modulemapper.merges('cordova/plugin/android/device', 'device');
// file: lib/common/plugin/echo.js
define("cordova/plugin/echo", function(require, exports, module) {
-var exec = require('cordova/exec');
+var exec = require('cordova/exec'),
+ utils = require('cordova/utils');
/**
* Sends the given message through exec() to the Echo plugin, which sends it back to the successCallback.
@@ -4950,11 +5168,25 @@ var exec = require('cordova/exec');
* @param forceAsync Whether to force an async return value (for testing native->js bridge).
*/
module.exports = function(successCallback, errorCallback, message, forceAsync) {
- var action = forceAsync ? 'echoAsync' : 'echo';
- if (!forceAsync && message.constructor == ArrayBuffer) {
- action = 'echoArrayBuffer';
+ var action = 'echo';
+ var messageIsMultipart = (utils.typeName(message) == "Array");
+ var args = messageIsMultipart ? message : [message];
+
+ if (utils.typeName(message) == 'ArrayBuffer') {
+ if (forceAsync) {
+ console.warn('Cannot echo ArrayBuffer with forced async, falling back to sync.');
+ }
+ action += 'ArrayBuffer';
+ } else if (messageIsMultipart) {
+ if (forceAsync) {
+ console.warn('Cannot echo MultiPart Array with forced async, falling back to sync.');
+ }
+ action += 'MultiPart';
+ } else if (forceAsync) {
+ action += 'Async';
}
- exec(successCallback, errorCallback, "Echo", action, [message]);
+
+ exec(successCallback, errorCallback, "Echo", action, args);
};
@@ -5643,10 +5875,13 @@ var exec = require('cordova/exec');
var utils = require('cordova/utils');
var UseConsole = true;
+var UseLogger = true;
var Queued = [];
var DeviceReady = false;
var CurrentLevel;
+var originalConsole = console;
+
/**
* Logging levels
*/
@@ -5707,8 +5942,7 @@ logger.level = function (value) {
* Getter/Setter for the useConsole functionality
*
* When useConsole is true, the logger will log via the
- * browser 'console' object. Otherwise, it will use the
- * native Logger plugin.
+ * browser 'console' object.
*/
logger.useConsole = function (value) {
if (arguments.length) UseConsole = !!value;
@@ -5733,6 +5967,18 @@ logger.useConsole = function (value) {
};
/**
+ * Getter/Setter for the useLogger functionality
+ *
+ * When useLogger is true, the logger will log via the
+ * native Logger plugin.
+ */
+logger.useLogger = function (value) {
+ // Enforce boolean
+ if (arguments.length) UseLogger = !!value;
+ return UseLogger;
+};
+
+/**
* Logs a message at the LOG level.
*
* Parameters passed after message are used applied to
@@ -5784,10 +6030,10 @@ function logWithArgs(level, args) {
* Parameters passed after message are used applied to
* the message with utils.format()
*/
-logger.logLevel = function(level, message /* , ... */) {
+logger.logLevel = function(level /* , ... */) {
// format the message with the parameters
- var formatArgs = [].slice.call(arguments, 2);
- message = utils.vformat(message, formatArgs);
+ var formatArgs = [].slice.call(arguments, 1);
+ var message = logger.format.apply(logger.format, formatArgs);
if (LevelsMap[level] === null) {
throw new Error("invalid logging level: " + level);
@@ -5801,27 +6047,115 @@ logger.logLevel = function(level, message /* , ... */) {
return;
}
- // if not using the console, use the native logger
- if (!UseConsole) {
+ // Log using the native logger if that is enabled
+ if (UseLogger) {
exec(null, null, "Logger", "logLevel", [level, message]);
- return;
}
- // make sure console is not using logger
- if (console.__usingCordovaLogger) {
- throw new Error("console and logger are too intertwingly");
- }
+ // Log using the console if that is enabled
+ if (UseConsole) {
+ // make sure console is not using logger
+ if (console.__usingCordovaLogger) {
+ throw new Error("console and logger are too intertwingly");
+ }
- // log to the console
- switch (level) {
- case logger.LOG: console.log(message); break;
- case logger.ERROR: console.log("ERROR: " + message); break;
- case logger.WARN: console.log("WARN: " + message); break;
- case logger.INFO: console.log("INFO: " + message); break;
- case logger.DEBUG: console.log("DEBUG: " + message); break;
+ // log to the console
+ switch (level) {
+ case logger.LOG: originalConsole.log(message); break;
+ case logger.ERROR: originalConsole.log("ERROR: " + message); break;
+ case logger.WARN: originalConsole.log("WARN: " + message); break;
+ case logger.INFO: originalConsole.log("INFO: " + message); break;
+ case logger.DEBUG: originalConsole.log("DEBUG: " + message); break;
+ }
}
};
+
+/**
+ * Formats a string and arguments following it ala console.log()
+ *
+ * Any remaining arguments will be appended to the formatted string.
+ *
+ * for rationale, see FireBug's Console API:
+ * http://getfirebug.com/wiki/index.php/Console_API
+ */
+logger.format = function(formatString, args) {
+ return __format(arguments[0], [].slice.call(arguments,1)).join(' ');
+};
+
+
+//------------------------------------------------------------------------------
+/**
+ * Formats a string and arguments following it ala vsprintf()
+ *
+ * format chars:
+ * %j - format arg as JSON
+ * %o - format arg as JSON
+ * %c - format arg as ''
+ * %% - replace with '%'
+ * any other char following % will format it's
+ * arg via toString().
+ *
+ * Returns an array containing the formatted string and any remaining
+ * arguments.
+ */
+function __format(formatString, args) {
+ if (formatString === null || formatString === undefined) return [""];
+ if (arguments.length == 1) return [formatString.toString()];
+
+ if (typeof formatString != "string")
+ formatString = formatString.toString();
+
+ var pattern = /(.*?)%(.)(.*)/;
+ var rest = formatString;
+ var result = [];
+
+ while (args.length) {
+ var match = pattern.exec(rest);
+ if (!match) break;
+
+ var arg = args.shift();
+ rest = match[3];
+ result.push(match[1]);
+
+ if (match[2] == '%') {
+ result.push('%');
+ args.unshift(arg);
+ continue;
+ }
+
+ result.push(__formatted(arg, match[2]));
+ }
+
+ result.push(rest);
+
+ var remainingArgs = [].slice.call(args);
+ remainingArgs.unshift(result.join(''));
+ return remainingArgs;
+}
+
+function __formatted(object, formatChar) {
+
+ try {
+ switch(formatChar) {
+ case 'j':
+ case 'o': return JSON.stringify(object);
+ case 'c': return '';
+ }
+ }
+ catch (e) {
+ return "error JSON.stringify()ing argument: " + e;
+ }
+
+ if ((object === null) || (object === undefined)) {
+ return Object.prototype.toString.call(object);
+ }
+
+ return object.toString();
+}
+
+
+//------------------------------------------------------------------------------
// when deviceready fires, log queued messages
logger.__onDeviceReady = function() {
if (DeviceReady) return;
@@ -5950,6 +6284,7 @@ modulemapper.defaults('cordova/plugin/Connection', 'Connection');
define("cordova/plugin/notification", function(require, exports, module) {
var exec = require('cordova/exec');
+var platform = require('cordova/platform');
/**
* Provides access to notifications on the device.
@@ -5978,15 +6313,55 @@ module.exports = {
* @param {String} message Message to print in the body of the alert
* @param {Function} resultCallback The callback that is called when user clicks on a button.
* @param {String} title Title of the alert dialog (default: Confirm)
- * @param {String} buttonLabels Comma separated list of the labels of the buttons (default: 'OK,Cancel')
+ * @param {Array} buttonLabels Array of the labels of the buttons (default: ['OK', 'Cancel'])
*/
confirm: function(message, resultCallback, title, buttonLabels) {
var _title = (title || "Confirm");
- var _buttonLabels = (buttonLabels || "OK,Cancel");
+ var _buttonLabels = (buttonLabels || ["OK", "Cancel"]);
+
+ // Strings are deprecated!
+ if (typeof _buttonLabels === 'string') {
+ console.log("Notification.confirm(string, function, string, string) is deprecated. Use Notification.confirm(string, function, string, array).");
+ }
+
+ // Some platforms take an array of button label names.
+ // Other platforms take a comma separated list.
+ // For compatibility, we convert to the desired type based on the platform.
+ if (platform.id == "android" || platform.id == "ios" || platform.id == "windowsphone" || platform.id == "blackberry10") {
+ if (typeof _buttonLabels === 'string') {
+ var buttonLabelString = _buttonLabels;
+ _buttonLabels = _buttonLabels.split(","); // not crazy about changing the var type here
+ }
+ } else {
+ if (Array.isArray(_buttonLabels)) {
+ var buttonLabelArray = _buttonLabels;
+ _buttonLabels = buttonLabelArray.toString();
+ }
+ }
exec(resultCallback, null, "Notification", "confirm", [message, _title, _buttonLabels]);
},
/**
+ * Open a native prompt dialog, with a customizable title and button text.
+ * The following results are returned to the result callback:
+ * buttonIndex Index number of the button selected.
+ * input1 The text entered in the prompt dialog box.
+ *
+ * @param {String} message Dialog message to display (default: "Prompt message")
+ * @param {Function} resultCallback The callback that is called when user clicks on a button.
+ * @param {String} title Title of the dialog (default: "Prompt")
+ * @param {Array} buttonLabels Array of strings for the button labels (default: ["OK","Cancel"])
+ * @param {String} defaultText Textbox input value (default: "Default text")
+ */
+ prompt: function(message, resultCallback, title, buttonLabels, defaultText) {
+ var _message = (message || "Prompt message");
+ var _title = (title || "Prompt");
+ var _buttonLabels = (buttonLabels || ["OK","Cancel"]);
+ var _defaultText = (defaultText || "Default text");
+ exec(resultCallback, null, "Notification", "prompt", [_message, _title, _buttonLabels, _defaultText]);
+ },
+
+ /**
* Causes the device to vibrate.
*
* @param {Integer} mills The number of milliseconds to vibrate for.
@@ -6308,62 +6683,6 @@ utils.alert = function(msg) {
}
};
-/**
- * Formats a string and arguments following it ala sprintf()
- *
- * see utils.vformat() for more information
- */
-utils.format = function(formatString /* ,... */) {
- var args = [].slice.call(arguments, 1);
- return utils.vformat(formatString, args);
-};
-
-/**
- * Formats a string and arguments following it ala vsprintf()
- *
- * format chars:
- * %j - format arg as JSON
- * %o - format arg as JSON
- * %c - format arg as ''
- * %% - replace with '%'
- * any other char following % will format it's
- * arg via toString().
- *
- * for rationale, see FireBug's Console API:
- * http://getfirebug.com/wiki/index.php/Console_API
- */
-utils.vformat = function(formatString, args) {
- if (formatString === null || formatString === undefined) return "";
- if (arguments.length == 1) return formatString.toString();
- if (typeof formatString != "string") return formatString.toString();
-
- var pattern = /(.*?)%(.)(.*)/;
- var rest = formatString;
- var result = [];
-
- while (args.length) {
- var arg = args.shift();
- var match = pattern.exec(rest);
-
- if (!match) break;
-
- rest = match[3];
-
- result.push(match[1]);
-
- if (match[2] == '%') {
- result.push('%');
- args.unshift(arg);
- continue;
- }
-
- result.push(formatted(arg, match[2]));
- }
-
- result.push(rest);
-
- return result.join('');
-};
//------------------------------------------------------------------------------
function UUIDcreatePart(length) {
@@ -6378,83 +6697,251 @@ function UUIDcreatePart(length) {
return uuidpart;
}
-//------------------------------------------------------------------------------
-function formatted(object, formatChar) {
-
- try {
- switch(formatChar) {
- case 'j':
- case 'o': return JSON.stringify(object);
- case 'c': return '';
- }
- }
- catch (e) {
- return "error JSON.stringify()ing argument: " + e;
- }
-
- if ((object === null) || (object === undefined)) {
- return Object.prototype.toString.call(object);
- }
-
- return object.toString();
-}
});
-
window.cordova = require('cordova');
-
// file: lib/scripts/bootstrap.js
(function (context) {
+ console.log('loading cordova');
+ if (context._cordovaJsLoaded) {
+ throw new Error('cordova.js included multiple times.');
+ }
+ context._cordovaJsLoaded = true;
+
+ var channel = require('cordova/channel');
+ var platformInitChannelsArray = [channel.onNativeReady, channel.onPluginsReady];
+
+ function logUnfiredChannels(arr) {
+ for (var i = 0; i < arr.length; ++i) {
+ if (arr[i].state != 2) {
+ console.log('Channel not fired: ' + arr[i].type);
+ }
+ }
+ }
+
+ window.setTimeout(function() {
+ if (channel.onDeviceReady.state != 2) {
+ console.log('deviceready has not fired after 5 seconds.');
+ logUnfiredChannels(platformInitChannelsArray);
+ logUnfiredChannels(channel.deviceReadyChannelsArray);
+ }
+ }, 5000);
+
// Replace navigator before any modules are required(), to ensure it happens as soon as possible.
// We replace it so that properties that can't be clobbered can instead be overridden.
- if (context.navigator) {
+ function replaceNavigator(origNavigator) {
var CordovaNavigator = function() {};
- CordovaNavigator.prototype = context.navigator;
- context.navigator = new CordovaNavigator();
+ CordovaNavigator.prototype = origNavigator;
+ var newNavigator = new CordovaNavigator();
+ // This work-around really only applies to new APIs that are newer than Function.bind.
+ // Without it, APIs such as getGamepads() break.
+ if (CordovaNavigator.bind) {
+ for (var key in origNavigator) {
+ if (typeof origNavigator[key] == 'function') {
+ newNavigator[key] = origNavigator[key].bind(origNavigator);
+ }
+ }
+ }
+ return newNavigator;
+ }
+ if (context.navigator) {
+ context.navigator = replaceNavigator(context.navigator);
}
- var channel = require("cordova/channel"),
- _self = {
- boot: function () {
- /**
- * Create all cordova objects once page has fully loaded and native side is ready.
- */
- channel.join(function() {
- var builder = require('cordova/builder'),
- platform = require('cordova/platform');
+ // _nativeReady is global variable that the native side can set
+ // to signify that the native code is ready. It is a global since
+ // it may be called before any cordova JS is ready.
+ if (window._nativeReady) {
+ channel.onNativeReady.fire();
+ }
+
+ /**
+ * Create all cordova objects once native side is ready.
+ */
+ channel.join(function() {
+ // Call the platform-specific initialization
+ require('cordova/platform').initialize();
+
+ // Fire event to notify that all objects are created
+ channel.onCordovaReady.fire();
+
+ // Fire onDeviceReady event once page has fully loaded, all
+ // constructors have run and cordova info has been received from native
+ // side.
+ // This join call is deliberately made after platform.initialize() in
+ // order that plugins may manipulate channel.deviceReadyChannelsArray
+ // if necessary.
+ channel.join(function() {
+ require('cordova').fireDocumentEvent('deviceready');
+ }, channel.deviceReadyChannelsArray);
+
+ }, platformInitChannelsArray);
+
+}(window));
- builder.buildIntoButDoNotClobber(platform.defaults, context);
- builder.buildIntoAndClobber(platform.clobbers, context);
- builder.buildIntoAndMerge(platform.merges, context);
+// file: lib/scripts/bootstrap-android.js
- // Call the platform-specific initialization
- platform.initialize();
+require('cordova/channel').onNativeReady.fire();
- // Fire event to notify that all objects are created
- channel.onCordovaReady.fire();
+// file: lib/scripts/plugin_loader.js
- // Fire onDeviceReady event once all constructors have run and
- // cordova info has been received from native side.
- channel.join(function() {
- require('cordova').fireDocumentEvent('deviceready');
- }, channel.deviceReadyChannelsArray);
+// Tries to load all plugins' js-modules.
+// This is an async process, but onDeviceReady is blocked on onPluginsReady.
+// onPluginsReady is fired when there are no plugins to load, or they are all done.
+(function (context) {
+ // To be populated with the handler by handlePluginsObject.
+ var onScriptLoadingComplete;
+
+ var scriptCounter = 0;
+ function scriptLoadedCallback() {
+ scriptCounter--;
+ if (scriptCounter === 0) {
+ onScriptLoadingComplete && onScriptLoadingComplete();
+ }
+ }
- }, [ channel.onDOMContentLoaded, channel.onNativeReady ]);
+ function scriptErrorCallback(err) {
+ // Open Question: If a script path specified in cordova_plugins.js does not exist, do we fail for all?
+ // this is currently just continuing.
+ scriptCounter--;
+ if (scriptCounter === 0) {
+ onScriptLoadingComplete && onScriptLoadingComplete();
+ }
+ }
+
+ // Helper function to inject a <script> tag.
+ function injectScript(path) {
+ scriptCounter++;
+ var script = document.createElement("script");
+ script.onload = scriptLoadedCallback;
+ script.onerror = scriptErrorCallback;
+ script.src = path;
+ document.head.appendChild(script);
+ }
+
+ // Called when:
+ // * There are plugins defined and all plugins are finished loading.
+ // * There are no plugins to load.
+ function finishPluginLoading() {
+ context.cordova.require('cordova/channel').onPluginsReady.fire();
+ }
+
+ // Handler for the cordova_plugins.js content.
+ // See plugman's plugin_loader.js for the details of this object.
+ // This function is only called if the really is a plugins array that isn't empty.
+ // Otherwise the onerror response handler will just call finishPluginLoading().
+ function handlePluginsObject(modules, path) {
+ // First create the callback for when all plugins are loaded.
+ var mapper = context.cordova.require('cordova/modulemapper');
+ onScriptLoadingComplete = function() {
+ // Loop through all the plugins and then through their clobbers and merges.
+ for (var i = 0; i < modules.length; i++) {
+ var module = modules[i];
+ if (module) {
+ try {
+ if (module.clobbers && module.clobbers.length) {
+ for (var j = 0; j < module.clobbers.length; j++) {
+ mapper.clobbers(module.id, module.clobbers[j]);
+ }
+ }
+
+ if (module.merges && module.merges.length) {
+ for (var k = 0; k < module.merges.length; k++) {
+ mapper.merges(module.id, module.merges[k]);
+ }
+ }
+
+ // Finally, if runs is truthy we want to simply require() the module.
+ // This can be skipped if it had any merges or clobbers, though,
+ // since the mapper will already have required the module.
+ if (module.runs && !(module.clobbers && module.clobbers.length) && !(module.merges && module.merges.length)) {
+ context.cordova.require(module.id);
+ }
+ }
+ catch(err) {
+ // error with module, most likely clobbers, should we continue?
+ }
+ }
}
+
+ finishPluginLoading();
};
- // boot up once native side is ready
- channel.onNativeReady.subscribe(_self.boot);
+ // Now inject the scripts.
+ for (var i = 0; i < modules.length; i++) {
+ injectScript(path + modules[i].file);
+ }
+ }
- // _nativeReady is global variable that the native side can set
- // to signify that the native code is ready. It is a global since
- // it may be called before any cordova JS is ready.
- if (window._nativeReady) {
- channel.onNativeReady.fire();
+ // Find the root of the app
+ var path = '';
+ var scripts = document.getElementsByTagName('script');
+ var term = 'cordova.js';
+ for (var n = scripts.length-1; n>-1; n--) {
+ var src = scripts[n].src;
+ if (src.indexOf(term) == (src.length - term.length)) {
+ path = src.substring(0, src.length - term.length);
+ break;
+ }
}
+ var plugins_json = path + 'cordova_plugins.json';
+ var plugins_js = path + 'cordova_plugins.js';
+
+ // One some phones (Windows) this xhr.open throws an Access Denied exception
+ // So lets keep trying, but with a script tag injection technique instead of XHR
+ var injectPluginScript = function injectPluginScript() {
+ try {
+ var script = document.createElement("script");
+ script.onload = function(){
+ var list = cordova.require("cordova/plugin_list");
+ handlePluginsObject(list,path);
+ };
+ script.onerror = function() {
+ // Error loading cordova_plugins.js, file not found or something
+ // this is an acceptable error, pre-3.0.0, so we just move on.
+ finishPluginLoading();
+ };
+ script.src = plugins_js;
+ document.head.appendChild(script);
+
+ } catch(err){
+ finishPluginLoading();
+ }
+ }
+
+
+ // Try to XHR the cordova_plugins.json file asynchronously.
+ var xhr = new XMLHttpRequest();
+ xhr.onload = function() {
+ // If the response is a JSON string which composes an array, call handlePluginsObject.
+ // If the request fails, or the response is not a JSON array, just call finishPluginLoading.
+ var obj;
+ try {
+ obj = (this.status == 0 || this.status == 200) && this.responseText && JSON.parse(this.responseText);
+ } catch (err) {
+ // obj will be undefined.
+ }
+ if (Array.isArray(obj) && obj.length > 0) {
+ handlePluginsObject(obj, path);
+ } else {
+ finishPluginLoading();
+ }
+ };
+ xhr.onerror = function() {
+ // In this case, the json file was not present, but XHR was allowed,
+ // so we should still try the script injection technique with the js file
+ // in case that is there.
+ injectPluginScript();
+ };
+ try { // we commented we were going to try, so let us actually try and catch
+ xhr.open('GET', plugins_json, true); // Async
+ xhr.send();
+ } catch(err){
+ injectPluginScript();
+ }
}(window));
diff --git a/www/cordova-independent.js b/www/cordova-independent.js
index e35d16e..26d2026 100644
--- a/www/cordova-independent.js
+++ b/www/cordova-independent.js
@@ -4,7 +4,7 @@
if (navigator.userAgent.match(/(iPhone|iPod|iPad)/)) {
scriptElement.src = 'cordova-ios-2.9.0.js';
} else if (navigator.userAgent.match(/Android/)) {
- scriptElement.src = 'cordova-android-2.5.0.js';
+ scriptElement.src = 'cordova-android-2.9.0.js';
} else {
alert("Unknown platform - userAgent is: " + navigator.userAgent);
}
diff --git a/www/index.html b/www/index.html
index d5335f3..11eb768 100644
--- a/www/index.html
+++ b/www/index.html
@@ -2,7 +2,6 @@
<html>
<head>
<title></title>
-
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no;" />
<meta charset="utf-8">