incubator-callback-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From shaz...@apache.org
Subject [12/27] Rename PhoneGap to Cordova.
Date Fri, 17 Feb 2012 01:38:49 GMT
http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/bcff9559/CordovaLib/CordovaLibTests/CDVWhitelistTests.h
----------------------------------------------------------------------
diff --git a/CordovaLib/CordovaLibTests/CDVWhitelistTests.h b/CordovaLib/CordovaLibTests/CDVWhitelistTests.h
new file mode 100644
index 0000000..db2a85e
--- /dev/null
+++ b/CordovaLib/CordovaLibTests/CDVWhitelistTests.h
@@ -0,0 +1,26 @@
+/*
+ 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.
+ */
+
+#import <SenTestingKit/SenTestingKit.h>
+
+@interface CDVWhitelistTests : SenTestCase {
+
+}
+
+@end

http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/bcff9559/CordovaLib/CordovaLibTests/CDVWhitelistTests.m
----------------------------------------------------------------------
diff --git a/CordovaLib/CordovaLibTests/CDVWhitelistTests.m b/CordovaLib/CordovaLibTests/CDVWhitelistTests.m
new file mode 100644
index 0000000..55d8378
--- /dev/null
+++ b/CordovaLib/CordovaLibTests/CDVWhitelistTests.m
@@ -0,0 +1,255 @@
+/*
+ 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.
+ */
+
+#import "CDVWhitelistTests.h"
+#import "CDVWhitelist.h"
+
+@implementation CDVWhitelistTests
+
+- (void)setUp
+{
+    [super setUp];
+    
+    // setup code here
+}
+
+- (void)tearDown
+{
+    // Tear-down code here.
+
+    [super tearDown];
+}
+
+- (void) testAllowedSchemes
+{
+    NSArray* allowedHosts = [NSArray arrayWithObjects: 
+                             @"*.apache.org",
+                             nil];
+    
+    CDVWhitelist* whitelist = [[CDVWhitelist alloc] initWithArray:allowedHosts];
+    
+    STAssertTrue([whitelist schemeIsAllowed:@"http"], nil);
+    STAssertTrue([whitelist schemeIsAllowed:@"https"], nil);
+    STAssertTrue([whitelist schemeIsAllowed:@"ftp"], nil);
+    STAssertTrue([whitelist schemeIsAllowed:@"ftps"], nil);
+    STAssertFalse([whitelist schemeIsAllowed:@"gopher"], nil);
+    
+    [whitelist release];
+
+}
+
+- (void) testSubdomainWildcard
+{
+    NSArray* allowedHosts = [NSArray arrayWithObjects: 
+                     @"*.apache.org",
+                     nil];
+    
+    CDVWhitelist* whitelist = [[CDVWhitelist alloc] initWithArray:allowedHosts];
+    
+    STAssertTrue([whitelist URLIsAllowed:[NSURL URLWithString:@"http://build.apache.org"]], nil);
+    STAssertTrue([whitelist URLIsAllowed:[NSURL URLWithString:@"http://apache.org"]], nil);
+    STAssertTrue([whitelist URLIsAllowed:[NSURL URLWithString:@"http://sub1.sub0.build.apache.org"]], nil);
+    STAssertFalse([whitelist URLIsAllowed:[NSURL URLWithString:@"http://apache.org.ca"]], nil);
+    
+    [whitelist release];
+}
+
+- (void) testWildcardInTLD
+{
+    // NOTE: if the user chooses to do this (a wildcard in the TLD, not a wildcard as the TLD), we allow it because we assume they know what they are doing! We don't replace it with known TLDs
+    // This might be applicable for custom TLDs on a local network DNS
+    
+    NSArray* allowedHosts = [NSArray arrayWithObjects: 
+                             @"apache.o*g",
+                             nil];
+    
+    CDVWhitelist* whitelist = [[CDVWhitelist alloc] initWithArray:allowedHosts];
+    
+    STAssertTrue([whitelist URLIsAllowed:[NSURL URLWithString:@"http://apache.ogg"]], nil);
+    STAssertFalse([whitelist URLIsAllowed:[NSURL URLWithString:@"http://apache.foo"]], nil);
+    
+    [whitelist release];
+}
+
+- (void) testTLDWildcard
+{    
+    NSArray* allowedHosts = [NSArray arrayWithObjects: 
+                             @"apache.*",
+                             nil];
+    
+    CDVWhitelist* whitelist = [[CDVWhitelist alloc] initWithArray:allowedHosts];
+    
+    NSString* hostname = @"apache";
+    
+    NSArray* knownTLDs = [NSArray arrayWithObjects:
+                          @"aero", @"asia", @"arpa", @"biz", @"cat",
+                          @"com", @"coop", @"edu", @"gov", @"info",
+                          @"int", @"jobs", @"mil", @"mobi", @"museum",
+                          @"name", @"net", @"org", @"pro", @"tel",
+                          @"travel", @"xxx",
+                          nil];
+    
+    // 26*26 combos
+    NSMutableArray* twoCharCountryCodes = [NSMutableArray arrayWithCapacity:(26*26)];
+    for (char c0 = 'a'; c0 <= 'z'; ++c0)
+    {
+        for (char c1 = 'a'; c1 <= 'z'; ++c1)
+        {
+            [twoCharCountryCodes addObject:[NSString stringWithFormat:@"%c%c", c0, c1]];
+        }
+    }
+
+    NSMutableArray* shouldPass = [NSMutableArray arrayWithCapacity:[knownTLDs count]+[twoCharCountryCodes count]];
+
+    NSEnumerator* knownTLDEnumerator = [knownTLDs objectEnumerator];
+    NSString* tld = nil;
+    
+    while (tld = [knownTLDEnumerator nextObject])
+    {
+        [shouldPass addObject:[NSURL URLWithString:[NSString stringWithFormat:@"http://%@.%@", hostname, tld]]];
+    }
+
+    NSEnumerator* twoCharCountryCodesEnumerator = [twoCharCountryCodes objectEnumerator];
+    NSString* cc = nil;
+    
+    while (cc = [twoCharCountryCodesEnumerator nextObject])
+    {
+        [shouldPass addObject:[NSURL URLWithString:[NSString stringWithFormat:@"http://%@.%@", hostname, cc]]];
+    }
+    
+    NSEnumerator* shouldPassEnumerator = [shouldPass objectEnumerator];
+    NSURL* url = nil;
+
+    while (url = [shouldPassEnumerator nextObject])
+    {
+        STAssertTrue([whitelist URLIsAllowed:url], @"Url tested :%@", [url description]);
+    }
+    
+    STAssertFalse(([whitelist URLIsAllowed:[NSURL URLWithString:[NSString stringWithFormat:@"http://%@.%@", hostname, @"faketld"]]]), nil);
+    STAssertFalse([whitelist URLIsAllowed:[NSURL URLWithString:@"http://unknownhostname.faketld"]], nil);
+    STAssertFalse([whitelist URLIsAllowed:[NSURL URLWithString:@"http://unknownhostname.com"]], nil);
+    STAssertFalse([whitelist URLIsAllowed:[NSURL URLWithString:@"http://www.apache.org"]], nil);
+    
+    [whitelist release];
+}
+
+- (void) testCatchallWildcardOnly
+{    
+    NSArray* allowedHosts = [NSArray arrayWithObjects: 
+                             @"*",
+                             nil];
+    
+    CDVWhitelist* whitelist = [[CDVWhitelist alloc] initWithArray:allowedHosts];
+    
+    STAssertTrue([whitelist URLIsAllowed:[NSURL URLWithString:@"http://apache.org"]], nil);
+    STAssertTrue([whitelist URLIsAllowed:[NSURL URLWithString:@"http://build.apache.prg"]], nil);
+    STAssertTrue([whitelist URLIsAllowed:[NSURL URLWithString:@"http://MyDangerousSite.org"]], nil);
+    STAssertTrue([whitelist URLIsAllowed:[NSURL URLWithString:@"http://apache.org.SuspiciousSite.com"]], nil);
+    
+    [whitelist release];
+}
+
+- (void) testWildcardInHostname
+{    
+    NSArray* allowedHosts = [NSArray arrayWithObjects: 
+                             @"www.*apac*he.org",
+                             nil];
+    
+    CDVWhitelist* whitelist = [[CDVWhitelist alloc] initWithArray:allowedHosts];
+        
+    STAssertTrue([whitelist URLIsAllowed:[NSURL URLWithString:@"http://www.apache.org"]], nil);
+    STAssertTrue([whitelist URLIsAllowed:[NSURL URLWithString:@"http://www.apacMAChe.org"]], nil);
+    STAssertTrue([whitelist URLIsAllowed:[NSURL URLWithString:@"http://www.MACapache.org"]], nil);
+    STAssertTrue([whitelist URLIsAllowed:[NSURL URLWithString:@"http://www.MACapacMAChe.org"]], nil);
+    STAssertFalse([whitelist URLIsAllowed:[NSURL URLWithString:@"http://apache.org"]], nil);
+    
+    [whitelist release];
+}
+
+- (void) testExactMatch
+{    
+    NSArray* allowedHosts = [NSArray arrayWithObjects: 
+                             @"www.apache.org",
+                             nil];
+    
+    CDVWhitelist* whitelist = [[CDVWhitelist alloc] initWithArray:allowedHosts];
+    
+    STAssertTrue([whitelist URLIsAllowed:[NSURL URLWithString:@"http://www.apache.org"]], nil);
+    STAssertFalse([whitelist URLIsAllowed:[NSURL URLWithString:@"http://build.apache.org"]], nil);
+    STAssertFalse([whitelist URLIsAllowed:[NSURL URLWithString:@"http://apache.org"]], nil);
+    
+    [whitelist release];
+}
+
+- (void) testWildcardMix
+{    
+    NSArray* allowedHosts = [NSArray arrayWithObjects: 
+                             @"*.apac*he.*",
+                             nil];
+    
+    CDVWhitelist* whitelist = [[CDVWhitelist alloc] initWithArray:allowedHosts];
+    
+    STAssertTrue([whitelist URLIsAllowed:[NSURL URLWithString:@"http://www.apache.org"]], nil);
+    STAssertTrue([whitelist URLIsAllowed:[NSURL URLWithString:@"http://apache.org"]], nil);
+    STAssertTrue([whitelist URLIsAllowed:[NSURL URLWithString:@"http://apacMAChe.ca"]], nil);
+    STAssertTrue([whitelist URLIsAllowed:[NSURL URLWithString:@"http://apacMAChe.museum"]], nil);
+    STAssertFalse([whitelist URLIsAllowed:[NSURL URLWithString:@"http://blahMAChe.museum"]], nil);
+    
+    [whitelist release];
+}
+
+- (void) testIpExactMatch
+{    
+    NSArray* allowedHosts = [NSArray arrayWithObjects: 
+                             @"192.168.1.1",
+                             @"192.168.2.1",
+                             nil];
+    
+    CDVWhitelist* whitelist = [[CDVWhitelist alloc] initWithArray:allowedHosts];
+    
+    STAssertFalse([whitelist URLIsAllowed:[NSURL URLWithString:@"http://apache.org"]], nil);
+    STAssertTrue([whitelist URLIsAllowed:[NSURL URLWithString:@"http://192.168.1.1"]], nil);
+    STAssertTrue([whitelist URLIsAllowed:[NSURL URLWithString:@"http://192.168.2.1"]], nil);
+    STAssertFalse([whitelist URLIsAllowed:[NSURL URLWithString:@"http://192.168.3.1"]], nil);
+    
+    [whitelist release];
+}
+
+- (void) testIpWildcardMatch
+{    
+    NSArray* allowedHosts = [NSArray arrayWithObjects: 
+                             @"192.168.1.*",
+                             @"192.168.2.*",
+                             nil];
+    
+    CDVWhitelist* whitelist = [[CDVWhitelist alloc] initWithArray:allowedHosts];
+    
+    STAssertFalse([whitelist URLIsAllowed:[NSURL URLWithString:@"http://apache.org"]], nil);
+    STAssertTrue([whitelist URLIsAllowed:[NSURL URLWithString:@"http://192.168.1.1"]], nil);
+    STAssertTrue([whitelist URLIsAllowed:[NSURL URLWithString:@"http://192.168.1.2"]], nil);
+    STAssertTrue([whitelist URLIsAllowed:[NSURL URLWithString:@"http://192.168.2.1"]], nil);
+    STAssertTrue([whitelist URLIsAllowed:[NSURL URLWithString:@"http://192.168.2.2"]], nil);
+    STAssertFalse([whitelist URLIsAllowed:[NSURL URLWithString:@"http://192.168.3.1"]], nil);
+    
+    [whitelist release];
+}
+
+
+
+@end

http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/bcff9559/CordovaLib/CordovaLibTests/CordovaLibTests-Info.plist
----------------------------------------------------------------------
diff --git a/CordovaLib/CordovaLibTests/CordovaLibTests-Info.plist b/CordovaLib/CordovaLibTests/CordovaLibTests-Info.plist
new file mode 100644
index 0000000..2b819ff
--- /dev/null
+++ b/CordovaLib/CordovaLibTests/CordovaLibTests-Info.plist
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>en</string>
+	<key>CFBundleExecutable</key>
+	<string>${EXECUTABLE_NAME}</string>
+	<key>CFBundleIdentifier</key>
+	<string>org.apache.cordova.${PRODUCT_NAME:rfc1034identifier}</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundlePackageType</key>
+	<string>BNDL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>1</string>
+</dict>
+</plist>

http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/bcff9559/CordovaLib/CordovaLibTests/CordovaLibTests-Prefix.pch
----------------------------------------------------------------------
diff --git a/CordovaLib/CordovaLibTests/CordovaLibTests-Prefix.pch b/CordovaLib/CordovaLibTests/CordovaLibTests-Prefix.pch
new file mode 100644
index 0000000..059c8de
--- /dev/null
+++ b/CordovaLib/CordovaLibTests/CordovaLibTests-Prefix.pch
@@ -0,0 +1,25 @@
+/*
+ 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.
+ */
+//
+// Prefix header for all source files of the 'CordovaLibTests' target in the 'CordovaLibTests' project
+//
+
+#ifdef __OBJC__
+    #import <UIKit/UIKit.h>
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/bcff9559/CordovaLib/CordovaLibTests/en.lproj/InfoPlist.strings
----------------------------------------------------------------------
diff --git a/CordovaLib/CordovaLibTests/en.lproj/InfoPlist.strings b/CordovaLib/CordovaLibTests/en.lproj/InfoPlist.strings
new file mode 100644
index 0000000..01d5c8c
--- /dev/null
+++ b/CordovaLib/CordovaLibTests/en.lproj/InfoPlist.strings
@@ -0,0 +1,20 @@
+/*
+ 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.
+ */
+/* Localized versions of Info.plist keys */
+

http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/bcff9559/CordovaLib/CordovaLib_Prefix.pch
----------------------------------------------------------------------
diff --git a/CordovaLib/CordovaLib_Prefix.pch b/CordovaLib/CordovaLib_Prefix.pch
new file mode 100644
index 0000000..9545580
--- /dev/null
+++ b/CordovaLib/CordovaLib_Prefix.pch
@@ -0,0 +1,22 @@
+/*
+ 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.
+ */
+
+#ifdef __OBJC__
+    #import <Foundation/Foundation.h>
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/bcff9559/CordovaLib/Makefile
----------------------------------------------------------------------
diff --git a/CordovaLib/Makefile b/CordovaLib/Makefile
new file mode 100644
index 0000000..9b49ed5
--- /dev/null
+++ b/CordovaLib/Makefile
@@ -0,0 +1,70 @@
+#
+# 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.
+#
+
+SHELL = /bin/sh
+CHMOD = chmod
+CP = cp
+MV = mv
+NOOP = $(SHELL) -c true
+RM_F = rm -f
+RM_IR = rm -iR
+RM_RF = rm -rf
+TEST_F = test -f
+TOUCH = touch
+UMASK_NULL = umask 0
+DEV_NULL = > /dev/null 2>&1
+MKPATH = mkdir -p
+CAT = cat
+MAKE = make
+OPEN = open
+JAVA = java
+ECHO = echo
+ECHO_N = echo -n
+CDV_JS_CORE = javascripts/core
+CDV_VER = $(shell head -1 VERSION)
+
+all :: javascripts/cordova-$(CDV_VER).js
+
+javascripts/cordova-$(CDV_VER).js: clean $(CDV_JS_CORE)/license.js $(CDV_JS_CORE)/cordova.js.base $(CDV_JS_CORE)/acceleration.js $(CDV_JS_CORE)/accelerometer.js $(CDV_JS_CORE)/battery.js $(CDV_JS_CORE)/camera.js $(CDV_JS_CORE)/capture.js $(CDV_JS_CORE)/contact.js $(CDV_JS_CORE)/debugconsole.js $(CDV_JS_CORE)/device.js $(CDV_JS_CORE)/file.js $(CDV_JS_CORE)/filetransfer.js $(CDV_JS_CORE)/geolocation.js $(CDV_JS_CORE)/compass.js $(CDV_JS_CORE)/media.js $(CDV_JS_CORE)/notification.js $(CDV_JS_CORE)/orientation.js $(CDV_JS_CORE)/position.js $(CDV_JS_CORE)/sms.js $(CDV_JS_CORE)/telephony.js $(CDV_JS_CORE)/network.js $(CDV_JS_CORE)/splashscreen.js
+	$(RM_F) $@
+	$(CAT) $(CDV_JS_CORE)/license.js | sed 's/{VERSION}/$(CDV_VER)/' >> $@
+	$(CAT) $(CDV_JS_CORE)/cordova.js.base >> $@
+	$(CAT) $(CDV_JS_CORE)/debugconsole.js >> $@
+	$(CAT) $(CDV_JS_CORE)/position.js >> $@
+	$(CAT) $(CDV_JS_CORE)/acceleration.js >> $@
+	$(CAT) $(CDV_JS_CORE)/accelerometer.js >> $@
+	$(CAT) $(CDV_JS_CORE)/battery.js >> $@
+	$(CAT) $(CDV_JS_CORE)/camera.js >> $@
+	$(CAT) $(CDV_JS_CORE)/device.js >> $@
+	$(CAT) $(CDV_JS_CORE)/capture.js >> $@
+	$(CAT) $(CDV_JS_CORE)/contact.js >> $@
+	$(CAT) $(CDV_JS_CORE)/file.js >> $@
+	$(CAT) $(CDV_JS_CORE)/filetransfer.js >> $@
+	$(CAT) $(CDV_JS_CORE)/geolocation.js >> $@
+	$(CAT) $(CDV_JS_CORE)/compass.js >> $@
+	$(CAT) $(CDV_JS_CORE)/media.js >> $@
+	$(CAT) $(CDV_JS_CORE)/notification.js >> $@
+	$(CAT) $(CDV_JS_CORE)/orientation.js >> $@
+	$(CAT) $(CDV_JS_CORE)/sms.js >> $@
+	$(CAT) $(CDV_JS_CORE)/telephony.js >> $@
+	$(CAT) $(CDV_JS_CORE)/network.js >> $@
+	$(CAT) $(CDV_JS_CORE)/splashscreen.js >> $@
+	
+clean:
+	$(RM_F) javascripts/cordova-*.js
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/bcff9559/CordovaLib/VERSION
----------------------------------------------------------------------
diff --git a/CordovaLib/VERSION b/CordovaLib/VERSION
new file mode 100644
index 0000000..13175fd
--- /dev/null
+++ b/CordovaLib/VERSION
@@ -0,0 +1 @@
+1.4.1
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/bcff9559/CordovaLib/javascripts/core/acceleration.js
----------------------------------------------------------------------
diff --git a/CordovaLib/javascripts/core/acceleration.js b/CordovaLib/javascripts/core/acceleration.js
new file mode 100644
index 0000000..d2d29de
--- /dev/null
+++ b/CordovaLib/javascripts/core/acceleration.js
@@ -0,0 +1,42 @@
+if (!Cordova.hasResource("acceleration")) {
+	Cordova.addResource("acceleration");
+ 	
+
+/**
+ * This class contains acceleration information
+ * @constructor
+ * @param {Number} x The force applied by the device in the x-axis.
+ * @param {Number} y The force applied by the device in the y-axis.
+ * @param {Number} z The force applied by the device in the z-axis.
+ */
+Acceleration = function(x, y, z) {
+	/**
+	 * The force applied by the device in the x-axis.
+	 */
+	this.x = x;
+	/**
+	 * The force applied by the device in the y-axis.
+	 */
+	this.y = y;
+	/**
+	 * The force applied by the device in the z-axis.
+	 */
+	this.z = z;
+	/**
+	 * The time that the acceleration was obtained.
+	 */
+	this.timestamp = new Date().getTime();
+}
+
+/**
+ * This class specifies the options for requesting acceleration data.
+ * @constructor
+ */
+AccelerationOptions = function() {
+	/**
+	 * The timeout after which if acceleration data cannot be obtained the errorCallback
+	 * is called.
+	 */
+	this.timeout = 10000;
+}
+};
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/bcff9559/CordovaLib/javascripts/core/accelerometer.js
----------------------------------------------------------------------
diff --git a/CordovaLib/javascripts/core/accelerometer.js b/CordovaLib/javascripts/core/accelerometer.js
new file mode 100644
index 0000000..beb7ff6
--- /dev/null
+++ b/CordovaLib/javascripts/core/accelerometer.js
@@ -0,0 +1,160 @@
+if (!Cordova.hasResource("accelerometer")) {
+	Cordova.addResource("accelerometer");
+
+/**
+ * This class provides access to device accelerometer data.
+ * @constructor
+ */
+Accelerometer = function() 
+{
+	/**
+	 * The last known acceleration.
+	 */
+	this.lastAcceleration = new Acceleration(0,0,0);
+}
+
+/**
+ * Asynchronously aquires the current acceleration.
+ * @param {Function} successCallback The function to call when the acceleration
+ * data is available
+ * @param {Function} errorCallback The function to call when there is an error 
+ * getting the acceleration data.
+ * @param {AccelerationOptions} options The options for getting the accelerometer data
+ * such as timeout.
+ */
+Accelerometer.prototype.getCurrentAcceleration = function(successCallback, errorCallback, options) {
+	// If the acceleration is available then call success
+	// If the acceleration is not available then call error
+	
+	// Created for iPhone, Iphone passes back _accel obj litteral
+	if (typeof successCallback == "function") {
+		successCallback(this.lastAcceleration);
+	}
+};
+
+// private callback called from Obj-C by name
+Accelerometer.prototype._onAccelUpdate = function(x,y,z)
+{
+   this.lastAcceleration = new Acceleration(x,y,z);
+};
+
+/**
+ * Asynchronously aquires the acceleration repeatedly at a given interval.
+ * @param {Function} successCallback The function to call each time the acceleration
+ * data is available
+ * @param {Function} errorCallback The function to call when there is an error 
+ * getting the acceleration data.
+ * @param {AccelerationOptions} options The options for getting the accelerometer data
+ * such as timeout.
+ */
+
+Accelerometer.prototype.watchAcceleration = function(successCallback, errorCallback, options) {
+	//this.getCurrentAcceleration(successCallback, errorCallback, options);
+	// TODO: add the interval id to a list so we can clear all watches
+ 	var frequency = (options != undefined && options.frequency != undefined) ? options.frequency : 10000;
+	var updatedOptions = {
+		desiredFrequency:frequency 
+	}
+	Cordova.exec(null, null, "org.apache.cordova.accelerometer", "start", [options]);
+
+	return setInterval(function() {
+		navigator.accelerometer.getCurrentAcceleration(successCallback, errorCallback, options);
+	}, frequency);
+};
+
+/**
+ * Clears the specified accelerometer watch.
+ * @param {String} watchId The ID of the watch returned from #watchAcceleration.
+ */
+Accelerometer.prototype.clearWatch = function(watchId) {
+	Cordova.exec(null, null, "org.apache.cordova.accelerometer", "stop", []);
+	clearInterval(watchId);
+};
+
+Accelerometer.install = function()
+{
+    if (typeof navigator.accelerometer == "undefined") {
+		navigator.accelerometer = new Accelerometer();
+	}
+};
+
+Accelerometer.installDeviceMotionHandler = function()
+{
+	if (!(window.DeviceMotionEvent == undefined)) {
+		// supported natively, so we don't have to add support
+		return;
+	}	
+	
+	var self = this;
+	var devicemotionEvent = 'devicemotion';
+	self.deviceMotionWatchId = null;
+	self.deviceMotionListenerCount = 0;
+	self.deviceMotionLastEventTimestamp = 0;
+	
+	// backup original `window.addEventListener`, `window.removeEventListener`
+    var _addEventListener = window.addEventListener;
+    var _removeEventListener = window.removeEventListener;
+													
+	var windowDispatchAvailable = !(window.dispatchEvent === undefined); // undefined in iOS 3.x
+													
+	var accelWin = function(acceleration) {
+		var evt = document.createEvent('Events');
+	    evt.initEvent(devicemotionEvent);
+	
+		evt.acceleration = null; // not all devices have gyroscope, don't care for now if we actually have it.
+		evt.rotationRate = null; // not all devices have gyroscope, don't care for now if we actually have it:
+		evt.accelerationIncludingGravity = acceleration; // accelerometer, all iOS devices have it
+		
+		var currentTime = new Date().getTime();
+		evt.interval =  (self.deviceMotionLastEventTimestamp == 0) ? 0 : (currentTime - self.deviceMotionLastEventTimestamp);
+		self.deviceMotionLastEventTimestamp = currentTime;
+		
+		if (windowDispatchAvailable) {
+			window.dispatchEvent(evt);
+		} else {
+			document.dispatchEvent(evt);
+		}
+	};
+	
+	var accelFail = function() {
+		
+	};
+													
+    // override `window.addEventListener`
+    window.addEventListener = function() {
+        if (arguments[0] === devicemotionEvent) {
+            ++(self.deviceMotionListenerCount);
+			if (self.deviceMotionListenerCount == 1) { // start
+				self.deviceMotionWatchId = navigator.accelerometer.watchAcceleration(accelWin, accelFail, { frequency:500});
+			}
+		} 
+													
+		if (!windowDispatchAvailable) {
+			return document.addEventListener.apply(this, arguments);
+		} else {
+			return _addEventListener.apply(this, arguments);
+		}
+    };	
+
+    // override `window.removeEventListener'
+    window.removeEventListener = function() {
+        if (arguments[0] === devicemotionEvent) {
+            --(self.deviceMotionListenerCount);
+			if (self.deviceMotionListenerCount == 0) { // stop
+				navigator.accelerometer.clearWatch(self.deviceMotionWatchId);
+			}
+		} 
+		
+		if (!windowDispatchAvailable) {
+			return document.removeEventListener.apply(this, arguments);
+		} else {
+			return _removeEventListener.apply(this, arguments);
+		}
+    };	
+};
+
+
+Cordova.addConstructor(Accelerometer.install);
+Cordova.addConstructor(Accelerometer.installDeviceMotionHandler);
+
+};
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/bcff9559/CordovaLib/javascripts/core/battery.js
----------------------------------------------------------------------
diff --git a/CordovaLib/javascripts/core/battery.js b/CordovaLib/javascripts/core/battery.js
new file mode 100644
index 0000000..685a630
--- /dev/null
+++ b/CordovaLib/javascripts/core/battery.js
@@ -0,0 +1,123 @@
+
+if (!Cordova.hasResource("battery")) {
+Cordova.addResource("battery");
+
+/**
+ * This class contains information about the current battery status.
+ * @constructor
+ */
+var Battery = function() {
+    this._level = null;
+    this._isPlugged = null;
+    this._batteryListener = [];
+    this._lowListener = [];
+    this._criticalListener = [];
+};
+
+/**
+ * Registers as an event producer for battery events.
+ * 
+ * @param {Object} eventType
+ * @param {Object} handler
+ * @param {Object} add
+ */
+Battery.prototype.eventHandler = function(eventType, handler, add) {
+    var me = navigator.battery;
+    if (add) {
+        // If there are no current registered event listeners start the battery listener on native side.
+        if (me._batteryListener.length === 0 && me._lowListener.length === 0 && me._criticalListener.length === 0) {
+            Cordova.exec(me._status, me._error, "org.apache.cordova.battery", "start", []);
+        }
+        
+        // Register the event listener in the proper array
+        if (eventType === "batterystatus") {
+            var pos = me._batteryListener.indexOf(handler);
+            if (pos === -1) {
+            	me._batteryListener.push(handler);
+            }
+        } else if (eventType === "batterylow") {
+            var pos = me._lowListener.indexOf(handler);
+            if (pos === -1) {
+            	me._lowListener.push(handler);
+            }
+        } else if (eventType === "batterycritical") {
+            var pos = me._criticalListener.indexOf(handler);
+            if (pos === -1) {
+            	me._criticalListener.push(handler);
+            }
+        }
+    } else {
+        // Remove the event listener from the proper array
+        if (eventType === "batterystatus") {
+            var pos = me._batteryListener.indexOf(handler);
+            if (pos > -1) {
+                me._batteryListener.splice(pos, 1);        
+            }
+        } else if (eventType === "batterylow") {
+            var pos = me._lowListener.indexOf(handler);
+            if (pos > -1) {
+                me._lowListener.splice(pos, 1);        
+            }
+        } else if (eventType === "batterycritical") {
+            var pos = me._criticalListener.indexOf(handler);
+            if (pos > -1) {
+                me._criticalListener.splice(pos, 1);        
+            }
+        }
+        
+        // If there are no more registered event listeners stop the battery listener on native side.
+        if (me._batteryListener.length === 0 && me._lowListener.length === 0 && me._criticalListener.length === 0) {
+            Cordova.exec(null, null, "org.apache.cordova.battery", "stop", []);
+        }
+    }
+};
+
+/**
+ * Callback for battery status
+ * 
+ * @param {Object} info			keys: level, isPlugged
+ */
+Battery.prototype._status = function(info) {
+	if (info) {
+		var me = this;
+		if (me._level != info.level || me._isPlugged != info.isPlugged) {
+			// Fire batterystatus event
+			//Cordova.fireWindowEvent("batterystatus", info);
+			// use this workaround since iOS 3.x does have window.dispatchEvent
+			Cordova.fireEvent("batterystatus", window, info);	
+
+			// Fire low battery event
+			if (info.level == 20 || info.level == 5) {
+				if (info.level == 20) {
+					//Cordova.fireWindowEvent("batterylow", info);
+					// use this workaround since iOS 3.x does not have window.dispatchEvent
+					Cordova.fireEvent("batterylow", window, info);
+				}
+				else {
+					//Cordova.fireWindowEvent("batterycritical", info);
+					// use this workaround since iOS 3.x does not have window.dispatchEvent
+					Cordova.fireEvent("batterycritical", window, info);
+				}
+			}
+		}
+		me._level = info.level;
+		me._isPlugged = info.isPlugged;	
+	}
+};
+
+/**
+ * Error callback for battery start
+ */
+Battery.prototype._error = function(e) {
+    console.log("Error initializing Battery: " + e);
+};
+
+Cordova.addConstructor(function() {
+    if (typeof navigator.battery === "undefined") {
+        navigator.battery = new Battery();
+        Cordova.addWindowEventHandler("batterystatus", navigator.battery.eventHandler);
+        Cordova.addWindowEventHandler("batterylow", navigator.battery.eventHandler);
+        Cordova.addWindowEventHandler("batterycritical", navigator.battery.eventHandler);
+    }
+});
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/bcff9559/CordovaLib/javascripts/core/camera.js
----------------------------------------------------------------------
diff --git a/CordovaLib/javascripts/core/camera.js b/CordovaLib/javascripts/core/camera.js
new file mode 100644
index 0000000..1cc5ebb
--- /dev/null
+++ b/CordovaLib/javascripts/core/camera.js
@@ -0,0 +1,117 @@
+if (!Cordova.hasResource("camera")) {
+	Cordova.addResource("camera");
+	
+
+/**
+ * This class provides access to the device camera.
+ * @constructor
+ */
+Camera = function() {
+	
+}
+/**
+ *  Available Camera Options
+ *  {boolean} allowEdit - true to allow editing image, default = false
+ *	{number} quality 0-100 (low to high) default =  100
+ *  {Camera.DestinationType} destinationType default = DATA_URL
+ *	{Camera.PictureSourceType} sourceType default = CAMERA
+ *	{number} targetWidth - width in pixels to scale image default = 0 (no scaling)
+ *  {number} targetHeight - height in pixels to scale image default = 0 (no scaling)
+ *  {Camera.EncodingType} - encodingType default = JPEG
+ *  {boolean} correctOrientation - Rotate the image to correct for the orientation of the device during capture (iOS only)
+ *  {boolean} saveToPhotoAlbum - Save the image to the photo album on the device after capture (iOS only)
+ */
+/**
+ * Format of image that is returned from getPicture.
+ *
+ * Example: navigator.camera.getPicture(success, fail,
+ *              { quality: 80,
+ *                destinationType: Camera.DestinationType.DATA_URL,
+ *                sourceType: Camera.PictureSourceType.PHOTOLIBRARY})
+ */
+Camera.DestinationType = {
+    DATA_URL: 0,                // Return base64 encoded string
+    FILE_URI: 1                 // Return file uri 
+};
+Camera.prototype.DestinationType = Camera.DestinationType;
+
+/**
+ * Source to getPicture from.
+ *
+ * Example: navigator.camera.getPicture(success, fail,
+ *              { quality: 80,
+ *                destinationType: Camera.DestinationType.DATA_URL,
+ *                sourceType: Camera.PictureSourceType.PHOTOLIBRARY})
+ */
+Camera.PictureSourceType = {
+    PHOTOLIBRARY : 0,           // Choose image from picture library 
+    CAMERA : 1,                 // Take picture from camera
+    SAVEDPHOTOALBUM : 2         // Choose image from picture library 
+};
+Camera.prototype.PictureSourceType = Camera.PictureSourceType;
+
+/** 
+ * Encoding of image returned from getPicture. 
+ * 
+ * Example: navigator.camera.getPicture(success, fail, 
+ *              { quality: 80, 
+ *                destinationType: Camera.DestinationType.DATA_URL, 
+ *                sourceType: Camera.PictureSourceType.CAMERA, 
+ *                encodingType: Camera.EncodingType.PNG}) 
+ */ 
+Camera.EncodingType = { 
+	JPEG: 0,                    // Return JPEG encoded image 
+	PNG: 1                      // Return PNG encoded image 
+};
+Camera.prototype.EncodingType = Camera.EncodingType;
+
+/** 
+ * Type of pictures to select from.  Only applicable when
+ *	PictureSourceType is PHOTOLIBRARY or SAVEDPHOTOALBUM 
+ * 
+ * Example: navigator.camera.getPicture(success, fail, 
+ *              { quality: 80, 
+ *                destinationType: Camera.DestinationType.DATA_URL, 
+ *                sourceType: Camera.PictureSourceType.PHOTOLIBRARY, 
+ *                mediaType: Camera.MediaType.PICTURE}) 
+ */ 
+Camera.MediaType = { 
+	PICTURE: 0,             // allow selection of still pictures only. DEFAULT. Will return format specified via DestinationType
+	VIDEO: 1,                // allow selection of video only, ONLY RETURNS URL
+	ALLMEDIA : 2			// allow selection from all media types
+};
+Camera.prototype.MediaType = Camera.MediaType;
+
+/**
+ * Gets a picture from source defined by "options.sourceType", and returns the
+ * image as defined by the "options.destinationType" option.
+
+ * The defaults are sourceType=CAMERA and destinationType=DATA_URL.
+ *
+ * @param {Function} successCallback
+ * @param {Function} errorCallback
+ * @param {Object} options
+ */
+Camera.prototype.getPicture = function(successCallback, errorCallback, options) {
+	// successCallback required
+	if (typeof successCallback != "function") {
+        console.log("Camera Error: successCallback is not a function");
+        return;
+    }
+
+    // errorCallback optional
+    if (errorCallback && (typeof errorCallback != "function")) {
+        console.log("Camera Error: errorCallback is not a function");
+        return;
+    }
+	
+	Cordova.exec(successCallback, errorCallback, "org.apache.cordova.camera","getPicture",[options]);
+};
+
+
+
+Cordova.addConstructor(function() {
+    if (typeof navigator.camera == "undefined") navigator.camera = new Camera();
+});
+};
+

http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/bcff9559/CordovaLib/javascripts/core/capture.js
----------------------------------------------------------------------
diff --git a/CordovaLib/javascripts/core/capture.js b/CordovaLib/javascripts/core/capture.js
new file mode 100644
index 0000000..44bfc97
--- /dev/null
+++ b/CordovaLib/javascripts/core/capture.js
@@ -0,0 +1,194 @@
+if (!Cordova.hasResource("capture")) {
+	Cordova.addResource("capture");
+/**
+ * The CaptureError interface encapsulates all errors in the Capture API.
+ */
+function CaptureError() {
+   this.code = null;
+};
+
+// Capture error codes
+CaptureError.CAPTURE_INTERNAL_ERR = 0;
+CaptureError.CAPTURE_APPLICATION_BUSY = 1;
+CaptureError.CAPTURE_INVALID_ARGUMENT = 2;
+CaptureError.CAPTURE_NO_MEDIA_FILES = 3;
+CaptureError.CAPTURE_NOT_SUPPORTED = 20;
+
+/**
+ * The Capture interface exposes an interface to the camera and microphone of the hosting device.
+ */
+function Capture() {
+	this.supportedAudioModes = [];
+	this.supportedImageModes = [];
+	this.supportedVideoModes = [];
+};
+
+/**
+ * Launch audio recorder application for recording audio clip(s).
+ * 
+ * @param {Function} successCB
+ * @param {Function} errorCB
+ * @param {CaptureAudioOptions} options
+ *
+ * No audio recorder to launch for iOS - return CAPTURE_NOT_SUPPORTED
+ */
+Capture.prototype.captureAudio = function(successCallback, errorCallback, options) {
+	/*if (errorCallback && typeof errorCallback === "function") {
+		errorCallback({
+				"code": CaptureError.CAPTURE_NOT_SUPPORTED
+			});
+	}*/
+    Cordova.exec(successCallback, errorCallback, "org.apache.cordova.mediacapture", "captureAudio", [options]);
+};
+
+/**
+ * Launch camera application for taking image(s).
+ * 
+ * @param {Function} successCB
+ * @param {Function} errorCB
+ * @param {CaptureImageOptions} options
+ */
+Capture.prototype.captureImage = function(successCallback, errorCallback, options) {
+    Cordova.exec(successCallback, errorCallback, "org.apache.cordova.mediacapture", "captureImage", [options]);
+};
+
+/**
+ * Casts a PluginResult message property  (array of objects) to an array of MediaFile objects
+ * (used in Objective-C)
+ *
+ * @param {PluginResult} pluginResult
+ */
+Capture.prototype._castMediaFile = function(pluginResult) {
+    var mediaFiles = [];
+    var i;
+    for (i=0; i<pluginResult.message.length; i++) {
+        var mediaFile = new MediaFile();
+	    mediaFile.name = pluginResult.message[i].name;
+	    mediaFile.fullPath = pluginResult.message[i].fullPath;
+	    mediaFile.type = pluginResult.message[i].type;
+	    mediaFile.lastModifiedDate = pluginResult.message[i].lastModifiedDate;
+	    mediaFile.size = pluginResult.message[i].size;
+        mediaFiles.push(mediaFile);
+    }
+    pluginResult.message = mediaFiles;
+    return pluginResult;
+};
+
+/**
+ * Launch device camera application for recording video(s).
+ * 
+ * @param {Function} successCB
+ * @param {Function} errorCB
+ * @param {CaptureVideoOptions} options
+ */
+Capture.prototype.captureVideo = function(successCallback, errorCallback, options) {
+    Cordova.exec(successCallback, errorCallback, "org.apache.cordova.mediacapture", "captureVideo", [options]);
+};
+
+/**
+ * Encapsulates a set of parameters that the capture device supports.
+ */
+function ConfigurationData() {
+    // The ASCII-encoded string in lower case representing the media type. 
+    this.type; 
+    // The height attribute represents height of the image or video in pixels. 
+    // In the case of a sound clip this attribute has value 0. 
+    this.height = 0;
+    // The width attribute represents width of the image or video in pixels. 
+    // In the case of a sound clip this attribute has value 0
+    this.width = 0;
+};
+
+/**
+ * Encapsulates all image capture operation configuration options.
+ */
+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; 
+};
+
+/**
+ * Encapsulates all video capture operation configuration options.
+ */
+var CaptureVideoOptions = function() {
+    // Upper limit of videos user can record. Value must be equal or greater than 1.
+    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;
+};
+
+/**
+ * Encapsulates all audio capture operation configuration options.
+ */
+var CaptureAudioOptions = function() {
+    // Upper limit of sound clips user can record. Value must be equal or greater than 1.
+    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;
+};
+
+/**
+ * Represents a single file.
+ * 
+ * name {DOMString} name of the file, without path information
+ * fullPath {DOMString} the full path of the file, including the name
+ * type {DOMString} mime type
+ * lastModifiedDate {Date} last modified date
+ * size {Number} size of the file in bytes
+ */
+function MediaFile(name, fullPath, type, lastModifiedDate, size) {
+    this.name = name || null;
+    this.fullPath = fullPath || null;
+    this.type = type || null;
+    this.lastModifiedDate = lastModifiedDate || null;
+    this.size = size || 0;
+}
+
+/**
+ * Request capture format data for a specific file and type
+ * 
+ * @param {Function} successCB
+ * @param {Function} errorCB
+ */
+MediaFile.prototype.getFormatData = function(successCallback, errorCallback) {
+	if (typeof this.fullPath === "undefined" || this.fullPath === null) {
+		errorCallback({
+				"code": CaptureError.CAPTURE_INVALID_ARGUMENT
+			});
+	} else {
+    	Cordova.exec(successCallback, errorCallback, "org.apache.cordova.mediacapture", "getFormatData", [this.fullPath, this.type]);
+	}	
+};
+
+/**
+ * MediaFileData encapsulates format information of a media file.
+ * 
+ * @param {DOMString} codecs
+ * @param {long} bitrate
+ * @param {long} height
+ * @param {long} width
+ * @param {float} duration
+ */
+function MediaFileData(codecs, bitrate, height, width, duration) {
+    this.codecs = codecs || null;
+    this.bitrate = bitrate || 0;
+    this.height = height || 0;
+    this.width = width || 0;
+    this.duration = duration || 0;
+}
+
+Cordova.addConstructor(function() {
+    if (typeof navigator.device === "undefined") {
+        navigator.device = window.device = new Device();
+    }
+    if (typeof navigator.device.capture === "undefined") {
+        navigator.device.capture = window.device.capture = new Capture();
+    }
+});
+};

http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/bcff9559/CordovaLib/javascripts/core/compass.js
----------------------------------------------------------------------
diff --git a/CordovaLib/javascripts/core/compass.js b/CordovaLib/javascripts/core/compass.js
new file mode 100644
index 0000000..443984c
--- /dev/null
+++ b/CordovaLib/javascripts/core/compass.js
@@ -0,0 +1,155 @@
+if (!Cordova.hasResource("compass")) {
+	Cordova.addResource("compass");
+
+CompassError = function(){
+   this.code = null;
+};
+
+// Capture error codes
+CompassError.COMPASS_INTERNAL_ERR = 0;
+CompassError.COMPASS_NOT_SUPPORTED = 20;
+
+CompassHeading = function() {
+	this.magneticHeading = null;
+	this.trueHeading = null;
+	this.headingAccuracy = null;
+	this.timestamp = null;
+}	
+/**
+ * This class provides access to device Compass data.
+ * @constructor
+ */
+Compass = function() {
+    /**
+     * List of compass watch timers
+     */
+    this.timers = {};
+};
+
+/**
+ * Asynchronously acquires the current heading.
+ * @param {Function} successCallback The function to call when the heading
+ * data is available
+ * @param {Function} errorCallback The function to call when there is an error 
+ * getting the heading data.
+ * @param {PositionOptions} options The options for getting the heading data (not used).
+ */
+Compass.prototype.getCurrentHeading = function(successCallback, errorCallback, options) {
+ 	// successCallback required
+    if (typeof successCallback !== "function") {
+        console.log("Compass Error: successCallback is not a function");
+        return;
+    }
+
+    // errorCallback optional
+    if (errorCallback && (typeof errorCallback !== "function")) {
+        console.log("Compass Error: errorCallback is not a function");
+        return;
+    }
+
+    // Get heading
+    Cordova.exec(successCallback, errorCallback, "org.apache.cordova.geolocation", "getCurrentHeading", []);
+};
+
+/**
+ * Asynchronously acquires the heading repeatedly at a given interval.
+ * @param {Function} successCallback The function to call each time the heading
+ * data is available
+ * @param {Function} errorCallback The function to call when there is an error 
+ * getting the heading data.
+ * @param {HeadingOptions} options The options for getting the heading data
+ * such as timeout and the frequency of the watch.
+ */
+Compass.prototype.watchHeading= function(successCallback, errorCallback, options) 
+{
+	// Default interval (100 msec)
+    var frequency = (options !== undefined) ? options.frequency : 100;
+
+    // successCallback required
+    if (typeof successCallback !== "function") {
+        console.log("Compass Error: successCallback is not a function");
+        return;
+    }
+
+    // errorCallback optional
+    if (errorCallback && (typeof errorCallback !== "function")) {
+        console.log("Compass Error: errorCallback is not a function");
+        return;
+    }
+
+    // Start watch timer to get headings
+    var id = Cordova.createUUID();
+    navigator.compass.timers[id] = setInterval(
+        function() {
+            Cordova.exec(successCallback, errorCallback, "org.apache.cordova.geolocation", "getCurrentHeading", [{repeats: 1}]);
+        }, frequency);
+
+    return id;
+};
+
+
+/**
+ * Clears the specified heading watch.
+ * @param {String} watchId The ID of the watch returned from #watchHeading.
+ */
+Compass.prototype.clearWatch = function(id) 
+{
+	// Stop javascript timer & remove from timer list
+    if (id && navigator.compass.timers[id]) {
+        clearInterval(navigator.compass.timers[id]);
+        delete navigator.compass.timers[id];
+    }
+    if (navigator.compass.timers.length == 0) {
+    	// stop the 
+    	Cordova.exec(null, null, "org.apache.cordova.geolocation", "stopHeading", []);
+    }
+};
+
+/** iOS only
+ * Asynchronously fires when the heading changes from the last reading.  The amount of distance 
+ * required to trigger the event is specified in the filter paramter.
+ * @param {Function} successCallback The function to call each time the heading
+ * data is available
+ * @param {Function} errorCallback The function to call when there is an error 
+ * getting the heading data.
+ * @param {HeadingOptions} options The options for getting the heading data
+ * 			@param {filter} number of degrees change to trigger a callback with heading data (float)
+ *
+ * In iOS this function is more efficient than calling watchHeading  with a frequency for updates.
+ * Only one watchHeadingFilter can be in effect at one time.  If a watchHeadingFilter is in effect, calling
+ * getCurrentHeading or watchHeading will use the existing filter value for specifying heading change. 
+  */
+Compass.prototype.watchHeadingFilter = function(successCallback, errorCallback, options) 
+{
+ 
+ 	if (options === undefined || options.filter === undefined) {
+ 		console.log("Compass Error:  options.filter not specified");
+ 		return;
+ 	}
+
+    // successCallback required
+    if (typeof successCallback !== "function") {
+        console.log("Compass Error: successCallback is not a function");
+        return;
+    }
+
+    // errorCallback optional
+    if (errorCallback && (typeof errorCallback !== "function")) {
+        console.log("Compass Error: errorCallback is not a function");
+        return;
+    }
+    Cordova.exec(successCallback, errorCallback, "org.apache.cordova.geolocation", "watchHeadingFilter", [options]);
+}
+Compass.prototype.clearWatchFilter = function() 
+{
+    	Cordova.exec(null, null, "org.apache.cordova.geolocation", "stopHeading", []);
+};
+
+Cordova.addConstructor(function() 
+{
+    if (typeof navigator.compass == "undefined") 
+    {
+        navigator.compass = new Compass();
+    }
+});
+};

http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/bcff9559/CordovaLib/javascripts/core/contact.js
----------------------------------------------------------------------
diff --git a/CordovaLib/javascripts/core/contact.js b/CordovaLib/javascripts/core/contact.js
new file mode 100644
index 0000000..86b8891
--- /dev/null
+++ b/CordovaLib/javascripts/core/contact.js
@@ -0,0 +1,409 @@
+if (!Cordova.hasResource("contact")) {
+	Cordova.addResource("contact");
+
+
+/**
+* Contains information about a single contact.
+* @param {DOMString} id unique identifier
+* @param {DOMString} displayName
+* @param {ContactName} name
+* @param {DOMString} nickname
+* @param {ContactField[]} phoneNumbers array of phone numbers
+* @param {ContactField[]} emails array of email addresses
+* @param {ContactAddress[]} addresses array of addresses
+* @param {ContactField[]} ims instant messaging user ids
+* @param {ContactOrganization[]} organizations
+* @param {DOMString} birthday contact's birthday
+* @param {DOMString} note user notes about contact
+* @param {ContactField[]} photos
+* @param {Array.<ContactField>} categories
+* @param {ContactField[]} urls contact's web sites
+*/
+var Contact = function(id, displayName, name, nickname, phoneNumbers, emails, addresses,
+    ims, organizations, birthday, note, photos, categories, urls) {
+    this.id = id || null;
+    this.displayName = displayName || null;
+    this.name = name || null; // ContactName
+    this.nickname = nickname || null;
+    this.phoneNumbers = phoneNumbers || null; // ContactField[]
+    this.emails = emails || null; // ContactField[]
+    this.addresses = addresses || null; // ContactAddress[]
+    this.ims = ims || null; // ContactField[]
+    this.organizations = organizations || null; // ContactOrganization[]
+    this.birthday = birthday || null; // JS Date
+    this.note = note || null;
+    this.photos = photos || null; // ContactField[]
+    this.categories = categories || null; 
+    this.urls = urls || null; // ContactField[]
+};
+
+/**
+* Converts Dates to milliseconds before sending to iOS
+*/
+Contact.prototype.convertDatesOut = function()
+{
+	var dates = new Array("birthday");
+	for (var i=0; i<dates.length; i++){
+		var value = this[dates[i]];
+		if (value){
+			if (!value instanceof Date){
+				try {
+					value = new Date(value);
+				} catch(exception){
+					value = null;
+				}
+			}
+			if (value instanceof Date){
+				value = value.valueOf();
+			}
+			this[dates[i]] = value;
+		}
+	}
+	
+};
+/**
+* Converts milliseconds to JS Date when returning from iOS
+*/
+Contact.prototype.convertDatesIn = function()
+{
+	var dates = new Array("birthday");
+	for (var i=0; i<dates.length; i++){
+		var value = this[dates[i]];
+		if (value){
+			try {
+				this[dates[i]] = new Date(parseFloat(value));
+			} catch (exception){
+				console.log("exception creating date");
+			}
+		}
+	}
+};
+/**
+* Removes contact from device storage.
+* @param successCB success callback
+* @param errorCB error callback (optional)
+*/
+Contact.prototype.remove = function(successCB, errorCB) {
+	if (this.id == null) {
+        var errorObj = new ContactError();
+        errorObj.code = ContactError.UNKNOWN_ERROR;
+        errorCB(errorObj);
+    }
+    else {
+        Cordova.exec(successCB, errorCB, "org.apache.cordova.contacts", "remove", [{ "contact": this}]);
+    }
+};
+/**
+* iOS ONLY
+* displays contact via iOS UI
+*	NOT part of W3C spec so no official documentation
+*
+* @param errorCB error callback
+* @param options object
+*	allowsEditing: boolean AS STRING
+*		"true" to allow editing the contact
+*		"false" (default) display contact
+*/
+Contact.prototype.display = function(errorCB, options) { 
+	if (this.id == null) {
+        if (typeof errorCB == "function") {
+        	var errorObj = new ContactError();
+        	errorObj.code = ContactError.UNKNOWN_ERROR;
+        	errorCB(errorObj);
+		}
+    }
+    else {
+        Cordova.exec(null, errorCB, "org.apache.cordova.contacts","displayContact", [this.id, options]);
+    }
+};
+
+/**
+* Creates a deep copy of this Contact.
+* With the contact ID set to null.
+* @return copy of this Contact
+*/
+Contact.prototype.clone = function() {
+    var clonedContact = Cordova.clone(this);
+    clonedContact.id = null;
+    // Loop through and clear out any id's in phones, emails, etc.
+    if (clonedContact.phoneNumbers) {
+    	for (i=0; i<clonedContact.phoneNumbers.length; i++) {
+    		clonedContact.phoneNumbers[i].id = null;
+    	}
+    }
+    if (clonedContact.emails) {
+    	for (i=0; i<clonedContact.emails.length; i++) {
+    		clonedContact.emails[i].id = null;
+    	}
+    }
+    if (clonedContact.addresses) {
+    	for (i=0; i<clonedContact.addresses.length; i++) {
+    		clonedContact.addresses[i].id = null;
+    	}
+    }
+    if (clonedContact.ims) {
+    	for (i=0; i<clonedContact.ims.length; i++) {
+    		clonedContact.ims[i].id = null;
+    	}
+    }
+    if (clonedContact.organizations) {
+    	for (i=0; i<clonedContact.organizations.length; i++) {
+    		clonedContact.organizations[i].id = null;
+    	}
+    }
+    if (clonedContact.photos) {
+    	for (i=0; i<clonedContact.photos.length; i++) {
+    		clonedContact.photos[i].id = null;
+    	}
+    }
+    if (clonedContact.urls) {
+    	for (i=0; i<clonedContact.urls.length; i++) {
+    		clonedContact.urls[i].id = null;
+    	}
+    }
+    return clonedContact;
+};
+
+/**
+* Persists contact to device storage.
+* @param successCB success callback
+* @param errorCB error callback - optional
+*/
+Contact.prototype.save = function(successCB, errorCB) {
+	// don't modify the original contact
+	var cloned = Cordova.clone(this);
+	cloned.convertDatesOut(); 
+	Cordova.exec(successCB, errorCB, "org.apache.cordova.contacts","save", [{"contact": cloned}]);
+};
+
+/**
+* Contact name.
+* @param formatted
+* @param familyName
+* @param givenName
+* @param middle
+* @param prefix
+* @param suffix
+*/
+var ContactName = function(formatted, familyName, givenName, middle, prefix, suffix) {
+    this.formatted = formatted != "undefined" ? formatted : null;
+    this.familyName = familyName != "undefined" ? familyName : null;
+    this.givenName = givenName != "undefined" ? givenName : null;
+    this.middleName = middle != "undefined" ? middle : null;
+    this.honorificPrefix = prefix != "undefined" ? prefix : null;
+    this.honorificSuffix = suffix != "undefined" ? suffix : null;
+};
+
+/**
+* Generic contact field.
+* @param type
+* @param value
+* @param pref
+* @param id
+*/
+var ContactField = function(type, value, pref, id) {
+    this.type = type != "undefined" ? type : null;
+    this.value = value != "undefined" ? value : null;
+    this.pref = pref != "undefined" ? pref : null;
+    this.id = id != "undefined" ? id : null;
+};
+
+/**
+* Contact address.
+* @param pref - boolean is primary / preferred address
+* @param type - string - work, home…..
+* @param formatted
+* @param streetAddress
+* @param locality
+* @param region
+* @param postalCode
+* @param country
+*/
+var ContactAddress = function(pref, type, formatted, streetAddress, locality, region, postalCode, country, id) {
+	this.pref = pref != "undefined" ? pref : null;
+	this.type = type != "undefined" ? type : null;
+    this.formatted = formatted != "undefined" ? formatted : null;
+    this.streetAddress = streetAddress != "undefined" ? streetAddress : null;
+    this.locality = locality != "undefined" ? locality : null;
+    this.region = region != "undefined" ? region : null;
+    this.postalCode = postalCode != "undefined" ? postalCode : null;
+    this.country = country != "undefined" ? country : null;
+    this.id = id != "undefined" ? id : null;
+};
+
+/**
+* Contact organization.
+* @param pref - boolean is primary / preferred address
+* @param type - string - work, home…..
+* @param name
+* @param dept
+* @param title
+*/
+var ContactOrganization = function(pref, type, name, dept, title) {
+	this.pref = pref != "undefined" ? pref : null;
+	this.type = type != "undefined" ? type : null;
+    this.name = name != "undefined" ? name : null;
+    this.department = dept != "undefined" ? dept : null;
+    this.title = title != "undefined" ? title : null;
+};
+
+/**
+* Contact account.
+* @param domain
+* @param username
+* @param userid
+*/
+/*var ContactAccount = function(domain, username, userid) {
+    this.domain = domain != "undefined" ? domain : null;
+    this.username = username != "undefined" ? username : null;
+    this.userid = userid != "undefined" ? userid : null;
+}*/
+
+/**
+* Represents a group of Contacts.
+*/
+var Contacts = function() {
+    this.inProgress = false;
+    this.records = new Array();
+};
+/**
+* Returns an array of Contacts matching the search criteria.
+* @param fields that should be searched
+* @param successCB success callback
+* @param errorCB error callback (optional)
+* @param {ContactFindOptions} options that can be applied to contact searching
+* @return array of Contacts matching search criteria
+*/
+Contacts.prototype.find = function(fields, successCB, errorCB, options) {
+	if (successCB === null) {
+        throw new TypeError("You must specify a success callback for the find command.");
+    }
+    if (fields === null || fields === "undefined" || fields.length === "undefined" || fields.length <= 0) {
+    	if (typeof errorCB === "function") {
+			errorCB({"code": ContactError.INVALID_ARGUMENT_ERROR});
+    	}
+    } else {
+		Cordova.exec(successCB, errorCB, "org.apache.cordova.contacts","search", [{"fields":fields, "findOptions":options}]);
+    }
+};
+/**
+* need to turn the array of JSON strings representing contact objects into actual objects
+* @param array of JSON strings with contact data
+* @return call results callback with array of Contact objects
+*  This function is called from objective C Contacts.search() method.
+*/
+Contacts.prototype._findCallback = function(pluginResult) {
+	var contacts = new Array();
+	try {
+		for (var i=0; i<pluginResult.message.length; i++) {
+			var newContact = navigator.contacts.create(pluginResult.message[i]); 
+			newContact.convertDatesIn();
+			contacts.push(newContact);
+		}
+		pluginResult.message = contacts;
+	} catch(e){
+			console.log("Error parsing contacts: " +e);
+	}
+	return pluginResult;
+}
+
+/**
+* need to turn the JSON string representing contact object into actual object
+* @param JSON string with contact data
+* Call stored results function with  Contact object
+*  This function is called from objective C Contacts remove and save methods
+*/
+Contacts.prototype._contactCallback = function(pluginResult)
+{
+	var newContact = null;
+	if (pluginResult.message){
+		try {
+			newContact = navigator.contacts.create(pluginResult.message);
+			newContact.convertDatesIn();
+		} catch(e){
+			console.log("Error parsing contact");
+		}
+	}
+	pluginResult.message = newContact;
+	return pluginResult;
+	
+};
+/** 
+* Need to return an error object rather than just a single error code
+* @param error code
+* Call optional error callback if found.
+* Called from objective c find, remove, and save methods on error.
+*/
+Contacts.prototype._errCallback = function(pluginResult)
+{
+	var errorObj = new ContactError();
+   	errorObj.code = pluginResult.message;
+	pluginResult.message = errorObj;
+	return pluginResult;
+};
+// iPhone only api to create a new contact via the GUI
+Contacts.prototype.newContactUI = function(successCallback) { 
+    Cordova.exec(successCallback, null, "org.apache.cordova.contacts","newContact", []);
+};
+// iPhone only api to select a contact via the GUI
+Contacts.prototype.chooseContact = function(successCallback, options) {
+    Cordova.exec(successCallback, null, "org.apache.cordova.contacts","chooseContact", options);
+};
+
+
+/**
+* This function creates a new contact, but it does not persist the contact
+* to device storage. To persist the contact to device storage, invoke
+* contact.save().
+* @param properties an object who's properties will be examined to create a new Contact
+* @returns new Contact object
+*/
+Contacts.prototype.create = function(properties) {
+    var i;
+    var contact = new Contact();
+    for (i in properties) {
+        if (contact[i] !== 'undefined') {
+            contact[i] = properties[i];
+        }
+    }
+    return contact;
+};
+
+/**
+ * ContactFindOptions.
+ * @param filter used to match contacts against
+ * @param multiple boolean used to determine if more than one contact should be returned
+ */
+var ContactFindOptions = function(filter, multiple, updatedSince) {
+    this.filter = filter || '';
+    this.multiple = multiple || false;
+};
+
+/**
+ *  ContactError.
+ *  An error code assigned by an implementation when an error has occurred
+ */
+var ContactError = function() {
+    this.code=null;
+};
+
+/**
+ * Error codes
+ */
+ContactError.UNKNOWN_ERROR = 0;
+ContactError.INVALID_ARGUMENT_ERROR = 1;
+ContactError.TIMEOUT_ERROR = 2;
+ContactError.PENDING_OPERATION_ERROR = 3;
+ContactError.IO_ERROR = 4;
+ContactError.NOT_SUPPORTED_ERROR = 5;
+ContactError.PERMISSION_DENIED_ERROR = 20;
+
+/**
+ * Add the contact interface into the browser.
+ */
+Cordova.addConstructor(function() { 
+    if(typeof navigator.contacts == "undefined") {
+    	navigator.contacts = new Contacts();
+    }
+});
+};

http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/bcff9559/CordovaLib/javascripts/core/cordova.js.base
----------------------------------------------------------------------
diff --git a/CordovaLib/javascripts/core/cordova.js.base b/CordovaLib/javascripts/core/cordova.js.base
new file mode 100644
index 0000000..98be37b
--- /dev/null
+++ b/CordovaLib/javascripts/core/cordova.js.base
@@ -0,0 +1,548 @@
+/*
+ * Some base contributions
+ * Copyright (c) 2011, Proyectos Equis Ka, S.L.
+ */
+
+if (typeof Cordova === "undefined") {
+
+if (typeof(DeviceInfo) !== 'object'){
+    DeviceInfo = {};
+}
+/**
+ * This represents the Cordova API itself, and provides a global namespace for accessing
+ * information about the state of Cordova.
+ * @class
+ */
+Cordova = {
+    // This queue holds the currently executing command and all pending
+    // commands executed with Cordova.exec().
+    commandQueue: [],
+    // Indicates if we're currently in the middle of flushing the command
+    // queue on the native side.
+    commandQueueFlushing: false,
+    _constructors: [],
+    documentEventHandler: {},   // Collection of custom document event handlers
+    windowEventHandler: {} 
+};
+
+/**
+ * List of resource files loaded by Cordova.
+ * This is used to ensure JS and other files are loaded only once.
+ */
+Cordova.resources = {base: true};
+
+/**
+ * Determine if resource has been loaded by Cordova
+ *
+ * @param name
+ * @return
+ */
+Cordova.hasResource = function(name) {
+    return Cordova.resources[name];
+};
+
+/**
+ * Add a resource to list of loaded resources by Cordova
+ *
+ * @param name
+ */
+Cordova.addResource = function(name) {
+    Cordova.resources[name] = true;
+};
+
+/**
+ * Boolean flag indicating if the Cordova API is available and initialized.
+ */ // TODO: Remove this, it is unused here ... -jm
+Cordova.available = DeviceInfo.uuid != undefined;
+
+/**
+ * Add an initialization function to a queue that ensures it will run and initialize
+ * application constructors only once Cordova has been initialized.
+ * @param {Function} func The function callback you want run once Cordova is initialized
+ */
+Cordova.addConstructor = function(func) {
+    var state = document.readyState;
+    if ( ( state == 'loaded' || state == 'complete' ) && DeviceInfo.uuid != null )
+    {
+        func();
+    }
+    else
+    {
+        Cordova._constructors.push(func);
+    }
+};
+
+(function() 
+ {
+    var timer = setInterval(function()
+    {
+                            
+        var state = document.readyState;
+                            
+        if ( ( state == 'loaded' || state == 'complete' ) && DeviceInfo.uuid != null )
+        {
+            clearInterval(timer); // stop looking
+            // run our constructors list
+            while (Cordova._constructors.length > 0) 
+            {
+                var constructor = Cordova._constructors.shift();
+                try 
+                {
+                    constructor();
+                } 
+                catch(e) 
+                {
+                    if (typeof(console['log']) == 'function')
+                    {
+                        console.log("Failed to run constructor: " + console.processMessage(e));
+                    }
+                    else
+                    {
+                        alert("Failed to run constructor: " + e.message);
+                    }
+                }
+            }
+            // all constructors run, now fire the deviceready event
+            var e = document.createEvent('Events'); 
+            e.initEvent('deviceready');
+            document.dispatchEvent(e);
+        }
+    }, 1);
+})();
+
+// session id for calls
+Cordova.sessionKey = 0;
+
+// centralized callbacks
+Cordova.callbackId = 0;
+Cordova.callbacks = {};
+Cordova.callbackStatus = {
+    NO_RESULT: 0,
+    OK: 1,
+    CLASS_NOT_FOUND_EXCEPTION: 2,
+    ILLEGAL_ACCESS_EXCEPTION: 3,
+    INSTANTIATION_EXCEPTION: 4,
+    MALFORMED_URL_EXCEPTION: 5,
+    IO_EXCEPTION: 6,
+    INVALID_ACTION: 7,
+    JSON_EXCEPTION: 8,
+    ERROR: 9
+    };
+
+/**
+ * Creates a gap bridge iframe used to notify the native code about queued
+ * commands.
+ *
+ * @private
+ */
+Cordova.createGapBridge = function() {
+    gapBridge = document.createElement("iframe");
+    gapBridge.setAttribute("style", "display:none;");
+    gapBridge.setAttribute("height","0px");
+    gapBridge.setAttribute("width","0px");
+    gapBridge.setAttribute("frameborder","0");
+    document.documentElement.appendChild(gapBridge);
+    return gapBridge;
+}
+
+/** 
+ * Execute a Cordova command by queuing it and letting the native side know
+ * there are queued commands. The native side will then request all of the
+ * queued commands and execute them.
+ *
+ * Arguments may be in one of two formats:
+ *
+ * FORMAT ONE (preferable)
+ * The native side will call Cordova.callbackSuccess or
+ * Cordova.callbackError, depending upon the result of the action.
+ *
+ * @param {Function} success    The success callback
+ * @param {Function} fail       The fail callback
+ * @param {String} service      The name of the service to use
+ * @param {String} action       The name of the action to use
+ * @param {String[]} [args]     Zero or more arguments to pass to the method
+ *      
+ * FORMAT TWO
+ * @param {String} command    Command to be run in Cordova, e.g.
+ *                            "ClassName.method"
+ * @param {String[]} [args]   Zero or more arguments to pass to the method
+ *                            object parameters are passed as an array object
+ *                            [object1, object2] each object will be passed as
+ *                            JSON strings 
+ */
+Cordova.exec = function() { 
+    if (!Cordova.available) {
+        alert("ERROR: Attempting to call Cordova.exec()"
+              +" before 'deviceready'. Ignoring.");
+        return;
+    }
+
+    var successCallback, failCallback, service, action, actionArgs;
+    var callbackId = null;
+    if (typeof arguments[0] !== "string") {
+        // FORMAT ONE
+        successCallback = arguments[0];
+        failCallback = arguments[1];
+        service = arguments[2];
+        action = arguments[3];
+        actionArgs = arguments[4];
+
+        // Since we need to maintain backwards compatibility, we have to pass
+        // an invalid callbackId even if no callback was provided since plugins
+        // will be expecting it. The Cordova.exec() implementation allocates
+        // an invalid callbackId and passes it even if no callbacks were given.
+        callbackId = 'INVALID';
+    } else {
+        // FORMAT TWO
+        splitCommand = arguments[0].split(".");
+        action = splitCommand.pop();
+        service = splitCommand.join(".");
+        actionArgs = Array.prototype.splice.call(arguments, 1);
+    }
+    
+    // Start building the command object.
+    var command = {
+        className: service,
+        methodName: action,
+        arguments: []
+    };
+
+    // Register the callbacks and add the callbackId to the positional
+    // arguments if given.
+    if (successCallback || failCallback) {
+        callbackId = service + Cordova.callbackId++;
+        Cordova.callbacks[callbackId] = 
+            {success:successCallback, fail:failCallback};
+    }
+    if (callbackId != null) {
+        command.arguments.push(callbackId);
+    }
+
+    for (var i = 0; i < actionArgs.length; ++i) {
+        var arg = actionArgs[i];
+        if (arg == undefined || arg == null) {
+            continue;
+        } else if (typeof(arg) == 'object') {
+            command.options = arg;
+        } else {
+            command.arguments.push(arg);
+        }
+    }
+
+    // Stringify and queue the command. We stringify to command now to
+    // effectively clone the command arguments in case they are mutated before
+    // the command is executed.
+    Cordova.commandQueue.push(JSON.stringify(command));
+
+    // If the queue length is 1, then that means it was empty before we queued
+    // the given command, so let the native side know that we have some
+    // commands to execute, unless the queue is currently being flushed, in
+    // which case the command will be picked up without notification.
+    if (Cordova.commandQueue.length == 1 && !Cordova.commandQueueFlushing) {
+        if (!Cordova.gapBridge) {
+            Cordova.gapBridge = Cordova.createGapBridge();
+        }
+
+        Cordova.gapBridge.src = "gap://ready";
+    }
+}
+
+/**
+ * Called by native code to retrieve all queued commands and clear the queue.
+ */
+Cordova.getAndClearQueuedCommands = function() {
+  json = JSON.stringify(Cordova.commandQueue);
+  Cordova.commandQueue = [];
+  return json;
+}
+
+/**
+ * Called by native code when returning successful result from an action.
+ *
+ * @param callbackId
+ * @param args
+ *        args.status - Cordova.callbackStatus
+ *        args.message - return value
+ *        args.keepCallback - 0 to remove callback, 1 to keep callback in Cordova.callbacks[]
+ */
+Cordova.callbackSuccess = function(callbackId, args) {
+    if (Cordova.callbacks[callbackId]) {
+
+        // If result is to be sent to callback
+        if (args.status == Cordova.callbackStatus.OK) {
+            try {
+                if (Cordova.callbacks[callbackId].success) {
+                       Cordova.callbacks[callbackId].success(args.message);
+                }
+            }
+            catch (e) {
+                console.log("Error in success callback: "+callbackId+" = "+e);
+            }
+        }
+    
+        // Clear callback if not expecting any more results
+        if (!args.keepCallback) {
+            delete Cordova.callbacks[callbackId];
+        }
+    }
+};
+
+/**
+ * Called by native code when returning error result from an action.
+ *
+ * @param callbackId
+ * @param args
+ */
+Cordova.callbackError = function(callbackId, args) {
+    if (Cordova.callbacks[callbackId]) {
+        try {
+            if (Cordova.callbacks[callbackId].fail) {
+                Cordova.callbacks[callbackId].fail(args.message);
+            }
+        }
+        catch (e) {
+            console.log("Error in error callback: "+callbackId+" = "+e);
+        }
+        
+        // Clear callback if not expecting any more results
+        if (!args.keepCallback) {
+            delete Cordova.callbacks[callbackId];
+        }
+    }
+};
+
+
+/**
+ * Does a deep clone of the object.
+ *
+ * @param obj
+ * @return
+ */
+Cordova.clone = function(obj) {
+    if(!obj) { 
+        return obj;
+    }
+
+    if(obj instanceof Array){
+        var retVal = new Array();
+        for(var i = 0; i < obj.length; ++i){
+            retVal.push(Cordova.clone(obj[i]));
+        }
+        return retVal;
+    }
+
+    if (obj instanceof Function) {
+        return obj;
+    }
+
+    if(!(obj instanceof Object)){
+        return obj;
+    }
+    
+    if (obj instanceof Date) {
+        return obj;
+    }
+
+    retVal = new Object();
+    for(i in obj){
+        if(!(i in retVal) || retVal[i] != obj[i]) {
+            retVal[i] = Cordova.clone(obj[i]);
+        }
+    }
+    return retVal;
+};
+
+// Intercept calls to document.addEventListener 
+Cordova.m_document_addEventListener = document.addEventListener;
+
+// Intercept calls to window.addEventListener
+Cordova.m_window_addEventListener = window.addEventListener;
+
+/**
+ * Add a custom window event handler.
+ *
+ * @param {String} event            The event name that callback handles
+ * @param {Function} callback       The event handler
+ */
+Cordova.addWindowEventHandler = function(event, callback) {
+    Cordova.windowEventHandler[event] = callback;
+}
+
+/**
+ * Add a custom document event handler.
+ *
+ * @param {String} event            The event name that callback handles
+ * @param {Function} callback       The event handler
+ */
+Cordova.addDocumentEventHandler = function(event, callback) {
+    Cordova.documentEventHandler[event] = callback;
+}
+
+/**
+ * Intercept adding document event listeners and handle our own
+ *
+ * @param {Object} evt
+ * @param {Function} handler
+ * @param capture
+ */
+document.addEventListener = function(evt, handler, capture) {
+    var e = evt.toLowerCase();
+           
+    // If subscribing to an event that is handled by a plugin
+    if (typeof Cordova.documentEventHandler[e] !== "undefined") {
+        if (Cordova.documentEventHandler[e](e, handler, true)) {
+            return; // Stop default behavior
+        }
+    }
+    
+    Cordova.m_document_addEventListener.call(document, evt, handler, capture); 
+};
+
+/**
+ * Intercept adding window event listeners and handle our own
+ *
+ * @param {Object} evt
+ * @param {Function} handler
+ * @param capture
+ */
+window.addEventListener = function(evt, handler, capture) {
+    var e = evt.toLowerCase();
+        
+    // If subscribing to an event that is handled by a plugin
+    if (typeof Cordova.windowEventHandler[e] !== "undefined") {
+        if (Cordova.windowEventHandler[e](e, handler, true)) {
+            return; // Stop default behavior
+        }
+    }
+        
+    Cordova.m_window_addEventListener.call(window, evt, handler, capture);
+};
+
+// Intercept calls to document.removeEventListener and watch for events that
+// are generated by Cordova native code
+Cordova.m_document_removeEventListener = document.removeEventListener;
+
+// Intercept calls to window.removeEventListener
+Cordova.m_window_removeEventListener = window.removeEventListener;
+
+/**
+ * Intercept removing document event listeners and handle our own
+ *
+ * @param {Object} evt
+ * @param {Function} handler
+ * @param capture
+ */
+document.removeEventListener = function(evt, handler, capture) {
+    var e = evt.toLowerCase();
+
+    // If unsubcribing from an event that is handled by a plugin
+    if (typeof Cordova.documentEventHandler[e] !== "undefined") {
+        if (Cordova.documentEventHandler[e](e, handler, false)) {
+            return; // Stop default behavior
+        }
+    }
+
+    Cordova.m_document_removeEventListener.call(document, evt, handler, capture);
+};
+
+/**
+ * Intercept removing window event listeners and handle our own
+ *
+ * @param {Object} evt
+ * @param {Function} handler
+ * @param capture
+ */
+window.removeEventListener = function(evt, handler, capture) {
+    var e = evt.toLowerCase();
+
+    // If unsubcribing from an event that is handled by a plugin
+    if (typeof Cordova.windowEventHandler[e] !== "undefined") {
+        if (Cordova.windowEventHandler[e](e, handler, false)) {
+            return; // Stop default behavior
+        }
+    }
+
+    Cordova.m_window_removeEventListener.call(window, evt, handler, capture);
+};
+
+/**
+ * Method to fire document event
+ *
+ * @param {String} type             The event type to fire
+ * @param {Object} data             Data to send with event
+ */
+Cordova.fireDocumentEvent = function(type, data) {
+    var e = document.createEvent('Events');
+    e.initEvent(type);
+    if (data) {
+        for (var i in data) {
+            e[i] = data[i];
+        }
+    }
+    document.dispatchEvent(e);
+};
+
+/**
+ * Method to fire window event
+ *
+ * @param {String} type             The event type to fire
+ * @param {Object} data             Data to send with event
+ */
+Cordova.fireWindowEvent = function(type, data) {
+    var e = document.createEvent('Events');
+    e.initEvent(type);
+    if (data) {
+        for (var i in data) {
+            e[i] = data[i];
+        }
+    }
+    window.dispatchEvent(e);
+};
+
+/**
+ * Method to fire event from native code
+ * Leaving this generic version to handle problems with iOS 3.x. Is currently used by orientation and battery events
+ * Remove when iOS 3.x no longer supported and call fireWindowEvent or fireDocumentEvent directly
+ */
+Cordova.fireEvent = function(type, target, data) {
+    var e = document.createEvent('Events');
+    e.initEvent(type);
+    if (data) {
+        for (var i in data) {
+            e[i] = data[i];
+        }
+    }
+    target = target || document;
+    if (target.dispatchEvent === undefined) { // ie window.dispatchEvent is undefined in iOS 3.x
+        target = document;
+    } 
+
+    target.dispatchEvent(e);
+};
+/**
+ * Create a UUID
+ *
+ * @return
+ */
+Cordova.createUUID = function() {
+    return Cordova.UUIDcreatePart(4) + '-' +
+        Cordova.UUIDcreatePart(2) + '-' +
+        Cordova.UUIDcreatePart(2) + '-' +
+        Cordova.UUIDcreatePart(2) + '-' +
+        Cordova.UUIDcreatePart(6);
+};
+
+Cordova.UUIDcreatePart = function(length) {
+    var uuidpart = "";
+    for (var i=0; i<length; i++) {
+        var uuidchar = parseInt((Math.random() * 256)).toString(16);
+        if (uuidchar.length == 1) {
+            uuidchar = "0" + uuidchar;
+        }
+        uuidpart += uuidchar;
+    }
+    return uuidpart;
+};
+};
+
+

http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/bcff9559/CordovaLib/javascripts/core/debugconsole.js
----------------------------------------------------------------------
diff --git a/CordovaLib/javascripts/core/debugconsole.js b/CordovaLib/javascripts/core/debugconsole.js
new file mode 100644
index 0000000..5f0467d
--- /dev/null
+++ b/CordovaLib/javascripts/core/debugconsole.js
@@ -0,0 +1,108 @@
+if (!Cordova.hasResource("debugconsole")) {
+	Cordova.addResource("debugconsole");
+	
+/**
+ * This class provides access to the debugging console.
+ * @constructor
+ */
+var DebugConsole = function() {
+    this.winConsole = window.console;
+    this.logLevel = DebugConsole.INFO_LEVEL;
+}
+
+// from most verbose, to least verbose
+DebugConsole.ALL_LEVEL    = 1; // same as first level
+DebugConsole.INFO_LEVEL   = 1;
+DebugConsole.WARN_LEVEL   = 2;
+DebugConsole.ERROR_LEVEL  = 4;
+DebugConsole.NONE_LEVEL   = 8;
+													
+DebugConsole.prototype.setLevel = function(level) {
+    this.logLevel = level;
+};
+
+/**
+ * Utility function for rendering and indenting strings, or serializing
+ * objects to a string capable of being printed to the console.
+ * @param {Object|String} message The string or object to convert to an indented string
+ * @private
+ */
+DebugConsole.prototype.processMessage = function(message, maxDepth) {
+	if (maxDepth === undefined) maxDepth = 0;
+    if (typeof(message) != 'object') {
+        return (this.isDeprecated ? "WARNING: debug object is deprecated, please use console object \n" + message : message);
+    } else {
+        /**
+         * @function
+         * @ignore
+         */
+        function indent(str) {
+            return str.replace(/^/mg, "    ");
+        }
+        /**
+         * @function
+         * @ignore
+         */
+        function makeStructured(obj, depth) {
+            var str = "";
+            for (var i in obj) {
+                try {
+                    if (typeof(obj[i]) == 'object' && depth < maxDepth) {
+                        str += i + ":\n" + indent(makeStructured(obj[i])) + "\n";
+                    } else {
+                        str += i + " = " + indent(String(obj[i])).replace(/^    /, "") + "\n";
+                    }
+                } catch(e) {
+                    str += i + " = EXCEPTION: " + e.message + "\n";
+                }
+            }
+            return str;
+        }
+        
+        return ("Object:\n" + makeStructured(message, maxDepth));
+    }
+};
+
+/**
+ * Print a normal log message to the console
+ * @param {Object|String} message Message or object to print to the console
+ */
+DebugConsole.prototype.log = function(message, maxDepth) {
+    if (Cordova.available && this.logLevel <= DebugConsole.INFO_LEVEL)
+        Cordova.exec(null, null, 'org.apache.cordova.debugconsole', 'log',
+            [ this.processMessage(message, maxDepth), { logLevel: 'INFO' } ]
+        );
+    else
+        this.winConsole.log(message);
+};
+
+/**
+ * Print a warning message to the console
+ * @param {Object|String} message Message or object to print to the console
+ */
+DebugConsole.prototype.warn = function(message, maxDepth) {
+    if (Cordova.available && this.logLevel <= DebugConsole.WARN_LEVEL)
+    	Cordova.exec(null, null, 'org.apache.cordova.debugconsole', 'log',
+            [ this.processMessage(message, maxDepth), { logLevel: 'WARN' } ]
+        );
+    else
+        this.winConsole.error(message);
+};
+
+/**
+ * Print an error message to the console
+ * @param {Object|String} message Message or object to print to the console
+ */
+DebugConsole.prototype.error = function(message, maxDepth) {
+    if (Cordova.available && this.logLevel <= DebugConsole.ERROR_LEVEL)
+		Cordova.exec(null, null, 'org.apache.cordova.debugconsole', 'log',
+            [ this.processMessage(message, maxDepth), { logLevel: 'ERROR' } ]
+        );
+    else
+        this.winConsole.error(message);
+};
+
+Cordova.addConstructor(function() {
+    window.console = new DebugConsole();
+});
+};

http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/bcff9559/CordovaLib/javascripts/core/device.js
----------------------------------------------------------------------
diff --git a/CordovaLib/javascripts/core/device.js b/CordovaLib/javascripts/core/device.js
new file mode 100644
index 0000000..b8f8326
--- /dev/null
+++ b/CordovaLib/javascripts/core/device.js
@@ -0,0 +1,37 @@
+if (!Cordova.hasResource("device")) {
+	Cordova.addResource("device");
+
+/**
+ * this represents the mobile device, and provides properties for inspecting the model, version, UUID of the
+ * phone, etc.
+ * @constructor
+ */
+Device = function() 
+{
+    this.platform = null;
+    this.version  = null;
+    this.name     = null;
+    this.phonegap      = null;
+    this.uuid     = null;
+    try 
+	{      
+		this.platform = DeviceInfo.platform;
+		this.version  = DeviceInfo.version;
+		this.name     = DeviceInfo.name;
+		this.phonegap = DeviceInfo.gap;
+		this.uuid     = DeviceInfo.uuid;
+
+    } 
+	catch(e) 
+	{
+        // TODO: 
+    }
+	this.available = Cordova.available = this.uuid != null;
+}
+
+Cordova.addConstructor(function() {
+	if (typeof navigator.device === "undefined") {
+    	navigator.device = window.device = new Device();
+	}
+});
+};


Mime
View raw message