phonegap 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2009 Brian LeRoux. Licensed under the MIT License:
2
+ http://www.opensource.org/licenses/mit-license.php
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining
5
+ a copy of this software and associated documentation files (the
6
+ "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish,
8
+ distribute, sublicense, and/or sell copies of the Software, and to
9
+ permit persons to whom the Software is furnished to do so, subject to
10
+ the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,25 @@
1
+ PhoneGap Developer
2
+ ===
3
+ Command line utilities for PhoneGap:
4
+
5
+ - app generation
6
+ - app packaging
7
+ - system reporting
8
+
9
+ Usage
10
+ ---
11
+ phonegap --generate path/to/MyFreshApp
12
+ phonegap --build path/to/MyFreshApp
13
+ phonegap --report path/to/MyFreshApp
14
+
15
+ Options
16
+ ---
17
+ -h, --help ......... Displays help message.
18
+ -v, --version ..... Display the version and then exit.
19
+ -g, --generate ..... Generates a PhoneGap application skeleton.
20
+ -b, --build ........ Compiles your PhoneGapp application for supported platforms.
21
+ -r, --report ....... Generates a report for supported SDK's.
22
+
23
+
24
+ Copyright (c) 2009 Brian LeRoux. Licensed under the MIT License:
25
+ http://www.opensource.org/licenses/mit-license.php
data/Rakefile ADDED
@@ -0,0 +1,58 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "phonegap"
8
+ gem.summary = %Q{Command line utilities for PhoneGap.}
9
+ gem.email = "brian@westcoastlogic.com"
10
+ gem.homepage = "http://github.com/brianleroux/phonegap-dev"
11
+ gem.authors = ["Brian LeRoux"]
12
+ gem.rubyforge_project = "phonegap"
13
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
14
+ end
15
+
16
+ Jeweler::RubyforgeTasks.new
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
19
+ end
20
+
21
+ require 'rake/testtask'
22
+ Rake::TestTask.new(:test) do |test|
23
+ test.libs << 'lib' << 'test'
24
+ test.pattern = 'test/**/*_test.rb'
25
+ test.verbose = true
26
+ end
27
+
28
+ begin
29
+ require 'rcov/rcovtask'
30
+ Rcov::RcovTask.new do |test|
31
+ test.libs << 'test'
32
+ test.pattern = 'test/**/*_test.rb'
33
+ test.verbose = true
34
+ end
35
+ rescue LoadError
36
+ task :rcov do
37
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
38
+ end
39
+ end
40
+
41
+
42
+ task :default => :test
43
+
44
+ require 'rake/rdoctask'
45
+ Rake::RDocTask.new do |rdoc|
46
+ if File.exist?('VERSION.yml')
47
+ config = YAML.load(File.read('VERSION.yml'))
48
+ version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
49
+ else
50
+ version = ""
51
+ end
52
+
53
+ rdoc.rdoc_dir = 'rdoc'
54
+ rdoc.title = "phonegap #{version}"
55
+ rdoc.rdoc_files.include('README*')
56
+ rdoc.rdoc_files.include('lib/**/*.rb')
57
+ end
58
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.1
data/bin/phonegap ADDED
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env ruby
2
+ %w(optparse optparse/time ostruct pp phonegap).each { |x| require x }
3
+ #
4
+ # Wraps the command line and passes switches and options back to the PhoneGap class.
5
+ #
6
+ class PhoneGapConsole
7
+ def self.parse(args)
8
+ p = PhoneGap.new
9
+
10
+ opts = OptionParser.new do |opts|
11
+ b = <<-E
12
+
13
+ PhoneGap #{ p.version }
14
+ --------------
15
+ Usage: phonegap [options]
16
+
17
+ E
18
+ opts.banner = b.gsub(" ","")
19
+
20
+ opts.on("-g", "--generate PATH", "Generates a new PhoneGap application skeleton.") do |path|
21
+ puts p.generate(path)
22
+ exit
23
+ end
24
+
25
+ opts.on("-b", "--build PATH", "Compiles your PhoneGapp application for supported platforms.") do |path|
26
+ puts p.build(path)
27
+ exit
28
+ end
29
+
30
+ opts.on("-r", "--report", "Generates a report for supported SDK's.") do
31
+ puts p.report
32
+ exit
33
+ end
34
+
35
+ opts.on_tail("-h", "--help", "Display this message.") do
36
+ puts "#{ opts }\n"
37
+ exit
38
+ end
39
+
40
+ opts.on_tail("-v", "--version", "Display the version.") do
41
+ puts p.version
42
+ exit
43
+ end
44
+ end
45
+ opts.parse!(args)
46
+ end
47
+ end
48
+
49
+ PhoneGapConsole.parse(ARGV)
@@ -0,0 +1,11 @@
1
+ module Android
2
+ # FIXME
3
+ def android_supported?
4
+ false
5
+ end
6
+
7
+ # FIXME
8
+ def build_android(path)
9
+ FileUtils.mkdir_p(File.join(bin,'android')) if android_supported?
10
+ end
11
+ end
@@ -0,0 +1,32 @@
1
+ module Blackberry
2
+ # FIXME
3
+ def blackberry_supported?
4
+ false
5
+ end
6
+
7
+ # FIXME
8
+ def build_blackberry(path)
9
+ =begin
10
+ Blackberry uses something rapc.exe to do builds.
11
+ http://www.blackberry.com/developers/javaknowledge/bbJDE/kpa0203190506.shtml
12
+
13
+ From the command line something like this should work:
14
+
15
+ >> rapc.exe import=c:\foo\net_rim_api.jar codename=phonegap-bitches -midlet jad=my-app-properties-metadata.jad @file-list.txt
16
+
17
+ "@file-list.txt" is a newline separated list of .java files to include
18
+
19
+ It requires (at leaset) rapc.exe from the Blackberry JDE (which I am
20
+ not sure if we can redistribute or not) and JDK.
21
+
22
+ To sign the app from the command line you do this:
23
+
24
+ >> java -jar "SignatureTool.jar" -a -c -p <mypass> c:\phonegap-bitches.cod
25
+
26
+
27
+ There is also a handy projects that links all this to ANT tasks if we
28
+ want http://bb-ant-tools.sourceforge.net/
29
+ =end
30
+ FileUtils.mkdir_p(File.join(bin,'blackberry')) if blackberry_supported?
31
+ end
32
+ end
@@ -0,0 +1,22 @@
1
+ module Iphone
2
+ # TODO need to verify version is 3.0
3
+ def iphone_supported?
4
+ return File.exists?("/usr/bin/xcodebuild")
5
+ end
6
+
7
+ # builds the iphone using xcode, FIXME should use open toolchain
8
+ def build_iphone(path_to_build)
9
+ if iphone_supported?
10
+ FileUtils.mkdir_p(path_to_build)
11
+ www_local = File.join(path_to_build,'www')
12
+ www_build = File.join(install_path,'iphone')
13
+ puts '\building for iphone...\n'
14
+ puts "copying #{www_local} to #{www_build}...#{`cp -r #{www_local} #{www_build}`}\n"
15
+ # Debug, Release
16
+ conf = {'Release'=>'iphoneos3.0','Debug'=>'iphonesimulator3.0'}
17
+ puts `cd #{www_build}; /usr/bin/xcodebuild -alltargets -configuration Debug -sdk #{conf['Debug']}`
18
+ else
19
+ puts 'skipping iphone build: iphone sdk not installed'
20
+ end
21
+ end
22
+ end
File without changes
File without changes
@@ -0,0 +1,8 @@
1
+ {
2
+ title:'Untitled Application',
3
+ author:'unknown',
4
+ license:'',
5
+ description:'',
6
+ icon:'foo.png',
7
+ startup:'Default.png'
8
+ }
File without changes
@@ -0,0 +1,97 @@
1
+
2
+ body {
3
+ background:#222 none repeat scroll 0 0;
4
+ color:#666;
5
+ font-family:Helvetica;
6
+ font-size:72%;
7
+ line-height:1.5em;
8
+ margin:0;
9
+ border-top:1px solid #393939;
10
+ }
11
+
12
+ #info{
13
+ background:#ffa;
14
+ border: 1px solid #ffd324;
15
+ -webkit-border-radius: 5px;
16
+ border-radius: 5px;
17
+ clear:both;
18
+ margin:15px 6px 0;
19
+ width:295px;
20
+ padding:4px 0px 2px 10px;
21
+ }
22
+
23
+ #info h4{
24
+ font-size:.95em;
25
+ margin:0;
26
+ padding:0;
27
+ }
28
+
29
+ #stage.theme{
30
+ padding-top:3px;
31
+ }
32
+
33
+ /* Definition List */
34
+ #Page1 > dl{
35
+ padding-top:10px;
36
+ clear:both;
37
+ margin:0;
38
+ list-style-type:none;
39
+ padding-left:10px;
40
+ overflow:auto;
41
+ }
42
+
43
+ #Page1 > dl > dt{
44
+ font-weight:bold;
45
+ float:left;
46
+ margin-left:5px;
47
+ }
48
+
49
+ #Page1 > dl > dd{
50
+ width:45px;
51
+ float:left;
52
+ color:#a87;
53
+ font-weight:bold;
54
+ }
55
+
56
+ /* Content Styling */
57
+ h1, h2, p{
58
+ margin:1em 0 .5em 13px;
59
+ }
60
+
61
+ h1{
62
+ color:#eee;
63
+ font-size:1.6em;
64
+ text-align:center;
65
+ margin:0;
66
+ margin-top:15px;
67
+ padding:0;
68
+ }
69
+
70
+ h2{
71
+ clear:both;
72
+ margin:0;
73
+ padding:3px;
74
+ font-size:1em;
75
+ text-align:center;
76
+ }
77
+
78
+ /* Stage Buttons */
79
+ #stage.theme a.btn{
80
+ border: 1px solid #555;
81
+ -webkit-border-radius: 5px;
82
+ border-radius: 5px;
83
+ text-align:center;
84
+ display:block;
85
+ float:left;
86
+ background:#444;
87
+ width:150px;
88
+ color:#9ab;
89
+ font-size:1.1em;
90
+ text-decoration:none;
91
+ padding:1.2em 0;
92
+ margin:3px 0px 3px 5px;
93
+ }
94
+ #stage.theme a.btn.large{
95
+ width:308px;
96
+ padding:1.2em 0;
97
+ }
@@ -0,0 +1,1122 @@
1
+ if (typeof(DeviceInfo) != 'object')
2
+ DeviceInfo = {};
3
+
4
+ /**
5
+ * This represents the PhoneGap API itself, and provides a global namespace for accessing
6
+ * information about the state of PhoneGap.
7
+ * @class
8
+ */
9
+ PhoneGap = {
10
+ queue: {
11
+ ready: true,
12
+ commands: [],
13
+ timer: null
14
+ },
15
+ _constructors: []
16
+ };
17
+
18
+ /**
19
+ * Boolean flag indicating if the PhoneGap API is available and initialized.
20
+ */
21
+ PhoneGap.available = DeviceInfo.uuid != undefined;
22
+
23
+ /**
24
+ * Add an initialization function to a queue that ensures it will run and initialize
25
+ * application constructors only once PhoneGap has been initialized.
26
+ * @param {Function} func The function callback you want run once PhoneGap is initialized
27
+ */
28
+ PhoneGap.addConstructor = function(func) {
29
+ var state = document.readyState;
30
+ if (state != 'loaded' && state != 'complete')
31
+ PhoneGap._constructors.push(func);
32
+ else
33
+ func();
34
+ };
35
+ (function() {
36
+ var timer = setInterval(function() {
37
+ var state = document.readyState;
38
+ if (state != 'loaded' && state != 'complete')
39
+ return;
40
+ clearInterval(timer);
41
+ while (PhoneGap._constructors.length > 0) {
42
+ var constructor = PhoneGap._constructors.shift();
43
+ try {
44
+ constructor();
45
+ } catch(e) {
46
+ if (typeof(debug['log']) == 'function')
47
+ debug.log("Failed to run constructor: " + debug.processMessage(e));
48
+ else
49
+ alert("Failed to run constructor: " + e.message);
50
+ }
51
+ }
52
+ }, 1);
53
+ })();
54
+
55
+
56
+ /**
57
+ * Execute a PhoneGap command in a queued fashion, to ensure commands do not
58
+ * execute with any race conditions, and only run when PhoneGap is ready to
59
+ * recieve them.
60
+ * @param {String} command Command to be run in PhoneGap, e.g. "ClassName.method"
61
+ * @param {String[]} [args] Zero or more arguments to pass to the method
62
+ */
63
+ PhoneGap.exec = function() {
64
+ PhoneGap.queue.commands.push(arguments);
65
+ if (PhoneGap.queue.timer == null)
66
+ PhoneGap.queue.timer = setInterval(PhoneGap.run_command, 10);
67
+ };
68
+ /**
69
+ * Internal function used to dispatch the request to PhoneGap. This needs to be implemented per-platform to
70
+ * ensure that methods are called on the phone in a way appropriate for that device.
71
+ * @private
72
+ */
73
+ PhoneGap.run_command = function() {
74
+ };
75
+
76
+ /**
77
+ * This class contains acceleration information
78
+ * @constructor
79
+ * @param {Number} x The force applied by the device in the x-axis.
80
+ * @param {Number} y The force applied by the device in the y-axis.
81
+ * @param {Number} z The force applied by the device in the z-axis.
82
+ */
83
+ function Acceleration(x, y, z) {
84
+ /**
85
+ * The force applied by the device in the x-axis.
86
+ */
87
+ this.x = x;
88
+ /**
89
+ * The force applied by the device in the y-axis.
90
+ */
91
+ this.y = y;
92
+ /**
93
+ * The force applied by the device in the z-axis.
94
+ */
95
+ this.z = z;
96
+ /**
97
+ * The time that the acceleration was obtained.
98
+ */
99
+ this.timestamp = new Date().getTime();
100
+ }
101
+
102
+ /**
103
+ * This class specifies the options for requesting acceleration data.
104
+ * @constructor
105
+ */
106
+ function AccelerationOptions() {
107
+ /**
108
+ * The timeout after which if acceleration data cannot be obtained the errorCallback
109
+ * is called.
110
+ */
111
+ this.timeout = 10000;
112
+ }
113
+ /**
114
+ * This class provides access to device accelerometer data.
115
+ * @constructor
116
+ */
117
+ function Accelerometer() {
118
+ /**
119
+ * The last known acceleration.
120
+ */
121
+ this.lastAcceleration = null;
122
+ }
123
+
124
+ /**
125
+ * Asynchronously aquires the current acceleration.
126
+ * @param {Function} successCallback The function to call when the acceleration
127
+ * data is available
128
+ * @param {Function} errorCallback The function to call when there is an error
129
+ * getting the acceleration data.
130
+ * @param {AccelerationOptions} options The options for getting the accelerometer data
131
+ * such as timeout.
132
+ */
133
+ Accelerometer.prototype.getCurrentAcceleration = function(successCallback, errorCallback, options) {
134
+ // If the acceleration is available then call success
135
+ // If the acceleration is not available then call error
136
+
137
+ // Created for iPhone, Iphone passes back _accel obj litteral
138
+ if (typeof successCallback == "function") {
139
+ var accel = new Acceleration(_accel.x,_accel.y,_accel.z);
140
+ Accelerometer.lastAcceleration = accel;
141
+ successCallback(accel);
142
+ }
143
+ }
144
+
145
+ /**
146
+ * Asynchronously aquires the acceleration repeatedly at a given interval.
147
+ * @param {Function} successCallback The function to call each time the acceleration
148
+ * data is available
149
+ * @param {Function} errorCallback The function to call when there is an error
150
+ * getting the acceleration data.
151
+ * @param {AccelerationOptions} options The options for getting the accelerometer data
152
+ * such as timeout.
153
+ */
154
+
155
+ Accelerometer.prototype.watchAcceleration = function(successCallback, errorCallback, options) {
156
+ this.getCurrentAcceleration(successCallback, errorCallback, options);
157
+ // TODO: add the interval id to a list so we can clear all watches
158
+ var frequency = (options != undefined)? options.frequency : 10000;
159
+ return setInterval(function() {
160
+ navigator.accelerometer.getCurrentAcceleration(successCallback, errorCallback, options);
161
+ }, frequency);
162
+ }
163
+
164
+ /**
165
+ * Clears the specified accelerometer watch.
166
+ * @param {String} watchId The ID of the watch returned from #watchAcceleration.
167
+ */
168
+ Accelerometer.prototype.clearWatch = function(watchId) {
169
+ clearInterval(watchId);
170
+ }
171
+
172
+ PhoneGap.addConstructor(function() {
173
+ if (typeof navigator.accelerometer == "undefined") navigator.accelerometer = new Accelerometer();
174
+ });
175
+ /**
176
+ * This class provides access to the device camera.
177
+ * @constructor
178
+ */
179
+ function Camera() {
180
+
181
+ }
182
+
183
+
184
+ PhoneGap.addConstructor(function() {
185
+ if (typeof navigator.camera == "undefined") navigator.camera = new Camera();
186
+ });
187
+
188
+
189
+
190
+ /**
191
+ *
192
+ * @param {Function} successCallback
193
+ * @param {Function} errorCallback
194
+ * @param {Object} options
195
+ */
196
+ Camera.prototype.getPicture = function(successCallback, errorCallback, options) {
197
+ navigator.notification.alert("TEST","Your GeoLocation", "Thanks");
198
+ //PhoneGap.exec("Image.imagePickerController");
199
+ }
200
+
201
+
202
+ /**
203
+ * This class provides access to the device contacts.
204
+ * @constructor
205
+ */
206
+
207
+ function Contact(jsonObject) {
208
+ this.firstName = "";
209
+ this.lastName = "";
210
+ this.phoneNumber = "";
211
+ this.address = "";
212
+ }
213
+
214
+ Contact.prototype.displayName = function()
215
+ {
216
+ // TODO: can be tuned according to prefs
217
+ return this.firstName + " " + this.lastName;
218
+ }
219
+
220
+ function ContactManager() {
221
+ // Dummy object to hold array of contacts
222
+ this.contacts = [];
223
+ this.timestamp = new Date().getTime();
224
+ }
225
+
226
+ ContactManager.prototype.getAllContacts = function(successCallback, errorCallback, options) {
227
+ // Interface
228
+ }
229
+
230
+ PhoneGap.addConstructor(function() {
231
+ if (typeof navigator.ContactManager == "undefined") navigator.ContactManager = new ContactManager();
232
+ });
233
+ /**
234
+ * This class provides access to the debugging console.
235
+ * @constructor
236
+ */
237
+ function DebugConsole() {
238
+ }
239
+
240
+ /**
241
+ * Utility function for rendering and indenting strings, or serializing
242
+ * objects to a string capable of being printed to the console.
243
+ * @param {Object|String} message The string or object to convert to an indented string
244
+ * @private
245
+ */
246
+ DebugConsole.prototype.processMessage = function(message) {
247
+ if (typeof(message) != 'object') {
248
+ return message;
249
+ } else {
250
+ /**
251
+ * @function
252
+ * @ignore
253
+ */
254
+ function indent(str) {
255
+ return str.replace(/^/mg, " ");
256
+ }
257
+ /**
258
+ * @function
259
+ * @ignore
260
+ */
261
+ function makeStructured(obj) {
262
+ var str = "";
263
+ for (var i in obj) {
264
+ try {
265
+ if (typeof(obj[i]) == 'object') {
266
+ str += i + ":\n" + indent(makeStructured(obj[i])) + "\n";
267
+ } else {
268
+ str += i + " = " + indent(String(obj[i])).replace(/^ /, "") + "\n";
269
+ }
270
+ } catch(e) {
271
+ str += i + " = EXCEPTION: " + e.message + "\n";
272
+ }
273
+ }
274
+ return str;
275
+ }
276
+ return "Object:\n" + makeStructured(message);
277
+ }
278
+ };
279
+
280
+ /**
281
+ * Print a normal log message to the console
282
+ * @param {Object|String} message Message or object to print to the console
283
+ */
284
+ DebugConsole.prototype.log = function(message) {
285
+ };
286
+
287
+ /**
288
+ * Print a warning message to the console
289
+ * @param {Object|String} message Message or object to print to the console
290
+ */
291
+ DebugConsole.prototype.warn = function(message) {
292
+ };
293
+
294
+ /**
295
+ * Print an error message to the console
296
+ * @param {Object|String} message Message or object to print to the console
297
+ */
298
+ DebugConsole.prototype.error = function(message) {
299
+ };
300
+
301
+ PhoneGap.addConstructor(function() {
302
+ window.debug = new DebugConsole();
303
+ });
304
+ /**
305
+ * this represents the mobile device, and provides properties for inspecting the model, version, UUID of the
306
+ * phone, etc.
307
+ * @constructor
308
+ */
309
+ function Device() {
310
+ this.available = PhoneGap.available;
311
+ this.platform = null;
312
+ this.version = null;
313
+ this.name = null;
314
+ this.gap = null;
315
+ this.uuid = null;
316
+ try {
317
+ if (window['DroidGap'] != undefined && window.DroidGap.exists()) {
318
+ this.available = true;
319
+ this.isAndroid = true;
320
+ this.uuid = window.DroidGap.getUuid();
321
+ this.gapVersion = window.DroidGap.getVersion();
322
+ } else {
323
+ this.platform = DeviceInfo.platform;
324
+ this.version = DeviceInfo.version;
325
+ this.name = DeviceInfo.name;
326
+ this.gap = DeviceInfo.gap;
327
+ this.uuid = DeviceInfo.uuid;
328
+ }
329
+ } catch(e) {
330
+ this.available = false;
331
+ }
332
+ }
333
+
334
+ PhoneGap.addConstructor(function() {
335
+ navigator.device = window.device = new Device();
336
+ });
337
+ /**
338
+ * This class provides generic read and write access to the mobile device file system.
339
+ */
340
+ function File() {
341
+ /**
342
+ * The data of a file.
343
+ */
344
+ this.data = "";
345
+ /**
346
+ * The name of the file.
347
+ */
348
+ this.name = "";
349
+ }
350
+
351
+ /**
352
+ * Reads a file from the mobile device. This function is asyncronous.
353
+ * @param {String} fileName The name (including the path) to the file on the mobile device.
354
+ * The file name will likely be device dependant.
355
+ * @param {Function} successCallback The function to call when the file is successfully read.
356
+ * @param {Function} errorCallback The function to call when there is an error reading the file from the device.
357
+ */
358
+ File.prototype.read = function(fileName, successCallback, errorCallback) {
359
+
360
+ }
361
+
362
+ /**
363
+ * Writes a file to the mobile device.
364
+ * @param {File} file The file to write to the device.
365
+ */
366
+ File.prototype.write = function(file) {
367
+
368
+ }
369
+
370
+ PhoneGap.addConstructor(function() {
371
+ if (typeof navigator.file == "undefined") navigator.file = new File();
372
+ });
373
+ /**
374
+ * This class provides access to device GPS data.
375
+ * @constructor
376
+ */
377
+ function Geolocation() {
378
+ /**
379
+ * The last known GPS position.
380
+ */
381
+ this.lastPosition = null;
382
+ this.lastError = null;
383
+ this.callbacks = {
384
+ onLocationChanged: [],
385
+ onError: []
386
+ };
387
+ };
388
+
389
+ /**
390
+ * Asynchronously aquires the current position.
391
+ * @param {Function} successCallback The function to call when the position
392
+ * data is available
393
+ * @param {Function} errorCallback The function to call when there is an error
394
+ * getting the position data.
395
+ * @param {PositionOptions} options The options for getting the position data
396
+ * such as timeout.
397
+ */
398
+ Geolocation.prototype.getCurrentPosition = function(successCallback, errorCallback, options) {
399
+ var referenceTime = 0;
400
+ if (this.lastPosition)
401
+ referenceTime = this.lastPosition.timeout;
402
+ else
403
+ this.start(options);
404
+
405
+ var timeout = 20000;
406
+ var interval = 500;
407
+ if (typeof(options) == 'object' && options.interval)
408
+ interval = options.interval;
409
+
410
+ if (typeof(successCallback) != 'function')
411
+ successCallback = function() {};
412
+ if (typeof(errorCallback) != 'function')
413
+ errorCallback = function() {};
414
+
415
+ var dis = this;
416
+ var delay = 0;
417
+ var timer = setInterval(function() {
418
+ delay += interval;
419
+
420
+ if (typeof(dis.lastPosition) == 'object' && dis.lastPosition.timestamp > referenceTime) {
421
+ successCallback(dis.lastPosition);
422
+ clearInterval(timer);
423
+ } else if (delay >= timeout) {
424
+ errorCallback();
425
+ clearInterval(timer);
426
+ }
427
+ }, interval);
428
+ };
429
+
430
+ /**
431
+ * Asynchronously aquires the position repeatedly at a given interval.
432
+ * @param {Function} successCallback The function to call each time the position
433
+ * data is available
434
+ * @param {Function} errorCallback The function to call when there is an error
435
+ * getting the position data.
436
+ * @param {PositionOptions} options The options for getting the position data
437
+ * such as timeout and the frequency of the watch.
438
+ */
439
+ Geolocation.prototype.watchPosition = function(successCallback, errorCallback, options) {
440
+ // Invoke the appropriate callback with a new Position object every time the implementation
441
+ // determines that the position of the hosting device has changed.
442
+
443
+ this.getCurrentPosition(successCallback, errorCallback, options);
444
+ var frequency = 10000;
445
+ if (typeof(options) == 'object' && options.frequency)
446
+ frequency = options.frequency;
447
+
448
+ var that = this;
449
+ return setInterval(function() {
450
+ that.getCurrentPosition(successCallback, errorCallback, options);
451
+ }, frequency);
452
+ };
453
+
454
+
455
+ /**
456
+ * Clears the specified position watch.
457
+ * @param {String} watchId The ID of the watch returned from #watchPosition.
458
+ */
459
+ Geolocation.prototype.clearWatch = function(watchId) {
460
+ clearInterval(watchId);
461
+ };
462
+
463
+ /**
464
+ * Called by the geolocation framework when the current location is found.
465
+ * @param {PositionOptions} position The current position.
466
+ */
467
+ Geolocation.prototype.setLocation = function(position) {
468
+ this.lastPosition = position;
469
+ for (var i = 0; i < this.callbacks.onLocationChanged.length; i++) {
470
+ var f = this.callbacks.onLocationChanged.shift();
471
+ f(position);
472
+ }
473
+ };
474
+
475
+ /**
476
+ * Called by the geolocation framework when an error occurs while looking up the current position.
477
+ * @param {String} message The text of the error message.
478
+ */
479
+ Geolocation.prototype.setError = function(message) {
480
+ this.lastError = message;
481
+ for (var i = 0; i < this.callbacks.onError.length; i++) {
482
+ var f = this.callbacks.onError.shift();
483
+ f(message);
484
+ }
485
+ };
486
+
487
+ PhoneGap.addConstructor(function() {
488
+ if (typeof navigator.geolocation == "undefined") navigator.geolocation = new Geolocation();
489
+ });
490
+ /**
491
+ * This class provides access to native mapping applications on the device.
492
+ */
493
+ function Map() {
494
+
495
+ }
496
+
497
+ /**
498
+ * Shows a native map on the device with pins at the given positions.
499
+ * @param {Array} positions
500
+ */
501
+ Map.prototype.show = function(positions) {
502
+
503
+ }
504
+
505
+ PhoneGap.addConstructor(function() {
506
+ if (typeof navigator.map == "undefined") navigator.map = new Map();
507
+ });
508
+
509
+ /**
510
+ * This class provides access to the device media, interfaces to both sound and video
511
+ * @constructor
512
+ */
513
+ function Media(src) {
514
+ this.src = src;
515
+ }
516
+
517
+ Media.prototype.play = function() {
518
+ }
519
+
520
+ Media.prototype.pause = function() {
521
+ }
522
+
523
+ Media.prototype.stop = function() {
524
+ }
525
+
526
+
527
+ /**
528
+ * This class contains information about any Media errors.
529
+ * @constructor
530
+ */
531
+ function MediaError() {
532
+ this.code = null,
533
+ this.message = "";
534
+ }
535
+
536
+ MediaError.MEDIA_ERR_ABORTED = 1;
537
+ MediaError.MEDIA_ERR_NETWORK = 2;
538
+ MediaError.MEDIA_ERR_DECODE = 3;
539
+ MediaError.MEDIA_ERR_NONE_SUPPORTED = 4;
540
+
541
+
542
+ //if (typeof navigator.audio == "undefined") navigator.audio = new Media(src);
543
+ /**
544
+ * This class provides access to notifications on the device.
545
+ */
546
+ function Notification() {
547
+
548
+ }
549
+
550
+ /**
551
+ * Open a native alert dialog, with a customizable title and button text.
552
+ * @param {String} message Message to print in the body of the alert
553
+ * @param {String} [title="Alert"] Title of the alert dialog (default: Alert)
554
+ * @param {String} [buttonLabel="OK"] Label of the close button (default: OK)
555
+ */
556
+ Notification.prototype.alert = function(message, title, buttonLabel) {
557
+ // Default is to use a browser alert; this will use "index.html" as the title though
558
+ alert(message);
559
+ };
560
+
561
+ /**
562
+ * Start spinning the activity indicator on the statusbar
563
+ */
564
+ Notification.prototype.activityStart = function() {
565
+ };
566
+
567
+ /**
568
+ * Stop spinning the activity indicator on the statusbar, if it's currently spinning
569
+ */
570
+ Notification.prototype.activityStop = function() {
571
+ };
572
+
573
+ /**
574
+ * Causes the device to blink a status LED.
575
+ * @param {Integer} count The number of blinks.
576
+ * @param {String} colour The colour of the light.
577
+ */
578
+ Notification.prototype.blink = function(count, colour) {
579
+
580
+ };
581
+
582
+ /**
583
+ * Causes the device to vibrate.
584
+ * @param {Integer} mills The number of milliseconds to vibrate for.
585
+ */
586
+ Notification.prototype.vibrate = function(mills) {
587
+
588
+ };
589
+
590
+ /**
591
+ * Causes the device to beep.
592
+ * @param {Integer} count The number of beeps.
593
+ * @param {Integer} volume The volume of the beep.
594
+ */
595
+ Notification.prototype.beep = function(count, volume) {
596
+
597
+ };
598
+
599
+ // TODO: of course on Blackberry and Android there notifications in the UI as well
600
+
601
+ PhoneGap.addConstructor(function() {
602
+ if (typeof navigator.notification == "undefined") navigator.notification = new Notification();
603
+ });
604
+
605
+ /**
606
+ * This class provides access to the device orientation.
607
+ * @constructor
608
+ */
609
+ function Orientation() {
610
+ /**
611
+ * The current orientation, or null if the orientation hasn't changed yet.
612
+ */
613
+ this.currentOrientation = null;
614
+ }
615
+
616
+ /**
617
+ * Set the current orientation of the phone. This is called from the device automatically.
618
+ *
619
+ * When the orientation is changed, the DOMEvent \c orientationChanged is dispatched against
620
+ * the document element. The event has the property \c orientation which can be used to retrieve
621
+ * the device's current orientation, in addition to the \c Orientation.currentOrientation class property.
622
+ *
623
+ * @param {Number} orientation The orientation to be set
624
+ */
625
+ Orientation.prototype.setOrientation = function(orientation) {
626
+ Orientation.currentOrientation = orientation;
627
+ var e = document.createEvent('Events');
628
+ e.initEvent('orientationChanged', 'false', 'false');
629
+ e.orientation = orientation;
630
+ document.dispatchEvent(e);
631
+ };
632
+
633
+ /**
634
+ * Asynchronously aquires the current orientation.
635
+ * @param {Function} successCallback The function to call when the orientation
636
+ * is known.
637
+ * @param {Function} errorCallback The function to call when there is an error
638
+ * getting the orientation.
639
+ */
640
+ Orientation.prototype.getCurrentOrientation = function(successCallback, errorCallback) {
641
+ // If the position is available then call success
642
+ // If the position is not available then call error
643
+ };
644
+
645
+ /**
646
+ * Asynchronously aquires the orientation repeatedly at a given interval.
647
+ * @param {Function} successCallback The function to call each time the orientation
648
+ * data is available.
649
+ * @param {Function} errorCallback The function to call when there is an error
650
+ * getting the orientation data.
651
+ */
652
+ Orientation.prototype.watchOrientation = function(successCallback, errorCallback) {
653
+ // Invoke the appropriate callback with a new Position object every time the implementation
654
+ // determines that the position of the hosting device has changed.
655
+ this.getCurrentPosition(successCallback, errorCallback);
656
+ return setInterval(function() {
657
+ navigator.orientation.getCurrentOrientation(successCallback, errorCallback);
658
+ }, 10000);
659
+ };
660
+
661
+ /**
662
+ * Clears the specified orientation watch.
663
+ * @param {String} watchId The ID of the watch returned from #watchOrientation.
664
+ */
665
+ Orientation.prototype.clearWatch = function(watchId) {
666
+ clearInterval(watchId);
667
+ };
668
+
669
+ PhoneGap.addConstructor(function() {
670
+ if (typeof navigator.orientation == "undefined") navigator.orientation = new Orientation();
671
+ });
672
+ /**
673
+ * This class contains position information.
674
+ * @param {Object} lat
675
+ * @param {Object} lng
676
+ * @param {Object} acc
677
+ * @param {Object} alt
678
+ * @param {Object} altacc
679
+ * @param {Object} head
680
+ * @param {Object} vel
681
+ * @constructor
682
+ */
683
+ function Position(lat, lng, acc, alt, altacc, head, vel) {
684
+ /**
685
+ * The latitude of the position.
686
+ */
687
+ this.latitude = lat;
688
+ /**
689
+ * The longitude of the position,
690
+ */
691
+ this.longitude = lng;
692
+ /**
693
+ * The accuracy of the position.
694
+ */
695
+ this.accuracy = acc;
696
+ /**
697
+ * The altitude of the position.
698
+ */
699
+ this.altitude = alt;
700
+ /**
701
+ * The altitude accuracy of the position.
702
+ */
703
+ this.altitudeAccuracy = altacc;
704
+ /**
705
+ * The direction the device is moving at the position.
706
+ */
707
+ this.heading = head;
708
+ /**
709
+ * The velocity with which the device is moving at the position.
710
+ */
711
+ this.velocity = vel;
712
+ /**
713
+ * The time that the position was obtained.
714
+ */
715
+ this.timestamp = new Date().getTime();
716
+ }
717
+
718
+ /**
719
+ * This class specifies the options for requesting position data.
720
+ * @constructor
721
+ */
722
+ function PositionOptions() {
723
+ /**
724
+ * Specifies the desired position accuracy.
725
+ */
726
+ this.enableHighAccuracy = true;
727
+ /**
728
+ * The timeout after which if position data cannot be obtained the errorCallback
729
+ * is called.
730
+ */
731
+ this.timeout = 10000;
732
+ }
733
+
734
+ /**
735
+ * This class contains information about any GSP errors.
736
+ * @constructor
737
+ */
738
+ function PositionError() {
739
+ this.code = null;
740
+ this.message = "";
741
+ }
742
+
743
+ PositionError.UNKNOWN_ERROR = 0;
744
+ PositionError.PERMISSION_DENIED = 1;
745
+ PositionError.POSITION_UNAVAILABLE = 2;
746
+ PositionError.TIMEOUT = 3;
747
+ /**
748
+ * This class provides access to the device SMS functionality.
749
+ * @constructor
750
+ */
751
+ function Sms() {
752
+
753
+ }
754
+
755
+ /**
756
+ * Sends an SMS message.
757
+ * @param {Integer} number The phone number to send the message to.
758
+ * @param {String} message The contents of the SMS message to send.
759
+ * @param {Function} successCallback The function to call when the SMS message is sent.
760
+ * @param {Function} errorCallback The function to call when there is an error sending the SMS message.
761
+ * @param {PositionOptions} options The options for accessing the GPS location such as timeout and accuracy.
762
+ */
763
+ Sms.prototype.send = function(number, message, successCallback, errorCallback, options) {
764
+
765
+ }
766
+
767
+ PhoneGap.addConstructor(function() {
768
+ if (typeof navigator.sms == "undefined") navigator.sms = new Sms();
769
+ });
770
+ /**
771
+ * This class provides access to the telephony features of the device.
772
+ * @constructor
773
+ */
774
+ function Telephony() {
775
+
776
+ }
777
+
778
+ /**
779
+ * Calls the specifed number.
780
+ * @param {Integer} number The number to be called.
781
+ */
782
+ Telephony.prototype.call = function(number) {
783
+
784
+ }
785
+
786
+ PhoneGap.addConstructor(function() {
787
+ if (typeof navigator.telephony == "undefined") navigator.telephony = new Telephony();
788
+ });
789
+ /**
790
+ * This class exposes mobile phone interface controls to JavaScript, such as
791
+ * native tab and tool bars, etc.
792
+ * @constructor
793
+ */
794
+ function UIControls() {
795
+ this.tabBarTag = 0;
796
+ this.tabBarCallbacks = {};
797
+ }
798
+
799
+ /**
800
+ * Create a native tab bar that can have tab buttons added to it which can respond to events.
801
+ */
802
+ UIControls.prototype.createTabBar = function() {};
803
+
804
+ /**
805
+ * Show a tab bar. The tab bar has to be created first.
806
+ * @param {Object} [options] Options indicating how the tab bar should be shown:
807
+ * - \c height integer indicating the height of the tab bar (default: \c 49)
808
+ * - \c position specifies whether the tab bar will be placed at the \c top or \c bottom of the screen (default: \c bottom)
809
+ */
810
+ UIControls.prototype.showTabBar = function(options) {};
811
+
812
+ /**
813
+ * Hide a tab bar. The tab bar has to be created first.
814
+ */
815
+ UIControls.prototype.hideTabBar = function(animate) {};
816
+
817
+ /**
818
+ * Create a new tab bar item for use on a previously created tab bar. Use ::showTabBarItems to show the new item on the tab bar.
819
+ *
820
+ * If the supplied image name is one of the labels listed below, then this method will construct a tab button
821
+ * using the standard system buttons. Note that if you use one of the system images, that the \c title you supply will be ignored.
822
+ *
823
+ * <b>Tab Buttons</b>
824
+ * - tabButton:More
825
+ * - tabButton:Favorites
826
+ * - tabButton:Featured
827
+ * - tabButton:TopRated
828
+ * - tabButton:Recents
829
+ * - tabButton:Contacts
830
+ * - tabButton:History
831
+ * - tabButton:Bookmarks
832
+ * - tabButton:Search
833
+ * - tabButton:Downloads
834
+ * - tabButton:MostRecent
835
+ * - tabButton:MostViewed
836
+ * @param {String} name internal name to refer to this tab by
837
+ * @param {String} [title] title text to show on the tab, or null if no text should be shown
838
+ * @param {String} [image] image filename or internal identifier to show, or null if now image should be shown
839
+ * @param {Object} [options] Options for customizing the individual tab item
840
+ * - \c badge value to display in the optional circular badge on the item; if null or unspecified, the badge will be hidden
841
+ */
842
+ UIControls.prototype.createTabBarItem = function(name, label, image, options) {};
843
+
844
+ /**
845
+ * Update an existing tab bar item to change its badge value.
846
+ * @param {String} name internal name used to represent this item when it was created
847
+ * @param {Object} options Options for customizing the individual tab item
848
+ * - \c badge value to display in the optional circular badge on the item; if null or unspecified, the badge will be hidden
849
+ */
850
+ UIControls.prototype.updateTabBarItem = function(name, options) {};
851
+
852
+ /**
853
+ * Show previously created items on the tab bar
854
+ * @param {String} arguments... the item names to be shown
855
+ * @param {Object} [options] dictionary of options, notable options including:
856
+ * - \c animate indicates that the items should animate onto the tab bar
857
+ * @see createTabBarItem
858
+ * @see createTabBar
859
+ */
860
+ UIControls.prototype.showTabBarItems = function(tabs, options) {};
861
+
862
+ /**
863
+ * Manually select an individual tab bar item, or nil for deselecting a currently selected tab bar item.
864
+ * @param {String} tabName the name of the tab to select, or null if all tabs should be deselected
865
+ * @see createTabBarItem
866
+ * @see showTabBarItems
867
+ */
868
+ UIControls.prototype.selectTabBarItem = function(tab) {};
869
+
870
+ /**
871
+ * Function called when a tab bar item has been selected.
872
+ * @param {Number} tag the tag number for the item that has been selected
873
+ */
874
+ UIControls.prototype.tabBarItemSelected = function(tag) {
875
+ if (typeof(this.tabBarCallbacks[tag]) == 'function')
876
+ this.tabBarCallbacks[tag]();
877
+ };
878
+
879
+ /**
880
+ * Create a toolbar.
881
+ */
882
+ UIControls.prototype.createToolBar = function() {};
883
+
884
+ /**
885
+ * Function called when a tab bar item has been selected.
886
+ * @param {String} title the title to set within the toolbar
887
+ */
888
+ UIControls.prototype.setToolBarTitle = function(title) {};
889
+
890
+ PhoneGap.addConstructor(function() {
891
+ window.uicontrols = new UIControls();
892
+ });
893
+ Accelerometer.prototype.getCurrentAcceleration = function(successCallback, errorCallback, options) {
894
+ if (typeof successCallback == "function") {
895
+ var accel = new Acceleration(_accel.x,_accel.y,_accel.z);
896
+ Accelerometer.lastAcceleration = accel;
897
+ successCallback(accel);
898
+ }
899
+ }
900
+ // --- BjV Additions for 360/iDev
901
+ Bonjour = function() {
902
+ }
903
+
904
+ Bonjour.prototype.port = 0;
905
+ Bonjour.prototype.start = function(name) {
906
+ PhoneGap.exec("Bonjour.start");
907
+ }
908
+ Bonjour.prototype.stop = function() {
909
+ PhoneGap.exec("Bonjour.stop");
910
+ }
911
+ Bonjour.prototype.delegate = null;
912
+ // Gets the function name of a Function object, else uses "alert" if anonymous
913
+ function GetFunctionName(fn)
914
+ {
915
+ if (fn) {
916
+ var m = fn.toString().match(/^\s*function\s+([^\s\(]+)/);
917
+ return m ? m[1] : "alert";
918
+ } else {
919
+ return null;
920
+ }
921
+ }
922
+
923
+ ContactManager.prototype.getAllContacts = function(successCallback, errorCallback, options) {
924
+ PhoneGap.exec("Contacts.allContacts", GetFunctionName(successCallback), options);
925
+ }
926
+
927
+ // THE FUNCTIONS BELOW ARE iPHONE ONLY FOR NOW
928
+
929
+ ContactManager.prototype.newContact = function(contact, successCallback, options) {
930
+ if (!options) options = {};
931
+ options.successCallback = GetFunctionName(successCallback);
932
+
933
+ PhoneGap.exec("Contacts.newContact", contact.firstName, contact.lastName, contact.phoneNumber,
934
+ options);
935
+ }
936
+
937
+ ContactManager.prototype.chooseContact = function(successCallback, options) {
938
+ PhoneGap.exec("Contacts.chooseContact", GetFunctionName(successCallback), options);
939
+ }
940
+
941
+ ContactManager.prototype.displayContact = function(contactID, errorCallback, options) {
942
+ PhoneGap.exec("Contacts.displayContact", contactID, GetFunctionName(errorCallback), options);
943
+ }
944
+
945
+ ContactManager.prototype.removeContact = function(contactID, successCallback, options) {
946
+ PhoneGap.exec("Contacts.removeContact", contactID, GetFunctionName(successCallback), options);
947
+ }
948
+
949
+ ContactManager.prototype.contactsCount = function(successCallback, errorCallback) {
950
+ PhoneGap.exec("Contacts.contactsCount", GetFunctionName(successCallback));
951
+ }
952
+
953
+ DebugConsole.prototype.log = function(message) {
954
+ if (PhoneGap.available)
955
+ PhoneGap.exec('DebugConsole.log',
956
+ this.processMessage(message),
957
+ { logLevel: 'INFO' }
958
+ );
959
+ else
960
+ console.log(message);
961
+ };
962
+ DebugConsole.prototype.warn = function(message) {
963
+ if (PhoneGap.available)
964
+ PhoneGap.exec('DebugConsole.log',
965
+ this.processMessage(message),
966
+ { logLevel: 'WARN' }
967
+ );
968
+ else
969
+ console.error(message);
970
+ };
971
+ DebugConsole.prototype.error = function(message) {
972
+ if (PhoneGap.available)
973
+ PhoneGap.exec('DebugConsole.log',
974
+ this.processMessage(message),
975
+ { logLevel: 'ERROR' }
976
+ );
977
+ else
978
+ console.error(message);
979
+ };
980
+ Geolocation.prototype.start = function(args) {
981
+ PhoneGap.exec("Location.start", args);
982
+ };
983
+
984
+ Geolocation.prototype.stop = function() {
985
+ PhoneGap.exec("Location.stop");
986
+ };
987
+ /**
988
+ * Media/Audio override.
989
+ *
990
+ */
991
+
992
+ Media.prototype.play = function() {
993
+ if (this.src != null) {
994
+ PhoneGap.exec("Sound.play", this.src);
995
+ }
996
+ }
997
+ Notification.prototype.vibrate = function(mills) {
998
+ PhoneGap.exec("Notification.vibrate");
999
+ };
1000
+
1001
+ Notification.prototype.beep = function(count, volume) {
1002
+ // No Volume yet for the iphone interface
1003
+ // We can use a canned beep sound and call that
1004
+ new Media('beep.wav').play();
1005
+ };
1006
+
1007
+ Notification.prototype.alert = function(message, title, buttonLabel) {
1008
+ var options = {};
1009
+ if (title) options.title = title;
1010
+ if (buttonLabel) options.buttonLabel = buttonLabel;
1011
+
1012
+ if (PhoneGap.available)
1013
+ PhoneGap.exec('Notification.alert', message, options);
1014
+ else
1015
+ alert(message);
1016
+ };
1017
+
1018
+ Notification.prototype.activityStart = function() {
1019
+ PhoneGap.exec("Notification.activityStart");
1020
+ };
1021
+ Notification.prototype.activityStop = function() {
1022
+ PhoneGap.exec("Notification.activityStop");
1023
+ };
1024
+
1025
+ Notification.prototype.loadingStart = function(options) {
1026
+ PhoneGap.exec("Notification.loadingStart", options);
1027
+ };
1028
+ Notification.prototype.loadingStop = function() {
1029
+ PhoneGap.exec("Notification.loadingStop");
1030
+ };
1031
+ /**
1032
+ * Internal function used to dispatch the request to PhoneGap. It processes the
1033
+ * command queue and executes the next command on the list. If one of the
1034
+ * arguments is a JavaScript object, it will be passed on the QueryString of the
1035
+ * url, which will be turned into a dictionary on the other end.
1036
+ * @private
1037
+ */
1038
+ PhoneGap.run_command = function() {
1039
+ if (!PhoneGap.available || !PhoneGap.queue.ready)
1040
+ return;
1041
+
1042
+ PhoneGap.queue.ready = false;
1043
+
1044
+ var args = PhoneGap.queue.commands.shift();
1045
+ if (PhoneGap.queue.commands.length == 0) {
1046
+ clearInterval(PhoneGap.queue.timer);
1047
+ PhoneGap.queue.timer = null;
1048
+ }
1049
+
1050
+ var uri = [];
1051
+ var dict = null;
1052
+ for (var i = 1; i < args.length; i++) {
1053
+ var arg = args[i];
1054
+ if (arg == undefined || arg == null)
1055
+ arg = '';
1056
+ if (typeof(arg) == 'object')
1057
+ dict = arg;
1058
+ else
1059
+ uri.push(encodeURIComponent(arg));
1060
+ }
1061
+ var url = "gap://" + args[0] + "/" + uri.join("/");
1062
+ if (dict != null) {
1063
+ var query_args = [];
1064
+ for (var name in dict) {
1065
+ if (typeof(name) != 'string')
1066
+ continue;
1067
+ query_args.push(encodeURIComponent(name) + "=" + encodeURIComponent(dict[name]));
1068
+ }
1069
+ if (query_args.length > 0)
1070
+ url += "?" + query_args.join("&");
1071
+ }
1072
+ document.location = url;
1073
+
1074
+ };
1075
+ UIControls.prototype.createTabBar = function() {
1076
+ PhoneGap.exec("UIControls.createTabBar");
1077
+ };
1078
+
1079
+ UIControls.prototype.showTabBar = function(options) {
1080
+ if (!options) options = {};
1081
+ PhoneGap.exec("UIControls.showTabBar", options);
1082
+ };
1083
+
1084
+ UIControls.prototype.hideTabBar = function(animate) {
1085
+ if (animate == undefined || animate == null)
1086
+ animate = true;
1087
+ PhoneGap.exec("UIControls.hideTabBar", { animate: animate });
1088
+ };
1089
+
1090
+ UIControls.prototype.createTabBarItem = function(name, label, image, options) {
1091
+ var tag = this.tabBarTag++;
1092
+ if (options && 'onSelect' in options && typeof(options['onSelect']) == 'function') {
1093
+ this.tabBarCallbacks[tag] = options.onSelect;
1094
+ delete options.onSelect;
1095
+ }
1096
+ PhoneGap.exec("UIControls.createTabBarItem", name, label, image, tag, options);
1097
+ };
1098
+
1099
+ UIControls.prototype.updateTabBarItem = function(name, options) {
1100
+ if (!options) options = {};
1101
+ PhoneGap.exec("UIControls.updateTabBarItem", name, options);
1102
+ };
1103
+
1104
+ UIControls.prototype.showTabBarItems = function() {
1105
+ var parameters = [ "UIControls.showTabBarItems" ];
1106
+ for (var i = 0; i < arguments.length; i++) {
1107
+ parameters.push(arguments[i]);
1108
+ }
1109
+ PhoneGap.exec.apply(this, parameters);
1110
+ };
1111
+
1112
+ UIControls.prototype.selectTabBarItem = function(tab) {
1113
+ PhoneGap.exec("UIControls.selectTabBarItem", tab);
1114
+ };
1115
+
1116
+ UIControls.prototype.createToolBar = function() {
1117
+ PhoneGap.exec("UIControls.createToolBar");
1118
+ };
1119
+
1120
+ UIControls.prototype.setToolBarTitle = function(title) {
1121
+ PhoneGap.exec("UIControls.setToolBarTitle", title);
1122
+ };