You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by fi...@apache.org on 2013/03/25 22:53:24 UTC
[1/6] 2.6.0rc1 used for libs now. Bumped npm version to 2.6.0. added
androids local.properties to gitignore.
Updated Branches:
refs/heads/2.6.x [created] 37b92ff47
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLibTests/CDVLocalStorageTests.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLibTests/CDVLocalStorageTests.m b/lib/cordova-ios/CordovaLibTests/CDVLocalStorageTests.m
index 64a1435..675f5ea 100644
--- a/lib/cordova-ios/CordovaLibTests/CDVLocalStorageTests.m
+++ b/lib/cordova-ios/CordovaLibTests/CDVLocalStorageTests.m
@@ -71,9 +71,9 @@
CDVLocalStorage* localStorage = [self localStorage];
[self waitForConditionName:@"shouldBackup" block:^{
- [self evalJs:@"localStorage.setItem('foo', 'bar')"];
- return [localStorage shouldBackup];
- }];
+ [self evalJs:@"localStorage.setItem('foo', 'bar')"];
+ return [localStorage shouldBackup];
+ }];
[localStorage backup:[CDVInvokedUrlCommand new]];
STAssertFalse([localStorage shouldBackup], @"Should have backed up.");
@@ -92,8 +92,8 @@
- (void)testVerifyAndFixDatabaseLocations_noChangeRequired
{
NSString* const kBundlePath = @"/bpath";
- id fakeFileManager = [CDVFakeFileManager managerWithFileExistsBlock:^(NSString * path) {
- STFail (@"fileExists called.");
+ id fakeFileManager = [CDVFakeFileManager managerWithFileExistsBlock:^(NSString* path) {
+ STFail(@"fileExists called.");
return NO;
}];
NSMutableDictionary* appPlistDict = [NSMutableDictionary dictionaryWithObjectsAndKeys:
@@ -104,13 +104,13 @@
bundlePath:kBundlePath
fileManager:fakeFileManager];
- STAssertFalse (modified, @"Should not have applied fix.");
+ STAssertFalse(modified, @"Should not have applied fix.");
}
- (void)testVerifyAndFixDatabaseLocations_changeRequired1
{
NSString* const kBundlePath = @"/bpath";
- id fakeFileManager = [CDVFakeFileManager managerWithFileExistsBlock:^(NSString * path) {
+ id fakeFileManager = [CDVFakeFileManager managerWithFileExistsBlock:^(NSString* path) {
return YES;
}];
NSMutableDictionary* appPlistDict = [NSMutableDictionary dictionaryWithObjectsAndKeys:
@@ -120,15 +120,15 @@
bundlePath:kBundlePath
fileManager:fakeFileManager];
- STAssertTrue (modified, @"Should have applied fix.");
+ STAssertTrue(modified, @"Should have applied fix.");
NSString* newPath = [appPlistDict objectForKey:@"WebKitLocalStorageDatabasePathPreferenceKey"];
- STAssertTrue ([@"/bpath/Library/Caches" isEqualToString:newPath], nil);
+ STAssertTrue([@"/bpath/Library/Caches" isEqualToString: newPath], nil);
}
- (void)testVerifyAndFixDatabaseLocations_changeRequired2
{
NSString* const kBundlePath = @"/bpath";
- id fakeFileManager = [CDVFakeFileManager managerWithFileExistsBlock:^(NSString * path) {
+ id fakeFileManager = [CDVFakeFileManager managerWithFileExistsBlock:^(NSString* path) {
return NO;
}];
NSMutableDictionary* appPlistDict = [NSMutableDictionary dictionaryWithObjectsAndKeys:
@@ -138,9 +138,9 @@
bundlePath:kBundlePath
fileManager:fakeFileManager];
- STAssertTrue (modified, @"Should have applied fix.");
+ STAssertTrue(modified, @"Should have applied fix.");
NSString* newPath = [appPlistDict objectForKey:@"WebDatabaseDirectory"];
- STAssertTrue ([@"/bpath/Library/WebKit" isEqualToString:newPath], nil);
+ STAssertTrue([@"/bpath/Library/WebKit" isEqualToString: newPath], nil);
}
@end
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLibTests/CDVUserAgentTest.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLibTests/CDVUserAgentTest.m b/lib/cordova-ios/CordovaLibTests/CDVUserAgentTest.m
index dcbf30a..98659f8 100644
--- a/lib/cordova-ios/CordovaLibTests/CDVUserAgentTest.m
+++ b/lib/cordova-ios/CordovaLibTests/CDVUserAgentTest.m
@@ -82,8 +82,8 @@
NSString* getUserAgentCode = @"navigator.userAgent";
[self waitForConditionName:@"getting user-agents" block:^{
- return (BOOL)(rootVc.vc1.webView.request != nil && rootVc.vc2.webView.request != nil);
- }];
+ return (BOOL)(rootVc.vc1.webView.request != nil && rootVc.vc2.webView.request != nil);
+ }];
NSString* ua1 = [rootVc.vc1.webView stringByEvaluatingJavaScriptFromString:getUserAgentCode];
NSString* ua2 = [rootVc.vc2.webView stringByEvaluatingJavaScriptFromString:getUserAgentCode];
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLibTests/CDVWebViewTest.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLibTests/CDVWebViewTest.m b/lib/cordova-ios/CordovaLibTests/CDVWebViewTest.m
index c0cb173..e22992a 100644
--- a/lib/cordova-ios/CordovaLibTests/CDVWebViewTest.m
+++ b/lib/cordova-ios/CordovaLibTests/CDVWebViewTest.m
@@ -110,8 +110,8 @@
- (void)waitForPageLoad
{
[self waitForConditionName:@"PageLoad" block:^{
- return [@"true" isEqualToString:[self evalJs:@"window.pageIsLoaded"]];
- }];
+ return [@"true" isEqualToString :[self evalJs:@"window.pageIsLoaded"]];
+ }];
}
- (NSString*)evalJs:(NSString*)code
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLibTests/CordovaLibApp/config.xml
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLibTests/CordovaLibApp/config.xml b/lib/cordova-ios/CordovaLibTests/CordovaLibApp/config.xml
index 512bd1f..5610e5e 100644
--- a/lib/cordova-ios/CordovaLibTests/CordovaLibApp/config.xml
+++ b/lib/cordova-ios/CordovaLibTests/CordovaLibApp/config.xml
@@ -2,9 +2,9 @@
<widget>
<preference name="KeyboardDisplayRequiresUserAction" value="true" />
<preference name="SuppressesIncrementalRendering" value="false" />
- <preference name="UIWebViewBounce" value="true" />
+ <preference name="DisallowOverscroll" value="false" />
<preference name="TopActivityIndicator" value="gray" />
- <preference name="EnableLocation" value="false" />
+ <preference name="EnableLocation" value="false" /><!-- DEPRECATED -->
<preference name="EnableViewportScale" value="false" />
<preference name="AutoHideSplashScreen" value="true" />
<preference name="ShowSplashScreenSpinner" value="true" />
@@ -13,6 +13,8 @@
<preference name="MediaPlaybackRequiresUserAction" value="false" />
<preference name="AllowInlineMediaPlayback" value="false" />
<preference name="BackupWebStorage" value="cloud" />
+ <preference name="HideKeyboardFormAccessoryBar" value="false" />
+ <preference name="KeyboardShrinksView" value="false" />
<plugins>
<plugin name="LocalStorage" value="CDVLocalStorage" />
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLibTests/CordovaTests.xcodeproj/project.pbxproj
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLibTests/CordovaTests.xcodeproj/project.pbxproj b/lib/cordova-ios/CordovaLibTests/CordovaTests.xcodeproj/project.pbxproj
index f29ac11..219eb53 100644
--- a/lib/cordova-ios/CordovaLibTests/CordovaTests.xcodeproj/project.pbxproj
+++ b/lib/cordova-ios/CordovaLibTests/CordovaTests.xcodeproj/project.pbxproj
@@ -41,6 +41,8 @@
68A32D7D141030E4006B237C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 686357AE141002F100DF4CF2 /* CoreGraphics.framework */; };
68A32D7E141030EB006B237C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 686357AA141002F100DF4CF2 /* UIKit.framework */; };
68A32D7F141030F3006B237C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 686357AC141002F100DF4CF2 /* Foundation.framework */; };
+ 8220B5C216D541BD00EC3921 /* AssetsLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8220B5C116D541BD00EC3921 /* AssetsLibrary.framework */; };
+ 8220B5C616D542F500EC3921 /* AssetsLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8220B5C116D541BD00EC3921 /* AssetsLibrary.framework */; };
EB3B34E9161B5532003DBE7D /* libCordova.a in Frameworks */ = {isa = PBXBuildFile; fileRef = EB3B34E6161B5454003DBE7D /* libCordova.a */; };
EB89634A15FE66EA00E12277 /* CDVInvokedUrlCommandTests.m in Sources */ = {isa = PBXBuildFile; fileRef = EB89634915FE66EA00E12277 /* CDVInvokedUrlCommandTests.m */; };
EB96677216ADBCF500D86CDF /* CDVUserAgentTest.m in Sources */ = {isa = PBXBuildFile; fileRef = EB96677116ADBCF500D86CDF /* CDVUserAgentTest.m */; };
@@ -104,6 +106,7 @@
686357D414100AF200DF4CF2 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
686357DC14100B1600DF4CF2 /* CoreMedia.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = System/Library/Frameworks/CoreMedia.framework; sourceTree = SDKROOT; };
68A32D7414103017006B237C /* AddressBook.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AddressBook.framework; path = System/Library/Frameworks/AddressBook.framework; sourceTree = SDKROOT; };
+ 8220B5C116D541BD00EC3921 /* AssetsLibrary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AssetsLibrary.framework; path = System/Library/Frameworks/AssetsLibrary.framework; sourceTree = SDKROOT; };
EB37018115D18B2D00BEBC43 /* CordovaLib.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = CordovaLib.xcodeproj; path = ../CordovaLib/CordovaLib.xcodeproj; sourceTree = "<group>"; };
EB89634915FE66EA00E12277 /* CDVInvokedUrlCommandTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDVInvokedUrlCommandTests.m; sourceTree = "<group>"; };
EB96677116ADBCF500D86CDF /* CDVUserAgentTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDVUserAgentTest.m; sourceTree = "<group>"; };
@@ -120,6 +123,7 @@
buildActionMask = 2147483647;
files = (
EB3B34E9161B5532003DBE7D /* libCordova.a in Frameworks */,
+ 8220B5C216D541BD00EC3921 /* AssetsLibrary.framework in Frameworks */,
30F8AE0C152125B6006625B3 /* MobileCoreServices.framework in Frameworks */,
30F8AE0515212587006625B3 /* AddressBook.framework in Frameworks */,
30F8AE0615212587006625B3 /* AddressBookUI.framework in Frameworks */,
@@ -139,6 +143,7 @@
buildActionMask = 2147483647;
files = (
68A32D7514103017006B237C /* AddressBook.framework in Frameworks */,
+ 8220B5C616D542F500EC3921 /* AssetsLibrary.framework in Frameworks */,
68A32D7614103078006B237C /* CoreMedia.framework in Frameworks */,
68A32D7714103082006B237C /* AudioToolbox.framework in Frameworks */,
68A32D781410308B006B237C /* AVFoundation.framework in Frameworks */,
@@ -181,6 +186,7 @@
isa = PBXGroup;
children = (
68A32D7414103017006B237C /* AddressBook.framework */,
+ 8220B5C116D541BD00EC3921 /* AssetsLibrary.framework */,
686357DC14100B1600DF4CF2 /* CoreMedia.framework */,
686357CE14100ADA00DF4CF2 /* AudioToolbox.framework */,
686357CF14100ADB00DF4CF2 /* AVFoundation.framework */,
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLibTests/ExifTests.h
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLibTests/ExifTests.h b/lib/cordova-ios/CordovaLibTests/ExifTests.h
new file mode 100644
index 0000000..b46241b
--- /dev/null
+++ b/lib/cordova-ios/CordovaLibTests/ExifTests.h
@@ -0,0 +1,27 @@
+//
+// ExifTestTests.h
+// ExifTestTests
+//
+// Created by Lorin Beer on 2013-03-18.
+//
+//
+
+#import <SenTestingKit/SenTestingKit.h>
+
+#import "../ExifTest/CDVJpegHeaderWriter.h"
+
+#define ARC4RANDOM_MAX 0x100000000
+
+@interface ExifTestTests : SenTestCase {
+ CDVJpegHeaderWriter * testHeaderWriter;
+ NSNumber * testErrorThreshhold;
+}
+
+- (void) testContinuedFractionWithUInt;
+- (void) testContinuedFractionWithUFloat;
+- (void) testContinuedFractionsWorstCase;
+- (void) testFormatHexFromDecimal;
+- (void) testFormatNumberWithLeadingZeroes;
+- (void) testUnsignedRationalToString;
+- (void) testSignedRationalToString;
+@end
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLibTests/ExifTests.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLibTests/ExifTests.m b/lib/cordova-ios/CordovaLibTests/ExifTests.m
new file mode 100644
index 0000000..960ac95
--- /dev/null
+++ b/lib/cordova-ios/CordovaLibTests/ExifTests.m
@@ -0,0 +1,155 @@
+//
+// ExifTestTests.m
+// ExifTestTests
+//
+// Created by Lorin Beer on 2013-03-18.
+//
+//
+
+#import <SenTestingKit/SenTestingKit.h>
+
+#import "ExifTestTests.h"
+#import "../ExifTest/CDVJpegHeaderWriter.m"
+
+
+@implementation ExifTestTests
+
+- (void)setUp
+{
+ [super setUp];
+ testHeaderWriter = [[CDVJpegHeaderWriter alloc] init];
+ testErrorThreshhold = [NSNumber numberWithDouble: 0.000001];
+ NSLog(@"%x", ~10+1);
+
+
+}
+
+- (void)tearDown
+{
+ // Tear-down code here.
+
+ [super tearDown];
+}
+
+//==================================================================================================
+// rational approximation of decimal by continued fraction tests
+//==================================================================================================
+
+// tests continued fraction with random int
+- (void)testContinuedFractionWithUInt {
+ NSLog(@"Continued Fraction Test with random int value, numerator should be generated value, denominator should be 1");
+ NSNumber * numerator = @0;
+ NSNumber * denominator = @0;
+ NSNumber * testValue = [NSNumber numberWithInt: abs(arc4random())];
+ [testHeaderWriter decimalToUnsignedRational: testValue
+ withResultNumerator: &numerator
+ withResultDenominator: &denominator];
+ STAssertEquals([numerator intValue],
+ [testValue intValue],
+ @"Numerator did not match");
+ STAssertEquals([denominator intValue],
+ 1,
+ @"denominator was not one");
+}
+
+// tests continued fraction with random float
+- (void)testContinuedFractionWithUFloat {
+ NSLog(@"Continued Fraction Test with random double value, resulting fraction should be within acceptable error threshhold");
+ NSNumber * threshhold = @0.1;
+ NSNumber * numerator = @0;
+ NSNumber * denominator = @0;
+ NSLog(@"%f",((double)arc4random() / ARC4RANDOM_MAX) * 100.0f);
+ NSNumber * testValue = [NSNumber numberWithDouble:
+ ((double)arc4random() / ARC4RANDOM_MAX) * 100.0f];
+
+ [testHeaderWriter decimalToUnsignedRational: testValue
+ withResultNumerator: &numerator
+ withResultDenominator: &denominator];
+ NSLog(@"%lf, %lf",[testValue doubleValue], [numerator doubleValue]/[denominator doubleValue]);
+
+ STAssertEqualsWithAccuracy([testValue doubleValue],
+ [numerator doubleValue]/[denominator doubleValue],
+ [threshhold doubleValue],
+ @"rational approximation did not meet acceptable error threshhold");
+
+}
+
+// tests continued fraction in sqrt(2) worst case
+- (void)testContinuedFractionsWorstCase {
+ NSLog(@"Continued Fraction Test with provable worst case ~sqrt(2), resulting fraction should be within acceptable error threshhold");
+ NSNumber * threshhold = @0.1;
+ NSNumber * numerator = @0;
+ NSNumber * denominator = @0;
+ NSNumber * testValue = [NSNumber numberWithDouble: sqrt(2)];
+ [testHeaderWriter decimalToUnsignedRational: testValue
+ withResultNumerator: &numerator
+ withResultDenominator: &denominator];
+ STAssertEqualsWithAccuracy([testValue doubleValue],
+ [numerator doubleValue]/[denominator doubleValue],
+ [threshhold doubleValue],
+ @"rational approximation did not meet acceptable error threshhold");
+}
+
+// tests format hex from a decimal
+- (void) testFormatHexFromDecimal {
+ NSNumber * testValue = @1;
+ NSNumber * testPlaces = @8;
+ NSString * result = nil;
+ result = [testHeaderWriter formattedHexStringFromDecimalNumber: testValue
+ withPlaces: testPlaces];
+ // assert not nil
+ STAssertNotNil(result, @"nil renturned from formattedHexStringFromDecimalNumber");
+ // assert correct number of places
+ STAssertEquals([result length], [testPlaces unsignedIntegerValue],
+ @"returned string to wrong number of places. Should be = %i Was = %i",
+ [testPlaces intValue],
+ [result length]);
+ // assert correct hex representation
+ STAssertTrueNoThrow([result isEqualToString:@"00000001"], @"result should be equal to @00000001");
+
+}
+
+// tests format number string with leading zeroes
+- (void) testFormatNumberWithLeadingZeroes {
+ NSString * result = nil;
+ NSNumber * testValue = @8769; // Exif SubIFD Offset Tag
+ NSNumber * testPlaces = @6;
+ result = [testHeaderWriter formatNumberWithLeadingZeroes: testValue
+ withPlaces: testPlaces];
+ STAssertNotNil(result, @"nil renturned from formattedHexStringFromDecimalNumber");
+ STAssertEquals([result length],
+ [testPlaces unsignedIntegerValue],
+ @"returned string to wrong number of places. Should be = %i Was = %i",
+ [testPlaces intValue],
+ [result length]);
+ // assert correct hex representation
+ STAssertTrueNoThrow([result isEqualToString:@"008769"], @"result was = %@ should be = @008769", result);
+}
+
+- (void) testUnsignedRationalToString {
+ NSString * result = nil;
+ NSNumber * numerator = @1;
+ NSNumber * denominator = @10;
+ result = [testHeaderWriter formatRationalWithNumerator: numerator
+ withDenominator: denominator
+ asSigned: FALSE];
+ NSLog(result);
+ STAssertNotNil(result, @"nil returned from testUnsignedRationalToString");
+ STAssertTrueNoThrow([result length]==16, @"returned string with wrong length. Exif rationals are 8 bytes, string has %ld bytes",[result length]/2);
+ STAssertTrueNoThrow([result isEqualToString:@"000000010000000a"], @"result was = %@ should be = @0000000100000010", result);
+}
+
+- (void) testSignedRationalToString {
+ NSString * result = nil;
+ NSNumber * numerator = @-1;
+ NSNumber * denominator = @-10;
+ result = [testHeaderWriter formatRationalWithNumerator: numerator
+ withDenominator: denominator
+ asSigned: TRUE];
+ NSLog(result);
+ STAssertNotNil(result, @"nil returned from testSignedRationalToString");
+ STAssertTrueNoThrow([result length]==16, @"returned string with wrong length. Exif rationals are 8 bytes, string has %ld bytes",[result length]/2);
+ STAssertTrueNoThrow([result isEqualToString:@"fffffffffffffff6"], @"result was = %@ should be = @000000FF000000F6", result);
+}
+
+@end
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/RELEASENOTES.md
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/RELEASENOTES.md b/lib/cordova-ios/RELEASENOTES.md
index 843493e..e83c647 100644
--- a/lib/cordova-ios/RELEASENOTES.md
+++ b/lib/cordova-ios/RELEASENOTES.md
@@ -22,7 +22,65 @@
Cordova is a static library that enables developers to include the Cordova API in their iOS application projects easily, and also create new Cordova-based iOS application projects through the command-line.
- ### 2.5.0 (20130301) ###
+### 2.6.0 (20130401) ###
+
+* [CB-1547] Scope notifications to WebViews
+* [CB-2461] Distinguish sub-frame from top-level loads in InAppBrowser.
+* [CB-2523] Add setting to shrink webview when keyboard pops up
+* [CB-2220] Fix splashscreen origin when status bar is present
+* [CB-2220] Size the splash screen in the same way as the launch image
+* [CB-2389] Fix page load detection for late-loaded iframes
+* [CB-2220] Fix splash screen positioning when image is the size of device
+* [CB-2631] Fix crash when bad url given to FT.upload
+* [CB-2652] Make FileReader.readAs*() functions run on a background thread
+* [CB-2633] Add FileReader.readAsBinaryString()
+* [CB-2308] Correctly delegate to CDVInAppBrowser webView:didFailLoadWithError
+* [CB-2308] [ios] Report errors when InAppBrowser fails to load page
+* [CB-2527] Update iPad splash images to correct sizes
+* [CB-1452] Media position incorrect after being set beyond duration
+* [CB-2436] Wrong splashscreen is displayed when UILaunchImageFile is set
+* [CB-2634] Copy www fails w spaces in filenames
+* [CB-2618] xcode build from Network Drive Fails
+* [CB-2638] Fix iOS project warnings on Retina imgs
+* [CB-2491] Deprecate current Connection cell setting
+* [CB-2674] Add prompt to Notification API for iOS
+* [CB-2691] Splashscreen should block user interaction
+* [CB-2502] Fixing CDVViewController.commandDelegate property declaration
+* [CB-1933] Changed button labels to an array.
+* [CB-1688] Added a camera direction option.
+* [CB-2732] Only set camera device when allowed.
+* [CB-2530] [CB-2239] Multipart plugin result
+* [CB-2605] icon-72@2x.png not included in xcode project template
+* [CB-2545] Deprecate "EnableLocation" Project Setting - use the "onload" attribute of the <plugin> element
+* [CB-2384] Add new iOS Project Setting to suppress the form accessory bar above the keyboard
+* [CB-2195] Remove deprecated - iOS - BackupWebStorage Cordova.plist property change from boolean to string
+* [CB-2194] Remove deprecated - iOS - CDVCommandDelegate registerPlugin method
+* [CB-2699] Bug in dynamic loading of a plugin at CDVViewController's registerPlugin method
+* [CB-2384] Re-fix - Add new iOS Project Setting to suppress the form accessory bar above the keyboard
+* [CB-2759] Update www/ Application for iOS
+* [CB-2672] InAppBrowserBug fixed (not reporting actual URL after redirect)
+* [CB-861] Header support for FileTransfer download
+* Add a define that turns on logging of exec() bridge
+* Sort preferences in project template.
+* Add KeyboardShrinksView preference to project template
+* Revert accidentaly change in PluginResult that broke threading.
+* Remove NSLogs accidentally checked in.
+* Use noCopy versions of NSString init in Base64 code.
+* Add an associatedObject field to CDVPluginResult.
+* Uncrustified with v0.60 of the tool (up from 0.59).
+* Make sure version of uncrustify is correct in the pre-commit hook
+* Remove some unnecessary argument checks in CDVNotification
+* Implement readAsArrayBuffer
+* Changed UIWebViewBounce to DisallowOverscroll.
+* Retain cycle fix
+* Fixed static analyzer issues.
+* Interim .js for [CB-52] FileTransfer Basic Auth
+* Added KeyboardShrinksView preference to CordovaLibTest config.xml
+* Added \__CORDOVA_IOS\__ macro
+
+< br />
+
+### 2.5.0 (20130301) ###
* [CB-2395] Fix CDVViewController UserAgent lock
* [CB-2207] Use a custom script for www/ copying.
@@ -76,7 +134,7 @@
<br />
- ### 2.4.0 (20130205) ###
+### 2.4.0 (20130205) ###
* Make cordova_plist_to_config_xml able to handle binary plist files
* Ran splashscreen images through ImageOptim.
@@ -129,7 +187,7 @@
<br />
- ### 2.3.0 (20130107) ###
+### 2.3.0 (20130107) ###
* [CB-1550] iOS build, debug, emulate scripts should check xcode version
* [CB-1669] Issue an error when media.startRecord() is failing.
@@ -191,7 +249,7 @@
<br />
- ### 2.2.0 (20121031) ###
+### 2.2.0 (20121031) ###
* [CB-622] FileTransfer interface should provide progress monitoring
* [CB-622] Progress events for downloads
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/bin/templates/project/__TESTING__.xcodeproj/project.pbxproj
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/bin/templates/project/__TESTING__.xcodeproj/project.pbxproj b/lib/cordova-ios/bin/templates/project/__TESTING__.xcodeproj/project.pbxproj
index 1d9c170..f5ed342 100755
--- a/lib/cordova-ios/bin/templates/project/__TESTING__.xcodeproj/project.pbxproj
+++ b/lib/cordova-ios/bin/templates/project/__TESTING__.xcodeproj/project.pbxproj
@@ -40,6 +40,7 @@
30A0434814DC770100060A13 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 30A0434314DC770100060A13 /* Localizable.strings */; };
30A0434914DC770100060A13 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 30A0434614DC770100060A13 /* Localizable.strings */; };
30E5649213A7FCAF007403D8 /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 30E5649113A7FCAF007403D8 /* CoreMedia.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
+ 30FC414916E50CA1004E6F35 /* icon-72@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 30FC414816E50CA1004E6F35 /* icon-72@2x.png */; };
5B1594DD16A7569C00FEF299 /* AssetsLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5B1594DC16A7569C00FEF299 /* AssetsLibrary.framework */; };
D4A0D8761607E02300AEF8BB /* Default-568h@2x~iphone.png in Resources */ = {isa = PBXBuildFile; fileRef = D4A0D8751607E02300AEF8BB /* Default-568h@2x~iphone.png */; };
F840E1F1165FE0F500CFE078 /* config.xml in Resources */ = {isa = PBXBuildFile; fileRef = F840E1F0165FE0F500CFE078 /* config.xml */; };
@@ -100,6 +101,7 @@
30A0434414DC770100060A13 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = Localizable.strings; sourceTree = "<group>"; };
30A0434714DC770100060A13 /* se */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = se; path = Localizable.strings; sourceTree = "<group>"; };
30E5649113A7FCAF007403D8 /* CoreMedia.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = System/Library/Frameworks/CoreMedia.framework; sourceTree = SDKROOT; };
+ 30FC414816E50CA1004E6F35 /* icon-72@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-72@2x.png"; sourceTree = "<group>"; };
32CA4F630368D1EE00C91783 /* __TESTING__-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "__TESTING__-Prefix.pch"; sourceTree = "<group>"; };
5B1594DC16A7569C00FEF299 /* AssetsLibrary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AssetsLibrary.framework; path = System/Library/Frameworks/AssetsLibrary.framework; sourceTree = SDKROOT; };
8D1107310486CEB800E47090 /* __TESTING__-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "__TESTING__-Info.plist"; path = "../__TESTING__-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = "<group>"; };
@@ -254,6 +256,7 @@
308D052D1370CCF300D202BF /* icons */ = {
isa = PBXGroup;
children = (
+ 30FC414816E50CA1004E6F35 /* icon-72@2x.png */,
308D052E1370CCF300D202BF /* icon-72.png */,
308D052F1370CCF300D202BF /* icon.png */,
308D05301370CCF300D202BF /* icon@2x.png */,
@@ -382,6 +385,7 @@
3088BBC1154F3926009F9C59 /* Default@2x~iphone.png in Resources */,
3088BBC2154F3926009F9C59 /* Default~iphone.png in Resources */,
D4A0D8761607E02300AEF8BB /* Default-568h@2x~iphone.png in Resources */,
+ 30FC414916E50CA1004E6F35 /* icon-72@2x.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -400,7 +404,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "SRC_DIR=\"www\"\nDST_DIR=\"$BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME/www\"\nCOPY_HIDDEN=\n\nif [[ ! -e \"$SRC_DIR\" ]]; then\n echo \"Path does not exist: $SRC_DIR\"\n exit 1\nfi\n\nif [[ -n $COPY_HIDDEN ]]; then\n alias do_find='find \"$SRC_DIR\"'\nelse\n alias do_find='find \"$SRC_DIR\" -name \".*\" -prune -o'\nfi\n\ntime (\n# Code signing files must be removed or else there are\n# resource signing errors.\nrm -rf \"$DST_DIR\" \\\n \"$BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME/_CodeSignature\" \\\n \"$BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME/PkgInfo\" \\\n \"$BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME/embedded.mobileprovision\"\n\n# Directories\nfor p in $(do_find -type d -print); do\n subpath=\"${p#$SRC_DIR}\"\n mkdir \"$DST_DIR$subpath\" || exit 1\ndone\n\n# Symlinks\nfor p in $(do_find -type l -print); do\n subpath=\"${p#$SRC_DIR}\"\n cp -a \"$SRC_DIR$subpath\" \"$DST_DIR$subpath\" || exit 2\ndone\n\n# Files\nfor p in $(do_find -type f -print); do\n
subpath=\"${p#$SRC_DIR}\"\n if ! ln \"$SRC_DIR$subpath\" \"$DST_DIR$subpath\"; then\n cp -a \"$SRC_DIR$subpath\" \"$DST_DIR$subpath\" || exit 3\n fi\ndone\n\n)";
+ shellScript = "SRC_DIR=\"www\"\nDST_DIR=\"$BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME/www\"\nCOPY_HIDDEN=\nORIG_IFS=$IFS\nIFS=$(echo -en \"\\n\\b\")\n\nif [[ ! -e \"$SRC_DIR\" ]]; then\n echo \"Path does not exist: $SRC_DIR\"\n exit 1\nfi\n\nif [[ -n $COPY_HIDDEN ]]; then\n alias do_find='find \"$SRC_DIR\"'\nelse\n alias do_find='find \"$SRC_DIR\" -name \".*\" -prune -o'\nfi\n\ntime (\n# Code signing files must be removed or else there are\n# resource signing errors.\nrm -rf \"$DST_DIR\" \\\n \"$BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME/_CodeSignature\" \\\n \"$BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME/PkgInfo\" \\\n \"$BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME/embedded.mobileprovision\"\n\n# Directories\nfor p in $(do_find -type d -print); do\n subpath=\"${p#$SRC_DIR}\"\n mkdir \"$DST_DIR$subpath\" || exit 1\ndone\n\n# Symlinks\nfor p in $(do_find -type l -print); do\n subpath=\"${p#$SRC_DIR}\"\n rsync -a \"$SRC_DIR$subpath\" \"$DST_DIR$subpath\" || exit 2\ndone\n\n# Fi
les\nfor p in $(do_find -type f -print); do\n subpath=\"${p#$SRC_DIR}\"\n if ! ln \"$SRC_DIR$subpath\" \"$DST_DIR$subpath\" 2>/dev/null; then\n rsync -a \"$SRC_DIR$subpath\" \"$DST_DIR$subpath\" || exit 3\n fi\ndone\n\n)\nIFS=$ORIG_IFS";
};
/* End PBXShellScriptBuildPhase section */
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/bin/templates/project/__TESTING__/Classes/AppDelegate.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/bin/templates/project/__TESTING__/Classes/AppDelegate.m b/lib/cordova-ios/bin/templates/project/__TESTING__/Classes/AppDelegate.m
index 318f793..623ad8e 100644
--- a/lib/cordova-ios/bin/templates/project/__TESTING__/Classes/AppDelegate.m
+++ b/lib/cordova-ios/bin/templates/project/__TESTING__/Classes/AppDelegate.m
@@ -45,7 +45,7 @@
int cacheSizeMemory = 8 * 1024 * 1024; // 8MB
int cacheSizeDisk = 32 * 1024 * 1024; // 32MB
- NSURLCache* sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:cacheSizeMemory diskCapacity:cacheSizeDisk diskPath:@"nsurlcache"];
+ NSURLCache* sharedCache = [[[NSURLCache alloc] initWithMemoryCapacity:cacheSizeMemory diskCapacity:cacheSizeDisk diskPath:@"nsurlcache"] autorelease];
[NSURLCache setSharedURLCache:sharedCache];
self = [super init];
@@ -99,8 +99,8 @@
}
// repost the localnotification using the default NSNotificationCenter so multiple plugins may respond
-- (void) application:(UIApplication*)application
- didReceiveLocalNotification:(UILocalNotification*)notification
+- (void) application:(UIApplication*)application
+ didReceiveLocalNotification:(UILocalNotification*)notification
{
// re-post ( broadcast )
[[NSNotificationCenter defaultCenter] postNotificationName:CDVLocalNotification object:notification];
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/bin/templates/project/__TESTING__/Resources/splash/Default-568h@2x~iphone.png
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/bin/templates/project/__TESTING__/Resources/splash/Default-568h@2x~iphone.png b/lib/cordova-ios/bin/templates/project/__TESTING__/Resources/splash/Default-568h@2x~iphone.png
index d14b55b..10ed683 100644
Binary files a/lib/cordova-ios/bin/templates/project/__TESTING__/Resources/splash/Default-568h@2x~iphone.png and b/lib/cordova-ios/bin/templates/project/__TESTING__/Resources/splash/Default-568h@2x~iphone.png differ
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/bin/templates/project/__TESTING__/Resources/splash/Default-Landscape@2x~ipad.png
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/bin/templates/project/__TESTING__/Resources/splash/Default-Landscape@2x~ipad.png b/lib/cordova-ios/bin/templates/project/__TESTING__/Resources/splash/Default-Landscape@2x~ipad.png
index 72eb605..9f1e14f 100644
Binary files a/lib/cordova-ios/bin/templates/project/__TESTING__/Resources/splash/Default-Landscape@2x~ipad.png and b/lib/cordova-ios/bin/templates/project/__TESTING__/Resources/splash/Default-Landscape@2x~ipad.png differ
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/bin/templates/project/__TESTING__/Resources/splash/Default-Landscape~ipad.png
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/bin/templates/project/__TESTING__/Resources/splash/Default-Landscape~ipad.png b/lib/cordova-ios/bin/templates/project/__TESTING__/Resources/splash/Default-Landscape~ipad.png
index 30e8587..93a8d74 100644
Binary files a/lib/cordova-ios/bin/templates/project/__TESTING__/Resources/splash/Default-Landscape~ipad.png and b/lib/cordova-ios/bin/templates/project/__TESTING__/Resources/splash/Default-Landscape~ipad.png differ
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/bin/templates/project/__TESTING__/Resources/splash/Default-Portrait@2x~ipad.png
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/bin/templates/project/__TESTING__/Resources/splash/Default-Portrait@2x~ipad.png b/lib/cordova-ios/bin/templates/project/__TESTING__/Resources/splash/Default-Portrait@2x~ipad.png
index 435bbec..6d1c5d3 100644
Binary files a/lib/cordova-ios/bin/templates/project/__TESTING__/Resources/splash/Default-Portrait@2x~ipad.png and b/lib/cordova-ios/bin/templates/project/__TESTING__/Resources/splash/Default-Portrait@2x~ipad.png differ
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/bin/templates/project/__TESTING__/Resources/splash/Default-Portrait~ipad.png
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/bin/templates/project/__TESTING__/Resources/splash/Default-Portrait~ipad.png b/lib/cordova-ios/bin/templates/project/__TESTING__/Resources/splash/Default-Portrait~ipad.png
index 5e9786a..30e0a3d 100644
Binary files a/lib/cordova-ios/bin/templates/project/__TESTING__/Resources/splash/Default-Portrait~ipad.png and b/lib/cordova-ios/bin/templates/project/__TESTING__/Resources/splash/Default-Portrait~ipad.png differ
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/bin/templates/project/__TESTING__/config.xml
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/bin/templates/project/__TESTING__/config.xml b/lib/cordova-ios/bin/templates/project/__TESTING__/config.xml
index 64e7163..8889726 100644
--- a/lib/cordova-ios/bin/templates/project/__TESTING__/config.xml
+++ b/lib/cordova-ios/bin/templates/project/__TESTING__/config.xml
@@ -20,19 +20,21 @@
#
-->
<widget>
- <preference name="KeyboardDisplayRequiresUserAction" value="true" />
- <preference name="SuppressesIncrementalRendering" value="false" />
- <preference name="UIWebViewBounce" value="true" />
- <preference name="TopActivityIndicator" value="gray" />
- <preference name="EnableLocation" value="false" />
- <preference name="EnableViewportScale" value="false" />
+ <preference name="AllowInlineMediaPlayback" value="false" />
<preference name="AutoHideSplashScreen" value="true" />
- <preference name="ShowSplashScreenSpinner" value="true" />
+ <preference name="BackupWebStorage" value="cloud" />
+ <preference name="DisallowOverscroll" value="false" />
+ <preference name="EnableLocation" value="false" /><!-- DEPRECATED -->
+ <preference name="EnableViewportScale" value="false" />
<preference name="FadeSplashScreen" value="true" />
<preference name="FadeSplashScreenDuration" value=".25" />
+ <preference name="HideKeyboardFormAccessoryBar" value="false" />
+ <preference name="KeyboardDisplayRequiresUserAction" value="true" />
+ <preference name="KeyboardShrinksView" value="false" />
<preference name="MediaPlaybackRequiresUserAction" value="false" />
- <preference name="AllowInlineMediaPlayback" value="false" />
- <preference name="BackupWebStorage" value="cloud" />
+ <preference name="ShowSplashScreenSpinner" value="true" />
+ <preference name="SuppressesIncrementalRendering" value="false" />
+ <preference name="TopActivityIndicator" value="gray" />
<content src="index.html" />
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/bin/templates/project/www/index.html
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/bin/templates/project/www/index.html b/lib/cordova-ios/bin/templates/project/www/index.html
index 6374050..8bc9055 100644
--- a/lib/cordova-ios/bin/templates/project/www/index.html
+++ b/lib/cordova-ios/bin/templates/project/www/index.html
@@ -19,7 +19,7 @@
-->
<html>
<head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <meta charset="utf-8" />
<meta name="format-detection" content="telephone=no" />
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
<link rel="stylesheet" type="text/css" href="css/index.css" />
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/guides/Cordova Plugin Upgrade Guide.md
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/guides/Cordova Plugin Upgrade Guide.md b/lib/cordova-ios/guides/Cordova Plugin Upgrade Guide.md
index 869e4f4..7a03bc4 100644
--- a/lib/cordova-ios/guides/Cordova Plugin Upgrade Guide.md
+++ b/lib/cordova-ios/guides/Cordova Plugin Upgrade Guide.md
@@ -22,6 +22,12 @@
This document is for developers who need to upgrade their Cordova plugins to a newer Cordova version. Starting with Cordova 1.5.0, some classes have been renamed, which will require the plugin to be upgraded. Make sure your project itself has been upgraded using the [Cordova iOS Upgrading Guide](http://cordova.apache.org/docs/en/edge/guide_upgrading_ios_index.md.html#Upgrading%20Cordova%20iOS) document.
+## Upgrading older Cordova plugins to 2.6.0 ##
+
+1. **Install** Cordova 2.6.0
+2. Follow the **"Upgrading older Cordova plugins to 2.5.0"** section, if necessary
+3. The **registerPlugin** method of the **commandDelegate** property of plugin, which was deprecated, has been **removed**. Use the **registerPlugin** method directly from the **viewController** property of the plugin.
+
## Upgrading older Cordova plugins to 2.5.0 ##
1. **Install** Cordova 2.5.0
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/hooks/pre-commit
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/hooks/pre-commit b/lib/cordova-ios/hooks/pre-commit
index 7a420c9..80550f1 100755
--- a/lib/cordova-ios/hooks/pre-commit
+++ b/lib/cordova-ios/hooks/pre-commit
@@ -20,6 +20,12 @@
# Redirect output to stderr.
exec 1>&2
+test $SKIP_UNCRUSTIFY && exit 0
+
+if [[ "$(uncrustify --version | cut -d' ' -f2)" != 0.60 ]]; then
+ echo "Please install version 0.60 of uncrustify."
+ exit 1
+fi
RET=0
files=$(bin/uncrustify.sh --filter $(git diff --cached --name-only))
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/package.json
----------------------------------------------------------------------
diff --git a/package.json b/package.json
index d7bfb17..a749826 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "cordova",
- "version": "2.5.5",
+ "version": "2.6.0",
"preferGlobal": "true",
"description": "Cordova command line interface tool",
"main": "cordova",
[6/6] git commit: 2.6.0rc1 used for libs now. Bumped npm version to
2.6.0. added androids local.properties to gitignore.
Posted by fi...@apache.org.
2.6.0rc1 used for libs now. Bumped npm version to 2.6.0. added androids local.properties to gitignore.
Project: http://git-wip-us.apache.org/repos/asf/cordova-cli/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-cli/commit/37b92ff4
Tree: http://git-wip-us.apache.org/repos/asf/cordova-cli/tree/37b92ff4
Diff: http://git-wip-us.apache.org/repos/asf/cordova-cli/diff/37b92ff4
Branch: refs/heads/2.6.x
Commit: 37b92ff47d532490f67a635e0f3b011c03be8eb1
Parents: 50e8e4e
Author: Fil Maj <ma...@gmail.com>
Authored: Mon Mar 25 14:52:11 2013 -0700
Committer: Fil Maj <ma...@gmail.com>
Committed: Mon Mar 25 14:52:11 2013 -0700
----------------------------------------------------------------------
.gitignore | 2 +-
lib/cordova-android/VERSION | 2 +-
lib/cordova-android/bin/create | 16 +-
.../bin/templates/cordova/appinfo.jar | Bin 1574 -> 1574 bytes
.../bin/templates/project/assets/www/index.html | 2 +-
lib/cordova-android/bin/update | 139 ++++
lib/cordova-android/bin/update.bat | 32 +
lib/cordova-android/bin/update.js | 193 ++++++
.../framework/assets/js/cordova.android.js | 474 +++++++++++---
.../framework/assets/www/index.html | 2 +-
.../src/org/apache/cordova/AudioHandler.java | 6 +-
.../src/org/apache/cordova/AudioPlayer.java | 15 +-
.../src/org/apache/cordova/CameraLauncher.java | 16 +-
.../framework/src/org/apache/cordova/Capture.java | 14 +-
.../framework/src/org/apache/cordova/Config.java | 10 +
.../src/org/apache/cordova/CordovaArgs.java | 5 +-
.../org/apache/cordova/CordovaChromeClient.java | 2 +-
.../src/org/apache/cordova/CordovaWebView.java | 124 +---
.../org/apache/cordova/CordovaWebViewClient.java | 103 ++--
.../framework/src/org/apache/cordova/Device.java | 2 +-
.../framework/src/org/apache/cordova/DroidGap.java | 13 +-
.../src/org/apache/cordova/FileHelper.java | 142 ++++
.../src/org/apache/cordova/FileTransfer.java | 81 ++-
.../src/org/apache/cordova/FileUtils.java | 350 ++++-------
.../src/org/apache/cordova/GeoBroker.java | 2 +-
.../cordova/IceCreamCordovaWebViewClient.java | 16 +-
.../src/org/apache/cordova/InAppBrowser.java | 135 ++++-
.../src/org/apache/cordova/JSONUtils.java | 24 +
.../org/apache/cordova/NativeToJsMessageQueue.java | 13 +-
.../src/org/apache/cordova/Notification.java | 167 ++++-
.../org/apache/cordova/api/CallbackContext.java | 9 +
.../src/org/apache/cordova/api/CordovaPlugin.java | 18 +-
.../src/org/apache/cordova/api/PluginManager.java | 23 +-
.../src/org/apache/cordova/api/PluginResult.java | 11 +-
lib/cordova-blackberry/bin/create | 21 +-
.../bin/templates/project/www/index.html | 4 +-
.../ext/src/org/apache/cordova/util/FileUtils.java | 33 +-
.../javascript/cordova.blackberry.js | 365 +++++++++--
.../CordovaLib/Classes/CDVAvailability.h | 19 +-
lib/cordova-ios/CordovaLib/Classes/CDVCamera.h | 4 +-
lib/cordova-ios/CordovaLib/Classes/CDVCamera.m | 53 ++
lib/cordova-ios/CordovaLib/Classes/CDVCapture.m | 10 +-
.../CordovaLib/Classes/CDVCommandDelegate.h | 1 -
.../CordovaLib/Classes/CDVCommandDelegateImpl.m | 22 +-
.../CordovaLib/Classes/CDVCommandQueue.h | 8 +-
.../CordovaLib/Classes/CDVCommandQueue.m | 17 +-
.../CordovaLib/Classes/CDVConfigParser.m | 2 +-
lib/cordova-ios/CordovaLib/Classes/CDVConnection.m | 12 +-
lib/cordova-ios/CordovaLib/Classes/CDVContact.m | 32 +-
lib/cordova-ios/CordovaLib/Classes/CDVContacts.h | 14 +-
lib/cordova-ios/CordovaLib/Classes/CDVContacts.m | 490 +++++++-------
lib/cordova-ios/CordovaLib/Classes/CDVEcho.m | 7 +
lib/cordova-ios/CordovaLib/Classes/CDVExif.h | 43 ++
lib/cordova-ios/CordovaLib/Classes/CDVFile.h | 2 +
lib/cordova-ios/CordovaLib/Classes/CDVFile.m | 285 +++++----
.../CordovaLib/Classes/CDVFileTransfer.h | 8 +-
.../CordovaLib/Classes/CDVFileTransfer.m | 51 +-
.../CordovaLib/Classes/CDVGlobalization.m | 62 +-
.../CordovaLib/Classes/CDVInAppBrowser.h | 3 +
.../CordovaLib/Classes/CDVInAppBrowser.m | 41 +-
.../CordovaLib/Classes/CDVInvokedUrlCommand.h | 6 +-
.../CordovaLib/Classes/CDVJpegHeaderWriter.h | 60 ++
.../CordovaLib/Classes/CDVJpegHeaderWriter.m | 472 +++++++++++++
.../CordovaLib/Classes/CDVLocalStorage.h | 4 +-
.../CordovaLib/Classes/CDVLocalStorage.m | 36 +-
lib/cordova-ios/CordovaLib/Classes/CDVLocation.h | 8 +-
lib/cordova-ios/CordovaLib/Classes/CDVLocation.m | 24 +-
.../CordovaLib/Classes/CDVNotification.h | 1 +
.../CordovaLib/Classes/CDVNotification.m | 89 ++-
lib/cordova-ios/CordovaLib/Classes/CDVPlugin.h | 8 +-
lib/cordova-ios/CordovaLib/Classes/CDVPlugin.m | 9 +-
.../CordovaLib/Classes/CDVPluginResult.h | 7 +
.../CordovaLib/Classes/CDVPluginResult.m | 57 ++-
.../CordovaLib/Classes/CDVReachability.m | 28 +-
lib/cordova-ios/CordovaLib/Classes/CDVSound.m | 21 +-
.../CordovaLib/Classes/CDVSplashScreen.h | 3 +-
.../CordovaLib/Classes/CDVSplashScreen.m | 176 +++--
.../CordovaLib/Classes/CDVURLProtocol.m | 12 +-
.../CordovaLib/Classes/CDVUserAgentUtil.m | 2 +-
.../CordovaLib/Classes/CDVViewController.h | 10 +-
.../CordovaLib/Classes/CDVViewController.m | 140 ++++-
.../CordovaLib/Classes/CDVWebViewDelegate.m | 30 +-
lib/cordova-ios/CordovaLib/Classes/NSData+Base64.m | 19 +-
.../CordovaLib/Classes/NSDictionary+Extensions.m | 2 +-
.../CordovaLib.xcodeproj/project.pbxproj | 14 +
lib/cordova-ios/CordovaLib/VERSION | 2 +-
lib/cordova-ios/CordovaLib/cordova.ios.js | 521 ++++++++++++---
.../CordovaLibTests/CDVFakeFileManager.h | 2 +-
.../CordovaLibTests/CDVFileTransferTests.m | 12 +-
.../CordovaLibTests/CDVLocalStorageTests.m | 24 +-
lib/cordova-ios/CordovaLibTests/CDVUserAgentTest.m | 4 +-
lib/cordova-ios/CordovaLibTests/CDVWebViewTest.m | 4 +-
.../CordovaLibTests/CordovaLibApp/config.xml | 6 +-
.../CordovaTests.xcodeproj/project.pbxproj | 6 +
lib/cordova-ios/CordovaLibTests/ExifTests.h | 27 +
lib/cordova-ios/CordovaLibTests/ExifTests.m | 155 +++++
lib/cordova-ios/RELEASENOTES.md | 66 ++-
.../project/__TESTING__.xcodeproj/project.pbxproj | 6 +-
.../project/__TESTING__/Classes/AppDelegate.m | 6 +-
.../Resources/splash/Default-568h@2x~iphone.png | Bin 29944 -> 34225 bytes
.../Resources/splash/Default-Landscape@2x~ipad.png | Bin 75573 -> 77300 bytes
.../Resources/splash/Default-Landscape~ipad.png | Bin 33147 -> 34935 bytes
.../Resources/splash/Default-Portrait@2x~ipad.png | Bin 74097 -> 76546 bytes
.../Resources/splash/Default-Portrait~ipad.png | Bin 32666 -> 34278 bytes
.../bin/templates/project/__TESTING__/config.xml | 20 +-
.../bin/templates/project/www/index.html | 2 +-
.../guides/Cordova Plugin Upgrade Guide.md | 6 +
lib/cordova-ios/hooks/pre-commit | 6 +
package.json | 2 +-
109 files changed, 4423 insertions(+), 1464 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index 3abe651..b31c8bf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,8 +6,8 @@ spec/fixtures/projects/native
spec/fixtures/projects/cordova
lib/cordova-android/framework/bin
lib/cordova-android/framework/gen
+lib/cordova-android/framework/local.properties
.idea/*
spec/fixtures/*
.gitcore
*.jar
-lib/*
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/VERSION
----------------------------------------------------------------------
diff --git a/lib/cordova-android/VERSION b/lib/cordova-android/VERSION
index 437459c..f47de85 100644
--- a/lib/cordova-android/VERSION
+++ b/lib/cordova-android/VERSION
@@ -1 +1 @@
-2.5.0
+2.6.0rc1
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/bin/create
----------------------------------------------------------------------
diff --git a/lib/cordova-android/bin/create b/lib/cordova-android/bin/create
index ea214ac..2eae82b 100755
--- a/lib/cordova-android/bin/create
+++ b/lib/cordova-android/bin/create
@@ -59,10 +59,10 @@ function on_exit {
}
function createAppInfoJar {
- (cd "$BUILD_PATH"/bin/templates/cordova/ApplicationInfo &&
- javac ApplicationInfo.java &&
- jar -cfe ../appinfo.jar ApplicationInfo ApplicationInfo.class
- )
+ pushd "$BUILD_PATH"/bin/templates/cordova/ApplicationInfo > /dev/null
+ javac ApplicationInfo.java
+ jar -cfe ../appinfo.jar ApplicationInfo ApplicationInfo.class
+ popd > /dev/null
}
function on_error {
@@ -108,7 +108,7 @@ fi
# if this a distribution release no need to build a jar
if [ ! -e "$BUILD_PATH"/cordova-$VERSION.jar ] && [ -d "$BUILD_PATH"/framework ]
then
-# update the cordova-android framework for the desired target
+ # update the cordova-android framework for the desired target
"$ANDROID_BIN" update project --target $TARGET --path "$BUILD_PATH"/framework &> /dev/null
if [ ! -e "$BUILD_PATH"/framework/libs/commons-codec-1.7.jar ]; then
@@ -121,8 +121,10 @@ then
rm commons-codec-1.7-bin.zip && rm -rf commons-codec-1.7
fi
-# compile cordova.js and cordova.jar
- (cd "$BUILD_PATH"/framework && ant jar &> /dev/null )
+ # compile cordova.js and cordova.jar
+ pushd "$BUILD_PATH"/framework > /dev/null
+ ant jar > /dev/null
+ popd > /dev/null
fi
# create new android project
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/bin/templates/cordova/appinfo.jar
----------------------------------------------------------------------
diff --git a/lib/cordova-android/bin/templates/cordova/appinfo.jar b/lib/cordova-android/bin/templates/cordova/appinfo.jar
index fff4d0f..7f8ac60 100644
Binary files a/lib/cordova-android/bin/templates/cordova/appinfo.jar and b/lib/cordova-android/bin/templates/cordova/appinfo.jar differ
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/bin/templates/project/assets/www/index.html
----------------------------------------------------------------------
diff --git a/lib/cordova-android/bin/templates/project/assets/www/index.html b/lib/cordova-android/bin/templates/project/assets/www/index.html
index b8c0535..5596f62 100644
--- a/lib/cordova-android/bin/templates/project/assets/www/index.html
+++ b/lib/cordova-android/bin/templates/project/assets/www/index.html
@@ -33,7 +33,7 @@
<p class="event received">Device is Ready</p>
</div>
</div>
- <script type="text/javascript" src="cordova-2.5.0.js"></script>
+ <script type="text/javascript" src="cordova-2.6.0rc1.js"></script>
<script type="text/javascript" src="js/index.js"></script>
<script type="text/javascript">
app.initialize();
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/bin/update
----------------------------------------------------------------------
diff --git a/lib/cordova-android/bin/update b/lib/cordova-android/bin/update
new file mode 100755
index 0000000..0e86886
--- /dev/null
+++ b/lib/cordova-android/bin/update
@@ -0,0 +1,139 @@
+#! /bin/bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# update a cordova/android project's command line tools
+#
+# USAGE
+# ./update [path]
+#
+
+set -e
+
+if [ -z "$1" ] || [ "$1" == "-h" ]
+then
+ echo 'usage: update path'
+ echo "Make sure the Android SDK tools folder is in your PATH!"
+ exit 0
+fi
+
+BUILD_PATH="$( cd "$( dirname "$0" )/.." && pwd )"
+VERSION=$(cat "$BUILD_PATH"/VERSION)
+
+PROJECT_PATH="${1:-'./example'}"
+
+if [ ! -d "$PROJECT_PATH" ]
+then
+ echo "The project path has to exist for it to be updated"
+ exit 0
+fi
+
+
+# cleanup after exit and/or on error
+function on_exit {
+ if [ -f "$BUILD_PATH"/framework/assets/www/cordova-$VERSION.js ]
+ then
+ rm "$BUILD_PATH"/framework/assets/www/cordova-$VERSION.js
+ fi
+ if [ -f "$BUILD_PATH"/framework/cordova-$VERSION.jar ]
+ then
+ rm "$BUILD_PATH"/framework/cordova-$VERSION.jar
+ fi
+}
+
+function createAppInfoJar {
+ (cd "$BUILD_PATH"/bin/templates/cordova/ApplicationInfo &&
+ javac ApplicationInfo.java &&
+ jar -cfe ../appinfo.jar ApplicationInfo ApplicationInfo.class
+ )
+}
+
+function on_error {
+ echo "An unexpected error occurred: $previous_command exited with $?"
+ echo "Deleting project..."
+ [ -d "$PROJECT_PATH" ] && rm -rf "$PROJECT_PATH"
+ exit 1
+}
+
+function replace {
+ local pattern=$1
+ local filename=$2
+ # Mac OS X requires -i argument
+ if [[ "$OSTYPE" =~ "darwin" ]]
+ then
+ /usr/bin/sed -i '' -e $pattern "$filename"
+ elif [[ "$OSTYPE" =~ "linux" ]]
+ then
+ /bin/sed -i -e $pattern "$filename"
+ fi
+}
+
+# we do not want the script to silently fail
+trap 'previous_command=$this_command; this_command=$BASH_COMMAND' DEBUG
+trap on_error ERR
+trap on_exit EXIT
+
+ANDROID_BIN="${ANDROID_BIN:=$( which android )}"
+
+TARGET=$("$ANDROID_BIN" list targets | grep id: | tail -1 | cut -f 2 -d ' ' )
+API_LEVEL=$("$ANDROID_BIN" list target | grep "API level:" | tail -n 1 | cut -f 2 -d ':' | tr -d ' ')
+
+# check that build targets exist
+if [ -z "$TARGET" ] || [ -z "$API_LEVEL" ]
+then
+ echo "No Android Targets are installed. Please install at least one via the android SDK"
+ exit 1
+fi
+
+# if this a distribution release no need to build a jar
+if [ ! -e "$BUILD_PATH"/cordova-$VERSION.jar ] && [ -d "$BUILD_PATH"/framework ]
+then
+# update the cordova-android framework for the desired target
+ "$ANDROID_BIN" update project --target $TARGET --path "$BUILD_PATH"/framework &> /dev/null
+
+ if [ ! -e "$BUILD_PATH"/framework/libs/commons-codec-1.7.jar ]; then
+ # Use curl to get the jar (TODO: Support Apache Mirrors)
+ curl -OL http://archive.apache.org/dist/commons/codec/binaries/commons-codec-1.7-bin.zip &> /dev/null
+ unzip commons-codec-1.7-bin.zip &> /dev/null
+ mkdir -p "$BUILD_PATH"/framework/libs
+ cp commons-codec-1.7/commons-codec-1.7.jar "$BUILD_PATH"/framework/libs
+ # cleanup yo
+ rm commons-codec-1.7-bin.zip && rm -rf commons-codec-1.7
+ fi
+
+# compile cordova.js and cordova.jar
+ (cd "$BUILD_PATH"/framework && ant jar &> /dev/null )
+fi
+
+# copy cordova.js, cordova.jar and res/xml
+if [ -d "$BUILD_PATH"/framework ]
+then
+ cp "$BUILD_PATH"/framework/assets/www/cordova-$VERSION.js "$PROJECT_PATH"/assets/www/cordova-$VERSION.js
+ cp "$BUILD_PATH"/framework/cordova-$VERSION.jar "$PROJECT_PATH"/libs/cordova-$VERSION.jar
+else
+ cp "$BUILD_PATH"/cordova-$VERSION.js "$PROJECT_PATH"/assets/www/cordova-$VERSION.js
+ cp "$BUILD_PATH"/cordova-$VERSION.jar "$PROJECT_PATH"/libs/cordova-$VERSION.jar
+fi
+
+# creating cordova folder and copying run/build/log/launch scripts
+cp "$BUILD_PATH"/bin/templates/cordova/appinfo.jar "$PROJECT_PATH"/cordova/appinfo.jar
+cp "$BUILD_PATH"/bin/templates/cordova/cordova "$PROJECT_PATH"/cordova/cordova
+cp "$BUILD_PATH"/bin/templates/cordova/build "$PROJECT_PATH"/cordova/build
+cp "$BUILD_PATH"/bin/templates/cordova/release "$PROJECT_PATH"/cordova/release
+cp "$BUILD_PATH"/bin/templates/cordova/clean "$PROJECT_PATH"/cordova/clean
+cp "$BUILD_PATH"/bin/templates/cordova/log "$PROJECT_PATH"/cordova/log
+cp "$BUILD_PATH"/bin/templates/cordova/run "$PROJECT_PATH"/cordova/run
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/bin/update.bat
----------------------------------------------------------------------
diff --git a/lib/cordova-android/bin/update.bat b/lib/cordova-android/bin/update.bat
new file mode 100644
index 0000000..a61fd26
--- /dev/null
+++ b/lib/cordova-android/bin/update.bat
@@ -0,0 +1,32 @@
+:: 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.
+
+@ECHO OFF
+IF NOT DEFINED JAVA_HOME GOTO MISSING
+FOR %%X in (java.exe javac.exe ant.bat android.bat) do (
+ SET FOUND=%%~$PATH:X
+ IF NOT DEFINED FOUND GOTO MISSING
+)
+cscript "%~dp0\update.js" %*
+GOTO END
+:MISSING
+ECHO Missing one of the following:
+ECHO JDK: http://java.oracle.com
+ECHO Android SDK: http://developer.android.com
+ECHO Apache ant: http://ant.apache.org
+EXIT /B 1
+:END
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/bin/update.js
----------------------------------------------------------------------
diff --git a/lib/cordova-android/bin/update.js b/lib/cordova-android/bin/update.js
new file mode 100644
index 0000000..244dcc1
--- /dev/null
+++ b/lib/cordova-android/bin/update.js
@@ -0,0 +1,193 @@
+/*
+ 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.
+*/
+
+/*
+ * create a cordova/android project
+ *
+ * USAGE
+ * ./update [path]
+ */
+
+var fso = WScript.CreateObject('Scripting.FileSystemObject');
+
+function read(filename) {
+ var fso=WScript.CreateObject("Scripting.FileSystemObject");
+ var f=fso.OpenTextFile(filename, 1);
+ var s=f.ReadAll();
+ f.Close();
+ return s;
+}
+
+function checkTargets(targets) {
+ if(!targets) {
+ WScript.Echo("You do not have any android targets setup. Please create at least one target with the `android` command");
+ WScript.Quit(69);
+ }
+}
+
+function setTarget() {
+ var targets = shell.Exec('android.bat list targets').StdOut.ReadAll().match(/id:\s\d+/g);
+ checkTargets(targets);
+ return targets[targets.length - 1].replace(/id: /, ""); // TODO: give users the option to set their target
+}
+
+function setApiLevel() {
+ var targets = shell.Exec('android.bat list targets').StdOut.ReadAll().match(/API level:\s\d+/g);
+ checkTargets(targets);
+ return targets[targets.length - 1].replace(/API level: /, "");
+}
+
+function write(filename, contents) {
+ var fso=WScript.CreateObject("Scripting.FileSystemObject");
+ var f=fso.OpenTextFile(filename, 2, true);
+ f.Write(contents);
+ f.Close();
+}
+
+function replaceInFile(filename, regexp, replacement) {
+ write(filename, read(filename).replace(regexp, replacement));
+}
+
+function exec(command) {
+ var oShell=shell.Exec(command);
+ while (oShell.Status == 0) {
+ if(!oShell.StdOut.AtEndOfStream) {
+ var line = oShell.StdOut.ReadLine();
+ // XXX: Change to verbose mode
+ // WScript.StdOut.WriteLine(line);
+ }
+ WScript.sleep(100);
+ }
+}
+
+function createAppInfoJar() {
+ if(!fso.FileExists(ROOT+"\\bin\\templates\\cordova\\appinfo.jar")) {
+ WScript.Echo("Creating appinfo.jar...");
+ var cur = shell.CurrentDirectory;
+ shell.CurrentDirectory = ROOT+"\\bin\\templates\\cordova\\ApplicationInfo";
+ exec("javac ApplicationInfo.java");
+ exec("jar -cfe ..\\appinfo.jar ApplicationInfo ApplicationInfo.class");
+ shell.CurrentDirectory = cur;
+ }
+}
+
+function cleanup() {
+ if(fso.FileExists(ROOT + '\\framework\\cordova-'+VERSION+'.jar')) {
+ fso.DeleteFile(ROOT + '\\framework\\cordova-'+VERSION+'.jar');
+ }
+ if(fso.FileExists(ROOT + '\\framework\\assets\\www\\cordova-'+VERSION+'.js')) {
+ fso.DeleteFile(ROOT + '\\framework\\assets\\www\\cordova-'+VERSION+'.js');
+ }
+}
+
+function downloadCommonsCodec() {
+ if (!fso.FileExists(ROOT + '\\framework\\libs\\commons-codec-1.7.jar')) {
+ // We need the .jar
+ var url = 'http://archive.apache.org/dist/commons/codec/binaries/commons-codec-1.7-bin.zip';
+ var libsPath = ROOT + '\\framework\\libs';
+ var savePath = libsPath + '\\commons-codec-1.7-bin.zip';
+ if (!fso.FileExists(savePath)) {
+ if(!fso.FolderExists(ROOT + '\\framework\\libs')) {
+ fso.CreateFolder(libsPath);
+ }
+ // We need the zip to get the jar
+ var xhr = WScript.CreateObject('MSXML2.XMLHTTP');
+ xhr.open('GET', url, false);
+ xhr.send();
+ if (xhr.status == 200) {
+ var stream = WScript.CreateObject('ADODB.Stream');
+ stream.Open();
+ stream.Type = 1;
+ stream.Write(xhr.ResponseBody);
+ stream.Position = 0;
+ stream.SaveToFile(savePath);
+ stream.Close();
+ } else {
+ WScript.Echo('Could not retrieve the commons-codec. Please download it yourself and put into the framework/libs directory. This process may fail now. Sorry.');
+ }
+ }
+ var app = WScript.CreateObject('Shell.Application');
+ var source = app.NameSpace(savePath).Items();
+ var target = app.NameSpace(ROOT + '\\framework\\libs');
+ target.CopyHere(source, 256);
+
+ // Move the jar into libs
+ fso.MoveFile(ROOT + '\\framework\\libs\\commons-codec-1.7\\commons-codec-1.7.jar', ROOT + '\\framework\\libs\\commons-codec-1.7.jar');
+
+ // Clean up
+ fso.DeleteFile(ROOT + '\\framework\\libs\\commons-codec-1.7-bin.zip');
+ fso.DeleteFolder(ROOT + '\\framework\\libs\\commons-codec-1.7', true);
+ }
+}
+
+var args = WScript.Arguments, PROJECT_PATH="example",
+ shell=WScript.CreateObject("WScript.Shell");
+
+// working dir
+var ROOT = WScript.ScriptFullName.split('\\bin\\update.js').join('');
+
+if (args.Count() == 1) {
+ PROJECT_PATH=args(0);
+}
+
+if(!fso.FolderExists(PROJECT_PATH)) {
+ WScript.Echo("Project doesn't exist!");
+ WScript.Quit(1);
+}
+
+var TARGET=setTarget();
+var API_LEVEL=setApiLevel();
+var VERSION=read(ROOT+'\\VERSION').replace(/\r\n/,'').replace(/\n/,'');
+
+// build from source. distro should have these files
+if (!fso.FileExists(ROOT+'\\cordova-'+VERSION+'.jar') &&
+ !fso.FileExists(ROOT+'\\cordova-'+VERSION+'.js')) {
+ WScript.Echo("Building jar and js files...");
+ // update the cordova framework project to a target that exists on this machine
+ exec('android.bat update project --target '+TARGET+' --path '+ROOT+'\\framework');
+ // pull down commons codec if necessary
+ downloadCommonsCodec();
+ exec('ant.bat -f \"'+ ROOT +'\\framework\\build.xml\" jar');
+}
+
+// check if we have the source or the distro files
+WScript.Echo("Copying js, jar & config.xml files...");
+if(fso.FolderExists(ROOT + '\\framework')) {
+ exec('%comspec% /c copy "'+ROOT+'"\\framework\\assets\\www\\cordova-'+VERSION+'.js '+PROJECT_PATH+'\\assets\\www\\cordova-'+VERSION+'.js /Y');
+ exec('%comspec% /c copy "'+ROOT+'"\\framework\\cordova-'+VERSION+'.jar '+PROJECT_PATH+'\\libs\\cordova-'+VERSION+'.jar /Y');
+} else {
+ // copy in cordova.js
+ exec('%comspec% /c copy "'+ROOT+'"\\cordova-'+VERSION+'.js '+PROJECT_PATH+'\\assets\\www\\cordova-'+VERSION+'.js /Y');
+ // copy in cordova.jar
+ exec('%comspec% /c copy "'+ROOT+'"\\cordova-'+VERSION+'.jar '+PROJECT_PATH+'\\libs\\cordova-'+VERSION+'.jar /Y');
+ // copy in xml
+}
+
+// update cordova scripts
+createAppInfoJar();
+WScript.Echo("Copying cordova command tools...");
+exec('%comspec% /c copy "'+ROOT+'"\\bin\\templates\\cordova\\appinfo.jar ' + PROJECT_PATH + '\\cordova\\appinfo.jar /Y');
+exec('%comspec% /c copy "'+ROOT+'"\\bin\\templates\\cordova\\cordova.js ' + PROJECT_PATH + '\\cordova\\cordova.js /Y');
+exec('%comspec% /c copy "'+ROOT+'"\\bin\\templates\\cordova\\cordova.bat ' + PROJECT_PATH + '\\cordova\\cordova.bat /Y');
+exec('%comspec% /c copy "'+ROOT+'"\\bin\\templates\\cordova\\clean.bat ' + PROJECT_PATH + '\\cordova\\clean.bat /Y');
+exec('%comspec% /c copy "'+ROOT+'"\\bin\\templates\\cordova\\build.bat ' + PROJECT_PATH + '\\cordova\\build.bat /Y');
+exec('%comspec% /c copy "'+ROOT+'"\\bin\\templates\\cordova\\log.bat ' + PROJECT_PATH + '\\cordova\\log.bat /Y');
+exec('%comspec% /c copy "'+ROOT+'"\\bin\\templates\\cordova\\run.bat ' + PROJECT_PATH + '\\cordova\\run.bat /Y');
+
+cleanup();
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/framework/assets/js/cordova.android.js
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/assets/js/cordova.android.js b/lib/cordova-android/framework/assets/js/cordova.android.js
index bfd6545..a0c3278 100644
--- a/lib/cordova-android/framework/assets/js/cordova.android.js
+++ b/lib/cordova-android/framework/assets/js/cordova.android.js
@@ -1,8 +1,8 @@
// Platform: android
-// commit f50d20a87431c79a54572263729461883f611a53
+// commit 47593b2bc1dba9bf46545b1da24577f937966e12
-// File generated at :: Tue Feb 26 2013 13:37:51 GMT-0800 (PST)
+// File generated at :: Thu Mar 21 2013 10:49:00 GMT-0700 (PDT)
/*
Licensed to the Apache Software Foundation (ASF) under one
@@ -262,7 +262,7 @@ var cordova = {
*/
callbackSuccess: function(callbackId, args) {
try {
- cordova.callbackFromNative(callbackId, true, args.status, args.message, args.keepCallback);
+ cordova.callbackFromNative(callbackId, true, args.status, [args.message], args.keepCallback);
} catch (e) {
console.log("Error in error callback: " + callbackId + " = "+e);
}
@@ -275,7 +275,7 @@ var cordova = {
// TODO: Deprecate callbackSuccess and callbackError in favour of callbackFromNative.
// Derive success from status.
try {
- cordova.callbackFromNative(callbackId, false, args.status, args.message, args.keepCallback);
+ cordova.callbackFromNative(callbackId, false, args.status, [args.message], args.keepCallback);
} catch (e) {
console.log("Error in error callback: " + callbackId + " = "+e);
}
@@ -284,13 +284,13 @@ var cordova = {
/**
* Called by native code when returning the result from an action.
*/
- callbackFromNative: function(callbackId, success, status, message, keepCallback) {
+ callbackFromNative: function(callbackId, success, status, args, keepCallback) {
var callback = cordova.callbacks[callbackId];
if (callback) {
if (success && status == cordova.callbackStatus.OK) {
- callback.success && callback.success(message);
+ callback.success && callback.success.apply(null, args);
} else if (!success) {
- callback.fail && callback.fail(message);
+ callback.fail && callback.fail.apply(null, args);
}
// Clear callback if not expecting any more results
@@ -724,6 +724,9 @@ channel.createSticky('onCordovaInfoReady');
// Event to indicate that the connection property has been set.
channel.createSticky('onCordovaConnectionReady');
+// Event to indicate that all automatically loaded JS plugins are loaded and ready.
+channel.createSticky('onPluginsReady');
+
// Event to indicate that Cordova is ready
channel.createSticky('onDeviceReady');
@@ -900,7 +903,7 @@ androidExec.nativeToJsModes = nativeToJsModes;
androidExec.setJsToNativeBridgeMode = function(mode) {
if (mode == jsToNativeModes.JS_OBJECT && !window._cordovaNative) {
- console.log('Falling back on PROMPT mode since _cordovaNative is missing.');
+ console.log('Falling back on PROMPT mode since _cordovaNative is missing. Expected for Android 3.2 and lower only.');
mode = jsToNativeModes.PROMPT;
}
nativeApiProvider.setPreferPrompt(mode == jsToNativeModes.PROMPT);
@@ -958,10 +961,12 @@ function processMessage(message) {
arraybuffer[i] = bytes.charCodeAt(i);
}
payload = arraybuffer.buffer;
+ } else if (payloadKind == 'S') {
+ payload = window.atob(message.slice(nextSpaceIdx + 2));
} else {
payload = JSON.parse(message.slice(nextSpaceIdx + 1));
}
- cordova.callbackFromNative(callbackId, success, status, payload, keepCallback);
+ cordova.callbackFromNative(callbackId, success, status, [payload], keepCallback);
} else {
console.log("processMessage failed: invalid message:" + message);
}
@@ -1203,9 +1208,10 @@ cameraExport.getPicture = function(successCallback, errorCallback, options) {
var correctOrientation = !!options.correctOrientation;
var saveToPhotoAlbum = !!options.saveToPhotoAlbum;
var popoverOptions = getValue(options.popoverOptions, null);
+ var cameraDirection = getValue(options.cameraDirection, Camera.Direction.BACK);
var args = [quality, destinationType, sourceType, targetWidth, targetHeight, encodingType,
- mediaType, allowEdit, correctOrientation, saveToPhotoAlbum, popoverOptions];
+ mediaType, allowEdit, correctOrientation, saveToPhotoAlbum, popoverOptions, cameraDirection];
exec(successCallback, errorCallback, "Camera", "takePicture", args);
return new CameraPopoverHandle();
@@ -1248,6 +1254,10 @@ module.exports = {
ARROW_LEFT : 4,
ARROW_RIGHT : 8,
ARROW_ANY : 15
+ },
+ Direction:{
+ BACK: 0,
+ FRONT: 1
}
};
@@ -2439,14 +2449,7 @@ FileReader.prototype.readAsText = function(file, encoding) {
// Default encoding is UTF-8
var enc = encoding ? encoding : "UTF-8";
var me = this;
- var execArgs = [this._fileName, enc];
-
- // Maybe add slice parameters.
- if (file.end < file.size) {
- execArgs.push(file.start, file.end);
- } else if (file.start > 0) {
- execArgs.push(file.start);
- }
+ var execArgs = [this._fileName, enc, file.start, file.end];
// Read file
exec(
@@ -2515,14 +2518,7 @@ FileReader.prototype.readAsDataURL = function(file) {
}
var me = this;
- var execArgs = [this._fileName];
-
- // Maybe add slice parameters.
- if (file.end < file.size) {
- execArgs.push(file.start, file.end);
- } else if (file.start > 0) {
- execArgs.push(file.start);
- }
+ var execArgs = [this._fileName, file.start, file.end];
// Read file
exec(
@@ -2585,9 +2581,59 @@ FileReader.prototype.readAsBinaryString = function(file) {
if (initRead(this, file)) {
return this._realReader.readAsBinaryString(file);
}
- // TODO - Can't return binary data to browser.
- console.log('method "readAsBinaryString" is not supported at this time.');
- this.abort();
+
+ var me = this;
+ var execArgs = [this._fileName, file.start, file.end];
+
+ // Read file
+ exec(
+ // Success callback
+ function(r) {
+ // If DONE (cancelled), then don't do anything
+ if (me._readyState === FileReader.DONE) {
+ return;
+ }
+
+ // DONE state
+ me._readyState = FileReader.DONE;
+
+ me._result = r;
+
+ // If onload callback
+ if (typeof me.onload === "function") {
+ me.onload(new ProgressEvent("load", {target:me}));
+ }
+
+ // If onloadend callback
+ if (typeof me.onloadend === "function") {
+ me.onloadend(new ProgressEvent("loadend", {target:me}));
+ }
+ },
+ // Error callback
+ function(e) {
+ // If DONE (cancelled), then don't do anything
+ if (me._readyState === FileReader.DONE) {
+ return;
+ }
+
+ // DONE state
+ me._readyState = FileReader.DONE;
+
+ me._result = null;
+
+ // Save error
+ me._error = new FileError(e);
+
+ // If onerror callback
+ if (typeof me.onerror === "function") {
+ me.onerror(new ProgressEvent("error", {target:me}));
+ }
+
+ // If onloadend callback
+ if (typeof me.onloadend === "function") {
+ me.onloadend(new ProgressEvent("loadend", {target:me}));
+ }
+ }, "File", "readAsBinaryString", execArgs);
};
/**
@@ -2599,9 +2645,59 @@ FileReader.prototype.readAsArrayBuffer = function(file) {
if (initRead(this, file)) {
return this._realReader.readAsArrayBuffer(file);
}
- // TODO - Can't return binary data to browser.
- console.log('This method is not supported at this time.');
- this.abort();
+
+ var me = this;
+ var execArgs = [this._fileName, file.start, file.end];
+
+ // Read file
+ exec(
+ // Success callback
+ function(r) {
+ // If DONE (cancelled), then don't do anything
+ if (me._readyState === FileReader.DONE) {
+ return;
+ }
+
+ // DONE state
+ me._readyState = FileReader.DONE;
+
+ me._result = r;
+
+ // If onload callback
+ if (typeof me.onload === "function") {
+ me.onload(new ProgressEvent("load", {target:me}));
+ }
+
+ // If onloadend callback
+ if (typeof me.onloadend === "function") {
+ me.onloadend(new ProgressEvent("loadend", {target:me}));
+ }
+ },
+ // Error callback
+ function(e) {
+ // If DONE (cancelled), then don't do anything
+ if (me._readyState === FileReader.DONE) {
+ return;
+ }
+
+ // DONE state
+ me._readyState = FileReader.DONE;
+
+ me._result = null;
+
+ // Save error
+ me._error = new FileError(e);
+
+ // If onerror callback
+ if (typeof me.onerror === "function") {
+ me.onerror(new ProgressEvent("error", {target:me}));
+ }
+
+ // If onloadend callback
+ if (typeof me.onloadend === "function") {
+ me.onloadend(new ProgressEvent("loadend", {target:me}));
+ }
+ }, "File", "readAsArrayBuffer", execArgs);
};
module.exports = FileReader;
@@ -2647,6 +2743,38 @@ function newProgressEvent(result) {
return pe;
}
+function getBasicAuthHeader(urlString) {
+ var header = null;
+
+ if (window.btoa) {
+ // parse the url using the Location object
+ var url = document.createElement('a');
+ url.href = urlString;
+
+ var credentials = null;
+ var protocol = url.protocol + "//";
+ var origin = protocol + url.host;
+
+ // check whether there are the username:password credentials in the url
+ if (url.href.indexOf(origin) != 0) { // credentials found
+ var atIndex = url.href.indexOf("@");
+ credentials = url.href.substring(protocol.length, atIndex);
+ }
+
+ if (credentials) {
+ var authHeader = "Authorization";
+ var authHeaderValue = "Basic " + window.btoa(credentials);
+
+ header = {
+ name : authHeader,
+ value : authHeaderValue
+ };
+ }
+ }
+
+ return header;
+}
+
var idCounter = 0;
/**
@@ -2677,6 +2805,18 @@ FileTransfer.prototype.upload = function(filePath, server, successCallback, erro
var params = null;
var chunkedMode = true;
var headers = null;
+
+ var basicAuthHeader = getBasicAuthHeader(server);
+ if (basicAuthHeader) {
+ if (!options) {
+ options = new FileUploadOptions();
+ }
+ if (!options.headers) {
+ options.headers = {};
+ }
+ options.headers[basicAuthHeader.name] = basicAuthHeader.value;
+ }
+
if (options) {
fileKey = options.fileKey;
fileName = options.fileName;
@@ -2694,7 +2834,7 @@ FileTransfer.prototype.upload = function(filePath, server, successCallback, erro
}
var fail = errorCallback && function(e) {
- var error = new FileTransferError(e.code, e.source, e.target, e.http_status);
+ var error = new FileTransferError(e.code, e.source, e.target, e.http_status, e.body);
errorCallback(error);
};
@@ -2718,10 +2858,28 @@ FileTransfer.prototype.upload = function(filePath, server, successCallback, erro
* @param successCallback (Function} Callback to be invoked when upload has completed
* @param errorCallback {Function} Callback to be invoked upon error
* @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false
+ * @param options {FileDownloadOptions} Optional parameters such as headers
*/
-FileTransfer.prototype.download = function(source, target, successCallback, errorCallback, trustAllHosts) {
+FileTransfer.prototype.download = function(source, target, successCallback, errorCallback, trustAllHosts, options) {
argscheck.checkArgs('ssFF*', 'FileTransfer.download', arguments);
var self = this;
+
+ var basicAuthHeader = getBasicAuthHeader(source);
+ if (basicAuthHeader) {
+ if (!options) {
+ options = {};
+ }
+ if (!options.headers) {
+ options.headers = {};
+ }
+ options.headers[basicAuthHeader.name] = basicAuthHeader.value;
+ }
+
+ var headers = null;
+ if (options) {
+ headers = options.headers || null;
+ }
+
var win = function(result) {
if (typeof result.lengthComputable != "undefined") {
if (self.onprogress) {
@@ -2744,11 +2902,11 @@ FileTransfer.prototype.download = function(source, target, successCallback, erro
};
var fail = errorCallback && function(e) {
- var error = new FileTransferError(e.code, e.source, e.target, e.http_status);
+ var error = new FileTransferError(e.code, e.source, e.target, e.http_status, e.body);
errorCallback(error);
};
- exec(win, fail, 'FileTransfer', 'download', [source, target, trustAllHosts, this._id]);
+ exec(win, fail, 'FileTransfer', 'download', [source, target, trustAllHosts, this._id, headers]);
};
/**
@@ -3146,6 +3304,7 @@ function InAppBrowser() {
this.channels = {
'loadstart': channel.create('loadstart'),
'loadstop' : channel.create('loadstop'),
+ 'loaderror' : channel.create('loaderror'),
'exit' : channel.create('exit')
};
}
@@ -3176,7 +3335,7 @@ module.exports = function(strUrl, strWindowName, strWindowFeatures) {
var cb = function(eventname) {
iab._eventHandler(eventname);
};
- exec(cb, null, "InAppBrowser", "open", [strUrl, strWindowName, strWindowFeatures]);
+ exec(cb, cb, "InAppBrowser", "open", [strUrl, strWindowName, strWindowFeatures]);
return iab;
};
@@ -4940,7 +5099,8 @@ modulemapper.merges('cordova/plugin/android/device', 'device');
// file: lib/common/plugin/echo.js
define("cordova/plugin/echo", function(require, exports, module) {
-var exec = require('cordova/exec');
+var exec = require('cordova/exec'),
+ utils = require('cordova/utils');
/**
* Sends the given message through exec() to the Echo plugin, which sends it back to the successCallback.
@@ -4950,11 +5110,25 @@ var exec = require('cordova/exec');
* @param forceAsync Whether to force an async return value (for testing native->js bridge).
*/
module.exports = function(successCallback, errorCallback, message, forceAsync) {
- var action = forceAsync ? 'echoAsync' : 'echo';
- if (!forceAsync && message.constructor == ArrayBuffer) {
- action = 'echoArrayBuffer';
+ var action = 'echo';
+ var messageIsMultipart = (utils.typeName(message) == "Array");
+ var args = messageIsMultipart ? message : [message];
+
+ if (utils.typeName(message) == 'ArrayBuffer') {
+ if (forceAsync) {
+ console.warn('Cannot echo ArrayBuffer with forced async, falling back to sync.');
+ }
+ action += 'ArrayBuffer';
+ } else if (messageIsMultipart) {
+ if (forceAsync) {
+ console.warn('Cannot echo MultiPart Array with forced async, falling back to sync.');
+ }
+ action += 'MultiPart';
+ } else if (forceAsync) {
+ action += 'Async';
}
- exec(successCallback, errorCallback, "Echo", action, [message]);
+
+ exec(successCallback, errorCallback, "Echo", action, args);
};
@@ -5950,6 +6124,7 @@ modulemapper.defaults('cordova/plugin/Connection', 'Connection');
define("cordova/plugin/notification", function(require, exports, module) {
var exec = require('cordova/exec');
+var platform = require('cordova/platform');
/**
* Provides access to notifications on the device.
@@ -5978,15 +6153,53 @@ module.exports = {
* @param {String} message Message to print in the body of the alert
* @param {Function} resultCallback The callback that is called when user clicks on a button.
* @param {String} title Title of the alert dialog (default: Confirm)
- * @param {String} buttonLabels Comma separated list of the labels of the buttons (default: 'OK,Cancel')
+ * @param {Array} buttonLabels Array of the labels of the buttons (default: ['OK', 'Cancel'])
*/
confirm: function(message, resultCallback, title, buttonLabels) {
var _title = (title || "Confirm");
- var _buttonLabels = (buttonLabels || "OK,Cancel");
+ var _buttonLabels = (buttonLabels || ["OK", "Cancel"]);
+
+ // Strings are deprecated!
+ if (typeof _buttonLabels === 'string') {
+ console.log("Notification.confirm(string, function, string, string) is deprecated. Use Notification.confirm(string, function, string, array).");
+ }
+
+ // Android and iOS take an array of button label names.
+ // Other platforms take a comma separated list.
+ // For compatibility, we convert to the desired type based on the platform.
+ if (platform.id == "android" || platform.id == "ios") {
+ if (typeof _buttonLabels === 'string') {
+ var buttonLabelString = _buttonLabels;
+ _buttonLabels = buttonLabelString.split(",");
+ }
+ } else {
+ if (Array.isArray(_buttonLabels)) {
+ var buttonLabelArray = _buttonLabels;
+ _buttonLabels = buttonLabelArray.toString();
+ }
+ }
exec(resultCallback, null, "Notification", "confirm", [message, _title, _buttonLabels]);
},
/**
+ * Open a native prompt dialog, with a customizable title and button text.
+ * The following results are returned to the result callback:
+ * buttonIndex Index number of the button selected.
+ * input1 The text entered in the prompt dialog box.
+ *
+ * @param {String} message Dialog message to display (default: "Prompt message")
+ * @param {Function} resultCallback The callback that is called when user clicks on a button.
+ * @param {String} title Title of the dialog (default: "Prompt")
+ * @param {Array} buttonLabels Array of strings for the button labels (default: ["OK","Cancel"])
+ */
+ prompt: function(message, resultCallback, title, buttonLabels) {
+ var _message = (message || "Prompt message");
+ var _title = (title || "Prompt");
+ var _buttonLabels = (buttonLabels || ["OK","Cancel"]);
+ exec(resultCallback, null, "Notification", "prompt", [_message, _title, _buttonLabels]);
+ },
+
+ /**
* Causes the device to vibrate.
*
* @param {Integer} mills The number of milliseconds to vibrate for.
@@ -6409,53 +6622,160 @@ window.cordova = require('cordova');
(function (context) {
// Replace navigator before any modules are required(), to ensure it happens as soon as possible.
// We replace it so that properties that can't be clobbered can instead be overridden.
- if (context.navigator) {
+ function replaceNavigator(origNavigator) {
var CordovaNavigator = function() {};
- CordovaNavigator.prototype = context.navigator;
- context.navigator = new CordovaNavigator();
+ CordovaNavigator.prototype = origNavigator;
+ var newNavigator = new CordovaNavigator();
+ // This work-around really only applies to new APIs that are newer than Function.bind.
+ // Without it, APIs such as getGamepads() break.
+ if (CordovaNavigator.bind) {
+ for (var key in origNavigator) {
+ if (typeof origNavigator[key] == 'function') {
+ newNavigator[key] = origNavigator[key].bind(origNavigator);
+ }
+ }
+ }
+ return newNavigator;
}
+ if (context.navigator) {
+ context.navigator = replaceNavigator(context.navigator);
+ }
+
+ var channel = require("cordova/channel");
+
+ // _nativeReady is global variable that the native side can set
+ // to signify that the native code is ready. It is a global since
+ // it may be called before any cordova JS is ready.
+ if (window._nativeReady) {
+ channel.onNativeReady.fire();
+ }
+
+ /**
+ * Create all cordova objects once page has fully loaded and native side is ready.
+ */
+ channel.join(function() {
+ var builder = require('cordova/builder'),
+ platform = require('cordova/platform');
+
+ builder.buildIntoButDoNotClobber(platform.defaults, context);
+ builder.buildIntoAndClobber(platform.clobbers, context);
+ builder.buildIntoAndMerge(platform.merges, context);
+
+ // Call the platform-specific initialization
+ platform.initialize();
+
+ // Fire event to notify that all objects are created
+ channel.onCordovaReady.fire();
+
+ // Fire onDeviceReady event once all constructors have run and
+ // cordova info has been received from native side.
+ channel.join(function() {
+ require('cordova').fireDocumentEvent('deviceready');
+ }, channel.deviceReadyChannelsArray);
+
+ }, [ channel.onDOMContentLoaded, channel.onNativeReady, channel.onPluginsReady ]);
- var channel = require("cordova/channel"),
- _self = {
- boot: function () {
- /**
- * Create all cordova objects once page has fully loaded and native side is ready.
- */
- channel.join(function() {
- var builder = require('cordova/builder'),
- platform = require('cordova/platform');
+}(window));
- builder.buildIntoButDoNotClobber(platform.defaults, context);
- builder.buildIntoAndClobber(platform.clobbers, context);
- builder.buildIntoAndMerge(platform.merges, context);
+// file: lib/scripts/plugin_loader.js
- // Call the platform-specific initialization
- platform.initialize();
+// Tries to load all plugins' js-modules.
+// This is an async process, but onDeviceReady is blocked on onPluginsReady.
+// onPluginsReady is fired when there are no plugins to load, or they are all done.
+(function (context) {
+ // To be populated with the handler by handlePluginsObject.
+ var onScriptLoadingComplete;
+
+ var scriptCounter = 0;
+ function scriptLoadedCallback() {
+ scriptCounter--;
+ if (scriptCounter === 0) {
+ onScriptLoadingComplete && onScriptLoadingComplete();
+ }
+ }
- // Fire event to notify that all objects are created
- channel.onCordovaReady.fire();
+ // Helper function to inject a <script> tag.
+ function injectScript(path) {
+ scriptCounter++;
+ var script = document.createElement("script");
+ script.onload = scriptLoadedCallback;
+ script.src = path;
+ document.head.appendChild(script);
+ }
+
+ // Called when:
+ // * There are plugins defined and all plugins are finished loading.
+ // * There are no plugins to load.
+ function finishPluginLoading() {
+ context.cordova.require('cordova/channel').onPluginsReady.fire();
+ }
+
+ // Handler for the cordova_plugins.json content.
+ // See plugman's plugin_loader.js for the details of this object.
+ // This function is only called if the really is a plugins array that isn't empty.
+ // Otherwise the XHR response handler will just call finishPluginLoading().
+ function handlePluginsObject(modules) {
+ // First create the callback for when all plugins are loaded.
+ var mapper = context.cordova.require('cordova/modulemapper');
+ onScriptLoadingComplete = function() {
+ // Loop through all the plugins and then through their clobbers and merges.
+ for (var i = 0; i < modules.length; i++) {
+ var module = modules[i];
+ if (!module) continue;
+
+ if (module.clobbers && module.clobbers.length) {
+ for (var j = 0; j < module.clobbers.length; j++) {
+ mapper.clobbers(module.id, module.clobbers[j]);
+ }
+ }
- // Fire onDeviceReady event once all constructors have run and
- // cordova info has been received from native side.
- channel.join(function() {
- require('cordova').fireDocumentEvent('deviceready');
- }, channel.deviceReadyChannelsArray);
+ if (module.merges && module.merges.length) {
+ for (var k = 0; k < module.merges.length; k++) {
+ mapper.merges(module.id, module.merges[k]);
+ }
+ }
- }, [ channel.onDOMContentLoaded, channel.onNativeReady ]);
+ // Finally, if runs is truthy we want to simply require() the module.
+ // This can be skipped if it had any merges or clobbers, though,
+ // since the mapper will already have required the module.
+ if (module.runs && !(module.clobbers && module.clobbers.length) && !(module.merges && module.merges.length)) {
+ context.cordova.require(module.id);
+ }
}
- };
- // boot up once native side is ready
- channel.onNativeReady.subscribe(_self.boot);
+ finishPluginLoading();
+ };
- // _nativeReady is global variable that the native side can set
- // to signify that the native code is ready. It is a global since
- // it may be called before any cordova JS is ready.
- if (window._nativeReady) {
- channel.onNativeReady.fire();
+ // Now inject the scripts.
+ for (var i = 0; i < modules.length; i++) {
+ injectScript(modules[i].file);
+ }
}
+ // Try to XHR the cordova_plugins.json file asynchronously.
+ var xhr = new context.XMLHttpRequest();
+ xhr.onreadystatechange = function() {
+ if (this.readyState != 4) { // not DONE
+ return;
+ }
+
+ // If the response is a JSON string which composes an array, call handlePluginsObject.
+ // If the request fails, or the response is not a JSON array, just call finishPluginLoading.
+ if (this.status == 200) {
+ var obj = JSON.parse(this.responseText);
+ if (obj && obj instanceof Array && obj.length > 0) {
+ handlePluginsObject(obj);
+ } else {
+ finishPluginLoading();
+ }
+ } else {
+ finishPluginLoading();
+ }
+ };
+ xhr.open('GET', 'cordova_plugins.json', true); // Async
+ xhr.send();
}(window));
+
})();
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/framework/assets/www/index.html
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/assets/www/index.html b/lib/cordova-android/framework/assets/www/index.html
index a10905d..3b15a4e 100644
--- a/lib/cordova-android/framework/assets/www/index.html
+++ b/lib/cordova-android/framework/assets/www/index.html
@@ -19,7 +19,7 @@
<html>
<head>
<title></title>
- <script src="cordova-2.5.0.js"></script>
+ <script src="cordova-2.6.0rc1.js"></script>
</head>
<body>
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/framework/src/org/apache/cordova/AudioHandler.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/AudioHandler.java b/lib/cordova-android/framework/src/org/apache/cordova/AudioHandler.java
index ed5757f..fd8c9df 100644
--- a/lib/cordova-android/framework/src/org/apache/cordova/AudioHandler.java
+++ b/lib/cordova-android/framework/src/org/apache/cordova/AudioHandler.java
@@ -68,13 +68,13 @@ public class AudioHandler extends CordovaPlugin {
String result = "";
if (action.equals("startRecordingAudio")) {
- this.startRecordingAudio(args.getString(0), FileUtils.stripFileProtocol(args.getString(1)));
+ this.startRecordingAudio(args.getString(0), FileHelper.stripFileProtocol(args.getString(1)));
}
else if (action.equals("stopRecordingAudio")) {
this.stopRecordingAudio(args.getString(0));
}
else if (action.equals("startPlayingAudio")) {
- this.startPlayingAudio(args.getString(0), FileUtils.stripFileProtocol(args.getString(1)));
+ this.startPlayingAudio(args.getString(0), FileHelper.stripFileProtocol(args.getString(1)));
}
else if (action.equals("seekToAudio")) {
this.seekToAudio(args.getString(0), args.getInt(1));
@@ -102,7 +102,7 @@ public class AudioHandler extends CordovaPlugin {
}
else if (action.equals("create")) {
String id = args.getString(0);
- String src = FileUtils.stripFileProtocol(args.getString(1));
+ String src = FileHelper.stripFileProtocol(args.getString(1));
AudioPlayer audio = new AudioPlayer(this, id, src);
this.players.put(id, audio);
}
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/framework/src/org/apache/cordova/AudioPlayer.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/AudioPlayer.java b/lib/cordova-android/framework/src/org/apache/cordova/AudioPlayer.java
index 99dbb3d..0170728 100644
--- a/lib/cordova-android/framework/src/org/apache/cordova/AudioPlayer.java
+++ b/lib/cordova-android/framework/src/org/apache/cordova/AudioPlayer.java
@@ -167,13 +167,18 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
public void moveFile(String file) {
/* this is a hack to save the file as the specified name */
File f = new File(this.tempFile);
- if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
- f.renameTo(new File(Environment.getExternalStorageDirectory().getAbsolutePath()
- + File.separator + file));
- } else {
- f.renameTo(new File("/data/data/" + handler.cordova.getActivity().getPackageName() + "/cache/" + file));
+
+ if (!file.startsWith("/")) {
+ if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
+ file = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + file;
+ } else {
+ file = "/data/data/" + handler.cordova.getActivity().getPackageName() + "/cache/" + file;
+ }
}
+ String logMsg = "renaming " + this.tempFile + " to " + file;
+ Log.d(LOG_TAG, logMsg);
+ if (!f.renameTo(new File(file))) Log.e(LOG_TAG, "FAILED " + logMsg);
}
/**
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/framework/src/org/apache/cordova/CameraLauncher.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/CameraLauncher.java b/lib/cordova-android/framework/src/org/apache/cordova/CameraLauncher.java
index aec0def..9473828 100755
--- a/lib/cordova-android/framework/src/org/apache/cordova/CameraLauncher.java
+++ b/lib/cordova-android/framework/src/org/apache/cordova/CameraLauncher.java
@@ -289,7 +289,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
// If sending base64 image back
if (destType == DATA_URL) {
- bitmap = getScaledBitmap(FileUtils.stripFileProtocol(imageUri.toString()));
+ bitmap = getScaledBitmap(FileHelper.stripFileProtocol(imageUri.toString()));
if (bitmap == null) {
// Try to get the bitmap from intent.
bitmap = (Bitmap)intent.getExtras().get("data");
@@ -329,7 +329,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
this.callbackContext.success(uri.toString());
} else {
- bitmap = getScaledBitmap(FileUtils.stripFileProtocol(imageUri.toString()));
+ bitmap = getScaledBitmap(FileHelper.stripFileProtocol(imageUri.toString()));
if (rotate != 0 && this.correctOrientation) {
bitmap = getRotatedBitmap(rotate, bitmap, exif);
@@ -344,7 +344,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
if (this.encodingType == JPEG) {
String exifPath;
if (this.saveToPhotoAlbum) {
- exifPath = FileUtils.getRealPathFromURI(uri, this.cordova);
+ exifPath = FileHelper.getRealPath(uri, this.cordova);
} else {
exifPath = uri.getPath();
}
@@ -395,8 +395,8 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
this.callbackContext.success(uri.toString());
} else {
// Get the path to the image. Makes loading so much easier.
- String imagePath = FileUtils.getRealPathFromURI(uri, this.cordova);
- String mimeType = FileUtils.getMimeType(imagePath);
+ String imagePath = FileHelper.getRealPath(uri, this.cordova);
+ String mimeType = FileHelper.getMimeType(imagePath, this.cordova);
// Log.d(LOG_TAG, "Real path = " + imagePath);
// Log.d(LOG_TAG, "mime type = " + mimeType);
// If we don't have a valid image so quit.
@@ -458,7 +458,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
// Restore exif data to file
if (this.encodingType == JPEG) {
- exif.createOutFile(FileUtils.getRealPathFromURI(uri, this.cordova));
+ exif.createOutFile(FileHelper.getRealPath(uri, this.cordova));
exif.writeExifData();
}
@@ -521,7 +521,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
*/
private void writeUncompressedImage(Uri uri) throws FileNotFoundException,
IOException {
- FileInputStream fis = new FileInputStream(FileUtils.stripFileProtocol(imageUri.toString()));
+ FileInputStream fis = new FileInputStream(FileHelper.stripFileProtocol(imageUri.toString()));
OutputStream os = this.cordova.getActivity().getContentResolver().openOutputStream(uri);
byte[] buffer = new byte[4096];
int len;
@@ -685,7 +685,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
}
// Clean up initial camera-written image file.
- (new File(FileUtils.stripFileProtocol(oldImage.toString()))).delete();
+ (new File(FileHelper.stripFileProtocol(oldImage.toString()))).delete();
checkForDuplicateImage(imageType);
// Scan for the gallery to update pic refs in gallery
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/framework/src/org/apache/cordova/Capture.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/Capture.java b/lib/cordova-android/framework/src/org/apache/cordova/Capture.java
index 3eecf37..5f737ca 100644
--- a/lib/cordova-android/framework/src/org/apache/cordova/Capture.java
+++ b/lib/cordova-android/framework/src/org/apache/cordova/Capture.java
@@ -23,6 +23,7 @@ import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
+import android.os.Build;
import org.apache.cordova.api.CallbackContext;
import org.apache.cordova.api.CordovaPlugin;
import org.apache.cordova.api.LOG;
@@ -128,7 +129,7 @@ public class Capture extends CordovaPlugin {
// If the mimeType isn't set the rest will fail
// so let's see if we can determine it.
if (mimeType == null || mimeType.equals("") || "null".equals(mimeType)) {
- mimeType = FileUtils.getMimeType(filePath);
+ mimeType = FileHelper.getMimeType(filePath, cordova);
}
Log.d(LOG_TAG, "Mime type = " + mimeType);
@@ -155,7 +156,7 @@ public class Capture extends CordovaPlugin {
private JSONObject getImageData(String filePath, JSONObject obj) throws JSONException {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
- BitmapFactory.decodeFile(FileUtils.stripFileProtocol(filePath), options);
+ BitmapFactory.decodeFile(FileHelper.stripFileProtocol(filePath), options);
obj.put("height", options.outHeight);
obj.put("width", options.outWidth);
return obj;
@@ -216,9 +217,10 @@ public class Capture extends CordovaPlugin {
*/
private void captureVideo(double duration) {
Intent intent = new Intent(android.provider.MediaStore.ACTION_VIDEO_CAPTURE);
- // Introduced in API 8
- //intent.putExtra(android.provider.MediaStore.EXTRA_DURATION_LIMIT, duration);
+ if(Build.VERSION.SDK_INT > 8){
+ intent.putExtra("android.intent.extra.durationLimit", duration);
+ }
this.cordova.startActivityForResult((CordovaPlugin) this, intent, CAPTURE_VIDEO);
}
@@ -346,7 +348,7 @@ public class Capture extends CordovaPlugin {
* @throws IOException
*/
private JSONObject createMediaFile(Uri data) {
- File fp = new File(FileUtils.getRealPathFromURI(data, this.cordova));
+ File fp = new File(FileHelper.getRealPath(data, this.cordova));
JSONObject obj = new JSONObject();
try {
@@ -363,7 +365,7 @@ public class Capture extends CordovaPlugin {
obj.put("type", VIDEO_3GPP);
}
} else {
- obj.put("type", FileUtils.getMimeType(fp.getAbsolutePath()));
+ obj.put("type", FileHelper.getMimeType(fp.getAbsolutePath(), cordova));
}
obj.put("lastModifiedDate", fp.lastModified());
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/framework/src/org/apache/cordova/Config.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/Config.java b/lib/cordova-android/framework/src/org/apache/cordova/Config.java
index 01eb2bb..f5de38d 100644
--- a/lib/cordova-android/framework/src/org/apache/cordova/Config.java
+++ b/lib/cordova-android/framework/src/org/apache/cordova/Config.java
@@ -143,6 +143,16 @@ public class Config {
boolean value = xml.getAttributeValue(null, "value").equals("true");
action.getIntent().putExtra(name, value);
}
+ else if(name.equals("InAppBrowserStorageEnabled"))
+ {
+ boolean value = xml.getAttributeValue(null, "value").equals("true");
+ action.getIntent().putExtra(name, value);
+ }
+ else if(name.equals("disallowOverscroll"))
+ {
+ boolean value = xml.getAttributeValue(null, "value").equals("true");
+ action.getIntent().putExtra(name, value);
+ }
else
{
String value = xml.getAttributeValue(null, "value");
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/framework/src/org/apache/cordova/CordovaArgs.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/CordovaArgs.java b/lib/cordova-android/framework/src/org/apache/cordova/CordovaArgs.java
index 3a8b7c0..d40d26e 100644
--- a/lib/cordova-android/framework/src/org/apache/cordova/CordovaArgs.java
+++ b/lib/cordova-android/framework/src/org/apache/cordova/CordovaArgs.java
@@ -20,6 +20,7 @@ package org.apache.cordova;
import org.json.JSONArray;
import org.json.JSONException;
+import org.json.JSONObject;
import android.util.Base64;
@@ -52,7 +53,7 @@ public class CordovaArgs {
return baseArgs.getJSONArray(index);
}
- public Object getJSONObject(int index) throws JSONException {
+ public JSONObject getJSONObject(int index) throws JSONException {
return baseArgs.getJSONObject(index);
}
@@ -85,7 +86,7 @@ public class CordovaArgs {
return baseArgs.optJSONArray(index);
}
- public Object optJSONObject(int index) {
+ public JSONObject optJSONObject(int index) {
return baseArgs.optJSONObject(index);
}
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/framework/src/org/apache/cordova/CordovaChromeClient.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/CordovaChromeClient.java b/lib/cordova-android/framework/src/org/apache/cordova/CordovaChromeClient.java
index e650781..fb6d45f 100755
--- a/lib/cordova-android/framework/src/org/apache/cordova/CordovaChromeClient.java
+++ b/lib/cordova-android/framework/src/org/apache/cordova/CordovaChromeClient.java
@@ -205,7 +205,7 @@ public class CordovaChromeClient extends WebChromeClient {
// Security check to make sure any requests are coming from the page initially
// loaded in webview and not another loaded in an iframe.
boolean reqOk = false;
- if (url.startsWith("file://") || url.indexOf(this.appView.baseUrl) == 0 || Config.isUrlWhiteListed(url)) {
+ if (url.startsWith("file://") || Config.isUrlWhiteListed(url)) {
reqOk = true;
}
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/framework/src/org/apache/cordova/CordovaWebView.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/CordovaWebView.java b/lib/cordova-android/framework/src/org/apache/cordova/CordovaWebView.java
index 4731adb..e653a95 100755
--- a/lib/cordova-android/framework/src/org/apache/cordova/CordovaWebView.java
+++ b/lib/cordova-android/framework/src/org/apache/cordova/CordovaWebView.java
@@ -47,6 +47,7 @@ import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
+import android.view.inputmethod.InputMethodManager;
import android.webkit.WebBackForwardList;
import android.webkit.WebHistoryItem;
import android.webkit.WebChromeClient;
@@ -74,12 +75,7 @@ public class CordovaWebView extends WebView {
@SuppressWarnings("unused")
private CordovaChromeClient chromeClient;
- //This is for the polyfill history
private String url;
- String baseUrl;
- private Stack<String> urls = new Stack<String>();
-
- boolean useBrowserHistory = true;
// Flag to track that a loadUrl timeout occurred
int loadUrlTimeout = 0;
@@ -211,7 +207,8 @@ public class CordovaWebView extends WebView {
private void initWebViewClient(CordovaInterface cordova) {
- if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB)
+ if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB ||
+ android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.JELLY_BEAN_MR1)
{
this.setWebViewClient(new CordovaWebViewClient(this.cordova, this));
}
@@ -254,14 +251,23 @@ public class CordovaWebView extends WebView {
Log.d(TAG, "This should never happen: InvocationTargetException means this isn't Android anymore.");
}
+ //We don't save any form data in the application
+ settings.setSaveFormData(false);
+ settings.setSavePassword(false);
+
// Jellybean rightfully tried to lock this down. Too bad they didn't give us a whitelist
// while we do this
if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
Level16Apis.enableUniversalAccess(settings);
// Enable database
- settings.setDatabaseEnabled(true);
+ // We keep this disabled because we use or shim to get around DOM_EXCEPTION_ERROR_16
String databasePath = this.cordova.getActivity().getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath();
- settings.setDatabasePath(databasePath);
+ if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB)
+ {
+ settings.setDatabaseEnabled(true);
+ settings.setDatabasePath(databasePath);
+ }
+
settings.setGeolocationDatabasePath(databasePath);
// Enable DOM storage
@@ -360,7 +366,7 @@ public class CordovaWebView extends WebView {
String initUrl = this.getProperty("url", null);
// If first page of app, then set URL to load to be the one passed in
- if (initUrl == null || (this.urls.size() > 0)) {
+ if (initUrl == null) {
this.loadUrlIntoView(url);
}
// Otherwise use the URL specified in the activity's extras bundle
@@ -381,7 +387,7 @@ public class CordovaWebView extends WebView {
String initUrl = this.getProperty("url", null);
// If first page of app, then set URL to load to be the one passed in
- if (initUrl == null || (this.urls.size() > 0)) {
+ if (initUrl == null) {
this.loadUrlIntoView(url, time);
}
// Otherwise use the URL specified in the activity's extras bundle
@@ -399,21 +405,8 @@ public class CordovaWebView extends WebView {
LOG.d(TAG, ">>> loadUrl(" + url + ")");
this.url = url;
- if (this.baseUrl == null) {
- int i = url.lastIndexOf('/');
- if (i > 0) {
- this.baseUrl = url.substring(0, i + 1);
- }
- else {
- this.baseUrl = this.url + "/";
- }
-
- this.pluginManager.init();
+ this.pluginManager.init();
- if (!this.useBrowserHistory) {
- this.urls.push(url);
- }
- }
// Create a timeout timer for loadUrl
final CordovaWebView me = this;
@@ -468,7 +461,7 @@ public class CordovaWebView extends WebView {
if (LOG.isLoggable(LOG.DEBUG) && !url.startsWith("javascript:")) {
LOG.d(TAG, ">>> loadUrlNow()");
}
- if (url.startsWith("file://") || url.indexOf(this.baseUrl) == 0 || url.startsWith("javascript:") || Config.isUrlWhiteListed(url)) {
+ if (url.startsWith("file://") || url.startsWith("javascript:") || Config.isUrlWhiteListed(url)) {
super.loadUrl(url);
}
}
@@ -484,7 +477,7 @@ public class CordovaWebView extends WebView {
// If not first page of app, then load immediately
// Add support for browser history if we use it.
- if ((url.startsWith("javascript:")) || this.urls.size() > 0 || this.canGoBack()) {
+ if ((url.startsWith("javascript:")) || this.canGoBack()) {
}
// If first page, then show splashscreen
@@ -532,25 +525,6 @@ public class CordovaWebView extends WebView {
}
}
- /**
- * Returns the top url on the stack without removing it from
- * the stack.
- */
- public String peekAtUrlStack() {
- if (this.urls.size() > 0) {
- return this.urls.peek();
- }
- return "";
- }
-
- /**
- * Add a url to the stack
- *
- * @param url
- */
- public void pushUrl(String url) {
- this.urls.push(url);
- }
/**
* Go to previous page in history. (We manage our own history)
@@ -561,37 +535,15 @@ public class CordovaWebView extends WebView {
// Check webview first to see if there is a history
// This is needed to support curPage#diffLink, since they are added to appView's history, but not our history url array (JQMobile behavior)
- if (super.canGoBack() && this.useBrowserHistory) {
+ if (super.canGoBack()) {
printBackForwardList();
super.goBack();
return true;
}
- // If our managed history has prev url
- else if (this.urls.size() > 1 && !this.useBrowserHistory) {
- this.urls.pop(); // Pop current url
- String url = this.urls.pop(); // Pop prev url that we want to load, since it will be added back by loadUrl()
- this.loadUrl(url);
- return true;
- }
-
return false;
}
- /**
- * Return true if there is a history item.
- *
- * @return
- */
- public boolean canGoBack() {
- if (super.canGoBack() && this.useBrowserHistory) {
- return true;
- }
- else if (this.urls.size() > 1) {
- return true;
- }
- return false;
- }
/**
* Load the specified URL in the Cordova webview or a new browser instance.
@@ -615,14 +567,8 @@ public class CordovaWebView extends WebView {
if (!openExternal) {
// Make sure url is in whitelist
- if (url.startsWith("file://") || url.indexOf(this.baseUrl) == 0 || Config.isUrlWhiteListed(url)) {
+ if (url.startsWith("file://") || Config.isUrlWhiteListed(url)) {
// TODO: What about params?
-
- // Clear out current url from history, since it will be replacing it
- if (clearHistory) {
- this.urls.clear();
- }
-
// Load new URL
this.loadUrl(url);
}
@@ -659,13 +605,6 @@ public class CordovaWebView extends WebView {
* <log level="DEBUG" />
*/
private void loadConfiguration() {
- // Config has already been loaded, and it stores these preferences on the Intent.
- if("false".equals(this.getProperty("useBrowserHistory", "true")))
- {
- //Switch back to the old browser history and state the six month policy
- this.useBrowserHistory = false;
- Log.w(TAG, "useBrowserHistory=false is deprecated as of Cordova 2.2.0 and will be removed six months after the 2.2.0 release. Please use the browser history and use history.back().");
- }
if ("true".equals(this.getProperty("fullscreen", "false"))) {
this.cordova.getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
@@ -719,13 +658,20 @@ public class CordovaWebView extends WebView {
}
else if(keyCode == KeyEvent.KEYCODE_BACK)
{
- //Because exit is fired on the keyDown and not the key up on Android 4.x
- //we need to check for this.
- //Also, I really wished "canGoBack" worked!
- if(this.useBrowserHistory)
- return !(this.startOfHistory()) || this.bound;
- else
- return this.urls.size() > 1 || this.bound;
+ return !(this.startOfHistory()) || this.bound;
+ }
+ else if(keyCode == KeyEvent.KEYCODE_MENU)
+ {
+ //How did we get here? Is there a childView?
+ View childView = this.getFocusedChild();
+ if(childView != null)
+ {
+ //Make sure we close the keyboard if it's present
+ InputMethodManager imm = (InputMethodManager) cordova.getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
+ imm.hideSoftInputFromWindow(childView.getWindowToken(), 0);
+ cordova.getActivity().openOptionsMenu();
+ }
+ return true;
}
return super.onKeyDown(keyCode, event);
[4/6] 2.6.0rc1 used for libs now. Bumped npm version to 2.6.0. added
androids local.properties to gitignore.
Posted by fi...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/util/FileUtils.java
----------------------------------------------------------------------
diff --git a/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/util/FileUtils.java b/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/util/FileUtils.java
index 2655ef6..20ef492 100644
--- a/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/util/FileUtils.java
+++ b/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/util/FileUtils.java
@@ -23,6 +23,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
+import java.util.Random;
import javax.microedition.io.Connector;
import javax.microedition.io.file.FileConnection;
@@ -35,6 +36,7 @@ import net.rim.device.api.io.FileNotFoundException;
import net.rim.device.api.io.IOUtilities;
import net.rim.device.api.io.MIMETypeAssociations;
import net.rim.device.api.system.Application;
+import net.rim.device.api.system.ControlledAccessException;
/**
* Contains file utility methods.
@@ -45,7 +47,13 @@ public class FileUtils {
public static final String LOCAL_PROTOCOL = "local://";
public static final String FILE_PROTOCOL = "file://";
- private static final String APP_TMP_DIR = "tmp" + CordovaExtension.getAppID();
+ private static final String APP_TMP_DIR;
+
+ // init APP_TMP_DIR with a random value
+ static {
+ Random gen = new Random();
+ APP_TMP_DIR = "tmp" + Math.abs(gen.nextInt());
+ }
/**
* Reads file as byte array.
@@ -226,6 +234,9 @@ public class FileUtils {
return;
}
fconn.mkdir();
+ } catch (ControlledAccessException e) {
+ Logger.log("ControlledAccessException on dir " + dirPath + ", either directory conflict after reinstall of app, or device is connected via usb, see Cordova Docs File Blackberry Quirks");
+ Logger.log(e.toString());
}
finally {
try {
@@ -237,6 +248,26 @@ public class FileUtils {
}
/**
+ * Determines the size of a file on the file system. Size always represents number of bytes contained in the file; never pre-allocated but empty space
+ * @return size in bytes of the selected file, or -1 if the file does not exist or is inaccessible
+ */
+ public static long fileSize(String path) throws IOException {
+ FileConnection fconn = null;
+ long fsize = -1;
+ try {
+ fconn = (FileConnection)Connector.open(path);
+ fsize = fconn.fileSize();
+ } catch (IOException e) {
+ Logger.log(FileUtils.class.getName() + " fileSize: " + path + "not found or inaccessible");
+ } finally {
+ try {
+ if (fconn != null) fconn.close();
+ } catch (IOException ignored) {}
+ }
+ return fsize;
+ }
+
+ /**
* Copies a file or directory to a new location. If copying a directory, the
* entire contents of the directory are copied recursively.
*
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-blackberry/javascript/cordova.blackberry.js
----------------------------------------------------------------------
diff --git a/lib/cordova-blackberry/javascript/cordova.blackberry.js b/lib/cordova-blackberry/javascript/cordova.blackberry.js
index 988dd43..fbe61f5 100644
--- a/lib/cordova-blackberry/javascript/cordova.blackberry.js
+++ b/lib/cordova-blackberry/javascript/cordova.blackberry.js
@@ -1,8 +1,8 @@
// Platform: blackberry
-// commit c5437f050947a65045222c6ac9fa70cf71ba334e
+// commit bbf1562d4934b1331ffb263424b6ae054cedeb71
-// File generated at :: Wed Feb 27 2013 13:16:46 GMT-0800 (PST)
+// File generated at :: Fri Mar 22 2013 14:49:45 GMT-0700 (PDT)
/*
Licensed to the Apache Software Foundation (ASF) under one
@@ -725,7 +725,6 @@ channel.createSticky('onCordovaInfoReady');
channel.createSticky('onCordovaConnectionReady');
// Event to indicate that all automatically loaded JS plugins are loaded and ready.
-// This is used in conjunction with the automatic plugin JS loading CLI prototype.
channel.createSticky('onPluginsReady');
// Event to indicate that Cordova is ready
@@ -1033,9 +1032,10 @@ cameraExport.getPicture = function(successCallback, errorCallback, options) {
var correctOrientation = !!options.correctOrientation;
var saveToPhotoAlbum = !!options.saveToPhotoAlbum;
var popoverOptions = getValue(options.popoverOptions, null);
+ var cameraDirection = getValue(options.cameraDirection, Camera.Direction.BACK);
var args = [quality, destinationType, sourceType, targetWidth, targetHeight, encodingType,
- mediaType, allowEdit, correctOrientation, saveToPhotoAlbum, popoverOptions];
+ mediaType, allowEdit, correctOrientation, saveToPhotoAlbum, popoverOptions, cameraDirection];
exec(successCallback, errorCallback, "Camera", "takePicture", args);
return new CameraPopoverHandle();
@@ -1078,6 +1078,10 @@ module.exports = {
ARROW_LEFT : 4,
ARROW_RIGHT : 8,
ARROW_ANY : 15
+ },
+ Direction:{
+ BACK: 0,
+ FRONT: 1
}
};
@@ -2269,14 +2273,7 @@ FileReader.prototype.readAsText = function(file, encoding) {
// Default encoding is UTF-8
var enc = encoding ? encoding : "UTF-8";
var me = this;
- var execArgs = [this._fileName, enc];
-
- // Maybe add slice parameters.
- if (file.end < file.size) {
- execArgs.push(file.start, file.end);
- } else if (file.start > 0) {
- execArgs.push(file.start);
- }
+ var execArgs = [this._fileName, enc, file.start, file.end];
// Read file
exec(
@@ -2345,14 +2342,7 @@ FileReader.prototype.readAsDataURL = function(file) {
}
var me = this;
- var execArgs = [this._fileName];
-
- // Maybe add slice parameters.
- if (file.end < file.size) {
- execArgs.push(file.start, file.end);
- } else if (file.start > 0) {
- execArgs.push(file.start);
- }
+ var execArgs = [this._fileName, file.start, file.end];
// Read file
exec(
@@ -2415,9 +2405,59 @@ FileReader.prototype.readAsBinaryString = function(file) {
if (initRead(this, file)) {
return this._realReader.readAsBinaryString(file);
}
- // TODO - Can't return binary data to browser.
- console.log('method "readAsBinaryString" is not supported at this time.');
- this.abort();
+
+ var me = this;
+ var execArgs = [this._fileName, file.start, file.end];
+
+ // Read file
+ exec(
+ // Success callback
+ function(r) {
+ // If DONE (cancelled), then don't do anything
+ if (me._readyState === FileReader.DONE) {
+ return;
+ }
+
+ // DONE state
+ me._readyState = FileReader.DONE;
+
+ me._result = r;
+
+ // If onload callback
+ if (typeof me.onload === "function") {
+ me.onload(new ProgressEvent("load", {target:me}));
+ }
+
+ // If onloadend callback
+ if (typeof me.onloadend === "function") {
+ me.onloadend(new ProgressEvent("loadend", {target:me}));
+ }
+ },
+ // Error callback
+ function(e) {
+ // If DONE (cancelled), then don't do anything
+ if (me._readyState === FileReader.DONE) {
+ return;
+ }
+
+ // DONE state
+ me._readyState = FileReader.DONE;
+
+ me._result = null;
+
+ // Save error
+ me._error = new FileError(e);
+
+ // If onerror callback
+ if (typeof me.onerror === "function") {
+ me.onerror(new ProgressEvent("error", {target:me}));
+ }
+
+ // If onloadend callback
+ if (typeof me.onloadend === "function") {
+ me.onloadend(new ProgressEvent("loadend", {target:me}));
+ }
+ }, "File", "readAsBinaryString", execArgs);
};
/**
@@ -2429,9 +2469,59 @@ FileReader.prototype.readAsArrayBuffer = function(file) {
if (initRead(this, file)) {
return this._realReader.readAsArrayBuffer(file);
}
- // TODO - Can't return binary data to browser.
- console.log('This method is not supported at this time.');
- this.abort();
+
+ var me = this;
+ var execArgs = [this._fileName, file.start, file.end];
+
+ // Read file
+ exec(
+ // Success callback
+ function(r) {
+ // If DONE (cancelled), then don't do anything
+ if (me._readyState === FileReader.DONE) {
+ return;
+ }
+
+ // DONE state
+ me._readyState = FileReader.DONE;
+
+ me._result = r;
+
+ // If onload callback
+ if (typeof me.onload === "function") {
+ me.onload(new ProgressEvent("load", {target:me}));
+ }
+
+ // If onloadend callback
+ if (typeof me.onloadend === "function") {
+ me.onloadend(new ProgressEvent("loadend", {target:me}));
+ }
+ },
+ // Error callback
+ function(e) {
+ // If DONE (cancelled), then don't do anything
+ if (me._readyState === FileReader.DONE) {
+ return;
+ }
+
+ // DONE state
+ me._readyState = FileReader.DONE;
+
+ me._result = null;
+
+ // Save error
+ me._error = new FileError(e);
+
+ // If onerror callback
+ if (typeof me.onerror === "function") {
+ me.onerror(new ProgressEvent("error", {target:me}));
+ }
+
+ // If onloadend callback
+ if (typeof me.onloadend === "function") {
+ me.onloadend(new ProgressEvent("loadend", {target:me}));
+ }
+ }, "File", "readAsArrayBuffer", execArgs);
};
module.exports = FileReader;
@@ -2477,6 +2567,38 @@ function newProgressEvent(result) {
return pe;
}
+function getBasicAuthHeader(urlString) {
+ var header = null;
+
+ if (window.btoa) {
+ // parse the url using the Location object
+ var url = document.createElement('a');
+ url.href = urlString;
+
+ var credentials = null;
+ var protocol = url.protocol + "//";
+ var origin = protocol + url.host;
+
+ // check whether there are the username:password credentials in the url
+ if (url.href.indexOf(origin) != 0) { // credentials found
+ var atIndex = url.href.indexOf("@");
+ credentials = url.href.substring(protocol.length, atIndex);
+ }
+
+ if (credentials) {
+ var authHeader = "Authorization";
+ var authHeaderValue = "Basic " + window.btoa(credentials);
+
+ header = {
+ name : authHeader,
+ value : authHeaderValue
+ };
+ }
+ }
+
+ return header;
+}
+
var idCounter = 0;
/**
@@ -2507,6 +2629,18 @@ FileTransfer.prototype.upload = function(filePath, server, successCallback, erro
var params = null;
var chunkedMode = true;
var headers = null;
+
+ var basicAuthHeader = getBasicAuthHeader(server);
+ if (basicAuthHeader) {
+ if (!options) {
+ options = new FileUploadOptions();
+ }
+ if (!options.headers) {
+ options.headers = {};
+ }
+ options.headers[basicAuthHeader.name] = basicAuthHeader.value;
+ }
+
if (options) {
fileKey = options.fileKey;
fileName = options.fileName;
@@ -2548,10 +2682,28 @@ FileTransfer.prototype.upload = function(filePath, server, successCallback, erro
* @param successCallback (Function} Callback to be invoked when upload has completed
* @param errorCallback {Function} Callback to be invoked upon error
* @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false
+ * @param options {FileDownloadOptions} Optional parameters such as headers
*/
-FileTransfer.prototype.download = function(source, target, successCallback, errorCallback, trustAllHosts) {
+FileTransfer.prototype.download = function(source, target, successCallback, errorCallback, trustAllHosts, options) {
argscheck.checkArgs('ssFF*', 'FileTransfer.download', arguments);
var self = this;
+
+ var basicAuthHeader = getBasicAuthHeader(source);
+ if (basicAuthHeader) {
+ if (!options) {
+ options = {};
+ }
+ if (!options.headers) {
+ options.headers = {};
+ }
+ options.headers[basicAuthHeader.name] = basicAuthHeader.value;
+ }
+
+ var headers = null;
+ if (options) {
+ headers = options.headers || null;
+ }
+
var win = function(result) {
if (typeof result.lengthComputable != "undefined") {
if (self.onprogress) {
@@ -2578,7 +2730,7 @@ FileTransfer.prototype.download = function(source, target, successCallback, erro
errorCallback(error);
};
- exec(win, fail, 'FileTransfer', 'download', [source, target, trustAllHosts, this._id]);
+ exec(win, fail, 'FileTransfer', 'download', [source, target, trustAllHosts, this._id, headers]);
};
/**
@@ -2976,6 +3128,7 @@ function InAppBrowser() {
this.channels = {
'loadstart': channel.create('loadstart'),
'loadstop' : channel.create('loadstop'),
+ 'loaderror' : channel.create('loaderror'),
'exit' : channel.create('exit')
};
}
@@ -3006,7 +3159,7 @@ module.exports = function(strUrl, strWindowName, strWindowFeatures) {
var cb = function(eventname) {
iab._eventHandler(eventname);
};
- exec(cb, null, "InAppBrowser", "open", [strUrl, strWindowName, strWindowFeatures]);
+ exec(cb, cb, "InAppBrowser", "open", [strUrl, strWindowName, strWindowFeatures]);
return iab;
};
@@ -8682,6 +8835,7 @@ modulemapper.defaults('cordova/plugin/Connection', 'Connection');
define("cordova/plugin/notification", function(require, exports, module) {
var exec = require('cordova/exec');
+var platform = require('cordova/platform');
/**
* Provides access to notifications on the device.
@@ -8710,15 +8864,53 @@ module.exports = {
* @param {String} message Message to print in the body of the alert
* @param {Function} resultCallback The callback that is called when user clicks on a button.
* @param {String} title Title of the alert dialog (default: Confirm)
- * @param {String} buttonLabels Comma separated list of the labels of the buttons (default: 'OK,Cancel')
+ * @param {Array} buttonLabels Array of the labels of the buttons (default: ['OK', 'Cancel'])
*/
confirm: function(message, resultCallback, title, buttonLabels) {
var _title = (title || "Confirm");
- var _buttonLabels = (buttonLabels || "OK,Cancel");
+ var _buttonLabels = (buttonLabels || ["OK", "Cancel"]);
+
+ // Strings are deprecated!
+ if (typeof _buttonLabels === 'string') {
+ console.log("Notification.confirm(string, function, string, string) is deprecated. Use Notification.confirm(string, function, string, array).");
+ }
+
+ // Android and iOS take an array of button label names.
+ // Other platforms take a comma separated list.
+ // For compatibility, we convert to the desired type based on the platform.
+ if (platform.id == "android" || platform.id == "ios") {
+ if (typeof _buttonLabels === 'string') {
+ var buttonLabelString = _buttonLabels;
+ _buttonLabels = buttonLabelString.split(",");
+ }
+ } else {
+ if (Array.isArray(_buttonLabels)) {
+ var buttonLabelArray = _buttonLabels;
+ _buttonLabels = buttonLabelArray.toString();
+ }
+ }
exec(resultCallback, null, "Notification", "confirm", [message, _title, _buttonLabels]);
},
/**
+ * Open a native prompt dialog, with a customizable title and button text.
+ * The following results are returned to the result callback:
+ * buttonIndex Index number of the button selected.
+ * input1 The text entered in the prompt dialog box.
+ *
+ * @param {String} message Dialog message to display (default: "Prompt message")
+ * @param {Function} resultCallback The callback that is called when user clicks on a button.
+ * @param {String} title Title of the dialog (default: "Prompt")
+ * @param {Array} buttonLabels Array of strings for the button labels (default: ["OK","Cancel"])
+ */
+ prompt: function(message, resultCallback, title, buttonLabels) {
+ var _message = (message || "Prompt message");
+ var _title = (title || "Prompt");
+ var _buttonLabels = (buttonLabels || ["OK","Cancel"]);
+ exec(resultCallback, null, "Notification", "prompt", [_message, _title, _buttonLabels]);
+ },
+
+ /**
* Causes the device to vibrate.
*
* @param {Integer} mills The number of milliseconds to vibrate for.
@@ -10506,15 +10698,6 @@ window.cordova = require('cordova');
/**
* Create all cordova objects once page has fully loaded and native side is ready.
*/
- var joinEvents = [ channel.onDOMContentLoaded, channel.onNativeReady ];
-
- // If this property is set to something truthy, join on onPluginsReady too.
- // This property is set by the automatic JS installation prototype in cordova-cli,
- // and will be removed when the prototype either becomes mainline or is dropped.
- if (window.__onPluginsLoadedHack) {
- joinEvents.push(channel.onPluginsReady);
- }
-
channel.join(function() {
var builder = require('cordova/builder'),
platform = require('cordova/platform');
@@ -10535,7 +10718,7 @@ window.cordova = require('cordova');
require('cordova').fireDocumentEvent('deviceready');
}, channel.deviceReadyChannelsArray);
- }, joinEvents);
+ }, [ channel.onDOMContentLoaded, channel.onNativeReady, channel.onPluginsReady ]);
}(window));
@@ -10565,5 +10748,105 @@ document.addEventListener("DOMContentLoaded", function () {
}
});
+// file: lib/scripts/plugin_loader.js
+
+// Tries to load all plugins' js-modules.
+// This is an async process, but onDeviceReady is blocked on onPluginsReady.
+// onPluginsReady is fired when there are no plugins to load, or they are all done.
+(function (context) {
+ // To be populated with the handler by handlePluginsObject.
+ var onScriptLoadingComplete;
+
+ var scriptCounter = 0;
+ function scriptLoadedCallback() {
+ scriptCounter--;
+ if (scriptCounter === 0) {
+ onScriptLoadingComplete && onScriptLoadingComplete();
+ }
+ }
+
+ // Helper function to inject a <script> tag.
+ function injectScript(path) {
+ scriptCounter++;
+ var script = document.createElement("script");
+ script.onload = scriptLoadedCallback;
+ script.src = path;
+ document.head.appendChild(script);
+ }
+
+ // Called when:
+ // * There are plugins defined and all plugins are finished loading.
+ // * There are no plugins to load.
+ function finishPluginLoading() {
+ context.cordova.require('cordova/channel').onPluginsReady.fire();
+ }
+
+ // Handler for the cordova_plugins.json content.
+ // See plugman's plugin_loader.js for the details of this object.
+ // This function is only called if the really is a plugins array that isn't empty.
+ // Otherwise the XHR response handler will just call finishPluginLoading().
+ function handlePluginsObject(modules) {
+ // First create the callback for when all plugins are loaded.
+ var mapper = context.cordova.require('cordova/modulemapper');
+ onScriptLoadingComplete = function() {
+ // Loop through all the plugins and then through their clobbers and merges.
+ for (var i = 0; i < modules.length; i++) {
+ var module = modules[i];
+ if (!module) continue;
+
+ if (module.clobbers && module.clobbers.length) {
+ for (var j = 0; j < module.clobbers.length; j++) {
+ mapper.clobbers(module.id, module.clobbers[j]);
+ }
+ }
+
+ if (module.merges && module.merges.length) {
+ for (var k = 0; k < module.merges.length; k++) {
+ mapper.merges(module.id, module.merges[k]);
+ }
+ }
+
+ // Finally, if runs is truthy we want to simply require() the module.
+ // This can be skipped if it had any merges or clobbers, though,
+ // since the mapper will already have required the module.
+ if (module.runs && !(module.clobbers && module.clobbers.length) && !(module.merges && module.merges.length)) {
+ context.cordova.require(module.id);
+ }
+ }
+
+ finishPluginLoading();
+ };
+
+ // Now inject the scripts.
+ for (var i = 0; i < modules.length; i++) {
+ injectScript(modules[i].file);
+ }
+ }
+
+ // Try to XHR the cordova_plugins.json file asynchronously.
+ var xhr = new context.XMLHttpRequest();
+ xhr.onreadystatechange = function() {
+ if (this.readyState != 4) { // not DONE
+ return;
+ }
+
+ // If the response is a JSON string which composes an array, call handlePluginsObject.
+ // If the request fails, or the response is not a JSON array, just call finishPluginLoading.
+ if (this.status == 200) {
+ var obj = JSON.parse(this.responseText);
+ if (obj && obj instanceof Array && obj.length > 0) {
+ handlePluginsObject(obj);
+ } else {
+ finishPluginLoading();
+ }
+ } else {
+ finishPluginLoading();
+ }
+ };
+ xhr.open('GET', 'cordova_plugins.json', true); // Async
+ xhr.send();
+}(window));
+
+
})();
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/CDVAvailability.h
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVAvailability.h b/lib/cordova-ios/CordovaLib/Classes/CDVAvailability.h
index 33c6799..947ae2d 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVAvailability.h
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVAvailability.h
@@ -17,6 +17,8 @@
under the License.
*/
+#define __CORDOVA_IOS__
+
#define __CORDOVA_0_9_6 906
#define __CORDOVA_1_0_0 10000
#define __CORDOVA_1_1_0 10100
@@ -37,6 +39,7 @@
#define __CORDOVA_2_3_0 20300
#define __CORDOVA_2_4_0 20400
#define __CORDOVA_2_5_0 20500
+#define __CORDOVA_2_6_0 20600
#define __CORDOVA_NA 99999 /* not available */
/*
@@ -47,7 +50,7 @@
#endif
*/
#ifndef CORDOVA_VERSION_MIN_REQUIRED
- #define CORDOVA_VERSION_MIN_REQUIRED __CORDOVA_2_5_0
+ #define CORDOVA_VERSION_MIN_REQUIRED __CORDOVA_2_6_0
#endif
/*
@@ -65,12 +68,20 @@
/* Return the string version of the decimal version */
#define CDV_VERSION [NSString stringWithFormat:@"%d.%d.%d", \
- (CORDOVA_VERSION_MIN_REQUIRED / 10000), \
- (CORDOVA_VERSION_MIN_REQUIRED % 10000) / 100, \
- (CORDOVA_VERSION_MIN_REQUIRED % 10000) % 100]
+ (CORDOVA_VERSION_MIN_REQUIRED / 10000), \
+ (CORDOVA_VERSION_MIN_REQUIRED % 10000) / 100, \
+ (CORDOVA_VERSION_MIN_REQUIRED % 10000) % 100]
#ifdef __clang__
#define CDV_DEPRECATED(version, msg) __attribute__((deprecated("Deprecated in Cordova " #version ". " msg)))
#else
#define CDV_DEPRECATED(version, msg) __attribute__((deprecated()))
#endif
+
+// Enable this to log all exec() calls.
+#define CDV_ENABLE_EXEC_LOGGING 0
+#if CDV_ENABLE_EXEC_LOGGING
+ #define CDV_EXEC_LOG NSLog
+#else
+ #define CDV_EXEC_LOG(...) do {} while (NO)
+#endif
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/CDVCamera.h
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVCamera.h b/lib/cordova-ios/CordovaLib/Classes/CDVCamera.h
index 204d25f..65eac77 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVCamera.h
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVCamera.h
@@ -61,8 +61,8 @@ typedef NSUInteger CDVMediaType;
// ======================================================================= //
@interface CDVCamera : CDVPlugin <UIImagePickerControllerDelegate,
- UINavigationControllerDelegate,
- UIPopoverControllerDelegate>
+ UINavigationControllerDelegate,
+ UIPopoverControllerDelegate>
{}
@property (strong) CDVCameraPicker* pickerController;
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/CDVCamera.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVCamera.m b/lib/cordova-ios/CordovaLib/Classes/CDVCamera.m
index aabe844..ab1154e 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVCamera.m
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVCamera.m
@@ -18,6 +18,7 @@
*/
#import "CDVCamera.h"
+#import "CDVJpegHeaderWriter.h"
#import "NSArray+Comparisons.h"
#import "NSData+Base64.h"
#import "NSDictionary+Extensions.h"
@@ -60,6 +61,8 @@ static NSSet* org_apache_cordova_validArrowDirections;
* 7 allowsEdit
* 8 correctOrientation
* 9 saveToPhotoAlbum
+ * 10 popoverOptions
+ * 11 cameraDirection
*/
- (void)takePicture:(CDVInvokedUrlCommand*)command
{
@@ -82,6 +85,12 @@ static NSSet* org_apache_cordova_validArrowDirections;
return;
}
+ NSNumber* cameraDirection = [arguments objectAtIndex:11];
+ UIImagePickerControllerCameraDevice cameraDevice = UIImagePickerControllerCameraDeviceRear; // default
+ if (cameraDirection != nil) {
+ cameraDevice = (UIImagePickerControllerSourceType)[cameraDirection intValue];
+ }
+
bool allowEdit = [[arguments objectAtIndex:7] boolValue];
NSNumber* targetWidth = [arguments objectAtIndex:3];
NSNumber* targetHeight = [arguments objectAtIndex:4];
@@ -105,6 +114,7 @@ static NSSet* org_apache_cordova_validArrowDirections;
cameraPicker.delegate = self;
cameraPicker.sourceType = sourceType;
+ cameraPicker.cameraDevice = cameraDevice;
cameraPicker.allowsEditing = allowEdit; // THIS IS ALL IT TAKES FOR CROPPING - jm
cameraPicker.callbackId = callbackId;
cameraPicker.targetSize = targetSize;
@@ -289,6 +299,49 @@ static NSSet* org_apache_cordova_validArrowDirections;
data = UIImagePNGRepresentation(scaledImage == nil ? image : scaledImage);
} else {
data = UIImageJPEGRepresentation(scaledImage == nil ? image : scaledImage, cameraPicker.quality / 100.0f);
+
+ CDVJpegHeaderWriter * exifWriter = [[CDVJpegHeaderWriter alloc] init];
+
+ NSString * headerstring = [exifWriter createExifAPP1: [info objectForKey:@"UIImagePickerControllerMediaMetadata"]];
+ NSMutableData * exifdata = [NSMutableData dataWithCapacity: [headerstring length]/2];
+ int idx;
+ for (idx = 0; idx+1 < [headerstring length]; idx+=2) {
+ NSRange range = NSMakeRange(idx, 2);
+ NSString* hexStr = [headerstring substringWithRange:range];
+ NSScanner* scanner = [NSScanner scannerWithString:hexStr];
+ unsigned int intValue;
+ [scanner scanHexInt:&intValue];
+ [exifdata appendBytes:&intValue length:1];
+ }
+
+ NSMutableData * ddata = [NSMutableData dataWithCapacity: [data length]];
+ NSMakeRange(0,4);
+ int loc = 0;
+ bool done = false;
+ // read the jpeg data until we encounter the app1==0xFFE1 marker
+ while (loc+1 < [data length]) {
+ NSData * blag = [data subdataWithRange: NSMakeRange(loc,2)];
+ if( [[blag description] isEqualToString : @"<ffe1>"]) {
+ // read the APP1 block size bits
+ NSString * the = [exifWriter hexStringFromData:[data subdataWithRange: NSMakeRange(loc+2,2)]];
+ NSNumber * app1width = [exifWriter numericFromHexString:the];
+ //consume the original app1 block
+ [ddata appendData:exifdata];
+ // advance our loc marker past app1
+ loc += [app1width intValue] + 2;
+ done = true;
+ } else {
+ if(!done) {
+ [ddata appendData:blag];
+ loc += 2;
+ } else {
+ break;
+ }
+ }
+ }
+ // copy the remaining data
+ [ddata appendData:[data subdataWithRange: NSMakeRange(loc,[data length]-loc)]];
+ data = ddata;
}
if (cameraPicker.returnType == DestinationTypeFileUri) {
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/CDVCapture.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVCapture.m b/lib/cordova-ios/CordovaLib/Classes/CDVCapture.m
index ed9f664..d89e3d3 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVCapture.m
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVCapture.m
@@ -169,7 +169,7 @@
}
// write to temp directory and return URI
- NSString* docsPath = [NSTemporaryDirectory ()stringByStandardizingPath]; // use file system temporary directory
+ NSString* docsPath = [NSTemporaryDirectory()stringByStandardizingPath]; // use file system temporary directory
NSError* err = nil;
NSFileManager* fileMgr = [[NSFileManager alloc] init];
@@ -439,7 +439,7 @@
if ([command isKindOfClass:[CDVFile class]]) {
CDVFile* cdvFile = (CDVFile*)command;
NSString* mimeType = [cdvFile getMimeTypeFromPath:fullPath];
- [fileDict setObject:(mimeType != nil ? (NSObject*)mimeType:[NSNull null]) forKey:@"type"];
+ [fileDict setObject:(mimeType != nil ? (NSObject*)mimeType : [NSNull null]) forKey:@"type"];
}
}
NSDictionary* fileAttrs = [fileMgr attributesOfItemAtPath:fullPath error:nil];
@@ -533,7 +533,6 @@
// delegate to CVDAudioRecorderViewController
return [self.topViewController supportedInterfaceOrientations];
}
-
#endif
@end
@@ -663,7 +662,7 @@
// create file to record to in temporary dir
- NSString* docsPath = [NSTemporaryDirectory ()stringByStandardizingPath]; // use file system temporary directory
+ NSString* docsPath = [NSTemporaryDirectory()stringByStandardizingPath]; // use file system temporary directory
NSError* err = nil;
NSFileManager* fileMgr = [[NSFileManager alloc] init];
@@ -701,7 +700,6 @@
orientation = orientation | (supported & UIInterfaceOrientationMaskPortraitUpsideDown);
return orientation;
}
-
#endif
- (void)viewDidUnload
@@ -766,7 +764,7 @@
BOOL isUIAccessibilityAnnouncementNotification = (&UIAccessibilityAnnouncementNotification != NULL);
if (isUIAccessibilityAnnouncementNotification) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 500ull * NSEC_PER_MSEC), dispatch_get_main_queue(), ^{
- UIAccessibilityPostNotification (UIAccessibilityAnnouncementNotification, NSLocalizedString (@"timed recording complete", nil));
+ UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification, NSLocalizedString(@"timed recording complete", nil));
});
}
} else {
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/CDVCommandDelegate.h
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVCommandDelegate.h b/lib/cordova-ios/CordovaLib/Classes/CDVCommandDelegate.h
index e177c63..0401136 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVCommandDelegate.h
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVCommandDelegate.h
@@ -30,7 +30,6 @@
- (NSString*)pathForResource:(NSString*)resourcepath;
- (id)getCommandInstance:(NSString*)pluginName;
-- (void)registerPlugin:(CDVPlugin*)plugin withClassName:(NSString*)className CDV_DEPRECATED(2.2, "Use CDVViewController to register plugins, or use config.xml.");
// Plugins should not be using this interface to call other plugins since it
// will result in bogus callbacks being made.
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/CDVCommandDelegateImpl.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVCommandDelegateImpl.m b/lib/cordova-ios/CordovaLib/Classes/CDVCommandDelegateImpl.m
index e399289..fa0e5e0 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVCommandDelegateImpl.m
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVCommandDelegateImpl.m
@@ -55,7 +55,11 @@
- (void)evalJsHelper2:(NSString*)js
{
+ CDV_EXEC_LOG(@"Exec: evalling: %@", [js substringToIndex:MIN([js length], 160)]);
NSString* commandsJSON = [_viewController.webView stringByEvaluatingJavaScriptFromString:js];
+ if ([commandsJSON length] > 0) {
+ CDV_EXEC_LOG(@"Exec: Retrieved new exec messages by chaining.");
+ }
[_commandQueue enqueCommandBatch:commandsJSON];
}
@@ -78,21 +82,16 @@
- (void)sendPluginResult:(CDVPluginResult*)result callbackId:(NSString*)callbackId
{
+ CDV_EXEC_LOG(@"Exec(%@): Sending result. Status=%@", callbackId, result.status);
// This occurs when there is are no win/fail callbacks for the call.
- if ([@"INVALID" isEqualToString:callbackId]) {
+ if ([@"INVALID" isEqualToString : callbackId]) {
return;
}
int status = [result.status intValue];
BOOL keepCallback = [result.keepCallback boolValue];
- id message = result.message == nil ? [NSNull null] : result.message;
+ NSString* argumentsAsJSON = [result argumentsAsJSON];
- // Use an array to encode the message as JSON.
- message = [NSArray arrayWithObject:message];
- NSString* encodedMessage = [message JSONString];
- // And then strip off the outer []s.
- encodedMessage = [encodedMessage substringWithRange:NSMakeRange(1, [encodedMessage length] - 2)];
- NSString* js = [NSString stringWithFormat:@"cordova.require('cordova/exec').nativeCallback('%@',%d,%@,%d)",
- callbackId, status, encodedMessage, keepCallback];
+ NSString* js = [NSString stringWithFormat:@"cordova.require('cordova/exec').nativeCallback('%@',%d,%@,%d)", callbackId, status, argumentsAsJSON, keepCallback];
[self evalJsHelper:js];
}
@@ -122,11 +121,6 @@
return [_viewController getCommandInstance:pluginName];
}
-- (void)registerPlugin:(CDVPlugin*)plugin withClassName:(NSString*)className
-{
- [_viewController registerPlugin:plugin withClassName:className];
-}
-
- (void)runInBackground:(void (^)())block
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), block);
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/CDVCommandQueue.h
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVCommandQueue.h b/lib/cordova-ios/CordovaLib/Classes/CDVCommandQueue.h
index ebdf844..27c47b5 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVCommandQueue.h
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVCommandQueue.h
@@ -22,13 +22,7 @@
@class CDVInvokedUrlCommand;
@class CDVViewController;
-@interface CDVCommandQueue : NSObject {
- @private
- NSInteger _lastCommandQueueFlushRequestId;
- __weak CDVViewController* _viewController;
- NSMutableArray* _queue;
- BOOL _currentlyExecuting;
-}
+@interface CDVCommandQueue : NSObject
@property (nonatomic, readonly) BOOL currentlyExecuting;
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/CDVCommandQueue.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVCommandQueue.m b/lib/cordova-ios/CordovaLib/Classes/CDVCommandQueue.m
index a8a58b7..1a0dfa0 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVCommandQueue.m
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVCommandQueue.m
@@ -23,6 +23,14 @@
#import "CDVViewController.h"
#import "CDVCommandDelegateImpl.h"
+@interface CDVCommandQueue () {
+ NSInteger _lastCommandQueueFlushRequestId;
+ __weak CDVViewController* _viewController;
+ NSMutableArray* _queue;
+ BOOL _currentlyExecuting;
+}
+@end
+
@implementation CDVCommandQueue
@synthesize currentlyExecuting = _currentlyExecuting;
@@ -74,6 +82,9 @@
@"cordova.require('cordova/exec').nativeFetchMessages()"];
[self enqueCommandBatch:queuedCommandsJSON];
+ if ([queuedCommandsJSON length] > 0) {
+ CDV_EXEC_LOG(@"Exec: Retrieved new exec messages by request.");
+ }
}
- (void)executePending
@@ -92,13 +103,15 @@
// Iterate over and execute all of the commands.
for (NSArray* jsonEntry in commandBatch) {
CDVInvokedUrlCommand* command = [CDVInvokedUrlCommand commandFromJson:jsonEntry];
+ CDV_EXEC_LOG(@"Exec(%@): Calling %@.%@", command.callbackId, command.className, command.methodName);
+
if (![self execute:command]) {
#ifdef DEBUG
NSString* commandJson = [jsonEntry JSONString];
static NSUInteger maxLogLength = 1024;
NSString* commandString = ([commandJson length] > maxLogLength) ?
- [NSString stringWithFormat:@"%@[...]", [commandJson substringToIndex:maxLogLength]] :
- commandJson;
+ [NSString stringWithFormat:@"%@[...]", [commandJson substringToIndex:maxLogLength]] :
+ commandJson;
DLog(@"FAILED pluginJSON = %@", commandString);
#endif
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/CDVConfigParser.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVConfigParser.m b/lib/cordova-ios/CordovaLib/Classes/CDVConfigParser.m
index 6fd5913..ffc8ede 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVConfigParser.m
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVConfigParser.m
@@ -52,7 +52,7 @@
} else if ([elementName isEqualToString:@"plugin"]) {
NSString* name = [attributeDict[@"name"] lowercaseString];
pluginsDict[name] = attributeDict[@"value"];
- if ([@"true" isEqualToString:attributeDict[@"onload"]]) {
+ if ([@"true" isEqualToString : attributeDict[@"onload"]]) {
[self.startupPluginNames addObject:name];
}
} else if ([elementName isEqualToString:@"access"]) {
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/CDVConnection.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVConnection.m b/lib/cordova-ios/CordovaLib/Classes/CDVConnection.m
index 3030711..b3f5cab 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVConnection.m
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVConnection.m
@@ -52,7 +52,8 @@
return @"none";
case ReachableViaWWAN:
- return @"2g"; // no generic default, so we use the lowest common denominator
+ // Return value of '2g' is deprecated as of 2.6.0 and will be replaced with 'cellular' in 3.0.0
+ return @"2g";
case ReachableViaWiFi:
return @"wifi";
@@ -66,7 +67,8 @@
{
return [theConnectionType isEqualToString:@"2g"] ||
[theConnectionType isEqualToString:@"3g"] ||
- [theConnectionType isEqualToString:@"4g"];
+ [theConnectionType isEqualToString:@"4g"] ||
+ [theConnectionType isEqualToString:@"cellular"];
}
- (void)updateReachability:(CDVReachability*)reachability
@@ -111,6 +113,7 @@
self.internetReach = [CDVReachability reachabilityForInternetConnection];
self.connectionType = [self w3cConnectionTypeFor:self.internetReach];
[self.internetReach startNotifier];
+ [self printDeprecationNotice];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateConnectionType:)
name:kReachabilityChangedNotification object:nil];
if (&UIApplicationDidEnterBackgroundNotification && &UIApplicationWillEnterForegroundNotification) {
@@ -121,4 +124,9 @@
return self;
}
+- (void)printDeprecationNotice
+{
+ NSLog(@"DEPRECATION NOTICE: The Connection ReachableViaWWAN return value of '2g' is deprecated as of Cordova version 2.6.0 and will be changed to 'cellular' in a future release. ");
+}
+
@end
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/CDVContact.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVContact.m b/lib/cordova-ios/CordovaLib/Classes/CDVContact.m
index 9efaf10..3844525 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVContact.m
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVContact.m
@@ -38,7 +38,9 @@ static NSDictionary* org_apache_cordova_contacts_defaultFields = nil;
if ((self = [super init]) != nil) {
ABRecordRef rec = ABPersonCreate();
self.record = rec;
- CFRelease(rec);
+ if (rec) {
+ CFRelease(rec);
+ }
}
return self;
}
@@ -167,9 +169,9 @@ static NSDictionary* org_apache_cordova_contacts_defaultFields = nil;
if (org_apache_cordova_contacts_objectAndProperties == nil) {
org_apache_cordova_contacts_objectAndProperties = [NSDictionary dictionaryWithObjectsAndKeys:
[NSArray arrayWithObjects:kW3ContactGivenName, kW3ContactFamilyName,
- kW3ContactMiddleName, kW3ContactHonorificPrefix, kW3ContactHonorificSuffix, kW3ContactFormattedName, nil], kW3ContactName,
+ kW3ContactMiddleName, kW3ContactHonorificPrefix, kW3ContactHonorificSuffix, kW3ContactFormattedName, nil], kW3ContactName,
[NSArray arrayWithObjects:kW3ContactStreetAddress, kW3ContactLocality, kW3ContactRegion,
- kW3ContactPostalCode, kW3ContactCountry, /*kW3ContactAddressFormatted,*/ nil], kW3ContactAddresses,
+ kW3ContactPostalCode, kW3ContactCountry, /*kW3ContactAddressFormatted,*/ nil], kW3ContactAddresses,
[NSArray arrayWithObjects:kW3ContactOrganizationName, kW3ContactTitle, kW3ContactDepartment, nil], kW3ContactOrganizations,
[NSArray arrayWithObjects:kW3ContactFieldType, kW3ContactFieldValue, kW3ContactFieldPrimary, nil], kW3ContactPhoneNumbers,
[NSArray arrayWithObjects:kW3ContactFieldType, kW3ContactFieldValue, kW3ContactFieldPrimary, nil], kW3ContactEmails,
@@ -228,7 +230,7 @@ static NSDictionary* org_apache_cordova_contacts_defaultFields = nil;
NSArray* propArray = [[CDVContact defaultObjectAndProperties] objectForKey:kW3ContactName];
for (id i in propArray) {
- if (![(NSString*) i isEqualToString:kW3ContactFormattedName]) { // kW3ContactFormattedName is generated from ABRecordCopyCompositeName() and can't be set
+ if (![(NSString*)i isEqualToString : kW3ContactFormattedName]) { // kW3ContactFormattedName is generated from ABRecordCopyCompositeName() and can't be set
[self setValue:[dict valueForKey:i] forProperty:(ABPropertyID)[(NSNumber*)[[CDVContact defaultW3CtoAB] objectForKey:i] intValue]
inRecord:person asUpdate:bUpdate];
}
@@ -298,9 +300,9 @@ static NSDictionary* org_apache_cordova_contacts_defaultFields = nil;
bRemove = YES;
}
if ([dict isKindOfClass:[NSDictionary class]] || (bRemove == YES)) {
- [self setValue:(bRemove ? @"":[dict valueForKey:@"name"]) forProperty:kABPersonOrganizationProperty inRecord:person asUpdate:bUpdate];
- [self setValue:(bRemove ? @"":[dict valueForKey:kW3ContactTitle]) forProperty:kABPersonJobTitleProperty inRecord:person asUpdate:bUpdate];
- [self setValue:(bRemove ? @"":[dict valueForKey:kW3ContactDepartment]) forProperty:kABPersonDepartmentProperty inRecord:person asUpdate:bUpdate];
+ [self setValue:(bRemove ? @"" : [dict valueForKey:@"name"]) forProperty:kABPersonOrganizationProperty inRecord:person asUpdate:bUpdate];
+ [self setValue:(bRemove ? @"" : [dict valueForKey:kW3ContactTitle]) forProperty:kABPersonJobTitleProperty inRecord:person asUpdate:bUpdate];
+ [self setValue:(bRemove ? @"" : [dict valueForKey:kW3ContactDepartment]) forProperty:kABPersonDepartmentProperty inRecord:person asUpdate:bUpdate];
}
}
// add dates
@@ -658,7 +660,7 @@ static NSDictionary* org_apache_cordova_contacts_defaultFields = nil;
[dict setObject:setValue forKey:(NSString*)[[CDVContact defaultW3CtoAB] valueForKey:(NSString*)k]];
} else if ((value == nil) || ([value isKindOfClass:[NSString class]] && ([value length] != 0))) {
// value not provided in contact dictionary - if prop exists in AB dictionary, preserve it
- valueAB = [(__bridge NSDictionary*) existingDictionary valueForKey:[[CDVContact defaultW3CtoAB] valueForKey:k]];
+ valueAB = [(__bridge NSDictionary*)existingDictionary valueForKey : [[CDVContact defaultW3CtoAB] valueForKey:k]];
if (valueAB != nil) {
[dict setValue:valueAB forKey:[[CDVContact defaultW3CtoAB] valueForKey:k]];
}
@@ -893,7 +895,7 @@ static NSDictionary* org_apache_cordova_contacts_defaultFields = nil;
if (data != nil) {
[nc setObject:data forKey:kW3ContactName];
}
- if ([self.returnFields objectForKey:kW3ContactDisplayName] && ((data == nil) || ([(NSDictionary*) data objectForKey:kW3ContactFormattedName] == [NSNull null]))) {
+ if ([self.returnFields objectForKey:kW3ContactDisplayName] && ((data == nil) || ([(NSDictionary*)data objectForKey : kW3ContactFormattedName] == [NSNull null]))) {
// user asked for displayName which iOS doesn't support but there is no other name data being returned
// try and use Composite Name so some name is returned
id tryName = (__bridge_transfer NSString*)ABRecordCopyCompositeName(self.record);
@@ -1114,7 +1116,7 @@ static NSDictionary* org_apache_cordova_contacts_defaultFields = nil;
// always set id
value = [NSNumber numberWithUnsignedInt:ABMultiValueGetIdentifierAtIndex(multi, i)];
[newDict setObject:(value != nil) ? value:[NSNull null] forKey:kW3ContactFieldId];
- [(NSMutableArray*) valuesArray addObject:newDict];
+ [(NSMutableArray*)valuesArray addObject : newDict];
}
} else {
valuesArray = [NSNull null];
@@ -1188,7 +1190,7 @@ static NSDictionary* org_apache_cordova_contacts_defaultFields = nil;
}
if ([newAddress count] > 0) { // ?? this will always be true since we set id,label,primary field??
- [(NSMutableArray*) addresses addObject:newAddress];
+ [(NSMutableArray*)addresses addObject : newAddress];
}
CFRelease(dict);
} // end of loop through addresses
@@ -1244,7 +1246,7 @@ static NSDictionary* org_apache_cordova_contacts_defaultFields = nil;
bFound = CFDictionaryGetValueIfPresent(dict, kABPersonInstantMessageServiceKey, (void*)&value);
if (bFound && (value != NULL)) {
CFRetain(value);
- [newDict setObject:(id)[[CDVContact class] convertPropertyLabelToContactType:(__bridge NSString*)value] forKey:kW3ContactFieldType];
+ [newDict setObject:(id)[[CDVContact class] convertPropertyLabelToContactType : (__bridge NSString*)value] forKey:kW3ContactFieldType];
CFRelease(value);
} else {
[newDict setObject:[NSNull null] forKey:kW3ContactFieldType];
@@ -1254,7 +1256,7 @@ static NSDictionary* org_apache_cordova_contacts_defaultFields = nil;
id identifier = [NSNumber numberWithUnsignedInt:ABMultiValueGetIdentifierAtIndex(multi, i)];
[newDict setObject:(identifier != nil) ? identifier:[NSNull null] forKey:kW3ContactFieldId];
- [(NSMutableArray*) imArray addObject:newDict];
+ [(NSMutableArray*)imArray addObject : newDict];
CFRelease(dict);
}
} else {
@@ -1308,7 +1310,7 @@ static NSDictionary* org_apache_cordova_contacts_defaultFields = nil;
[newDict setObject:@"false" forKey:kW3ContactFieldPrimary];
[newDict setObject:[NSNull null] forKey:kW3ContactFieldType];
array = [NSMutableArray arrayWithCapacity:1];
- [(NSMutableArray*) array addObject:newDict];
+ [(NSMutableArray*)array addObject : newDict];
} else {
array = [NSNull null];
}
@@ -1327,7 +1329,7 @@ static NSDictionary* org_apache_cordova_contacts_defaultFields = nil;
NSData* data = (__bridge NSData*)photoData;
// write to temp directory and store URI in photos array
// get the temp directory path
- NSString* docsPath = [NSTemporaryDirectory ()stringByStandardizingPath];
+ NSString* docsPath = [NSTemporaryDirectory()stringByStandardizingPath];
NSError* err = nil;
NSString* filePath = [NSString stringWithFormat:@"%@/photo_XXXXX", docsPath];
char template[filePath.length + 1];
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/CDVContacts.h
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVContacts.h b/lib/cordova-ios/CordovaLib/Classes/CDVContacts.h
index 17470c0..0342f5b 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVContacts.h
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVContacts.h
@@ -24,9 +24,9 @@
#import "CDVContact.h"
@interface CDVContacts : CDVPlugin <ABNewPersonViewControllerDelegate,
- ABPersonViewControllerDelegate,
- ABPeoplePickerNavigationControllerDelegate
- >
+ ABPersonViewControllerDelegate,
+ ABPeoplePickerNavigationControllerDelegate
+ >
{
ABAddressBookRef addressBook;
}
@@ -63,7 +63,7 @@
- (void)newPersonViewController:(ABNewPersonViewController*)newPersonViewController didCompleteWithNewPerson:(ABRecordRef)person;
- (BOOL)personViewController:(ABPersonViewController*)personViewController shouldPerformDefaultActionForPerson:(ABRecordRef)person
- property :(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifierForValue;
+ property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifierForValue;
/*
* search - searches for contacts. Only person records are currently supported.
@@ -140,9 +140,9 @@
- (CDVAddressBookAccessError*)initWithCode:(CDVContactError)code;
@end
-typedef void (^CDVAddressBookWorkerBlock)(
- ABAddressBookRef addressBook,
- CDVAddressBookAccessError * error
+typedef void (^ CDVAddressBookWorkerBlock)(
+ ABAddressBookRef addressBook,
+ CDVAddressBookAccessError* error
);
@interface CDVAddressBookHelper : NSObject
{}
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/CDVContacts.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVContacts.m b/lib/cordova-ios/CordovaLib/Classes/CDVContacts.m
index 3faf6ba..6cb9f08 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVContacts.m
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVContacts.m
@@ -77,26 +77,26 @@
CDVAddressBookHelper* abHelper = [[CDVAddressBookHelper alloc] init];
CDVContacts* __weak weakSelf = self; // play it safe to avoid retain cycles
- [abHelper createAddressBook: ^(ABAddressBookRef addrBook, CDVAddressBookAccessError * errCode) {
- if (addrBook == NULL) {
- // permission was denied or other error just return (no error callback)
- return;
- }
- CDVNewContactsController* npController = [[CDVNewContactsController alloc] init];
- npController.addressBook = addrBook; // a CF retaining assign
- CFRelease (addrBook);
+ [abHelper createAddressBook: ^(ABAddressBookRef addrBook, CDVAddressBookAccessError* errCode) {
+ if (addrBook == NULL) {
+ // permission was denied or other error just return (no error callback)
+ return;
+ }
+ CDVNewContactsController* npController = [[CDVNewContactsController alloc] init];
+ npController.addressBook = addrBook; // a CF retaining assign
+ CFRelease(addrBook);
- npController.newPersonViewDelegate = self;
- npController.callbackId = callbackId;
+ npController.newPersonViewDelegate = self;
+ npController.callbackId = callbackId;
- UINavigationController* navController = [[UINavigationController alloc] initWithRootViewController:npController];
+ UINavigationController* navController = [[UINavigationController alloc] initWithRootViewController:npController];
- if ([weakSelf.viewController respondsToSelector:@selector(presentViewController:::)]) {
- [weakSelf.viewController presentViewController:navController animated:YES completion:nil];
- } else {
- [weakSelf.viewController presentModalViewController:navController animated:YES];
- }
- }];
+ if ([weakSelf.viewController respondsToSelector:@selector(presentViewController:::)]) {
+ [weakSelf.viewController presentViewController:navController animated:YES completion:nil];
+ } else {
+ [weakSelf.viewController presentModalViewController:navController animated:YES];
+ }
+ }];
}
- (void)newPersonViewController:(ABNewPersonViewController*)newPersonViewController didCompleteWithNewPerson:(ABRecordRef)person
@@ -130,48 +130,48 @@
CDVAddressBookHelper* abHelper = [[CDVAddressBookHelper alloc] init];
CDVContacts* __weak weakSelf = self; // play it safe to avoid retain cycles
- [abHelper createAddressBook: ^(ABAddressBookRef addrBook, CDVAddressBookAccessError * errCode) {
- if (addrBook == NULL) {
- // permission was denied or other error - return error
- CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageToErrorObject:errCode ? errCode.errorCode:UNKNOWN_ERROR];
- [weakSelf.commandDelegate sendPluginResult:result callbackId:callbackId];
- return;
- }
- ABRecordRef rec = ABAddressBookGetPersonWithRecordID (addrBook, recordID);
-
- if (rec) {
- CDVDisplayContactViewController* personController = [[CDVDisplayContactViewController alloc] init];
- personController.displayedPerson = rec;
- personController.personViewDelegate = self;
- personController.allowsEditing = NO;
+ [abHelper createAddressBook: ^(ABAddressBookRef addrBook, CDVAddressBookAccessError* errCode) {
+ if (addrBook == NULL) {
+ // permission was denied or other error - return error
+ CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageToErrorObject:errCode ? errCode.errorCode:UNKNOWN_ERROR];
+ [weakSelf.commandDelegate sendPluginResult:result callbackId:callbackId];
+ return;
+ }
+ ABRecordRef rec = ABAddressBookGetPersonWithRecordID(addrBook, recordID);
- // create this so DisplayContactViewController will have a "back" button.
- UIViewController* parentController = [[UIViewController alloc] init];
- UINavigationController* navController = [[UINavigationController alloc] initWithRootViewController:parentController];
+ if (rec) {
+ CDVDisplayContactViewController* personController = [[CDVDisplayContactViewController alloc] init];
+ personController.displayedPerson = rec;
+ personController.personViewDelegate = self;
+ personController.allowsEditing = NO;
- [navController pushViewController:personController animated:YES];
+ // create this so DisplayContactViewController will have a "back" button.
+ UIViewController* parentController = [[UIViewController alloc] init];
+ UINavigationController* navController = [[UINavigationController alloc] initWithRootViewController:parentController];
- if ([self.viewController respondsToSelector:@selector(presentViewController:::)]) {
- [self.viewController presentViewController:navController animated:YES completion:nil];
- } else {
- [self.viewController presentModalViewController:navController animated:YES];
- }
+ [navController pushViewController:personController animated:YES];
- if (bEdit) {
- // create the editing controller and push it onto the stack
- ABPersonViewController* editPersonController = [[ABPersonViewController alloc] init];
- editPersonController.displayedPerson = rec;
- editPersonController.personViewDelegate = self;
- editPersonController.allowsEditing = YES;
- [navController pushViewController:editPersonController animated:YES];
- }
+ if ([self.viewController respondsToSelector:@selector(presentViewController:::)]) {
+ [self.viewController presentViewController:navController animated:YES completion:nil];
} else {
- // no record, return error
- CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:UNKNOWN_ERROR];
- [weakSelf.commandDelegate sendPluginResult:result callbackId:callbackId];
+ [self.viewController presentModalViewController:navController animated:YES];
}
- CFRelease (addrBook);
- }];
+
+ if (bEdit) {
+ // create the editing controller and push it onto the stack
+ ABPersonViewController* editPersonController = [[ABPersonViewController alloc] init];
+ editPersonController.displayedPerson = rec;
+ editPersonController.personViewDelegate = self;
+ editPersonController.allowsEditing = YES;
+ [navController pushViewController:editPersonController animated:YES];
+ }
+ } else {
+ // no record, return error
+ CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:UNKNOWN_ERROR];
+ [weakSelf.commandDelegate sendPluginResult:result callbackId:callbackId];
+ }
+ CFRelease(addrBook);
+ }];
}
- (BOOL)personViewController:(ABPersonViewController*)personViewController shouldPerformDefaultActionForPerson:(ABRecordRef)person
@@ -284,95 +284,95 @@
NSDictionary* findOptions = [command.arguments objectAtIndex:1 withDefault:[NSNull null]];
[self.commandDelegate runInBackground:^{
- // from Apple: Important You must ensure that an instance of ABAddressBookRef is used by only one thread.
- // which is why address book is created within the dispatch queue.
- // more details here: http: //blog.byadrian.net/2012/05/05/ios-addressbook-framework-and-gcd/
- CDVAddressBookHelper* abHelper = [[CDVAddressBookHelper alloc] init];
- CDVContacts* __weak weakSelf = self; // play it safe to avoid retain cycles
- // it gets uglier, block within block.....
- [abHelper createAddressBook: ^(ABAddressBookRef addrBook, CDVAddressBookAccessError * errCode) {
- if (addrBook == NULL) {
- // permission was denied or other error - return error
- CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageToErrorObject:errCode ? errCode.errorCode:UNKNOWN_ERROR];
- [weakSelf.commandDelegate sendPluginResult:result callbackId:callbackId];
- return;
- }
+ // from Apple: Important You must ensure that an instance of ABAddressBookRef is used by only one thread.
+ // which is why address book is created within the dispatch queue.
+ // more details here: http: //blog.byadrian.net/2012/05/05/ios-addressbook-framework-and-gcd/
+ CDVAddressBookHelper* abHelper = [[CDVAddressBookHelper alloc] init];
+ CDVContacts* __weak weakSelf = self; // play it safe to avoid retain cycles
+ // it gets uglier, block within block.....
+ [abHelper createAddressBook: ^(ABAddressBookRef addrBook, CDVAddressBookAccessError* errCode) {
+ if (addrBook == NULL) {
+ // permission was denied or other error - return error
+ CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageToErrorObject:errCode ? errCode.errorCode:UNKNOWN_ERROR];
+ [weakSelf.commandDelegate sendPluginResult:result callbackId:callbackId];
+ return;
+ }
- NSArray* foundRecords = nil;
- // get the findOptions values
- BOOL multiple = NO; // default is false
- NSString* filter = nil;
- if (![findOptions isKindOfClass:[NSNull class]]) {
- id value = nil;
- filter = (NSString*)[findOptions objectForKey:@"filter"];
- value = [findOptions objectForKey:@"multiple"];
- if ([value isKindOfClass:[NSNumber class]]) {
- // multiple is a boolean that will come through as an NSNumber
- multiple = [(NSNumber*) value boolValue];
- // NSLog(@"multiple is: %d", multiple);
- }
- }
+ NSArray* foundRecords = nil;
+ // get the findOptions values
+ BOOL multiple = NO; // default is false
+ NSString* filter = nil;
+ if (![findOptions isKindOfClass:[NSNull class]]) {
+ id value = nil;
+ filter = (NSString*)[findOptions objectForKey:@"filter"];
+ value = [findOptions objectForKey:@"multiple"];
+ if ([value isKindOfClass:[NSNumber class]]) {
+ // multiple is a boolean that will come through as an NSNumber
+ multiple = [(NSNumber*)value boolValue];
+ // NSLog(@"multiple is: %d", multiple);
+ }
+ }
- NSDictionary* returnFields = [[CDVContact class] calcReturnFields:fields];
-
- NSMutableArray* matches = nil;
- if (!filter || [filter isEqualToString:@""]) {
- // get all records
- foundRecords = (__bridge_transfer NSArray*)ABAddressBookCopyArrayOfAllPeople (addrBook);
- if (foundRecords && [foundRecords count] > 0) {
- // create Contacts and put into matches array
- // doesn't make sense to ask for all records when multiple == NO but better check
- int xferCount = multiple == YES ? [foundRecords count]:1;
- matches = [NSMutableArray arrayWithCapacity:xferCount];
-
- for (int k = 0; k < xferCount; k++) {
- CDVContact* xferContact = [[CDVContact alloc] initFromABRecord:(__bridge ABRecordRef)[foundRecords objectAtIndex:k]];
- [matches addObject:xferContact];
- xferContact = nil;
- }
- }
- } else {
- foundRecords = (__bridge_transfer NSArray*)ABAddressBookCopyArrayOfAllPeople (addrBook);
- matches = [NSMutableArray arrayWithCapacity:1];
- BOOL bFound = NO;
- int testCount = [foundRecords count];
-
- for (int j = 0; j < testCount; j++) {
- CDVContact* testContact = [[CDVContact alloc] initFromABRecord:(__bridge ABRecordRef)[foundRecords objectAtIndex:j]];
- if (testContact) {
- bFound = [testContact foundValue:filter inFields:returnFields];
- if (bFound) {
- [matches addObject:testContact];
- }
- testContact = nil;
- }
- }
+ NSDictionary* returnFields = [[CDVContact class] calcReturnFields:fields];
+
+ NSMutableArray* matches = nil;
+ if (!filter || [filter isEqualToString:@""]) {
+ // get all records
+ foundRecords = (__bridge_transfer NSArray*)ABAddressBookCopyArrayOfAllPeople(addrBook);
+ if (foundRecords && ([foundRecords count] > 0)) {
+ // create Contacts and put into matches array
+ // doesn't make sense to ask for all records when multiple == NO but better check
+ int xferCount = multiple == YES ? [foundRecords count] : 1;
+ matches = [NSMutableArray arrayWithCapacity:xferCount];
+
+ for (int k = 0; k < xferCount; k++) {
+ CDVContact* xferContact = [[CDVContact alloc] initFromABRecord:(__bridge ABRecordRef)[foundRecords objectAtIndex:k]];
+ [matches addObject:xferContact];
+ xferContact = nil;
}
- NSMutableArray* returnContacts = [NSMutableArray arrayWithCapacity:1];
-
- if (matches != nil && [matches count] > 0) {
- // convert to JS Contacts format and return in callback
- // - returnFields determines what properties to return
- @autoreleasepool {
- int count = multiple == YES ? [matches count]:1;
-
- for (int i = 0; i < count; i++) {
- CDVContact* newContact = [matches objectAtIndex:i];
- NSDictionary* aContact = [newContact toDictionary:returnFields];
- [returnContacts addObject:aContact];
- }
+ }
+ } else {
+ foundRecords = (__bridge_transfer NSArray*)ABAddressBookCopyArrayOfAllPeople(addrBook);
+ matches = [NSMutableArray arrayWithCapacity:1];
+ BOOL bFound = NO;
+ int testCount = [foundRecords count];
+
+ for (int j = 0; j < testCount; j++) {
+ CDVContact* testContact = [[CDVContact alloc] initFromABRecord:(__bridge ABRecordRef)[foundRecords objectAtIndex:j]];
+ if (testContact) {
+ bFound = [testContact foundValue:filter inFields:returnFields];
+ if (bFound) {
+ [matches addObject:testContact];
}
+ testContact = nil;
}
- // return found contacts (array is empty if no contacts found)
- CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsArray:returnContacts];
- [weakSelf.commandDelegate sendPluginResult:result callbackId:callbackId];
- // NSLog(@"findCallback string: %@", jsString);
-
- if (addrBook) {
- CFRelease (addrBook);
+ }
+ }
+ NSMutableArray* returnContacts = [NSMutableArray arrayWithCapacity:1];
+
+ if ((matches != nil) && ([matches count] > 0)) {
+ // convert to JS Contacts format and return in callback
+ // - returnFields determines what properties to return
+ @autoreleasepool {
+ int count = multiple == YES ? [matches count] : 1;
+
+ for (int i = 0; i < count; i++) {
+ CDVContact* newContact = [matches objectAtIndex:i];
+ NSDictionary* aContact = [newContact toDictionary:returnFields];
+ [returnContacts addObject:aContact];
}
- }];
- }]; // end of workQueue block
+ }
+ }
+ // return found contacts (array is empty if no contacts found)
+ CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsArray:returnContacts];
+ [weakSelf.commandDelegate sendPluginResult:result callbackId:callbackId];
+ // NSLog(@"findCallback string: %@", jsString);
+
+ if (addrBook) {
+ CFRelease(addrBook);
+ }
+ }];
+ }]; // end of workQueue block
return;
}
@@ -383,81 +383,10 @@
NSDictionary* contactDict = [command.arguments objectAtIndex:0];
[self.commandDelegate runInBackground:^{
- CDVAddressBookHelper* abHelper = [[CDVAddressBookHelper alloc] init];
- CDVContacts* __weak weakSelf = self; // play it safe to avoid retain cycles
-
- [abHelper createAddressBook: ^(ABAddressBookRef addrBook, CDVAddressBookAccessError * errorCode) {
- CDVPluginResult* result = nil;
- if (addrBook == NULL) {
- // permission was denied or other error - return error
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:errorCode ? errorCode.errorCode:UNKNOWN_ERROR];
- [weakSelf.commandDelegate sendPluginResult:result callbackId:callbackId];
- return;
- }
-
- bool bIsError = FALSE, bSuccess = FALSE;
- BOOL bUpdate = NO;
- CDVContactError errCode = UNKNOWN_ERROR;
- CFErrorRef error;
- NSNumber* cId = [contactDict valueForKey:kW3ContactId];
- CDVContact* aContact = nil;
- ABRecordRef rec = nil;
- if (cId && ![cId isKindOfClass:[NSNull class]]) {
- rec = ABAddressBookGetPersonWithRecordID (addrBook, [cId intValue]);
- if (rec) {
- aContact = [[CDVContact alloc] initFromABRecord:rec];
- bUpdate = YES;
- }
- }
- if (!aContact) {
- aContact = [[CDVContact alloc] init];
- }
-
- bSuccess = [aContact setFromContactDict:contactDict asUpdate:bUpdate];
- if (bSuccess) {
- if (!bUpdate) {
- bSuccess = ABAddressBookAddRecord (addrBook, [aContact record], &error);
- }
- if (bSuccess) {
- bSuccess = ABAddressBookSave (addrBook, &error);
- }
- if (!bSuccess) { // need to provide error codes
- bIsError = TRUE;
- errCode = IO_ERROR;
- } else {
- // give original dictionary back? If generate dictionary from saved contact, have no returnFields specified
- // so would give back all fields (which W3C spec. indicates is not desired)
- // for now (while testing) give back saved, full contact
- NSDictionary* newContact = [aContact toDictionary:[CDVContact defaultFields]];
- // NSString* contactStr = [newContact JSONRepresentation];
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:newContact];
- }
- } else {
- bIsError = TRUE;
- errCode = IO_ERROR;
- }
- CFRelease (addrBook);
-
- if (bIsError) {
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:errCode];
- }
-
- if (result) {
- [weakSelf.commandDelegate sendPluginResult:result callbackId:callbackId];
- }
- }];
- }]; // end of queue
-}
-
-- (void)remove:(CDVInvokedUrlCommand*)command
-{
- NSString* callbackId = command.callbackId;
- NSNumber* cId = [command.arguments objectAtIndex:0];
-
- CDVAddressBookHelper* abHelper = [[CDVAddressBookHelper alloc] init];
- CDVContacts* __weak weakSelf = self; // play it safe to avoid retain cycles
+ CDVAddressBookHelper* abHelper = [[CDVAddressBookHelper alloc] init];
+ CDVContacts* __weak weakSelf = self; // play it safe to avoid retain cycles
- [abHelper createAddressBook: ^(ABAddressBookRef addrBook, CDVAddressBookAccessError * errorCode) {
+ [abHelper createAddressBook: ^(ABAddressBookRef addrBook, CDVAddressBookAccessError* errorCode) {
CDVPluginResult* result = nil;
if (addrBook == NULL) {
// permission was denied or other error - return error
@@ -467,50 +396,121 @@
}
bool bIsError = FALSE, bSuccess = FALSE;
+ BOOL bUpdate = NO;
CDVContactError errCode = UNKNOWN_ERROR;
CFErrorRef error;
+ NSNumber* cId = [contactDict valueForKey:kW3ContactId];
+ CDVContact* aContact = nil;
ABRecordRef rec = nil;
- if (cId && ![cId isKindOfClass:[NSNull class]] && ([cId intValue] != kABRecordInvalidID)) {
- rec = ABAddressBookGetPersonWithRecordID (addrBook, [cId intValue]);
+ if (cId && ![cId isKindOfClass:[NSNull class]]) {
+ rec = ABAddressBookGetPersonWithRecordID(addrBook, [cId intValue]);
if (rec) {
- bSuccess = ABAddressBookRemoveRecord (addrBook, rec, &error);
- if (!bSuccess) {
- bIsError = TRUE;
- errCode = IO_ERROR;
- } else {
- bSuccess = ABAddressBookSave (addrBook, &error);
- if (!bSuccess) {
- bIsError = TRUE;
- errCode = IO_ERROR;
- } else {
- // set id to null
- // [contactDict setObject:[NSNull null] forKey:kW3ContactId];
- // result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary: contactDict];
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
- // NSString* contactStr = [contactDict JSONRepresentation];
- }
- }
- } else {
- // no record found return error
+ aContact = [[CDVContact alloc] initFromABRecord:rec];
+ bUpdate = YES;
+ }
+ }
+ if (!aContact) {
+ aContact = [[CDVContact alloc] init];
+ }
+
+ bSuccess = [aContact setFromContactDict:contactDict asUpdate:bUpdate];
+ if (bSuccess) {
+ if (!bUpdate) {
+ bSuccess = ABAddressBookAddRecord(addrBook, [aContact record], &error);
+ }
+ if (bSuccess) {
+ bSuccess = ABAddressBookSave(addrBook, &error);
+ }
+ if (!bSuccess) { // need to provide error codes
bIsError = TRUE;
- errCode = UNKNOWN_ERROR;
+ errCode = IO_ERROR;
+ } else {
+ // give original dictionary back? If generate dictionary from saved contact, have no returnFields specified
+ // so would give back all fields (which W3C spec. indicates is not desired)
+ // for now (while testing) give back saved, full contact
+ NSDictionary* newContact = [aContact toDictionary:[CDVContact defaultFields]];
+ // NSString* contactStr = [newContact JSONRepresentation];
+ result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:newContact];
}
} else {
- // invalid contact id provided
bIsError = TRUE;
- errCode = INVALID_ARGUMENT_ERROR;
+ errCode = IO_ERROR;
}
+ CFRelease(addrBook);
- if (addrBook) {
- CFRelease (addrBook);
- }
if (bIsError) {
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:errCode];
}
+
if (result) {
[weakSelf.commandDelegate sendPluginResult:result callbackId:callbackId];
}
}];
+ }]; // end of queue
+}
+
+- (void)remove:(CDVInvokedUrlCommand*)command
+{
+ NSString* callbackId = command.callbackId;
+ NSNumber* cId = [command.arguments objectAtIndex:0];
+
+ CDVAddressBookHelper* abHelper = [[CDVAddressBookHelper alloc] init];
+ CDVContacts* __weak weakSelf = self; // play it safe to avoid retain cycles
+
+ [abHelper createAddressBook: ^(ABAddressBookRef addrBook, CDVAddressBookAccessError* errorCode) {
+ CDVPluginResult* result = nil;
+ if (addrBook == NULL) {
+ // permission was denied or other error - return error
+ result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:errorCode ? errorCode.errorCode:UNKNOWN_ERROR];
+ [weakSelf.commandDelegate sendPluginResult:result callbackId:callbackId];
+ return;
+ }
+
+ bool bIsError = FALSE, bSuccess = FALSE;
+ CDVContactError errCode = UNKNOWN_ERROR;
+ CFErrorRef error;
+ ABRecordRef rec = nil;
+ if (cId && ![cId isKindOfClass:[NSNull class]] && ([cId intValue] != kABRecordInvalidID)) {
+ rec = ABAddressBookGetPersonWithRecordID(addrBook, [cId intValue]);
+ if (rec) {
+ bSuccess = ABAddressBookRemoveRecord(addrBook, rec, &error);
+ if (!bSuccess) {
+ bIsError = TRUE;
+ errCode = IO_ERROR;
+ } else {
+ bSuccess = ABAddressBookSave(addrBook, &error);
+ if (!bSuccess) {
+ bIsError = TRUE;
+ errCode = IO_ERROR;
+ } else {
+ // set id to null
+ // [contactDict setObject:[NSNull null] forKey:kW3ContactId];
+ // result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary: contactDict];
+ result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
+ // NSString* contactStr = [contactDict JSONRepresentation];
+ }
+ }
+ } else {
+ // no record found return error
+ bIsError = TRUE;
+ errCode = UNKNOWN_ERROR;
+ }
+ } else {
+ // invalid contact id provided
+ bIsError = TRUE;
+ errCode = INVALID_ARGUMENT_ERROR;
+ }
+
+ if (addrBook) {
+ CFRelease(addrBook);
+ }
+ if (bIsError) {
+ result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:errCode];
+ }
+ if (result) {
+ [weakSelf.commandDelegate sendPluginResult:result callbackId:callbackId];
+ }
+ }];
return;
}
@@ -569,24 +569,24 @@
addressBook = ABAddressBookCreateWithOptions(NULL, &error);
// NSLog(@"addressBook access: %lu", status);
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
- // callback can occur in background, address book must be accessed on thread it was created on
- dispatch_sync (dispatch_get_main_queue (), ^{
+ // callback can occur in background, address book must be accessed on thread it was created on
+ dispatch_sync(dispatch_get_main_queue(), ^{
if (error) {
- workerBlock (NULL, [[CDVAddressBookAccessError alloc] initWithCode:UNKNOWN_ERROR]);
+ workerBlock(NULL, [[CDVAddressBookAccessError alloc] initWithCode:UNKNOWN_ERROR]);
} else if (!granted) {
- workerBlock (NULL, [[CDVAddressBookAccessError alloc] initWithCode:PERMISSION_DENIED_ERROR]);
+ workerBlock(NULL, [[CDVAddressBookAccessError alloc] initWithCode:PERMISSION_DENIED_ERROR]);
} else {
// access granted
- workerBlock (addressBook, [[CDVAddressBookAccessError alloc] initWithCode:UNKNOWN_ERROR]);
+ workerBlock(addressBook, [[CDVAddressBookAccessError alloc] initWithCode:UNKNOWN_ERROR]);
}
});
- });
+ });
} else
#endif
{
// iOS 4 or 5 no checks needed
- addressBook = ABAddressBookCreate ();
- workerBlock (addressBook, NULL);
+ addressBook = ABAddressBookCreate();
+ workerBlock(addressBook, NULL);
}
}
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/CDVEcho.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVEcho.m b/lib/cordova-ios/CordovaLib/Classes/CDVEcho.m
index 916e315..c74990d 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVEcho.m
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVEcho.m
@@ -51,4 +51,11 @@
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}
+- (void)echoMultiPart:(CDVInvokedUrlCommand*)command
+{
+ CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsMultipart:command.arguments];
+
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+}
+
@end
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/CDVExif.h
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVExif.h b/lib/cordova-ios/CordovaLib/Classes/CDVExif.h
new file mode 100644
index 0000000..3e8adbd
--- /dev/null
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVExif.h
@@ -0,0 +1,43 @@
+/*
+ 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.
+ */
+
+#ifndef CordovaLib_ExifData_h
+#define CordovaLib_ExifData_h
+
+// exif data types
+typedef enum exifDataTypes {
+ EDT_UBYTE = 1, // 8 bit unsigned integer
+ EDT_ASCII_STRING, // 8 bits containing 7 bit ASCII code, null terminated
+ EDT_USHORT, // 16 bit unsigned integer
+ EDT_ULONG, // 32 bit unsigned integer
+ EDT_URATIONAL, // 2 longs, first is numerator and second is denominator
+ EDT_SBYTE,
+ EDT_UNDEFINED, // 8 bits
+ EDT_SSHORT,
+ EDT_SLONG, // 32bit signed integer (2's complement)
+ EDT_SRATIONAL, // 2 SLONGS, first long is numerator, second is denominator
+ EDT_SINGLEFLOAT,
+ EDT_DOUBLEFLOAT
+} ExifDataTypes;
+
+// maps integer code for exif data types to width in bytes
+static const int DataTypeToWidth[] = {1,1,2,4,8,1,1,2,4,8,4,8};
+
+static const int RECURSE_HORIZON = 8;
+#endif
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/CDVFile.h
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVFile.h b/lib/cordova-ios/CordovaLib/Classes/CDVFile.h
index 4862921..eaf8cbe 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVFile.h
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVFile.h
@@ -21,6 +21,7 @@
#import "CDVPlugin.h"
enum CDVFileError {
+ NO_ERROR = 0,
NOT_FOUND_ERR = 1,
SECURITY_ERR = 2,
ABORT_ERR = 3,
@@ -76,6 +77,7 @@ extern NSString* const kCDVAssetsLibraryPrefix;
- (void)readAsText:(CDVInvokedUrlCommand*)command;
- (void)readAsDataURL:(CDVInvokedUrlCommand*)command;
+- (void)readAsArrayBuffer:(CDVInvokedUrlCommand*)command;
- (NSString*)getMimeTypeFromPath:(NSString*)fullPath;
- (void)write:(CDVInvokedUrlCommand*)command;
- (void)testFileExists:(CDVInvokedUrlCommand*)command;
[2/6] 2.6.0rc1 used for libs now. Bumped npm version to 2.6.0. added
androids local.properties to gitignore.
Posted by fi...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/CDVPlugin.h
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVPlugin.h b/lib/cordova-ios/CordovaLib/Classes/CDVPlugin.h
index f5b50eb..6e25a27 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVPlugin.h
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVPlugin.h
@@ -23,10 +23,10 @@
#import "NSMutableArray+QueueAdditions.h"
#import "CDVCommandDelegate.h"
-#define CDVPageDidLoadNotification @"CDVPageDidLoadNotification"
-#define CDVPluginHandleOpenURLNotification @"CDVPluginHandleOpenURLNotification"
-#define CDVPluginResetNotification @"CDVPluginResetNotification"
-#define CDVLocalNotification @"CDVLocalNotification"
+NSString* const CDVPageDidLoadNotification;
+NSString* const CDVPluginHandleOpenURLNotification;
+NSString* const CDVPluginResetNotification;
+NSString* const CDVLocalNotification;
@interface CDVPlugin : NSObject {}
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/CDVPlugin.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVPlugin.m b/lib/cordova-ios/CordovaLib/Classes/CDVPlugin.m
index a42d241..8c932a0 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVPlugin.m
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVPlugin.m
@@ -19,6 +19,11 @@
#import "CDVPlugin.h"
+NSString* const CDVPageDidLoadNotification = @"CDVPageDidLoadNotification";
+NSString* const CDVPluginHandleOpenURLNotification = @"CDVPluginHandleOpenURLNotification";
+NSString* const CDVPluginResetNotification = @"CDVPluginResetNotification";
+NSString* const CDVLocalNotification = @"CDVLocalNotification";
+
@interface CDVPlugin ()
@property (readwrite, assign) BOOL hasPendingOperation;
@@ -41,7 +46,7 @@
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onAppTerminate) name:UIApplicationWillTerminateNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMemoryWarning) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleOpenURL:) name:CDVPluginHandleOpenURLNotification object:nil];
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onReset) name:CDVPluginResetNotification object:nil];
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onReset) name:CDVPluginResetNotification object:theWebView];
self.webView = theWebView;
}
@@ -64,7 +69,7 @@
// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveLocalNotification:) name:CDVLocalNotification object:nil];
// Added in 2.5.0
- // [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pageDidLoad:) name:CDVPageDidLoadNotification object:nil];
+ // [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pageDidLoad:) name:CDVPageDidLoadNotification object:self.webView];
}
- (void)dispose
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/CDVPluginResult.h
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVPluginResult.h b/lib/cordova-ios/CordovaLib/Classes/CDVPluginResult.h
index 8683205..11b5377 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVPluginResult.h
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVPluginResult.h
@@ -37,6 +37,9 @@ typedef enum {
@property (nonatomic, strong, readonly) NSNumber* status;
@property (nonatomic, strong, readonly) id message;
@property (nonatomic, strong) NSNumber* keepCallback;
+// This property can be used to scope the lifetime of another object. For example,
+// Use it to store the associated NSData when `message` is created using initWithBytesNoCopy.
+@property (nonatomic, strong) id associatedObject;
- (CDVPluginResult*)init;
+ (CDVPluginResult*)resultWithStatus:(CDVCommandStatus)statusOrdinal;
@@ -47,6 +50,7 @@ typedef enum {
+ (CDVPluginResult*)resultWithStatus:(CDVCommandStatus)statusOrdinal messageAsBool:(BOOL)theMessage;
+ (CDVPluginResult*)resultWithStatus:(CDVCommandStatus)statusOrdinal messageAsDictionary:(NSDictionary*)theMessage;
+ (CDVPluginResult*)resultWithStatus:(CDVCommandStatus)statusOrdinal messageAsArrayBuffer:(NSData*)theMessage;
++ (CDVPluginResult*)resultWithStatus:(CDVCommandStatus)statusOrdinal messageAsMultipart:(NSArray*)theMessages;
+ (CDVPluginResult*)resultWithStatus:(CDVCommandStatus)statusOrdinal messageToErrorObject:(int)errorCode;
+ (void)setVerbose:(BOOL)verbose;
@@ -54,6 +58,9 @@ typedef enum {
- (void)setKeepCallbackAsBool:(BOOL)bKeepCallback;
+- (NSString*)argumentsAsJSON;
+
+// These methods are used by the legacy plugin return result method
- (NSString*)toJSONString;
- (NSString*)toSuccessCallbackString:(NSString*)callbackId;
- (NSString*)toErrorCallbackString:(NSString*)callbackId;
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/CDVPluginResult.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVPluginResult.m b/lib/cordova-ios/CordovaLib/Classes/CDVPluginResult.m
index d9ba08f..af7c528 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVPluginResult.m
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVPluginResult.m
@@ -29,10 +29,40 @@
@end
@implementation CDVPluginResult
-@synthesize status, message, keepCallback;
+@synthesize status, message, keepCallback, associatedObject;
static NSArray* org_apache_cordova_CommandStatusMsgs;
+id messageFromArrayBuffer(NSData* data)
+{
+ return @{
+ @"CDVType" : @"ArrayBuffer",
+ @"data" :[data base64EncodedString]
+ };
+}
+
+id massageMessage(id message)
+{
+ if ([message isKindOfClass:[NSData class]]) {
+ return messageFromArrayBuffer(message);
+ }
+ return message;
+}
+
+id messageFromMultipart(NSArray* theMessages)
+{
+ NSMutableArray* messages = [NSMutableArray arrayWithArray:theMessages];
+
+ for (NSUInteger i = 0; i < messages.count; ++i) {
+ [messages replaceObjectAtIndex:i withObject:massageMessage([messages objectAtIndex:i])];
+ }
+
+ return @{
+ @"CDVType" : @"MultiPart",
+ @"messages" : messages
+ };
+}
+
+ (void)initialize
{
org_apache_cordova_CommandStatusMsgs = [[NSArray alloc] initWithObjects:@"No result",
@@ -101,17 +131,17 @@ static NSArray* org_apache_cordova_CommandStatusMsgs;
+ (CDVPluginResult*)resultWithStatus:(CDVCommandStatus)statusOrdinal messageAsArrayBuffer:(NSData*)theMessage
{
- NSDictionary* arrDict = [NSDictionary dictionaryWithObjectsAndKeys:
- @"ArrayBuffer", @"CDVType",
- [theMessage base64EncodedString], @"data",
- nil];
+ return [[self alloc] initWithStatus:statusOrdinal message:messageFromArrayBuffer(theMessage)];
+}
- return [[self alloc] initWithStatus:statusOrdinal message:arrDict];
++ (CDVPluginResult*)resultWithStatus:(CDVCommandStatus)statusOrdinal messageAsMultipart:(NSArray*)theMessages
+{
+ return [[self alloc] initWithStatus:statusOrdinal message:messageFromMultipart(theMessages)];
}
+ (CDVPluginResult*)resultWithStatus:(CDVCommandStatus)statusOrdinal messageToErrorObject:(int)errorCode
{
- NSDictionary* errDict = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:errorCode] forKey:@"code"];
+ NSDictionary* errDict = @{@"code" :[NSNumber numberWithInt:errorCode]};
return [[self alloc] initWithStatus:statusOrdinal message:errDict];
}
@@ -121,6 +151,19 @@ static NSArray* org_apache_cordova_CommandStatusMsgs;
[self setKeepCallback:[NSNumber numberWithBool:bKeepCallback]];
}
+- (NSString*)argumentsAsJSON
+{
+ id arguments = (self.message == nil ? [NSNull null] : self.message);
+ NSArray* argumentsWrappedInArray = [NSArray arrayWithObject:arguments];
+
+ NSString* argumentsJSON = [argumentsWrappedInArray JSONString];
+
+ argumentsJSON = [argumentsJSON substringWithRange:NSMakeRange(1, [argumentsJSON length] - 2)];
+
+ return argumentsJSON;
+}
+
+// These methods are used by the legacy plugin return result method
- (NSString*)toJSONString
{
NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/CDVReachability.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVReachability.m b/lib/cordova-ios/CordovaLib/Classes/CDVReachability.m
index 3c5a48b..89f4ec9 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVReachability.m
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVReachability.m
@@ -61,18 +61,18 @@ static void CDVPrintReachabilityFlags(SCNetworkReachabilityFlags flags, const ch
{
#if kShouldPrintReachabilityFlags
NSLog(@"Reachability Flag Status: %c%c %c%c%c%c%c%c%c %s\n",
- (flags & kSCNetworkReachabilityFlagsIsWWAN) ? 'W' : '-',
- (flags & kSCNetworkReachabilityFlagsReachable) ? 'R' : '-',
-
- (flags & kSCNetworkReachabilityFlagsTransientConnection) ? 't' : '-',
- (flags & kSCNetworkReachabilityFlagsConnectionRequired) ? 'c' : '-',
- (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) ? 'C' : '-',
- (flags & kSCNetworkReachabilityFlagsInterventionRequired) ? 'i' : '-',
- (flags & kSCNetworkReachabilityFlagsConnectionOnDemand) ? 'D' : '-',
- (flags & kSCNetworkReachabilityFlagsIsLocalAddress) ? 'l' : '-',
- (flags & kSCNetworkReachabilityFlagsIsDirect) ? 'd' : '-',
- comment
- );
+ (flags & kSCNetworkReachabilityFlagsIsWWAN) ? 'W' : '-',
+ (flags & kSCNetworkReachabilityFlagsReachable) ? 'R' : '-',
+
+ (flags & kSCNetworkReachabilityFlagsTransientConnection) ? 't' : '-',
+ (flags & kSCNetworkReachabilityFlagsConnectionRequired) ? 'c' : '-',
+ (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) ? 'C' : '-',
+ (flags & kSCNetworkReachabilityFlagsInterventionRequired) ? 'i' : '-',
+ (flags & kSCNetworkReachabilityFlagsConnectionOnDemand) ? 'D' : '-',
+ (flags & kSCNetworkReachabilityFlagsIsLocalAddress) ? 'l' : '-',
+ (flags & kSCNetworkReachabilityFlagsIsDirect) ? 'd' : '-',
+ comment
+ );
#endif
}
@@ -90,7 +90,7 @@ static void CDVReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkRe
return;
}
- if (![(__bridge NSObject*) info isKindOfClass:[CDVReachability class]]) {
+ if (![(__bridge NSObject*)info isKindOfClass :[CDVReachability class]]) {
NSLog(@"info was wrong class in ReachabilityCallback");
return;
}
@@ -214,7 +214,7 @@ static void CDVReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkRe
}
if ((((flags & kSCNetworkReachabilityFlagsConnectionOnDemand) != 0) ||
- ((flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0))) {
+ ((flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0))) {
// ... and the connection is on-demand (or on-traffic) if the
// calling application is using the CFSocketStream or higher APIs
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/CDVSound.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVSound.m b/lib/cordova-ios/CordovaLib/Classes/CDVSound.m
index 99515d7..88fbbd6 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVSound.m
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVSound.m
@@ -87,7 +87,7 @@
NSLog(@"Will use resource '%@' from the documents folder with path = %@", resourcePath, filePath);
} else {
// if resourcePath is not from FileSystem put in tmp dir, else attempt to use provided resource path
- NSString* tmpPath = [NSTemporaryDirectory ()stringByStandardizingPath];
+ NSString* tmpPath = [NSTemporaryDirectory()stringByStandardizingPath];
BOOL isTmp = [resourcePath rangeOfString:tmpPath].location != NSNotFound;
BOOL isDoc = [resourcePath rangeOfString:docsPath].location != NSNotFound;
if (!isTmp && !isDoc) {
@@ -127,7 +127,7 @@
filePath = [self.commandDelegate pathForResource:resourcePath];
if (filePath == nil) {
// see if this exists in the documents/temp directory from a previous recording
- NSString* testPath = [NSString stringWithFormat:@"%@/%@", [NSTemporaryDirectory ()stringByStandardizingPath], resourcePath];
+ NSString* testPath = [NSString stringWithFormat:@"%@/%@", [NSTemporaryDirectory()stringByStandardizingPath], resourcePath];
if ([[NSFileManager defaultManager] fileExistsAtPath:testPath]) {
// inefficient as existence will be checked again below but only way to determine if file exists from previous recording
filePath = testPath;
@@ -385,7 +385,7 @@
// bug in AVAudioPlayer when playing downloaded data in NSData - we have to download the file and play from disk
CFUUIDRef uuidRef = CFUUIDCreate(kCFAllocatorDefault);
CFStringRef uuidString = CFUUIDCreateString(kCFAllocatorDefault, uuidRef);
- NSString* filePath = [NSString stringWithFormat:@"%@/%@", [NSTemporaryDirectory ()stringByStandardizingPath], uuidString];
+ NSString* filePath = [NSString stringWithFormat:@"%@/%@", [NSTemporaryDirectory()stringByStandardizingPath], uuidString];
CFRelease(uuidString);
CFRelease(uuidRef);
@@ -458,9 +458,19 @@
double position = [[command.arguments objectAtIndex:1] doubleValue];
if ((audioFile != nil) && (audioFile.player != nil)) {
+ NSString* jsString;
double posInSeconds = position / 1000;
- audioFile.player.currentTime = posInSeconds;
- NSString* jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%f);", @"cordova.require('cordova/plugin/Media').onStatus", mediaId, MEDIA_POSITION, posInSeconds];
+ if (posInSeconds >= audioFile.player.duration) {
+ // The seek is past the end of file. Stop media and reset to beginning instead of seeking past the end.
+ [audioFile.player stop];
+ audioFile.player.currentTime = 0;
+ jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%.3f);\n%@(\"%@\",%d,%d);", @"cordova.require('cordova/plugin/Media').onStatus", mediaId, MEDIA_POSITION, 0.0, @"cordova.require('cordova/plugin/Media').onStatus", mediaId, MEDIA_STATE, MEDIA_STOPPED];
+ // NSLog(@"seekToEndJsString=%@",jsString);
+ } else {
+ audioFile.player.currentTime = posInSeconds;
+ jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%f);", @"cordova.require('cordova/plugin/Media').onStatus", mediaId, MEDIA_POSITION, posInSeconds];
+ // NSLog(@"seekJsString=%@",jsString);
+ }
[self.commandDelegate evalJs:jsString];
}
@@ -625,6 +635,7 @@
NSLog(@"Finished playing audio sample '%@'", audioFile.resourcePath);
}
if (flag) {
+ audioFile.player.currentTime = 0;
jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%d);", @"cordova.require('cordova/plugin/Media').onStatus", mediaId, MEDIA_STATE, MEDIA_STOPPED];
} else {
// jsString = [NSString stringWithFormat: @"%@(\"%@\",%d,%d);", @"cordova.require('cordova/plugin/Media').onStatus", mediaId, MEDIA_ERROR, MEDIA_ERR_DECODE];
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/CDVSplashScreen.h
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVSplashScreen.h b/lib/cordova-ios/CordovaLib/Classes/CDVSplashScreen.h
index a0868a0..704ab43 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVSplashScreen.h
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVSplashScreen.h
@@ -23,7 +23,8 @@
@interface CDVSplashScreen : CDVPlugin {
UIActivityIndicatorView* _activityView;
UIImageView* _imageView;
- UIView* _parentView;
+ NSString* _curImageName;
+ BOOL _visible;
}
- (void)show:(CDVInvokedUrlCommand*)command;
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/CDVSplashScreen.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVSplashScreen.m b/lib/cordova-ios/CordovaLib/Classes/CDVSplashScreen.m
index cba1b53..efe3eaa 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVSplashScreen.m
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVSplashScreen.m
@@ -19,29 +19,25 @@
#import "CDVSplashScreen.h"
-#define kSplashScreenStateShow 0
-#define kSplashScreenStateHide 1
-
#define kSplashScreenDurationDefault 0.25f
@implementation CDVSplashScreen
- (void)pluginInitialize
{
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pageDidLoad) name:CDVPageDidLoadNotification object:nil];
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onOrientationWillChange:) name:UIApplicationWillChangeStatusBarOrientationNotification object:nil];
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pageDidLoad) name:CDVPageDidLoadNotification object:self.webView];
- [self show:nil];
+ [self setVisible:YES];
}
- (void)show:(CDVInvokedUrlCommand*)command
{
- [self updateSplashScreenWithState:kSplashScreenStateShow];
+ [self setVisible:YES];
}
- (void)hide:(CDVInvokedUrlCommand*)command
{
- [self updateSplashScreenWithState:kSplashScreenStateHide];
+ [self setVisible:NO];
}
- (void)pageDidLoad
@@ -50,16 +46,13 @@
// if value is missing, default to yes
if ((autoHideSplashScreenValue == nil) || [autoHideSplashScreenValue boolValue]) {
- [self hide:nil];
+ [self setVisible:NO];
}
}
-- (void)onOrientationWillChange:(NSNotification*)notification
+- (void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary*)change context:(void*)context
{
- if (_imageView != nil) {
- UIInterfaceOrientation orientation = [notification.userInfo[UIApplicationStatusBarOrientationUserInfoKey] intValue];
- [self updateSplashImageForOrientation:orientation];
- }
+ [self updateImage];
}
- (void)createViews
@@ -83,43 +76,115 @@
topActivityIndicatorStyle = UIActivityIndicatorViewStyleGray;
}
+ UIView* parentView = self.viewController.view;
+ parentView.userInteractionEnabled = NO; // disable user interaction while splashscreen is shown
_activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:topActivityIndicatorStyle];
- _activityView.tag = 2;
- _activityView.center = self.viewController.view.center;
+ _activityView.center = CGPointMake(parentView.bounds.size.width / 2, parentView.bounds.size.height / 2);
+ _activityView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin
+ | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin;
[_activityView startAnimating];
+ // Set the frame & image later.
_imageView = [[UIImageView alloc] init];
- [self.viewController.view addSubview:_imageView];
- [self.viewController.view.superview addSubview:_activityView];
- [self.viewController.view.superview layoutSubviews];
+ [parentView addSubview:_imageView];
+ [parentView addSubview:_activityView];
+
+ // Frame is required when launching in portrait mode.
+ // Bounds for landscape since it captures the rotation.
+ [parentView addObserver:self forKeyPath:@"frame" options:0 context:nil];
+ [parentView addObserver:self forKeyPath:@"bounds" options:0 context:nil];
+
+ [self updateImage];
}
-- (void)updateSplashImageForOrientation:(UIInterfaceOrientation)orientation
+- (void)destroyViews
{
- // IPHONE (default)
- NSString* imageName = @"Default";
+ [_imageView removeFromSuperview];
+ [_activityView removeFromSuperview];
+ _imageView = nil;
+ _activityView = nil;
+ _curImageName = nil;
+
+ self.viewController.view.userInteractionEnabled = YES; // re-enable user interaction upon completion
+ [self.viewController.view removeObserver:self forKeyPath:@"frame"];
+ [self.viewController.view removeObserver:self forKeyPath:@"bounds"];
+}
+
+// Sets the view's frame and image.
+- (void)updateImage
+{
+ UIInterfaceOrientation orientation = self.viewController.interfaceOrientation;
+
+ // Use UILaunchImageFile if specified in plist. Otherwise, use Default.
+ NSString* imageName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"UILaunchImageFile"];
+
+ if (imageName) {
+ imageName = [imageName stringByDeletingPathExtension];
+ } else {
+ imageName = @"Default";
+ }
if (CDV_IsIPhone5()) {
imageName = [imageName stringByAppendingString:@"-568h"];
} else if (CDV_IsIPad()) {
- // set default to portrait upside down
- imageName = @"Default-Portrait"; // @"Default-PortraitUpsideDown.png";
+ switch (orientation) {
+ case UIInterfaceOrientationLandscapeLeft:
+ case UIInterfaceOrientationLandscapeRight:
+ imageName = [imageName stringByAppendingString:@"-Landscape"];
+ break;
+
+ case UIInterfaceOrientationPortrait:
+ case UIInterfaceOrientationPortraitUpsideDown:
+ default:
+ imageName = [imageName stringByAppendingString:@"-Portrait"];
+ break;
+ }
+ }
+
+ if (![imageName isEqualToString:_curImageName]) {
+ UIImage* img = [UIImage imageNamed:imageName];
+ _imageView.image = img;
+ _curImageName = imageName;
+ }
+
+ [self updateBounds];
+}
- if (orientation == UIInterfaceOrientationLandscapeLeft) {
- imageName = @"Default-Landscape.png"; // @"Default-LandscapeLeft.png";
- } else if (orientation == UIInterfaceOrientationLandscapeRight) {
- imageName = @"Default-Landscape.png"; // @"Default-LandscapeRight.png";
+- (void)updateBounds
+{
+ UIImage* img = _imageView.image;
+ CGRect imgBounds = CGRectMake(0, 0, img.size.width, img.size.height);
+
+ CGSize screenSize = [self.viewController.view convertRect:[UIScreen mainScreen].bounds fromView:nil].size;
+
+ // There's a special case when the image is the size of the screen.
+ if (CGSizeEqualToSize(screenSize, imgBounds.size)) {
+ CGRect statusFrame = [self.viewController.view convertRect:[UIApplication sharedApplication].statusBarFrame fromView:nil];
+ imgBounds.origin.y -= statusFrame.size.height;
+ } else {
+ CGRect viewBounds = self.viewController.view.bounds;
+ CGFloat imgAspect = imgBounds.size.width / imgBounds.size.height;
+ CGFloat viewAspect = viewBounds.size.width / viewBounds.size.height;
+ // This matches the behaviour of the native splash screen.
+ CGFloat ratio;
+ if (viewAspect > imgAspect) {
+ ratio = viewBounds.size.width / imgBounds.size.width;
+ } else {
+ ratio = viewBounds.size.height / imgBounds.size.height;
}
+ imgBounds.size.height *= ratio;
+ imgBounds.size.width *= ratio;
}
- _imageView.image = [UIImage imageNamed:imageName];
- _imageView.frame = CGRectMake(0, 0, _imageView.image.size.width, _imageView.image.size.height);
+ _imageView.frame = imgBounds;
}
-- (void)updateSplashScreenWithState:(int)state
+- (void)setVisible:(BOOL)visible
{
- float toAlpha = state == kSplashScreenStateShow ? 1.0f : 0.0f;
- BOOL hidden = state == kSplashScreenStateShow ? NO : YES;
+ if (visible == _visible) {
+ return;
+ }
+ _visible = visible;
id fadeSplashScreenValue = [self.commandDelegate.settings objectForKey:@"FadeSplashScreen"];
id fadeSplashScreenDuration = [self.commandDelegate.settings objectForKey:@"FadeSplashScreenDuration"];
@@ -129,45 +194,26 @@
if ((fadeSplashScreenValue == nil) || ![fadeSplashScreenValue boolValue]) {
fadeDuration = 0;
}
- if (hidden && (_imageView == nil)) {
- return;
- } else if (_imageView == nil) {
- [self createViews];
- fadeDuration = 0;
- }
-
- if (!hidden) {
- [self updateSplashImageForOrientation:self.viewController.interfaceOrientation];
- }
- if (fadeDuration == 0) {
- [_imageView setHidden:hidden];
- [_activityView setHidden:hidden];
- } else {
- if (state == kSplashScreenStateShow) {
- // reset states
- [_imageView setHidden:NO];
- [_activityView setHidden:NO];
- [_imageView setAlpha:0.0f];
- [_activityView setAlpha:0.0f];
+ // Never animate the showing of the splash screen.
+ if (visible) {
+ if (_imageView == nil) {
+ [self createViews];
}
-
+ } else if (fadeDuration == 0) {
+ [self destroyViews];
+ } else {
[UIView transitionWithView:self.viewController.view
duration:fadeDuration
options:UIViewAnimationOptionTransitionNone
animations:^(void) {
- [_imageView setAlpha:toAlpha];
- [_activityView setAlpha:toAlpha];
- }
+ [_imageView setAlpha:0];
+ [_activityView setAlpha:0];
+ }
+
completion:^(BOOL finished) {
- if (state == kSplashScreenStateHide) {
- // Clean-up resources.
- [_imageView removeFromSuperview];
- [_activityView removeFromSuperview];
- _imageView = nil;
- _activityView = nil;
- }
- }];
+ [self destroyViews];
+ }];
}
}
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/CDVURLProtocol.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVURLProtocol.m b/lib/cordova-ios/CordovaLib/Classes/CDVURLProtocol.m
index 1959c77..afc10de 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVURLProtocol.m
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVURLProtocol.m
@@ -31,7 +31,7 @@
@property (nonatomic) NSInteger statusCode;
@end
-static CDVWhitelist * gWhitelist = nil;
+static CDVWhitelist* gWhitelist = nil;
// Contains a set of NSNumbers of addresses of controllers. It doesn't store
// the actual pointer to avoid retaining.
static NSMutableSet* gRegisteredControllers = nil;
@@ -159,12 +159,12 @@ static CDVViewController *viewControllerForRequest(NSURLRequest* request)
[self sendResponseWithResponseCode:200 data:nil mimeType:nil];
return;
} else if ([[url absoluteString] hasPrefix:kCDVAssetsLibraryPrefix]) {
- ALAssetsLibraryAssetForURLResultBlock resultBlock = ^(ALAsset * asset) {
+ ALAssetsLibraryAssetForURLResultBlock resultBlock = ^(ALAsset* asset) {
if (asset) {
// We have the asset! Get the data and send it along.
ALAssetRepresentation* assetRepresentation = [asset defaultRepresentation];
- NSString* MIMEType = (__bridge_transfer NSString*)UTTypeCopyPreferredTagWithClass ((__bridge CFStringRef)[assetRepresentation UTI], kUTTagClassMIMEType);
- Byte* buffer = (Byte*)malloc ([assetRepresentation size]);
+ NSString* MIMEType = (__bridge_transfer NSString*)UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)[assetRepresentation UTI], kUTTagClassMIMEType);
+ Byte* buffer = (Byte*)malloc([assetRepresentation size]);
NSUInteger bufferSize = [assetRepresentation getBytes:buffer fromOffset:0.0 length:[assetRepresentation size] error:nil];
NSData* data = [NSData dataWithBytesNoCopy:buffer length:bufferSize freeWhenDone:YES];
[self sendResponseWithResponseCode:200 data:data mimeType:MIMEType];
@@ -173,7 +173,7 @@ static CDVViewController *viewControllerForRequest(NSURLRequest* request)
[self sendResponseWithResponseCode:404 data:nil mimeType:nil];
}
};
- ALAssetsLibraryAccessFailureBlock failureBlock = ^(NSError * error) {
+ ALAssetsLibraryAccessFailureBlock failureBlock = ^(NSError* error) {
// Retrieving the asset failed for some reason. Send an error.
[self sendResponseWithResponseCode:401 data:nil mimeType:nil];
};
@@ -202,7 +202,7 @@ static CDVViewController *viewControllerForRequest(NSURLRequest* request)
if (mimeType == nil) {
mimeType = @"text/plain";
}
- NSString* encodingName = [@"text/plain" isEqualToString:mimeType] ? @"UTF-8" : nil;
+ NSString* encodingName = [@"text/plain" isEqualToString : mimeType] ? @"UTF-8" : nil;
CDVHTTPURLResponse* response =
[[CDVHTTPURLResponse alloc] initWithURL:[[self request] URL]
MIMEType:mimeType
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/CDVUserAgentUtil.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVUserAgentUtil.m b/lib/cordova-ios/CordovaLib/Classes/CDVUserAgentUtil.m
index 5c43c51..9923d47 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVUserAgentUtil.m
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVUserAgentUtil.m
@@ -96,7 +96,7 @@ static NSMutableArray* gPendingSetUserAgentBlocks = nil;
void (^block)() = [gPendingSetUserAgentBlocks objectAtIndex:0];
[gPendingSetUserAgentBlocks removeObjectAtIndex:0];
gCurrentLockToken = ++gNextLockToken;
- NSLog (@"Gave lock %d", gCurrentLockToken);
+ NSLog(@"Gave lock %d", gCurrentLockToken);
block(gCurrentLockToken);
} else {
gCurrentLockToken = 0;
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/CDVViewController.h
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVViewController.h b/lib/cordova-ios/CordovaLib/Classes/CDVViewController.h
index 82e22f6..2338baf 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVViewController.h
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVViewController.h
@@ -22,15 +22,14 @@
#import "CDVAvailability.h"
#import "CDVInvokedUrlCommand.h"
#import "CDVCommandDelegate.h"
+#import "CDVCommandQueue.h"
#import "CDVWhitelist.h"
#import "CDVScreenOrientationDelegate.h"
-
-@class CDVCommandQueue;
-@class CDVCommandDelegateImpl;
+#import "CDVPlugin.h"
@interface CDVViewController : UIViewController <UIWebViewDelegate, CDVScreenOrientationDelegate>{
@protected
- CDVCommandDelegateImpl* _commandDelegate;
+ id <CDVCommandDelegate> _commandDelegate;
@protected
CDVCommandQueue* _commandQueue;
NSString* _userAgent;
@@ -49,7 +48,7 @@
@property (nonatomic, readwrite, copy) NSString* wwwFolderName;
@property (nonatomic, readwrite, copy) NSString* startPage;
@property (nonatomic, readonly, strong) CDVCommandQueue* commandQueue;
-@property (nonatomic, readonly, strong) CDVCommandDelegateImpl* commandDelegate;
+@property (nonatomic, readonly, strong) id <CDVCommandDelegate> commandDelegate;
@property (nonatomic, readonly) NSString* userAgent;
+ (NSDictionary*)getBundlePlist:(NSString*)plistName;
@@ -67,6 +66,7 @@
- (id)getCommandInstance:(NSString*)pluginName;
- (void)registerPlugin:(CDVPlugin*)plugin withClassName:(NSString*)className;
+- (void)registerPlugin:(CDVPlugin*)plugin withPluginName:(NSString*)pluginName;
- (BOOL)URLisAllowed:(NSURL*)url;
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/CDVViewController.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVViewController.m b/lib/cordova-ios/CordovaLib/Classes/CDVViewController.m
index bec716d..c7ad01b 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVViewController.m
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVViewController.m
@@ -19,7 +19,6 @@
#import <objc/message.h>
#import "CDV.h"
-#import "CDVCommandQueue.h"
#import "CDVCommandDelegateImpl.h"
#import "CDVConfigParser.h"
#import "CDVUserAgentUtil.h"
@@ -103,6 +102,48 @@
return self;
}
+- (void)viewWillAppear:(BOOL)animated
+{
+ [super viewWillAppear:animated];
+
+ NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
+ [nc addObserver:self
+ selector:@selector(keyboardWillShowOrHide:)
+ name:UIKeyboardWillShowNotification
+ object:nil];
+ [nc addObserver:self
+ selector:@selector(keyboardWillShowOrHide:)
+ name:UIKeyboardWillHideNotification
+ object:nil];
+}
+
+- (void)viewWillDisappear:(BOOL)animated
+{
+ [super viewWillDisappear:animated];
+
+ NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
+ [nc removeObserver:self name:UIKeyboardWillShowNotification object:nil];
+ [nc removeObserver:self name:UIKeyboardWillHideNotification object:nil];
+}
+
+- (void)keyboardWillShowOrHide:(NSNotification*)notif
+{
+ if (![@"true" isEqualToString:self.settings[@"KeyboardShrinksView"]]) {
+ return;
+ }
+ BOOL showEvent = [notif.name isEqualToString:UIKeyboardWillShowNotification];
+
+ CGRect keyboardFrame = [notif.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
+ keyboardFrame = [self.view convertRect:keyboardFrame fromView:nil];
+
+ CGRect newFrame = self.view.bounds;
+ if (showEvent) {
+ newFrame.size.height -= keyboardFrame.size.height;
+ }
+ self.webView.frame = newFrame;
+ self.webView.scrollView.contentInset = UIEdgeInsetsMake(0, 0, -keyboardFrame.size.height, 0);
+}
+
- (void)printDeprecationNotice
{
if (!IsAtLeastiOSVersion(@"5.0")) {
@@ -208,9 +249,6 @@
id backupWebStorage = self.settings[@"BackupWebStorage"];
if ([backupWebStorage isKindOfClass:[NSString class]]) {
backupWebStorageType = backupWebStorage;
- } else if ([backupWebStorage isKindOfClass:[NSNumber class]]) {
- NSLog(@"Deprecated: BackupWebStorage boolean property is a string property now (none, local, cloud). A boolean value of 'true' will be mapped to 'cloud'. Consult the docs: http://docs.cordova.io/en/edge/guide_project-settings_ios_index.md.html#Project%%20Settings%%20for%%20iOS");
- backupWebStorageType = [(NSNumber*) backupWebStorage boolValue] ? @"cloud" : @"none";
}
self.settings[@"BackupWebStorage"] = backupWebStorageType;
@@ -231,6 +269,10 @@
if ([self.settings objectForKey:@"MediaPlaybackRequiresUserAction"]) {
mediaPlaybackRequiresUserAction = [(NSNumber*)[settings objectForKey:@"MediaPlaybackRequiresUserAction"] boolValue];
}
+ BOOL hideKeyboardFormAccessoryBar = NO; // default value
+ if ([self.settings objectForKey:@"HideKeyboardFormAccessoryBar"]) {
+ hideKeyboardFormAccessoryBar = [(NSNumber*)[settings objectForKey:@"HideKeyboardFormAccessoryBar"] boolValue];
+ }
self.webView.scalesPageToFit = [enableViewportScale boolValue];
@@ -239,15 +281,27 @@
*/
if ([enableLocation boolValue]) {
+ NSLog(@"Deprecated: The 'EnableLocation' boolean property is deprecated in 2.5.0, and will be removed in 3.0.0. Use the 'onload' boolean attribute (of the CDVLocation plugin.");
[[self.commandDelegate getCommandInstance:@"Geolocation"] getLocation:[CDVInvokedUrlCommand new]];
}
+ if (hideKeyboardFormAccessoryBar) {
+ __weak CDVViewController* weakSelf = self;
+ [[NSNotificationCenter defaultCenter] addObserverForName:UIKeyboardWillShowNotification
+ object:nil
+ queue:[NSOperationQueue mainQueue]
+ usingBlock:^(NSNotification * notification) {
+ // we can't hide it here because the accessory bar hasn't been created yet, so we delay on the queue
+ [weakSelf performSelector:@selector(hideKeyboardFormAccessoryBar) withObject:nil afterDelay:0];
+ }];
+ }
+
/*
* Fire up CDVLocalStorage to work-around WebKit storage limitations: on all iOS 5.1+ versions for local-only backups, but only needed on iOS 5.1 for cloud backup.
*/
- if (IsAtLeastiOSVersion(@"5.1") && (([backupWebStorageType isEqualToString:@"local"]) ||
- ([backupWebStorageType isEqualToString:@"cloud"] && !IsAtLeastiOSVersion(@"6.0")))) {
- [self registerPlugin:[[CDVLocalStorage alloc] initWithWebView:self.webView] withClassName:NSStringFromClass([CDVLocalStorage class])];
+ if (IsAtLeastiOSVersion (@"5.1") && (([backupWebStorageType isEqualToString:@"local"]) ||
+ ([backupWebStorageType isEqualToString:@"cloud"] && !IsAtLeastiOSVersion (@"6.0")))) {
+ [self registerPlugin:[[CDVLocalStorage alloc] initWithWebView:self.webView] withClassName:NSStringFromClass ([CDVLocalStorage class])];
}
/*
@@ -260,12 +314,19 @@
self.webView.mediaPlaybackRequiresUserAction = NO;
}
- // UIWebViewBounce property - defaults to true
- NSNumber* bouncePreference = [self.settings objectForKey:@"UIWebViewBounce"];
- BOOL bounceAllowed = (bouncePreference == nil || [bouncePreference boolValue]);
+ // By default, overscroll bouncing is allowed.
+ // UIWebViewBounce has been renamed to DisallowOverscroll, but both are checked.
+ BOOL bounceAllowed = YES;
+ NSNumber* disallowOverscroll = [self.settings objectForKey:@"DisallowOverscroll"];
+ if (disallowOverscroll == nil) {
+ NSNumber* bouncePreference = [self.settings objectForKey:@"UIWebViewBounce"];
+ bounceAllowed = (bouncePreference == nil || [bouncePreference boolValue]);
+ } else {
+ bounceAllowed = ![disallowOverscroll boolValue];
+ }
// prevent webView from bouncing
- // based on UIWebViewBounce key in config.xml
+ // based on the DisallowOverscroll/UIWebViewBounce key in config.xml
if (!bounceAllowed) {
if ([self.webView respondsToSelector:@selector(scrollView)]) {
((UIScrollView*)[self.webView scrollView]).bounces = NO;
@@ -281,7 +342,7 @@
/*
* iOS 6.0 UIWebView properties
*/
- if (IsAtLeastiOSVersion(@"6.0")) {
+ if (IsAtLeastiOSVersion (@"6.0")) {
BOOL keyboardDisplayRequiresUserAction = YES; // KeyboardDisplayRequiresUserAction - defaults to YES
if ([self.settings objectForKey:@"KeyboardDisplayRequiresUserAction"] != nil) {
if ([self.settings objectForKey:@"KeyboardDisplayRequiresUserAction"]) {
@@ -330,6 +391,34 @@
}];
}
+- (void)hideKeyboardFormAccessoryBar
+{
+ NSArray* windows = [[UIApplication sharedApplication] windows];
+
+ for (UIWindow* window in windows) {
+ for (UIView* view in window.subviews) {
+ if ([[view description] hasPrefix:@"<UIPeripheralHostView"]) {
+ for (UIView* peripheralView in view.subviews) {
+ // hides the accessory bar
+ if ([[peripheralView description] hasPrefix:@"<UIWebFormAccessory"]) {
+ // remove the extra scroll space for the form accessory bar
+ CGRect newFrame = self.webView.scrollView.frame;
+ newFrame.size.height += peripheralView.frame.size.height;
+ self.webView.scrollView.frame = newFrame;
+
+ // remove the form accessory bar
+ [peripheralView removeFromSuperview];
+ }
+ // hides the thin grey line used to adorn the bar (iOS 6)
+ if ([[peripheralView description] hasPrefix:@"<UIImageView"]) {
+ [[peripheralView layer] setOpacity:0.0];
+ }
+ }
+ }
+ }
+ }
+}
+
- (NSArray*)parseInterfaceOrientations:(NSArray*)orientations
{
NSMutableArray* result = [[NSMutableArray alloc] init];
@@ -531,7 +620,7 @@
[self processOpenUrl];
- [[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:CDVPageDidLoadNotification object:nil]];
+ [[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:CDVPageDidLoadNotification object:self.webView]];
}
- (void)webView:(UIWebView*)theWebView didFailLoadWithError:(NSError*)error
@@ -660,6 +749,22 @@
[plugin pluginInitialize];
}
+- (void)registerPlugin:(CDVPlugin*)plugin withPluginName:(NSString*)pluginName
+{
+ if ([plugin respondsToSelector:@selector(setViewController:)]) {
+ [plugin setViewController:self];
+ }
+
+ if ([plugin respondsToSelector:@selector(setCommandDelegate:)]) {
+ [plugin setCommandDelegate:_commandDelegate];
+ }
+
+ NSString* className = NSStringFromClass([plugin class]);
+ [self.pluginObjects setObject:plugin forKey:className];
+ [self.pluginsMap setValue:className forKey:[pluginName lowercaseString]];
+ [plugin pluginInitialize];
+}
+
/**
Returns an instance of a CordovaCommand object, based on its name. If one exists already, it is returned.
*/
@@ -814,13 +919,8 @@
- (void)dealloc
{
[CDVURLProtocol unregisterViewController:self];
- [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillTerminateNotification object:nil];
- [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillResignActiveNotification object:nil];
- [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillEnterForegroundNotification object:nil];
- [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidBecomeActiveNotification object:nil];
- [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:nil];
- [[NSNotificationCenter defaultCenter] removeObserver:self name:NSCurrentLocaleDidChangeNotification object:nil];
- [[NSNotificationCenter defaultCenter] removeObserver:self name:CDVPluginHandleOpenURLNotification object:nil];
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
+
self.webView.delegate = nil;
self.webView = nil;
[CDVUserAgentUtil releaseLock:&_userAgentLockToken];
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/CDVWebViewDelegate.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVWebViewDelegate.m b/lib/cordova-ios/CordovaLib/Classes/CDVWebViewDelegate.m
index 9ee8186..a72bfb9 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVWebViewDelegate.m
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVWebViewDelegate.m
@@ -68,7 +68,9 @@ typedef enum {
if (![self isJsLoadTokenSet:webView]) {
_state = STATE_WAITING_FOR_FINISH;
[self setLoadToken:webView];
- [_delegate webViewDidStartLoad:webView];
+ if ([_delegate respondsToSelector:@selector(webViewDidStartLoad:)]) {
+ [_delegate webViewDidStartLoad:webView];
+ }
[self pollForPageLoadFinish:webView];
}
}
@@ -80,7 +82,9 @@ typedef enum {
}
if ([self isPageLoaded:webView]) {
_state = STATE_SHOULD_LOAD_MISSING;
- [_delegate webViewDidFinishLoad:webView];
+ if ([_delegate respondsToSelector:@selector(webViewDidFinishLoad:)]) {
+ [_delegate webViewDidFinishLoad:webView];
+ }
} else {
[self performSelector:@selector(pollForPageLoaded) withObject:webView afterDelay:50];
}
@@ -88,7 +92,11 @@ typedef enum {
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType
{
- BOOL shouldLoad = [_delegate webView:webView shouldStartLoadWithRequest:request navigationType:navigationType];
+ BOOL shouldLoad = YES;
+
+ if ([_delegate respondsToSelector:@selector(webView:shouldStartLoadWithRequest:navigationType:)]) {
+ shouldLoad = [_delegate webView:webView shouldStartLoadWithRequest:request navigationType:navigationType];
+ }
if (shouldLoad) {
BOOL isTopLevelNavigation = [request.URL isEqual:[request mainDocumentURL]];
@@ -104,7 +112,9 @@ typedef enum {
{
if (_state == STATE_NORMAL) {
if (_loadCount == 0) {
- [_delegate webViewDidStartLoad:webView];
+ if ([_delegate respondsToSelector:@selector(webViewDidStartLoad:)]) {
+ [_delegate webViewDidStartLoad:webView];
+ }
_loadCount += 1;
} else if (_loadCount > 0) {
_loadCount += 1;
@@ -128,8 +138,10 @@ typedef enum {
{
if (_state == STATE_NORMAL) {
if (_loadCount == 1) {
- [_delegate webViewDidFinishLoad:webView];
- _loadCount -= 1;
+ if ([_delegate respondsToSelector:@selector(webViewDidFinishLoad:)]) {
+ [_delegate webViewDidFinishLoad:webView];
+ }
+ _loadCount = -1;
} else if (_loadCount > 1) {
_loadCount -= 1;
}
@@ -143,8 +155,10 @@ typedef enum {
{
if (_state == STATE_NORMAL) {
if (_loadCount == 1) {
- [_delegate webView:webView didFailLoadWithError:error];
- _loadCount -= 1;
+ if ([_delegate respondsToSelector:@selector(webView:didFailLoadWithError:)]) {
+ [_delegate webView:webView didFailLoadWithError:error];
+ }
+ _loadCount = -1;
} else if (_loadCount > 1) {
_loadCount -= 1;
}
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/NSData+Base64.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/NSData+Base64.m b/lib/cordova-ios/CordovaLib/Classes/NSData+Base64.m
index 08c801b..d0f2189 100644
--- a/lib/cordova-ios/CordovaLib/Classes/NSData+Base64.m
+++ b/lib/cordova-ios/CordovaLib/Classes/NSData+Base64.m
@@ -249,13 +249,10 @@ char *CDVNewBase64Encode(
//
+ (NSData*)dataFromBase64String:(NSString*)aString
{
- NSData* data = [aString dataUsingEncoding:NSASCIIStringEncoding];
- size_t outputLength;
- void* outputBuffer = CDVNewBase64Decode([data bytes], [data length], &outputLength);
- NSData* result = [NSData dataWithBytes:outputBuffer length:outputLength];
+ size_t outputLength = 0;
+ void* outputBuffer = CDVNewBase64Decode([aString UTF8String], [aString length], &outputLength);
- free(outputBuffer);
- return result;
+ return [NSData dataWithBytesNoCopy:outputBuffer length:outputLength freeWhenDone:YES];
}
//
@@ -273,13 +270,11 @@ char *CDVNewBase64Encode(
char* outputBuffer =
CDVNewBase64Encode([self bytes], [self length], true, &outputLength);
- NSString* result =
- [[NSString alloc]
- initWithBytes:outputBuffer
- length:outputLength
- encoding:NSASCIIStringEncoding];
+ NSString* result = [[NSString alloc] initWithBytesNoCopy:outputBuffer
+ length:outputLength
+ encoding:NSASCIIStringEncoding
+ freeWhenDone:YES];
- free(outputBuffer);
return result;
}
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/NSDictionary+Extensions.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/NSDictionary+Extensions.m b/lib/cordova-ios/CordovaLib/Classes/NSDictionary+Extensions.m
index 80e9ac1..0361ff9 100644
--- a/lib/cordova-ios/CordovaLib/Classes/NSDictionary+Extensions.m
+++ b/lib/cordova-ios/CordovaLib/Classes/NSDictionary+Extensions.m
@@ -28,7 +28,7 @@
bool exists = false;
if (val != nil) {
- exists = [(NSString*) val compare:expectedValue options:NSCaseInsensitiveSearch] == 0;
+ exists = [(NSString*)val compare : expectedValue options : NSCaseInsensitiveSearch] == 0;
}
return exists;
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/CordovaLib.xcodeproj/project.pbxproj
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/CordovaLib.xcodeproj/project.pbxproj b/lib/cordova-ios/CordovaLib/CordovaLib.xcodeproj/project.pbxproj
index 4868020..e14f1f6 100644
--- a/lib/cordova-ios/CordovaLib/CordovaLib.xcodeproj/project.pbxproj
+++ b/lib/cordova-ios/CordovaLib/CordovaLib.xcodeproj/project.pbxproj
@@ -44,6 +44,9 @@
30F5EBAB14CA26E700987760 /* CDVCommandDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 30F5EBA914CA26E700987760 /* CDVCommandDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; };
3E76876D156A90EE00EB6FA3 /* CDVLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 3E76876B156A90EE00EB6FA3 /* CDVLogger.m */; };
3E76876F156A90EE00EB6FA3 /* CDVLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E76876C156A90EE00EB6FA3 /* CDVLogger.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 68B7516E16FD18190076A8B4 /* CDVJpegHeaderWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 68B7516B16FD18190076A8B4 /* CDVJpegHeaderWriter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 68B7516F16FD18190076A8B4 /* CDVJpegHeaderWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 68B7516C16FD18190076A8B4 /* CDVJpegHeaderWriter.m */; };
+ 68B7517016FD19F80076A8B4 /* CDVExif.h in Headers */ = {isa = PBXBuildFile; fileRef = 68B7516A16FD18190076A8B4 /* CDVExif.h */; settings = {ATTRIBUTES = (Public, ); }; };
8852C43A14B65FD800F0E735 /* CDVViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 8852C43614B65FD800F0E735 /* CDVViewController.h */; settings = {ATTRIBUTES = (Public, ); }; };
8852C43C14B65FD800F0E735 /* CDVViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8852C43714B65FD800F0E735 /* CDVViewController.m */; };
8887FD661090FBE7009987E8 /* CDVCamera.h in Headers */ = {isa = PBXBuildFile; fileRef = 8887FD261090FBE7009987E8 /* CDVCamera.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -141,6 +144,10 @@
686357DC14100B1600DF4CF2 /* CoreMedia.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = System/Library/Frameworks/CoreMedia.framework; sourceTree = SDKROOT; };
68A32D7114102E1C006B237C /* libCordova.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libCordova.a; sourceTree = BUILT_PRODUCTS_DIR; };
68A32D7414103017006B237C /* AddressBook.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AddressBook.framework; path = System/Library/Frameworks/AddressBook.framework; sourceTree = SDKROOT; };
+ 68B7516A16FD18190076A8B4 /* CDVExif.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CDVExif.h; path = Classes/CDVExif.h; sourceTree = "<group>"; };
+ 68B7516B16FD18190076A8B4 /* CDVJpegHeaderWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CDVJpegHeaderWriter.h; path = Classes/CDVJpegHeaderWriter.h; sourceTree = "<group>"; };
+ 68B7516C16FD18190076A8B4 /* CDVJpegHeaderWriter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CDVJpegHeaderWriter.m; path = Classes/CDVJpegHeaderWriter.m; sourceTree = "<group>"; };
+ 8220B5C316D5427E00EC3921 /* AssetsLibrary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AssetsLibrary.framework; path = System/Library/Frameworks/AssetsLibrary.framework; sourceTree = SDKROOT; };
8852C43614B65FD800F0E735 /* CDVViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CDVViewController.h; path = Classes/CDVViewController.h; sourceTree = "<group>"; };
8852C43714B65FD800F0E735 /* CDVViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CDVViewController.m; path = Classes/CDVViewController.m; sourceTree = "<group>"; };
8887FD261090FBE7009987E8 /* CDVCamera.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CDVCamera.h; path = Classes/CDVCamera.h; sourceTree = "<group>"; };
@@ -223,6 +230,7 @@
isa = PBXGroup;
children = (
68A32D7414103017006B237C /* AddressBook.framework */,
+ 8220B5C316D5427E00EC3921 /* AssetsLibrary.framework */,
686357DC14100B1600DF4CF2 /* CoreMedia.framework */,
686357CE14100ADA00DF4CF2 /* AudioToolbox.framework */,
686357CF14100ADB00DF4CF2 /* AVFoundation.framework */,
@@ -292,6 +300,9 @@
8887FD271090FBE7009987E8 /* CDVCamera.m */,
1F584B991385A28900ED25E8 /* CDVCapture.h */,
1F584B9A1385A28900ED25E8 /* CDVCapture.m */,
+ 68B7516A16FD18190076A8B4 /* CDVExif.h */,
+ 68B7516B16FD18190076A8B4 /* CDVJpegHeaderWriter.h */,
+ 68B7516C16FD18190076A8B4 /* CDVJpegHeaderWriter.m */,
1F3C04CC12BC247D004F9E10 /* CDVContact.h */,
1F3C04CD12BC247D004F9E10 /* CDVContact.m */,
8887FD2A1090FBE7009987E8 /* CDVContacts.h */,
@@ -364,6 +375,8 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
+ 68B7517016FD19F80076A8B4 /* CDVExif.h in Headers */,
+ 68B7516E16FD18190076A8B4 /* CDVJpegHeaderWriter.h in Headers */,
8887FD661090FBE7009987E8 /* CDVCamera.h in Headers */,
8887FD681090FBE7009987E8 /* NSDictionary+Extensions.h in Headers */,
8887FD6A1090FBE7009987E8 /* CDVContacts.h in Headers */,
@@ -502,6 +515,7 @@
30F3930C169F839700B22307 /* CDVJSON.m in Sources */,
EB96673C16A8970A00D86CDF /* CDVUserAgentUtil.m in Sources */,
EBFF4DBC16D3FE2E008F452B /* CDVWebViewDelegate.m in Sources */,
+ 68B7516F16FD18190076A8B4 /* CDVJpegHeaderWriter.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/VERSION
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/VERSION b/lib/cordova-ios/CordovaLib/VERSION
index 437459c..f47de85 100644
--- a/lib/cordova-ios/CordovaLib/VERSION
+++ b/lib/cordova-ios/CordovaLib/VERSION
@@ -1 +1 @@
-2.5.0
+2.6.0rc1
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/cordova.ios.js
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/cordova.ios.js b/lib/cordova-ios/CordovaLib/cordova.ios.js
index 3d83df3..8ed1706 100644
--- a/lib/cordova-ios/CordovaLib/cordova.ios.js
+++ b/lib/cordova-ios/CordovaLib/cordova.ios.js
@@ -1,8 +1,8 @@
// Platform: ios
-// commit f50d20a87431c79a54572263729461883f611a53
+// commit 47593b2bc1dba9bf46545b1da24577f937966e12
-// File generated at :: Tue Feb 26 2013 14:26:19 GMT-0800 (PST)
+// File generated at :: Thu Mar 21 2013 15:44:06 GMT-0700 (PDT)
/*
Licensed to the Apache Software Foundation (ASF) under one
@@ -262,7 +262,7 @@ var cordova = {
*/
callbackSuccess: function(callbackId, args) {
try {
- cordova.callbackFromNative(callbackId, true, args.status, args.message, args.keepCallback);
+ cordova.callbackFromNative(callbackId, true, args.status, [args.message], args.keepCallback);
} catch (e) {
console.log("Error in error callback: " + callbackId + " = "+e);
}
@@ -275,7 +275,7 @@ var cordova = {
// TODO: Deprecate callbackSuccess and callbackError in favour of callbackFromNative.
// Derive success from status.
try {
- cordova.callbackFromNative(callbackId, false, args.status, args.message, args.keepCallback);
+ cordova.callbackFromNative(callbackId, false, args.status, [args.message], args.keepCallback);
} catch (e) {
console.log("Error in error callback: " + callbackId + " = "+e);
}
@@ -284,13 +284,13 @@ var cordova = {
/**
* Called by native code when returning the result from an action.
*/
- callbackFromNative: function(callbackId, success, status, message, keepCallback) {
+ callbackFromNative: function(callbackId, success, status, args, keepCallback) {
var callback = cordova.callbacks[callbackId];
if (callback) {
if (success && status == cordova.callbackStatus.OK) {
- callback.success && callback.success(message);
+ callback.success && callback.success.apply(null, args);
} else if (!success) {
- callback.fail && callback.fail(message);
+ callback.fail && callback.fail.apply(null, args);
}
// Clear callback if not expecting any more results
@@ -724,6 +724,9 @@ channel.createSticky('onCordovaInfoReady');
// Event to indicate that the connection property has been set.
channel.createSticky('onCordovaConnectionReady');
+// Event to indicate that all automatically loaded JS plugins are loaded and ready.
+channel.createSticky('onPluginsReady');
+
// Event to indicate that Cordova is ready
channel.createSticky('onDeviceReady');
@@ -826,6 +829,7 @@ function massageArgsJsToNative(args) {
if (!args || utils.typeName(args) != 'Array') {
return args;
}
+ var ret = [];
var encodeArrayBufferAs8bitString = function(ab) {
return String.fromCharCode.apply(null, new Uint8Array(ab));
};
@@ -834,17 +838,19 @@ function massageArgsJsToNative(args) {
};
args.forEach(function(arg, i) {
if (utils.typeName(arg) == 'ArrayBuffer') {
- args[i] = {
+ ret.push({
'CDVType': 'ArrayBuffer',
'data': encodeArrayBufferAsBase64(arg)
- };
+ });
+ } else {
+ ret.push(arg);
}
});
- return args;
+ return ret;
}
-function massagePayloadNativeToJs(payload) {
- if (payload && payload.hasOwnProperty('CDVType') && payload.CDVType == 'ArrayBuffer') {
+function massageMessageNativeToJs(message) {
+ if (message.CDVType == 'ArrayBuffer') {
var stringToArrayBuffer = function(str) {
var ret = new Uint8Array(str.length);
for (var i = 0; i < str.length; i++) {
@@ -855,9 +861,23 @@ function massagePayloadNativeToJs(payload) {
var base64ToArrayBuffer = function(b64) {
return stringToArrayBuffer(atob(b64));
};
- payload = base64ToArrayBuffer(payload.data);
+ message = base64ToArrayBuffer(message.data);
+ }
+ return message;
+}
+
+function convertMessageToArgsNativeToJs(message) {
+ var args = [];
+ if (!message || !message.hasOwnProperty('CDVType')) {
+ args.push(message);
+ } else if (message.CDVType == 'MultiPart') {
+ message.messages.forEach(function(e) {
+ args.push(massageMessageNativeToJs(e));
+ });
+ } else {
+ args.push(massageMessageNativeToJs(message));
}
- return payload;
+ return args;
}
function iOSExec() {
@@ -964,11 +984,11 @@ iOSExec.nativeFetchMessages = function() {
return json;
};
-iOSExec.nativeCallback = function(callbackId, status, payload, keepCallback) {
+iOSExec.nativeCallback = function(callbackId, status, message, keepCallback) {
return iOSExec.nativeEvalAndFetch(function() {
var success = status === 0 || status === 1;
- payload = massagePayloadNativeToJs(payload);
- cordova.callbackFromNative(callbackId, success, status, payload, keepCallback);
+ var args = convertMessageToArgsNativeToJs(message);
+ cordova.callbackFromNative(callbackId, success, status, args, keepCallback);
});
};
@@ -1161,9 +1181,10 @@ cameraExport.getPicture = function(successCallback, errorCallback, options) {
var correctOrientation = !!options.correctOrientation;
var saveToPhotoAlbum = !!options.saveToPhotoAlbum;
var popoverOptions = getValue(options.popoverOptions, null);
+ var cameraDirection = getValue(options.cameraDirection, Camera.Direction.BACK);
var args = [quality, destinationType, sourceType, targetWidth, targetHeight, encodingType,
- mediaType, allowEdit, correctOrientation, saveToPhotoAlbum, popoverOptions];
+ mediaType, allowEdit, correctOrientation, saveToPhotoAlbum, popoverOptions, cameraDirection];
exec(successCallback, errorCallback, "Camera", "takePicture", args);
return new CameraPopoverHandle();
@@ -1206,6 +1227,10 @@ module.exports = {
ARROW_LEFT : 4,
ARROW_RIGHT : 8,
ARROW_ANY : 15
+ },
+ Direction:{
+ BACK: 0,
+ FRONT: 1
}
};
@@ -2398,14 +2423,7 @@ FileReader.prototype.readAsText = function(file, encoding) {
// Default encoding is UTF-8
var enc = encoding ? encoding : "UTF-8";
var me = this;
- var execArgs = [this._fileName, enc];
-
- // Maybe add slice parameters.
- if (file.end < file.size) {
- execArgs.push(file.start, file.end);
- } else if (file.start > 0) {
- execArgs.push(file.start);
- }
+ var execArgs = [this._fileName, enc, file.start, file.end];
// Read file
exec(
@@ -2474,14 +2492,7 @@ FileReader.prototype.readAsDataURL = function(file) {
}
var me = this;
- var execArgs = [this._fileName];
-
- // Maybe add slice parameters.
- if (file.end < file.size) {
- execArgs.push(file.start, file.end);
- } else if (file.start > 0) {
- execArgs.push(file.start);
- }
+ var execArgs = [this._fileName, file.start, file.end];
// Read file
exec(
@@ -2544,9 +2555,59 @@ FileReader.prototype.readAsBinaryString = function(file) {
if (initRead(this, file)) {
return this._realReader.readAsBinaryString(file);
}
- // TODO - Can't return binary data to browser.
- console.log('method "readAsBinaryString" is not supported at this time.');
- this.abort();
+
+ var me = this;
+ var execArgs = [this._fileName, file.start, file.end];
+
+ // Read file
+ exec(
+ // Success callback
+ function(r) {
+ // If DONE (cancelled), then don't do anything
+ if (me._readyState === FileReader.DONE) {
+ return;
+ }
+
+ // DONE state
+ me._readyState = FileReader.DONE;
+
+ me._result = r;
+
+ // If onload callback
+ if (typeof me.onload === "function") {
+ me.onload(new ProgressEvent("load", {target:me}));
+ }
+
+ // If onloadend callback
+ if (typeof me.onloadend === "function") {
+ me.onloadend(new ProgressEvent("loadend", {target:me}));
+ }
+ },
+ // Error callback
+ function(e) {
+ // If DONE (cancelled), then don't do anything
+ if (me._readyState === FileReader.DONE) {
+ return;
+ }
+
+ // DONE state
+ me._readyState = FileReader.DONE;
+
+ me._result = null;
+
+ // Save error
+ me._error = new FileError(e);
+
+ // If onerror callback
+ if (typeof me.onerror === "function") {
+ me.onerror(new ProgressEvent("error", {target:me}));
+ }
+
+ // If onloadend callback
+ if (typeof me.onloadend === "function") {
+ me.onloadend(new ProgressEvent("loadend", {target:me}));
+ }
+ }, "File", "readAsBinaryString", execArgs);
};
/**
@@ -2558,9 +2619,59 @@ FileReader.prototype.readAsArrayBuffer = function(file) {
if (initRead(this, file)) {
return this._realReader.readAsArrayBuffer(file);
}
- // TODO - Can't return binary data to browser.
- console.log('This method is not supported at this time.');
- this.abort();
+
+ var me = this;
+ var execArgs = [this._fileName, file.start, file.end];
+
+ // Read file
+ exec(
+ // Success callback
+ function(r) {
+ // If DONE (cancelled), then don't do anything
+ if (me._readyState === FileReader.DONE) {
+ return;
+ }
+
+ // DONE state
+ me._readyState = FileReader.DONE;
+
+ me._result = r;
+
+ // If onload callback
+ if (typeof me.onload === "function") {
+ me.onload(new ProgressEvent("load", {target:me}));
+ }
+
+ // If onloadend callback
+ if (typeof me.onloadend === "function") {
+ me.onloadend(new ProgressEvent("loadend", {target:me}));
+ }
+ },
+ // Error callback
+ function(e) {
+ // If DONE (cancelled), then don't do anything
+ if (me._readyState === FileReader.DONE) {
+ return;
+ }
+
+ // DONE state
+ me._readyState = FileReader.DONE;
+
+ me._result = null;
+
+ // Save error
+ me._error = new FileError(e);
+
+ // If onerror callback
+ if (typeof me.onerror === "function") {
+ me.onerror(new ProgressEvent("error", {target:me}));
+ }
+
+ // If onloadend callback
+ if (typeof me.onloadend === "function") {
+ me.onloadend(new ProgressEvent("loadend", {target:me}));
+ }
+ }, "File", "readAsArrayBuffer", execArgs);
};
module.exports = FileReader;
@@ -2606,6 +2717,38 @@ function newProgressEvent(result) {
return pe;
}
+function getBasicAuthHeader(urlString) {
+ var header = null;
+
+ if (window.btoa) {
+ // parse the url using the Location object
+ var url = document.createElement('a');
+ url.href = urlString;
+
+ var credentials = null;
+ var protocol = url.protocol + "//";
+ var origin = protocol + url.host;
+
+ // check whether there are the username:password credentials in the url
+ if (url.href.indexOf(origin) != 0) { // credentials found
+ var atIndex = url.href.indexOf("@");
+ credentials = url.href.substring(protocol.length, atIndex);
+ }
+
+ if (credentials) {
+ var authHeader = "Authorization";
+ var authHeaderValue = "Basic " + window.btoa(credentials);
+
+ header = {
+ name : authHeader,
+ value : authHeaderValue
+ };
+ }
+ }
+
+ return header;
+}
+
var idCounter = 0;
/**
@@ -2636,6 +2779,18 @@ FileTransfer.prototype.upload = function(filePath, server, successCallback, erro
var params = null;
var chunkedMode = true;
var headers = null;
+
+ var basicAuthHeader = getBasicAuthHeader(server);
+ if (basicAuthHeader) {
+ if (!options) {
+ options = new FileUploadOptions();
+ }
+ if (!options.headers) {
+ options.headers = {};
+ }
+ options.headers[basicAuthHeader.name] = basicAuthHeader.value;
+ }
+
if (options) {
fileKey = options.fileKey;
fileName = options.fileName;
@@ -2653,7 +2808,7 @@ FileTransfer.prototype.upload = function(filePath, server, successCallback, erro
}
var fail = errorCallback && function(e) {
- var error = new FileTransferError(e.code, e.source, e.target, e.http_status);
+ var error = new FileTransferError(e.code, e.source, e.target, e.http_status, e.body);
errorCallback(error);
};
@@ -2677,10 +2832,28 @@ FileTransfer.prototype.upload = function(filePath, server, successCallback, erro
* @param successCallback (Function} Callback to be invoked when upload has completed
* @param errorCallback {Function} Callback to be invoked upon error
* @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false
+ * @param options {FileDownloadOptions} Optional parameters such as headers
*/
-FileTransfer.prototype.download = function(source, target, successCallback, errorCallback, trustAllHosts) {
+FileTransfer.prototype.download = function(source, target, successCallback, errorCallback, trustAllHosts, options) {
argscheck.checkArgs('ssFF*', 'FileTransfer.download', arguments);
var self = this;
+
+ var basicAuthHeader = getBasicAuthHeader(source);
+ if (basicAuthHeader) {
+ if (!options) {
+ options = {};
+ }
+ if (!options.headers) {
+ options.headers = {};
+ }
+ options.headers[basicAuthHeader.name] = basicAuthHeader.value;
+ }
+
+ var headers = null;
+ if (options) {
+ headers = options.headers || null;
+ }
+
var win = function(result) {
if (typeof result.lengthComputable != "undefined") {
if (self.onprogress) {
@@ -2703,11 +2876,11 @@ FileTransfer.prototype.download = function(source, target, successCallback, erro
};
var fail = errorCallback && function(e) {
- var error = new FileTransferError(e.code, e.source, e.target, e.http_status);
+ var error = new FileTransferError(e.code, e.source, e.target, e.http_status, e.body);
errorCallback(error);
};
- exec(win, fail, 'FileTransfer', 'download', [source, target, trustAllHosts, this._id]);
+ exec(win, fail, 'FileTransfer', 'download', [source, target, trustAllHosts, this._id, headers]);
};
/**
@@ -3105,6 +3278,7 @@ function InAppBrowser() {
this.channels = {
'loadstart': channel.create('loadstart'),
'loadstop' : channel.create('loadstop'),
+ 'loaderror' : channel.create('loaderror'),
'exit' : channel.create('exit')
};
}
@@ -3135,7 +3309,7 @@ module.exports = function(strUrl, strWindowName, strWindowFeatures) {
var cb = function(eventname) {
iab._eventHandler(eventname);
};
- exec(cb, null, "InAppBrowser", "open", [strUrl, strWindowName, strWindowFeatures]);
+ exec(cb, cb, "InAppBrowser", "open", [strUrl, strWindowName, strWindowFeatures]);
return iab;
};
@@ -4341,7 +4515,8 @@ modulemapper.clobbers('cordova/plugin/device', 'device');
// file: lib/common/plugin/echo.js
define("cordova/plugin/echo", function(require, exports, module) {
-var exec = require('cordova/exec');
+var exec = require('cordova/exec'),
+ utils = require('cordova/utils');
/**
* Sends the given message through exec() to the Echo plugin, which sends it back to the successCallback.
@@ -4351,11 +4526,25 @@ var exec = require('cordova/exec');
* @param forceAsync Whether to force an async return value (for testing native->js bridge).
*/
module.exports = function(successCallback, errorCallback, message, forceAsync) {
- var action = forceAsync ? 'echoAsync' : 'echo';
- if (!forceAsync && message.constructor == ArrayBuffer) {
- action = 'echoArrayBuffer';
+ var action = 'echo';
+ var messageIsMultipart = (utils.typeName(message) == "Array");
+ var args = messageIsMultipart ? message : [message];
+
+ if (utils.typeName(message) == 'ArrayBuffer') {
+ if (forceAsync) {
+ console.warn('Cannot echo ArrayBuffer with forced async, falling back to sync.');
+ }
+ action += 'ArrayBuffer';
+ } else if (messageIsMultipart) {
+ if (forceAsync) {
+ console.warn('Cannot echo MultiPart Array with forced async, falling back to sync.');
+ }
+ action += 'MultiPart';
+ } else if (forceAsync) {
+ action += 'Async';
}
- exec(successCallback, errorCallback, "Echo", action, [message]);
+
+ exec(successCallback, errorCallback, "Echo", action, args);
};
@@ -5086,7 +5275,7 @@ function stringify(message) {
return "error JSON.stringify()ing argument: " + e;
}
} else {
- return message.toString();
+ return (typeof message === "undefined") ? "undefined" : message.toString();
}
} catch (e) {
return e.toString();
@@ -5100,10 +5289,20 @@ function stringify(message) {
function wrappedMethod(console, method) {
var origMethod = console[method];
- return function(message) {
+ return function() {
+
+ var args = [].slice.call(arguments),
+ len = args.length,
+ i = 0,
+ res = [];
+
+ for ( ; i < len; i++) {
+ res.push(stringify(args[i]));
+ }
+
exec(null, null,
'Debug Console', 'log',
- [ stringify(message), { logLevel: method.toUpperCase() } ]
+ [ res.join(' '), { logLevel: method.toUpperCase() } ]
);
if (!origMethod) return;
@@ -5572,6 +5771,7 @@ modulemapper.defaults('cordova/plugin/Connection', 'Connection');
define("cordova/plugin/notification", function(require, exports, module) {
var exec = require('cordova/exec');
+var platform = require('cordova/platform');
/**
* Provides access to notifications on the device.
@@ -5600,15 +5800,53 @@ module.exports = {
* @param {String} message Message to print in the body of the alert
* @param {Function} resultCallback The callback that is called when user clicks on a button.
* @param {String} title Title of the alert dialog (default: Confirm)
- * @param {String} buttonLabels Comma separated list of the labels of the buttons (default: 'OK,Cancel')
+ * @param {Array} buttonLabels Array of the labels of the buttons (default: ['OK', 'Cancel'])
*/
confirm: function(message, resultCallback, title, buttonLabels) {
var _title = (title || "Confirm");
- var _buttonLabels = (buttonLabels || "OK,Cancel");
+ var _buttonLabels = (buttonLabels || ["OK", "Cancel"]);
+
+ // Strings are deprecated!
+ if (typeof _buttonLabels === 'string') {
+ console.log("Notification.confirm(string, function, string, string) is deprecated. Use Notification.confirm(string, function, string, array).");
+ }
+
+ // Android and iOS take an array of button label names.
+ // Other platforms take a comma separated list.
+ // For compatibility, we convert to the desired type based on the platform.
+ if (platform.id == "android" || platform.id == "ios") {
+ if (typeof _buttonLabels === 'string') {
+ var buttonLabelString = _buttonLabels;
+ _buttonLabels = buttonLabelString.split(",");
+ }
+ } else {
+ if (Array.isArray(_buttonLabels)) {
+ var buttonLabelArray = _buttonLabels;
+ _buttonLabels = buttonLabelArray.toString();
+ }
+ }
exec(resultCallback, null, "Notification", "confirm", [message, _title, _buttonLabels]);
},
/**
+ * Open a native prompt dialog, with a customizable title and button text.
+ * The following results are returned to the result callback:
+ * buttonIndex Index number of the button selected.
+ * input1 The text entered in the prompt dialog box.
+ *
+ * @param {String} message Dialog message to display (default: "Prompt message")
+ * @param {Function} resultCallback The callback that is called when user clicks on a button.
+ * @param {String} title Title of the dialog (default: "Prompt")
+ * @param {Array} buttonLabels Array of strings for the button labels (default: ["OK","Cancel"])
+ */
+ prompt: function(message, resultCallback, title, buttonLabels) {
+ var _message = (message || "Prompt message");
+ var _title = (title || "Prompt");
+ var _buttonLabels = (buttonLabels || ["OK","Cancel"]);
+ exec(resultCallback, null, "Notification", "prompt", [_message, _title, _buttonLabels]);
+ },
+
+ /**
* Causes the device to vibrate.
*
* @param {Integer} mills The number of milliseconds to vibrate for.
@@ -6031,53 +6269,160 @@ window.cordova = require('cordova');
(function (context) {
// Replace navigator before any modules are required(), to ensure it happens as soon as possible.
// We replace it so that properties that can't be clobbered can instead be overridden.
- if (context.navigator) {
+ function replaceNavigator(origNavigator) {
var CordovaNavigator = function() {};
- CordovaNavigator.prototype = context.navigator;
- context.navigator = new CordovaNavigator();
+ CordovaNavigator.prototype = origNavigator;
+ var newNavigator = new CordovaNavigator();
+ // This work-around really only applies to new APIs that are newer than Function.bind.
+ // Without it, APIs such as getGamepads() break.
+ if (CordovaNavigator.bind) {
+ for (var key in origNavigator) {
+ if (typeof origNavigator[key] == 'function') {
+ newNavigator[key] = origNavigator[key].bind(origNavigator);
+ }
+ }
+ }
+ return newNavigator;
+ }
+ if (context.navigator) {
+ context.navigator = replaceNavigator(context.navigator);
}
- var channel = require("cordova/channel"),
- _self = {
- boot: function () {
- /**
- * Create all cordova objects once page has fully loaded and native side is ready.
- */
- channel.join(function() {
- var builder = require('cordova/builder'),
- platform = require('cordova/platform');
+ var channel = require("cordova/channel");
+
+ // _nativeReady is global variable that the native side can set
+ // to signify that the native code is ready. It is a global since
+ // it may be called before any cordova JS is ready.
+ if (window._nativeReady) {
+ channel.onNativeReady.fire();
+ }
+
+ /**
+ * Create all cordova objects once page has fully loaded and native side is ready.
+ */
+ channel.join(function() {
+ var builder = require('cordova/builder'),
+ platform = require('cordova/platform');
+
+ builder.buildIntoButDoNotClobber(platform.defaults, context);
+ builder.buildIntoAndClobber(platform.clobbers, context);
+ builder.buildIntoAndMerge(platform.merges, context);
+
+ // Call the platform-specific initialization
+ platform.initialize();
+
+ // Fire event to notify that all objects are created
+ channel.onCordovaReady.fire();
+
+ // Fire onDeviceReady event once all constructors have run and
+ // cordova info has been received from native side.
+ channel.join(function() {
+ require('cordova').fireDocumentEvent('deviceready');
+ }, channel.deviceReadyChannelsArray);
+
+ }, [ channel.onDOMContentLoaded, channel.onNativeReady, channel.onPluginsReady ]);
+
+}(window));
+
+// file: lib/scripts/plugin_loader.js
- builder.buildIntoButDoNotClobber(platform.defaults, context);
- builder.buildIntoAndClobber(platform.clobbers, context);
- builder.buildIntoAndMerge(platform.merges, context);
+// Tries to load all plugins' js-modules.
+// This is an async process, but onDeviceReady is blocked on onPluginsReady.
+// onPluginsReady is fired when there are no plugins to load, or they are all done.
+(function (context) {
+ // To be populated with the handler by handlePluginsObject.
+ var onScriptLoadingComplete;
+
+ var scriptCounter = 0;
+ function scriptLoadedCallback() {
+ scriptCounter--;
+ if (scriptCounter === 0) {
+ onScriptLoadingComplete && onScriptLoadingComplete();
+ }
+ }
+
+ // Helper function to inject a <script> tag.
+ function injectScript(path) {
+ scriptCounter++;
+ var script = document.createElement("script");
+ script.onload = scriptLoadedCallback;
+ script.src = path;
+ document.head.appendChild(script);
+ }
- // Call the platform-specific initialization
- platform.initialize();
+ // Called when:
+ // * There are plugins defined and all plugins are finished loading.
+ // * There are no plugins to load.
+ function finishPluginLoading() {
+ context.cordova.require('cordova/channel').onPluginsReady.fire();
+ }
- // Fire event to notify that all objects are created
- channel.onCordovaReady.fire();
+ // Handler for the cordova_plugins.json content.
+ // See plugman's plugin_loader.js for the details of this object.
+ // This function is only called if the really is a plugins array that isn't empty.
+ // Otherwise the XHR response handler will just call finishPluginLoading().
+ function handlePluginsObject(modules) {
+ // First create the callback for when all plugins are loaded.
+ var mapper = context.cordova.require('cordova/modulemapper');
+ onScriptLoadingComplete = function() {
+ // Loop through all the plugins and then through their clobbers and merges.
+ for (var i = 0; i < modules.length; i++) {
+ var module = modules[i];
+ if (!module) continue;
+
+ if (module.clobbers && module.clobbers.length) {
+ for (var j = 0; j < module.clobbers.length; j++) {
+ mapper.clobbers(module.id, module.clobbers[j]);
+ }
+ }
- // Fire onDeviceReady event once all constructors have run and
- // cordova info has been received from native side.
- channel.join(function() {
- require('cordova').fireDocumentEvent('deviceready');
- }, channel.deviceReadyChannelsArray);
+ if (module.merges && module.merges.length) {
+ for (var k = 0; k < module.merges.length; k++) {
+ mapper.merges(module.id, module.merges[k]);
+ }
+ }
- }, [ channel.onDOMContentLoaded, channel.onNativeReady ]);
+ // Finally, if runs is truthy we want to simply require() the module.
+ // This can be skipped if it had any merges or clobbers, though,
+ // since the mapper will already have required the module.
+ if (module.runs && !(module.clobbers && module.clobbers.length) && !(module.merges && module.merges.length)) {
+ context.cordova.require(module.id);
+ }
}
- };
- // boot up once native side is ready
- channel.onNativeReady.subscribe(_self.boot);
+ finishPluginLoading();
+ };
- // _nativeReady is global variable that the native side can set
- // to signify that the native code is ready. It is a global since
- // it may be called before any cordova JS is ready.
- if (window._nativeReady) {
- channel.onNativeReady.fire();
+ // Now inject the scripts.
+ for (var i = 0; i < modules.length; i++) {
+ injectScript(modules[i].file);
+ }
}
+ // Try to XHR the cordova_plugins.json file asynchronously.
+ var xhr = new context.XMLHttpRequest();
+ xhr.onreadystatechange = function() {
+ if (this.readyState != 4) { // not DONE
+ return;
+ }
+
+ // If the response is a JSON string which composes an array, call handlePluginsObject.
+ // If the request fails, or the response is not a JSON array, just call finishPluginLoading.
+ if (this.status == 200) {
+ var obj = JSON.parse(this.responseText);
+ if (obj && obj instanceof Array && obj.length > 0) {
+ handlePluginsObject(obj);
+ } else {
+ finishPluginLoading();
+ }
+ } else {
+ finishPluginLoading();
+ }
+ };
+ xhr.open('GET', 'cordova_plugins.json', true); // Async
+ xhr.send();
}(window));
+
})();
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLibTests/CDVFakeFileManager.h
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLibTests/CDVFakeFileManager.h b/lib/cordova-ios/CordovaLibTests/CDVFakeFileManager.h
index 41e5523..f9300a0 100644
--- a/lib/cordova-ios/CordovaLibTests/CDVFakeFileManager.h
+++ b/lib/cordova-ios/CordovaLibTests/CDVFakeFileManager.h
@@ -19,7 +19,7 @@
#import <Foundation/Foundation.h>
-typedef BOOL (^CDVFileExistsBlock)(NSString*);
+typedef BOOL (^ CDVFileExistsBlock)(NSString*);
// Used in place of an NSFileManager for unit tests. It implements only those functions
// which are required by the tests that use it.
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLibTests/CDVFileTransferTests.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLibTests/CDVFileTransferTests.m b/lib/cordova-ios/CordovaLibTests/CDVFileTransferTests.m
index 7488a5a..2effc98 100644
--- a/lib/cordova-ios/CordovaLibTests/CDVFileTransferTests.m
+++ b/lib/cordova-ios/CordovaLibTests/CDVFileTransferTests.m
@@ -140,15 +140,15 @@ static NSData *readStream(NSInputStream* stream)
- (void)testEscapePathComponentForUrlString
{
STAssertTrue([@"" isEqualToString:
- [_fileTransfer escapePathComponentForUrlString:@""]], nil);
+ [_fileTransfer escapePathComponentForUrlString:@""]], nil);
STAssertTrue([@"foo" isEqualToString:
- [_fileTransfer escapePathComponentForUrlString:@"foo"]], nil);
+ [_fileTransfer escapePathComponentForUrlString:@"foo"]], nil);
STAssertTrue([@"http://a.org/spa%20ce%25" isEqualToString:
- [_fileTransfer escapePathComponentForUrlString:@"http://a.org/spa ce%"]], nil);
+ [_fileTransfer escapePathComponentForUrlString:@"http://a.org/spa ce%"]], nil);
STAssertTrue([@"http://a.org/spa%20ce%25/" isEqualToString:
- [_fileTransfer escapePathComponentForUrlString:@"http://a.org/spa ce%/"]], nil);
+ [_fileTransfer escapePathComponentForUrlString:@"http://a.org/spa ce%/"]], nil);
STAssertTrue([@"http://a.org/%25/%25/" isEqualToString:
- [_fileTransfer escapePathComponentForUrlString:@"http://a.org/%/%/"]], nil);
+ [_fileTransfer escapePathComponentForUrlString:@"http://a.org/%/%/"]], nil);
}
- (void)testUpload_invalidServerUrl
@@ -208,7 +208,7 @@ static NSData *readStream(NSInputStream* stream)
{
[self setChunkedModeArg:NO];
[self setHeaders:[NSDictionary dictionaryWithObjectsAndKeys:@"val1", @"key1",
- [NSArray arrayWithObjects:@"val2a", @"val2b", nil], @"key2", [NSNull null], @"X-Requested-With", nil]];
+ [NSArray arrayWithObjects:@"val2a", @"val2b", nil], @"key2", [NSNull null], @"X-Requested-With", nil]];
NSURLRequest* request = [self requestForUpload];
STAssertTrue([@"val1" isEqualToString:[request valueForHTTPHeaderField:@"key1"]], nil);
STAssertTrue([@"val2a,val2b" isEqualToString:[request valueForHTTPHeaderField:@"key2"]], nil);
[3/6] 2.6.0rc1 used for libs now. Bumped npm version to 2.6.0. added
androids local.properties to gitignore.
Posted by fi...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/CDVFile.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVFile.m b/lib/cordova-ios/CordovaLib/Classes/CDVFile.m
index d52405d..8c65270 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVFile.m
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVFile.m
@@ -52,7 +52,7 @@ NSString* const kCDVAssetsLibraryPrefix = @"assets-library://";
paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
self.appLibraryPath = [paths objectAtIndex:0];
- self.appTempPath = [NSTemporaryDirectory ()stringByStandardizingPath]; // remove trailing slash from NSTemporaryDirectory()
+ self.appTempPath = [NSTemporaryDirectory()stringByStandardizingPath]; // remove trailing slash from NSTemporaryDirectory()
self.persistentPath = [NSString stringWithFormat:@"/%@", [self.appDocsPath lastPathComponent]];
self.temporaryPath = [NSString stringWithFormat:@"/%@", [self.appTempPath lastPathComponent]];
@@ -164,7 +164,7 @@ NSString* const kCDVAssetsLibraryPrefix = @"assets-library://";
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:QUOTA_EXCEEDED_ERR];
} else {
NSMutableDictionary* fileSystem = [NSMutableDictionary dictionaryWithCapacity:2];
- [fileSystem setObject:(type == TEMPORARY ? kW3FileTemporary:kW3FilePersistent) forKey:@"name"];
+ [fileSystem setObject:(type == TEMPORARY ? kW3FileTemporary : kW3FilePersistent) forKey:@"name"];
NSDictionary* dirEntry = [self getDirectoryEntry:fullPath isDirectory:YES];
[fileSystem setObject:dirEntry forKey:@"root"];
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:fileSystem];
@@ -486,7 +486,7 @@ NSString* const kCDVAssetsLibraryPrefix = @"assets-library://";
// In this case, we need to use an asynchronous method to retrieve the file.
// Because of this, we can't just assign to `result` and send it at the end of the method.
// Instead, we return after calling the asynchronous method and send `result` in each of the blocks.
- ALAssetsLibraryAssetForURLResultBlock resultBlock = ^(ALAsset * asset) {
+ ALAssetsLibraryAssetForURLResultBlock resultBlock = ^(ALAsset* asset) {
if (asset) {
// We have the asset! Retrieve the metadata and send it off.
NSDate* date = [asset valueForProperty:ALAssetPropertyDate];
@@ -499,7 +499,7 @@ NSString* const kCDVAssetsLibraryPrefix = @"assets-library://";
}
};
// TODO(maxw): Consider making this a class variable since it's the same every time.
- ALAssetsLibraryAccessFailureBlock failureBlock = ^(NSError * error) {
+ ALAssetsLibraryAccessFailureBlock failureBlock = ^(NSError* error) {
// Retrieving the asset failed for some reason. Send the appropriate error.
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsString:[error localizedDescription]];
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
@@ -525,7 +525,7 @@ NSString* const kCDVAssetsLibraryPrefix = @"assets-library://";
} else {
// didn't get fileAttribs
CDVFileError errorCode = ABORT_ERR;
- NSLog (@"error getting metadata: %@", [error localizedDescription]);
+ NSLog(@"error getting metadata: %@", [error localizedDescription]);
if ([error code] == NSFileNoSuchFileError) {
errorCode = NOT_FOUND_ERR;
}
@@ -779,7 +779,7 @@ NSString* const kCDVAssetsLibraryPrefix = @"assets-library://";
// In this case, we need to use an asynchronous method to retrieve the file.
// Because of this, we can't just assign to `result` and send it at the end of the method.
// Instead, we return after calling the asynchronous method and send `result` in each of the blocks.
- ALAssetsLibraryAssetForURLResultBlock resultBlock = ^(ALAsset * asset) {
+ ALAssetsLibraryAssetForURLResultBlock resultBlock = ^(ALAsset* asset) {
if (asset) {
// We have the asset! Get the data and try to copy it over.
if (![fileMgr fileExistsAtPath:destRootPath]) {
@@ -796,7 +796,7 @@ NSString* const kCDVAssetsLibraryPrefix = @"assets-library://";
// We're good to go! Write the file to the new destination.
ALAssetRepresentation* assetRepresentation = [asset defaultRepresentation];
- Byte* buffer = (Byte*)malloc ([assetRepresentation size]);
+ Byte* buffer = (Byte*)malloc([assetRepresentation size]);
NSUInteger bufferSize = [assetRepresentation getBytes:buffer fromOffset:0.0 length:[assetRepresentation size] error:nil];
NSData* data = [NSData dataWithBytesNoCopy:buffer length:bufferSize freeWhenDone:YES];
[data writeToFile:newFullPath atomically:YES];
@@ -808,7 +808,7 @@ NSString* const kCDVAssetsLibraryPrefix = @"assets-library://";
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
}
};
- ALAssetsLibraryAccessFailureBlock failureBlock = ^(NSError * error) {
+ ALAssetsLibraryAccessFailureBlock failureBlock = ^(NSError* error) {
// Retrieving the asset failed for some reason. Send the appropriate error.
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsString:[error localizedDescription]];
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
@@ -953,7 +953,7 @@ NSString* const kCDVAssetsLibraryPrefix = @"assets-library://";
// In this case, we need to use an asynchronous method to retrieve the file.
// Because of this, we can't just assign to `result` and send it at the end of the method.
// Instead, we return after calling the asynchronous method and send `result` in each of the blocks.
- ALAssetsLibraryAssetForURLResultBlock resultBlock = ^(ALAsset * asset) {
+ ALAssetsLibraryAssetForURLResultBlock resultBlock = ^(ALAsset* asset) {
if (asset) {
// We have the asset! Populate the dictionary and send it off.
NSMutableDictionary* fileInfo = [NSMutableDictionary dictionaryWithCapacity:5];
@@ -975,7 +975,7 @@ NSString* const kCDVAssetsLibraryPrefix = @"assets-library://";
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
}
};
- ALAssetsLibraryAccessFailureBlock failureBlock = ^(NSError * error) {
+ ALAssetsLibraryAccessFailureBlock failureBlock = ^(NSError* error) {
// Retrieving the asset failed for some reason. Send the appropriate error.
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsString:[error localizedDescription]];
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
@@ -1053,154 +1053,181 @@ NSString* const kCDVAssetsLibraryPrefix = @"assets-library://";
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
}
+- (void)readFileWithPath:(NSString*)path start:(NSInteger)start end:(NSInteger)end callback:(void (^)(NSData*, NSString* mimeType, CDVFileError))callback
+{
+ if (path == nil) {
+ callback(nil, nil, SYNTAX_ERR);
+ } else {
+ [self.commandDelegate runInBackground:^ {
+ if ([path hasPrefix:kCDVAssetsLibraryPrefix]) {
+ // In this case, we need to use an asynchronous method to retrieve the file.
+ // Because of this, we can't just assign to `result` and send it at the end of the method.
+ // Instead, we return after calling the asynchronous method and send `result` in each of the blocks.
+ ALAssetsLibraryAssetForURLResultBlock resultBlock = ^(ALAsset* asset) {
+ if (asset) {
+ // We have the asset! Get the data and send it off.
+ ALAssetRepresentation* assetRepresentation = [asset defaultRepresentation];
+ Byte* buffer = (Byte*)malloc([assetRepresentation size]);
+ NSUInteger bufferSize = [assetRepresentation getBytes:buffer fromOffset:0.0 length:[assetRepresentation size] error:nil];
+ NSData* data = [NSData dataWithBytesNoCopy:buffer length:bufferSize freeWhenDone:YES];
+ NSString* MIMEType = (__bridge_transfer NSString*)UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)[assetRepresentation UTI], kUTTagClassMIMEType);
+
+ callback(data, MIMEType, NO_ERROR);
+ } else {
+ callback(nil, nil, NOT_FOUND_ERR);
+ }
+ };
+ ALAssetsLibraryAccessFailureBlock failureBlock = ^(NSError* error) {
+ // Retrieving the asset failed for some reason. Send the appropriate error.
+ NSLog(@"Error: %@", error);
+ callback(nil, nil, SECURITY_ERR);
+ };
+
+ ALAssetsLibrary* assetsLibrary = [[ALAssetsLibrary alloc] init];
+ [assetsLibrary assetForURL:[NSURL URLWithString:path] resultBlock:resultBlock failureBlock:failureBlock];
+ } else {
+ NSString* mimeType = [self getMimeTypeFromPath:path];
+ if (mimeType == nil) {
+ mimeType = @"*/*";
+ }
+ NSFileHandle* file = [NSFileHandle fileHandleForReadingAtPath:path];
+ if (start > 0) {
+ [file seekToFileOffset:start];
+ }
+
+ NSData* readData;
+ if (end < 0) {
+ readData = [file readDataToEndOfFile];
+ } else {
+ readData = [file readDataOfLength:(end - start)];
+ }
+
+ [file closeFile];
+
+ callback(readData, mimeType, readData != nil ? NO_ERROR : NOT_FOUND_ERR);
+ }
+ }];
+ }
+}
+
/* read and return file data
* IN:
* NSArray* arguments
* 0 - NSString* fullPath
- * 1 - NSString* encoding - NOT USED, iOS reads and writes using UTF8!
- * 2 - NSString* start - OPTIONAL, only provided when not == 0.
- * 3 - NSString* end - OPTIONAL, only provided when not == length.
+ * 1 - NSString* encoding
+ * 2 - NSString* start
+ * 3 - NSString* end
*/
- (void)readAsText:(CDVInvokedUrlCommand*)command
{
// arguments
- NSString* argPath = [command.arguments objectAtIndex:0];
- NSInteger start = 0;
- NSInteger end = -1;
-
- if ([command.arguments count] >= 3) {
- start = [[command.arguments objectAtIndex:2] integerValue];
- }
- if ([command.arguments count] >= 4) {
- end = [[command.arguments objectAtIndex:3] integerValue];
+ NSString* path = [command argumentAtIndex:0];
+ NSString* encoding = [command argumentAtIndex:1];
+ NSInteger start = [[command argumentAtIndex:2] integerValue];
+ NSInteger end = [[command argumentAtIndex:3] integerValue];
+
+ // TODO: implement
+ if (![@"UTF-8" isEqualToString : encoding]) {
+ NSLog(@"Only UTF-8 encodings are currently supported by readAsText");
+ CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:ENCODING_ERR];
+ [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
+ return;
}
- // NSString* encoding = [command.arguments objectAtIndex:2]; // not currently used
- CDVPluginResult* result = nil;
-
- NSFileHandle* file = [NSFileHandle fileHandleForReadingAtPath:argPath];
-
- if ([argPath hasPrefix:kCDVAssetsLibraryPrefix]) {
- // can't read assets-library URLs as text
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_READABLE_ERR];
- } else if (!file) {
- // invalid path entry
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_FOUND_ERR];
- } else {
- if (start > 0) {
- [file seekToFileOffset:start];
- }
-
- NSData* readData;
- if (end < 0) {
- readData = [file readDataToEndOfFile];
- } else {
- readData = [file readDataOfLength:(end - start)];
+ [self readFileWithPath:path start:start end:end callback:^(NSData* data, NSString* mimeType, CDVFileError errorCode) {
+ CDVPluginResult* result = nil;
+ if (data != nil) {
+ NSString* str = [[NSString alloc] initWithBytesNoCopy:(void*)[data bytes] length:[data length] encoding:NSUTF8StringEncoding freeWhenDone:NO];
+ // Check that UTF8 conversion did not fail.
+ if (str != nil) {
+ result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:str];
+ result.associatedObject = data;
+ } else {
+ errorCode = ENCODING_ERR;
+ }
}
-
- [file closeFile];
- NSString* pNStrBuff = nil;
- if (readData) {
- pNStrBuff = [[NSString alloc] initWithBytes:[readData bytes] length:[readData length] encoding:NSUTF8StringEncoding];
- } else {
- // return empty string if no data
- pNStrBuff = @"";
+ if (result == nil) {
+ result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:errorCode];
}
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:pNStrBuff];
- }
- [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
+ [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
+ }];
}
/* Read content of text file and return as base64 encoded data url.
* IN:
* NSArray* arguments
* 0 - NSString* fullPath
+ * 1 - NSString* start
+ * 2 - NSString* end
*
* Determines the mime type from the file extension, returns ENCODING_ERR if mimetype can not be determined.
*/
- (void)readAsDataURL:(CDVInvokedUrlCommand*)command
{
- // arguments
- NSString* argPath = [command.arguments objectAtIndex:0];
- NSInteger start = 0;
- NSInteger end = -1;
-
- if ([command.arguments count] >= 2) {
- start = [[command.arguments objectAtIndex:1] integerValue];
- }
- if ([command.arguments count] >= 3) {
- end = [[command.arguments objectAtIndex:2] integerValue];
- }
+ NSString* path = [command argumentAtIndex:0];
+ NSInteger start = [[command argumentAtIndex:1] integerValue];
+ NSInteger end = [[command argumentAtIndex:2] integerValue];
+
+ [self readFileWithPath:path start:start end:end callback:^(NSData* data, NSString* mimeType, CDVFileError errorCode) {
+ CDVPluginResult* result = nil;
+ if (data != nil) {
+ // TODO: Would be faster to base64 encode directly to the final string.
+ NSString* output = [NSString stringWithFormat:@"data:%@;base64,%@", mimeType, [data base64EncodedString]];
+ result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:output];
+ } else {
+ result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:errorCode];
+ }
- CDVFileError errCode = ABORT_ERR;
- __block CDVPluginResult* result = nil;
+ [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
+ }];
+}
- if (!argPath) {
- errCode = SYNTAX_ERR;
- } else if ([argPath hasPrefix:kCDVAssetsLibraryPrefix]) {
- // In this case, we need to use an asynchronous method to retrieve the file.
- // Because of this, we can't just assign to `result` and send it at the end of the method.
- // Instead, we return after calling the asynchronous method and send `result` in each of the blocks.
- ALAssetsLibraryAssetForURLResultBlock resultBlock = ^(ALAsset * asset) {
- if (asset) {
- // We have the asset! Get the data and send it off.
- ALAssetRepresentation* assetRepresentation = [asset defaultRepresentation];
- Byte* buffer = (Byte*)malloc ([assetRepresentation size]);
- NSUInteger bufferSize = [assetRepresentation getBytes:buffer fromOffset:0.0 length:[assetRepresentation size] error:nil];
- NSData* data = [NSData dataWithBytesNoCopy:buffer length:bufferSize freeWhenDone:YES];
- NSString* mimeType = [self getMimeTypeFromPath:[assetRepresentation filename]];
- NSString* dataString = [NSString stringWithFormat:@"data:%@;base64,%@", mimeType, [data base64EncodedString]];
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:dataString];
- [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
- } else {
- // We couldn't find the asset. Send the appropriate error.
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_FOUND_ERR];
- [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
- }
- };
- ALAssetsLibraryAccessFailureBlock failureBlock = ^(NSError * error) {
- // Retrieving the asset failed for some reason. Send the appropriate error.
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsString:[error localizedDescription]];
- [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
- };
+/* Read content of text file and return as an arraybuffer
+ * IN:
+ * NSArray* arguments
+ * 0 - NSString* fullPath
+ * 1 - NSString* start
+ * 2 - NSString* end
+ */
- ALAssetsLibrary* assetsLibrary = [[ALAssetsLibrary alloc] init];
- [assetsLibrary assetForURL:[NSURL URLWithString:argPath] resultBlock:resultBlock failureBlock:failureBlock];
- return;
- } else {
- NSString* mimeType = [self getMimeTypeFromPath:argPath];
- if (!mimeType) {
- // can't return as data URL if can't figure out the mimeType
- errCode = ENCODING_ERR;
+- (void)readAsArrayBuffer:(CDVInvokedUrlCommand*)command
+{
+ NSString* path = [command argumentAtIndex:0];
+ NSInteger start = [[command argumentAtIndex:1] integerValue];
+ NSInteger end = [[command argumentAtIndex:2] integerValue];
+
+ [self readFileWithPath:path start:start end:end callback:^(NSData* data, NSString* mimeType, CDVFileError errorCode) {
+ CDVPluginResult* result = nil;
+ if (data != nil) {
+ result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsArrayBuffer:data];
} else {
- NSFileHandle* file = [NSFileHandle fileHandleForReadingAtPath:argPath];
- if (start > 0) {
- [file seekToFileOffset:start];
- }
+ result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:errorCode];
+ }
- NSData* readData;
- if (end < 0) {
- readData = [file readDataToEndOfFile];
- } else {
- readData = [file readDataOfLength:(end - start)];
- }
+ [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
+ }];
+}
- [file closeFile];
- if (readData) {
- NSString* output = [NSString stringWithFormat:@"data:%@;base64,%@", mimeType, [readData base64EncodedString]];
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:output];
- } else {
- errCode = NOT_FOUND_ERR;
- }
+- (void)readAsBinaryString:(CDVInvokedUrlCommand*)command
+{
+ NSString* path = [command argumentAtIndex:0];
+ NSInteger start = [[command argumentAtIndex:1] integerValue];
+ NSInteger end = [[command argumentAtIndex:2] integerValue];
+
+ [self readFileWithPath:path start:start end:end callback:^(NSData* data, NSString* mimeType, CDVFileError errorCode) {
+ CDVPluginResult* result = nil;
+ if (data != nil) {
+ NSString* payload = [[NSString alloc] initWithBytesNoCopy:(void*)[data bytes] length:[data length] encoding:NSASCIIStringEncoding freeWhenDone:NO];
+ result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:payload];
+ result.associatedObject = data;
+ } else {
+ result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:errorCode];
}
- }
- if (!result) {
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:errCode];
- }
- // NSLog(@"readAsDataURL return: %@", jsString);
- [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
+
+ [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
+ }];
}
/* helper function to get the mimeType from the file extension
@@ -1219,7 +1246,7 @@ NSString* const kCDVAssetsLibraryPrefix = @"assets-library://";
mimeType = (__bridge_transfer NSString*)UTTypeCopyPreferredTagWithClass(typeId, kUTTagClassMIMEType);
if (!mimeType) {
// special case for m4a
- if ([(__bridge NSString*) typeId rangeOfString:@"m4a-audio"].location != NSNotFound) {
+ if ([(__bridge NSString*)typeId rangeOfString : @"m4a-audio"].location != NSNotFound) {
mimeType = @"audio/mp4";
} else if ([[fullPath pathExtension] rangeOfString:@"wav"].location != NSNotFound) {
mimeType = @"audio/wav";
@@ -1343,7 +1370,7 @@ NSString* const kCDVAssetsLibraryPrefix = @"assets-library://";
NSString* appFile = argPath; // [ self getFullPath: argPath];
BOOL bExists = [fMgr fileExistsAtPath:appFile];
- CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:(bExists ? 1:0)];
+ CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:(bExists ? 1 : 0)];
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
}
@@ -1359,7 +1386,7 @@ NSString* const kCDVAssetsLibraryPrefix = @"assets-library://";
BOOL bIsDir = NO;
BOOL bExists = [fMgr fileExistsAtPath:appFile isDirectory:&bIsDir];
- CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:((bExists && bIsDir) ? 1:0)];
+ CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:((bExists && bIsDir) ? 1 : 0)];
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
}
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/CDVFileTransfer.h
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVFileTransfer.h b/lib/cordova-ios/CordovaLib/Classes/CDVFileTransfer.h
index f96bb7d..d82cdd3 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVFileTransfer.h
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVFileTransfer.h
@@ -48,10 +48,10 @@ extern NSString* const kOptionsKeyCookie;
- (NSMutableDictionary*)createFileTransferError:(int)code AndSource:(NSString*)source AndTarget:(NSString*)target;
- (NSMutableDictionary*)createFileTransferError:(int)code
- AndSource :(NSString*)source
- AndTarget :(NSString*)target
- AndHttpStatus :(int)httpStatus
- AndBody :(NSString*)body;
+ AndSource:(NSString*)source
+ AndTarget:(NSString*)target
+ AndHttpStatus:(int)httpStatus
+ AndBody:(NSString*)body;
@property (readonly) NSMutableDictionary* activeTransfers;
@end
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/CDVFileTransfer.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVFileTransfer.m b/lib/cordova-ios/CordovaLib/Classes/CDVFileTransfer.m
index 4ccdce6..5741aca 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVFileTransfer.m
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVFileTransfer.m
@@ -52,8 +52,8 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
while (totalBytesWritten < bytesToWrite) {
CFIndex result = CFWriteStreamWrite(stream,
- bytes + totalBytesWritten,
- bytesToWrite - totalBytesWritten);
+ bytes + totalBytesWritten,
+ bytesToWrite - totalBytesWritten);
if (result < 0) {
CFStreamError error = CFWriteStreamGetError(stream);
NSLog(@"WriteStreamError domain: %ld error: %ld", error.domain, error.error);
@@ -190,7 +190,7 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
[postBodyBeforeFile appendData:formBoundaryData];
[postBodyBeforeFile appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", key] dataUsingEncoding:NSUTF8StringEncoding]];
[postBodyBeforeFile appendData:[val dataUsingEncoding:NSUTF8StringEncoding]];
- [postBodyBeforeFile appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
+ [postBodyBeforeFile appendData:[@"\r\n" dataUsingEncoding : NSUTF8StringEncoding]];
}
[postBodyBeforeFile appendData:formBoundaryData];
@@ -213,22 +213,22 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
[req setHTTPBodyStream:CFBridgingRelease(readStream)];
[self.commandDelegate runInBackground:^{
- if (CFWriteStreamOpen (writeStream)) {
- NSData* chunks[] = {postBodyBeforeFile, fileData, postBodyAfterFile};
- int numChunks = sizeof (chunks) / sizeof (chunks[0]);
-
- for (int i = 0; i < numChunks; ++i) {
- CFIndex result = WriteDataToStream (chunks[i], writeStream);
- if (result <= 0) {
- break;
- }
+ if (CFWriteStreamOpen(writeStream)) {
+ NSData* chunks[] = {postBodyBeforeFile, fileData, postBodyAfterFile};
+ int numChunks = sizeof(chunks) / sizeof(chunks[0]);
+
+ for (int i = 0; i < numChunks; ++i) {
+ CFIndex result = WriteDataToStream(chunks[i], writeStream);
+ if (result <= 0) {
+ break;
}
- } else {
- NSLog (@"FileTransfer: Failed to open writeStream");
}
- CFWriteStreamClose (writeStream);
- CFRelease (writeStream);
- }];
+ } else {
+ NSLog(@"FileTransfer: Failed to open writeStream");
+ }
+ CFWriteStreamClose(writeStream);
+ CFRelease(writeStream);
+ }];
} else {
[postBodyBeforeFile appendData:fileData];
[postBodyBeforeFile appendData:postBodyAfterFile];
@@ -265,11 +265,11 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
// return unsupported result for assets-library URLs
if ([target hasPrefix:kCDVAssetsLibraryPrefix]) {
// Instead, we return after calling the asynchronous method and send `result` in each of the blocks.
- ALAssetsLibraryAssetForURLResultBlock resultBlock = ^(ALAsset * asset) {
+ ALAssetsLibraryAssetForURLResultBlock resultBlock = ^(ALAsset* asset) {
if (asset) {
// We have the asset! Get the data and send it off.
ALAssetRepresentation* assetRepresentation = [asset defaultRepresentation];
- Byte* buffer = (Byte*)malloc ([assetRepresentation size]);
+ Byte* buffer = (Byte*)malloc([assetRepresentation size]);
NSUInteger bufferSize = [assetRepresentation getBytes:buffer fromOffset:0.0 length:[assetRepresentation size] error:nil];
NSData* fileData = [NSData dataWithBytesNoCopy:buffer length:bufferSize freeWhenDone:YES];
[self uploadData:fileData command:command];
@@ -279,7 +279,7 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
}
};
- ALAssetsLibraryAccessFailureBlock failureBlock = ^(NSError * error) {
+ ALAssetsLibraryAccessFailureBlock failureBlock = ^(NSError* error) {
// Retrieving the asset failed for some reason. Send the appropriate error.
CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsString:[error localizedDescription]];
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
@@ -291,12 +291,18 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
} else {
// Extract the path part out of a file: URL.
NSString* filePath = [target hasPrefix:@"/"] ? [target copy] : [[NSURL URLWithString:target] path];
+ if (filePath == nil) {
+ // We couldn't find the asset. Send the appropriate error.
+ CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_FOUND_ERR];
+ [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
+ return;
+ }
// Memory map the file so that it can be read efficiently even if it is large.
NSData* fileData = [NSData dataWithContentsOfFile:filePath options:NSDataReadingMappedIfSafe error:&err];
if (err != nil) {
- NSLog (@"Error opening file %@: %@", target, err);
+ NSLog(@"Error opening file %@: %@", target, err);
}
[self uploadData:fileData command:command];
}
@@ -352,6 +358,7 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
NSString* filePath = [command.arguments objectAtIndex:1];
BOOL trustAllHosts = [[command.arguments objectAtIndex:2 withDefault:[NSNumber numberWithBool:YES]] boolValue]; // allow self-signed certs
NSString* objectId = [command.arguments objectAtIndex:3];
+ NSDictionary* headers = [command.arguments objectAtIndex:4 withDefault:nil];
// return unsupported result for assets-library URLs
if ([filePath hasPrefix:kCDVAssetsLibraryPrefix]) {
@@ -388,7 +395,7 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
}
NSMutableURLRequest* req = [NSMutableURLRequest requestWithURL:url];
- [self applyRequestHeaders:nil toRequest:req];
+ [self applyRequestHeaders:headers toRequest:req];
CDVFileTransferDelegate* delegate = [[CDVFileTransferDelegate alloc] init];
delegate.command = self;
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/CDVGlobalization.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVGlobalization.m b/lib/cordova-ios/CordovaLib/Classes/CDVGlobalization.m
index 4d960cd..9eb9721 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVGlobalization.m
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVGlobalization.m
@@ -138,14 +138,14 @@
// create the formatter using the user's current default locale and formats for dates and times
CFDateFormatterRef formatter = CFDateFormatterCreate(kCFAllocatorDefault,
- currentLocale,
- dateStyle,
- timeStyle);
+ currentLocale,
+ dateStyle,
+ timeStyle);
// if we have a valid date object then call the formatter
if (date) {
dateString = (__bridge_transfer NSString*)CFDateFormatterCreateStringWithDate(kCFAllocatorDefault,
- formatter,
- (__bridge CFDateRef)date);
+ formatter,
+ (__bridge CFDateRef)date);
}
// if the date was converted to a string successfully then return the result
@@ -227,18 +227,18 @@
// get the user's default settings for date and time formats
CFDateFormatterRef formatter = CFDateFormatterCreate(kCFAllocatorDefault,
- currentLocale,
- dateStyle,
- timeStyle);
+ currentLocale,
+ dateStyle,
+ timeStyle);
// set the parsing to be more lenient
CFDateFormatterSetProperty(formatter, kCFDateFormatterIsLenient, kCFBooleanTrue);
// parse tha date and time string
CFDateRef date = CFDateFormatterCreateDateFromString(kCFAllocatorDefault,
- formatter,
- (__bridge CFStringRef)dateString,
- NULL);
+ formatter,
+ (__bridge CFStringRef)dateString,
+ NULL);
// if we were able to parse the date then get the date and time components
if (date != NULL) {
@@ -336,9 +336,9 @@
// get the user's default settings for date and time formats
CFDateFormatterRef formatter = CFDateFormatterCreate(kCFAllocatorDefault,
- currentLocale,
- dateStyle,
- timeStyle);
+ currentLocale,
+ dateStyle,
+ timeStyle);
// get the date pattern to apply when formatting and parsing
CFStringRef datePattern = CFDateFormatterGetFormat(formatter);
@@ -415,9 +415,9 @@
}
CFDateFormatterRef formatter = CFDateFormatterCreate(kCFAllocatorDefault,
- currentLocale,
- kCFDateFormatterFullStyle,
- kCFDateFormatterFullStyle);
+ currentLocale,
+ kCFDateFormatterFullStyle,
+ kCFDateFormatterFullStyle);
if ((selector == CDV_SELECTOR_MONTHS) && (style == CDV_FORMAT_LONG)) {
dataStyle = kCFDateFormatterMonthSymbols;
@@ -545,13 +545,13 @@
}
CFNumberFormatterRef formatter = CFNumberFormatterCreate(kCFAllocatorDefault,
- currentLocale,
- style);
+ currentLocale,
+ style);
// get the localized string based upon the locale and user preferences
NSString* numberString = (__bridge_transfer NSString*)CFNumberFormatterCreateStringWithNumber(kCFAllocatorDefault,
- formatter,
- (__bridge CFNumberRef)number);
+ formatter,
+ (__bridge CFNumberRef)number);
if (numberString) {
NSDictionary* dictionary = [NSDictionary dictionaryWithObject:numberString forKey:@"value"];
@@ -612,8 +612,8 @@
}
CFNumberFormatterRef formatter = CFNumberFormatterCreate(kCFAllocatorDefault,
- currentLocale,
- style);
+ currentLocale,
+ style);
// we need to make this lenient so as to avoid problems with parsing currencies that have non-breaking space characters
if (style == kCFNumberFormatterCurrencyStyle) {
@@ -622,10 +622,10 @@
// parse againist the largest type to avoid data loss
Boolean rc = CFNumberFormatterGetValueFromString(formatter,
- (__bridge CFStringRef)numberString,
- NULL,
- kCFNumberDoubleType,
- &doubleValue);
+ (__bridge CFStringRef)numberString,
+ NULL,
+ kCFNumberDoubleType,
+ &doubleValue);
if (rc) {
NSDictionary* dictionary = [NSDictionary dictionaryWithObject:[NSNumber numberWithDouble:doubleValue] forKey:@"value"];
@@ -681,8 +681,8 @@
}
CFNumberFormatterRef formatter = CFNumberFormatterCreate(kCFAllocatorDefault,
- currentLocale,
- style);
+ currentLocale,
+ style);
NSString* numberPattern = (__bridge NSString*)CFNumberFormatterGetFormat(formatter);
@@ -749,8 +749,8 @@
// now set the currency code in the formatter
if (rc) {
CFNumberFormatterRef formatter = CFNumberFormatterCreate(kCFAllocatorDefault,
- currentLocale,
- kCFNumberFormatterCurrencyStyle);
+ currentLocale,
+ kCFNumberFormatterCurrencyStyle);
CFNumberFormatterSetProperty(formatter, kCFNumberFormatterCurrencyCode, (__bridge CFStringRef)currencyCode);
CFNumberFormatterSetProperty(formatter, kCFNumberFormatterInternationalCurrencySymbol, (__bridge CFStringRef)currencyCode);
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/CDVInAppBrowser.h
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVInAppBrowser.h b/lib/cordova-ios/CordovaLib/Classes/CDVInAppBrowser.h
index 9ff460a..f63250a 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVInAppBrowser.h
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVInAppBrowser.h
@@ -20,6 +20,7 @@
#import "CDVPlugin.h"
#import "CDVInvokedUrlCommand.h"
#import "CDVScreenOrientationDelegate.h"
+#import "CDVWebViewDelegate.h"
@class CDVInAppBrowserViewController;
@@ -27,6 +28,7 @@
- (void)browserLoadStart:(NSURL*)url;
- (void)browserLoadStop:(NSURL*)url;
+- (void)browserLoadError:(NSError*)error forUrl:(NSURL*)url;
- (void)browserExit;
@end
@@ -47,6 +49,7 @@
NSString* _userAgent;
NSString* _prevUserAgent;
NSInteger _userAgentLockToken;
+ CDVWebViewDelegate* _webViewDelegate;
}
@property (nonatomic, strong) IBOutlet UIWebView* webView;
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/CDVInAppBrowser.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVInAppBrowser.m b/lib/cordova-ios/CordovaLib/Classes/CDVInAppBrowser.m
index 14671a5..d001dfd 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVInAppBrowser.m
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVInAppBrowser.m
@@ -165,7 +165,7 @@
{
if (self.callbackId != nil) {
CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
- messageAsDictionary:@ {@"type":@"loadstart", @"url":[url absoluteString]}];
+ messageAsDictionary:@{@"type":@"loadstart", @"url":[url absoluteString]}];
[pluginResult setKeepCallback:[NSNumber numberWithBool:YES]];
[self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];
@@ -176,7 +176,18 @@
{
if (self.callbackId != nil) {
CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
- messageAsDictionary:@ {@"type":@"loadstop", @"url":[url absoluteString]}];
+ messageAsDictionary:@{@"type":@"loadstop", @"url":[url absoluteString]}];
+ [pluginResult setKeepCallback:[NSNumber numberWithBool:YES]];
+
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];
+ }
+}
+
+- (void)browserLoadError:(NSError*)error forUrl:(NSURL*)url
+{
+ if (self.callbackId != nil) {
+ CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR
+ messageAsDictionary:@{@"type":@"loaderror", @"url":[url absoluteString], @"code": [NSNumber numberWithInt:error.code], @"message": error.localizedDescription}];
[pluginResult setKeepCallback:[NSNumber numberWithBool:YES]];
[self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];
@@ -187,7 +198,7 @@
{
if (self.callbackId != nil) {
CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
- messageAsDictionary:@ {@"type":@"exit"}];
+ messageAsDictionary:@{@"type":@"exit"}];
[pluginResult setKeepCallback:[NSNumber numberWithBool:YES]];
[self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];
@@ -209,6 +220,7 @@
if (self != nil) {
_userAgent = userAgent;
_prevUserAgent = prevUserAgent;
+ _webViewDelegate = [[CDVWebViewDelegate alloc] initWithDelegate:self];
[self createViews];
}
@@ -229,7 +241,7 @@
[self.view addSubview:self.webView];
[self.view sendSubviewToBack:self.webView];
- self.webView.delegate = self;
+ self.webView.delegate = _webViewDelegate;
self.webView.backgroundColor = [UIColor whiteColor];
self.webView.clearsContextBeforeDrawing = YES;
@@ -391,10 +403,10 @@
[self.webView loadRequest:request];
} else {
[CDVUserAgentUtil acquireLock:^(NSInteger lockToken) {
- _userAgentLockToken = lockToken;
- [CDVUserAgentUtil setUserAgent:_userAgent lockToken:lockToken];
- [self.webView loadRequest:request];
- }];
+ _userAgentLockToken = lockToken;
+ [CDVUserAgentUtil setUserAgent:_userAgent lockToken:lockToken];
+ [self.webView loadRequest:request];
+ }];
}
}
@@ -419,14 +431,18 @@
self.forwardButton.enabled = theWebView.canGoForward;
[self.spinner startAnimating];
+}
+- (BOOL)webView:(UIWebView*)theWebView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
+{
if ((self.navigationDelegate != nil) && [self.navigationDelegate respondsToSelector:@selector(browserLoadStart:)]) {
- NSURL* url = theWebView.request.URL;
+ NSURL* url = request.URL;
if (url == nil) {
url = _requestedURL;
}
[self.navigationDelegate browserLoadStart:url];
}
+ return YES;
}
- (void)webViewDidFinishLoad:(UIWebView*)theWebView
@@ -450,7 +466,7 @@
// from it must pass through its white-list. This *does* break PDFs that
// contain links to other remote PDF/websites.
// More info at https://issues.apache.org/jira/browse/CB-2225
- BOOL isPDF = [@"true" isEqualToString:[theWebView stringByEvaluatingJavaScriptFromString:@"document.body==null"]];
+ BOOL isPDF = [@"true" isEqualToString :[theWebView stringByEvaluatingJavaScriptFromString:@"document.body==null"]];
if (isPDF) {
[CDVUserAgentUtil setUserAgent:_prevUserAgent lockToken:_userAgentLockToken];
}
@@ -471,6 +487,11 @@
[self.spinner stopAnimating];
self.addressLabel.text = @"Load Error";
+
+ if ((self.navigationDelegate != nil) && [self.navigationDelegate respondsToSelector:@selector(browserLoadError:forUrl:)]) {
+ NSURL* url = theWebView.request.URL;
+ [self.navigationDelegate browserLoadError:error forUrl:url];
+ }
}
#pragma mark CDVScreenOrientationDelegate
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/CDVInvokedUrlCommand.h
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVInvokedUrlCommand.h b/lib/cordova-ios/CordovaLib/Classes/CDVInvokedUrlCommand.h
index 6eb0099..7be8884 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVInvokedUrlCommand.h
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVInvokedUrlCommand.h
@@ -34,9 +34,9 @@
+ (CDVInvokedUrlCommand*)commandFromJson:(NSArray*)jsonEntry;
- (id)initWithArguments:(NSArray*)arguments
- callbackId :(NSString*)callbackId
- className :(NSString*)className
- methodName :(NSString*)methodName;
+ callbackId:(NSString*)callbackId
+ className:(NSString*)className
+ methodName:(NSString*)methodName;
- (id)initFromJson:(NSArray*)jsonEntry;
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/CDVJpegHeaderWriter.h
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVJpegHeaderWriter.h b/lib/cordova-ios/CordovaLib/Classes/CDVJpegHeaderWriter.h
new file mode 100644
index 0000000..02fe91f
--- /dev/null
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVJpegHeaderWriter.h
@@ -0,0 +1,60 @@
+/*
+ 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 <Foundation/Foundation.h>
+
+@interface CDVJpegHeaderWriter : NSObject {
+ NSDictionary * SubIFDTagFormatDict;
+ NSDictionary * IFD0TagFormatDict;
+}
+
+- (NSString*) createExifAPP1 : (NSDictionary*) datadict;
+- (NSString*) formattedHexStringFromDecimalNumber: (NSNumber*) numb
+ withPlaces: (NSNumber*) width;
+- (NSString*) formatNumberWithLeadingZeroes: (NSNumber*) numb
+ withPlaces: (NSNumber*) places;
+- (NSString*) decimalToUnsignedRational: (NSNumber*) numb
+ withResultNumerator: (NSNumber**) numerator
+ withResultDenominator: (NSNumber**) denominator;
+- (void) continuedFraction: (double) val
+ withFractionList: (NSMutableArray*) fractionlist
+ withHorizon: (int) horizon;
+//- (void) expandContinuedFraction: (NSArray*) fractionlist;
+- (void) splitDouble: (double) val
+ withIntComponent: (int*) rightside
+ withFloatRemainder: (double*) leftside;
+- (NSString*) formatRationalWithNumerator: (NSNumber*) numerator
+ withDenominator: (NSNumber*) denominator
+ asSigned: (Boolean) signedFlag;
+- (NSString*) hexStringFromData : (NSData*) data;
+- (NSNumber*) numericFromHexString : (NSString *) hexstring;
+
+/*
+- (void) readExifMetaData : (NSData*) imgdata;
+- (void) spliceImageData : (NSData*) imgdata withExifData: (NSDictionary*) exifdata;
+- (void) locateExifMetaData : (NSData*) imgdata;
+- (NSString*) createExifAPP1 : (NSDictionary*) datadict;
+- (void) createExifDataString : (NSDictionary*) datadict;
+- (NSString*) createDataElement : (NSString*) element
+ withElementData: (NSString*) data
+ withExternalDataBlock: (NSDictionary*) memblock;
+- (NSString*) hexStringFromData : (NSData*) data;
+- (NSNumber*) numericFromHexString : (NSString *) hexstring;
+*/
+@end
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/CDVJpegHeaderWriter.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVJpegHeaderWriter.m b/lib/cordova-ios/CordovaLib/Classes/CDVJpegHeaderWriter.m
new file mode 100644
index 0000000..7b59d11
--- /dev/null
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVJpegHeaderWriter.m
@@ -0,0 +1,472 @@
+/*
+ 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 "CDVJpegHeaderWriter.h"
+#include "CDVExif.h"
+
+// tag info shorthand, tagno: tag number, typecode: data type:, components: number of components
+#define TAGINF(tagno, typecode, components) [NSArray arrayWithObjects: tagno, typecode, components, nil]
+
+const uint mJpegId = 0xffd8; // JPEG format marker
+const uint mExifMarker = 0xffe1; // APP1 jpeg header marker
+const uint mExif = 0x45786966; // ASCII 'Exif', first characters of valid exif header after size
+const uint mMotorallaByteAlign = 0x4d4d; // 'MM', motorola byte align, msb first or 'sane'
+const uint mIntelByteAlgin = 0x4949; // 'II', Intel byte align, lsb first or 'batshit crazy reverso world'
+const uint mTiffLength = 0x2a; // after byte align bits, next to bits are 0x002a(MM) or 0x2a00(II), tiff version number
+
+
+@implementation CDVJpegHeaderWriter
+
+- (id) init {
+ self = [super init];
+ // supported tags for exif IFD
+ IFD0TagFormatDict = [[NSDictionary alloc] initWithObjectsAndKeys:
+ // TAGINF(@"010e", [NSNumber numberWithInt:EDT_ASCII_STRING], @0), @"ImageDescription",
+ TAGINF(@"0132", [NSNumber numberWithInt:EDT_ASCII_STRING], @20), @"DateTime",
+ TAGINF(@"010f", [NSNumber numberWithInt:EDT_ASCII_STRING], @0), @"Make",
+ TAGINF(@"0110", [NSNumber numberWithInt:EDT_ASCII_STRING], @0), @"Model",
+ TAGINF(@"0131", [NSNumber numberWithInt:EDT_ASCII_STRING], @0), @"Software",
+ TAGINF(@"011a", [NSNumber numberWithInt:EDT_URATIONAL], @1), @"XResolution",
+ TAGINF(@"011b", [NSNumber numberWithInt:EDT_URATIONAL], @1), @"YResolution",
+ // currently supplied outside of Exif data block by UIImagePickerControllerMediaMetadata, this is set manually in CDVCamera.m
+ TAGINF(@"0112", [NSNumber numberWithInt:EDT_USHORT], @1), @"Orientation",
+
+ // rest of the tags are supported by exif spec, but are not specified by UIImagePickerControllerMediaMedadata
+ // should camera hardware supply these values in future versions, or if they can be derived, ImageHeaderWriter will include them gracefully
+ TAGINF(@"0128", [NSNumber numberWithInt:EDT_USHORT], @1), @"ResolutionUnit",
+ TAGINF(@"013e", [NSNumber numberWithInt:EDT_URATIONAL], @2), @"WhitePoint",
+ TAGINF(@"013f", [NSNumber numberWithInt:EDT_URATIONAL], @6), @"PrimaryChromaticities",
+ TAGINF(@"0211", [NSNumber numberWithInt:EDT_URATIONAL], @3), @"YCbCrCoefficients",
+ TAGINF(@"0213", [NSNumber numberWithInt:EDT_USHORT], @1), @"YCbCrPositioning",
+ TAGINF(@"0214", [NSNumber numberWithInt:EDT_URATIONAL], @6), @"ReferenceBlackWhite",
+ TAGINF(@"8298", [NSNumber numberWithInt:EDT_URATIONAL], @0), @"Copyright",
+
+ // offset to exif subifd, we determine this dynamically based on the size of the main exif IFD
+ TAGINF(@"8769", [NSNumber numberWithInt:EDT_ULONG], @1), @"ExifOffset",
+ nil];
+
+ // supported tages for exif subIFD
+ SubIFDTagFormatDict = [[NSDictionary alloc] initWithObjectsAndKeys:
+ // TAGINF(@"9000", [NSNumber numberWithInt:], @), @"ExifVersion",
+ // TAGINF(@"9202",[NSNumber numberWithInt:EDT_URATIONAL],@1), @"ApertureValue",
+ // TAGINF(@"9203",[NSNumber numberWithInt:EDT_SRATIONAL],@1), @"BrightnessValue",
+ TAGINF(@"a001",[NSNumber numberWithInt:EDT_USHORT],@1), @"ColorSpace",
+ TAGINF(@"9004",[NSNumber numberWithInt:EDT_ASCII_STRING],@20), @"DateTimeDigitized",
+ TAGINF(@"9003",[NSNumber numberWithInt:EDT_ASCII_STRING],@20), @"DateTimeOriginal",
+ TAGINF(@"a402", [NSNumber numberWithInt:EDT_USHORT], @1), @"ExposureMode",
+ TAGINF(@"8822", [NSNumber numberWithInt:EDT_USHORT], @1), @"ExposureProgram",
+ TAGINF(@"829a", [NSNumber numberWithInt:EDT_URATIONAL], @1), @"ExposureTime",
+ TAGINF(@"829d", [NSNumber numberWithInt:EDT_URATIONAL], @1), @"FNumber",
+ TAGINF(@"9209", [NSNumber numberWithInt:EDT_USHORT], @1), @"Flash",
+ // FocalLengthIn35mmFilm
+ TAGINF(@"a405", [NSNumber numberWithInt:EDT_USHORT], @1), @"FocalLenIn35mmFilm",
+ TAGINF(@"920a", [NSNumber numberWithInt:EDT_URATIONAL], @1), @"FocalLength",
+
+ //TAGINF(@"8827", [NSNumber numberWithInt:EDT_USHORT], @2), @"ISOSpeedRatings",
+
+ TAGINF(@"9207",[NSNumber numberWithInt:EDT_USHORT],@1), @"MeteringMode",
+ // specific to compressed data
+ TAGINF(@"a002", [NSNumber numberWithInt:EDT_ULONG],@1), @"PixelXDimension",
+ TAGINF(@"a003", [NSNumber numberWithInt:EDT_ULONG],@1), @"PixelYDimension",
+ // data type undefined, but this is a DSC camera, so value is always 1, treat as ushort
+ TAGINF(@"a301", [NSNumber numberWithInt:EDT_USHORT],@1), @"SceneType",
+ TAGINF(@"a217",[NSNumber numberWithInt:EDT_USHORT],@1), @"SensingMethod",
+ // TAGINF(@"9201", [NSNumber numberWithInt:EDT_SRATIONAL], @1), @"ShutterSpeedValue",
+ // specifies location of main subject in scene (x,y,wdith,height) expressed before rotation processing
+ // TAGINF(@"9214", [NSNumber numberWithInt:EDT_USHORT], @4), @"SubjectArea",
+ TAGINF(@"a403", [NSNumber numberWithInt:EDT_USHORT], @1), @"WhiteBalance",
+ nil];
+ return self;
+}
+
+/**
+ * Create the Exif data block as a hex string
+ * jpeg uses Application Markers (APP's) as markers for application data
+ * APP1 is the application marker reserved for exif data
+ *
+ * (NSDictionary*) datadict - with subdictionaries marked '{TIFF}' and '{EXIF}' as returned by imagePickerController with a valid
+ * didFinishPickingMediaWithInfo data dict, under key @"UIImagePickerControllerMediaMetadata"
+ *
+ * the following constructs a hex string to Exif specifications, and is therefore brittle
+ * altering the order of arguments to the string constructors, modifying field sizes or formats,
+ * and any other minor change will likely prevent the exif data from being read
+ */
+- (NSString*) createExifAPP1 : (NSDictionary*) datadict {
+ NSMutableString * app1; // holds finalized product
+ NSString * exifIFD; // exif information file directory
+ NSString * subExifIFD; // subexif information file directory
+
+ // FFE1 is the hex APP1 marker code, and will allow client apps to read the data
+ NSString * app1marker = @"ffe1";
+ // SSSS size, to be determined
+ // EXIF ascii characters followed by 2bytes of zeros
+ NSString * exifmarker = @"457869660000";
+ // Tiff header: 4d4d is motorolla byte align (big endian), 002a is hex for 42
+ NSString * tiffheader = @"4d4d002a";
+ //first IFD offset from the Tiff header to IFD0. Since we are writing it, we know it's address 0x08
+ NSString * ifd0offset = @"00000008";
+
+ //data labeled as TIFF in UIImagePickerControllerMediaMetaData is part of the EXIF IFD0 portion of APP1
+ exifIFD = [self createExifIFDFromDict: [datadict objectForKey:@"{TIFF}"] withFormatDict: IFD0TagFormatDict isIFD0:YES];
+
+ //data labeled as EXIF in UIImagePickerControllerMediaMetaData is part of the EXIF Sub IFD portion of APP1
+ subExifIFD = [self createExifIFDFromDict: [datadict objectForKey:@"{Exif}"] withFormatDict: SubIFDTagFormatDict isIFD0:NO];
+
+ // construct the complete app1 data block
+ app1 = [[NSMutableString alloc] initWithFormat: @"%@%04x%@%@%@%@%@",
+ app1marker,
+ 16+[exifIFD length]/2+[subExifIFD length]/2/*16+[exifIFD length]/2*/,
+ exifmarker,
+ tiffheader,
+ ifd0offset,
+ exifIFD,
+ subExifIFD];
+
+ return app1;
+}
+
+// returns hex string representing a valid exif information file directory constructed from the datadict and formatdict
+- (NSString*) createExifIFDFromDict : (NSDictionary*) datadict withFormatDict : (NSDictionary*) formatdict isIFD0 : (BOOL) ifd0flag {
+ NSArray * datakeys = [datadict allKeys]; // all known data keys
+ NSArray * knownkeys = [formatdict allKeys]; // only keys in knowkeys are considered for entry in this IFD
+ NSMutableArray * ifdblock = [[NSMutableArray alloc] initWithCapacity: [datadict count]]; // all ifd entries
+ NSMutableArray * ifddatablock = [[NSMutableArray alloc] initWithCapacity: [datadict count]]; // data block entries
+ ifd0flag = NO; // ifd0 requires a special flag and has offset to next ifd appended to end
+
+ // iterate through known provided data keys
+ for (int i = 0; i < [datakeys count]; i++) {
+ NSString * key = [datakeys objectAtIndex:i];
+ // don't muck about with unknown keys
+ if ([knownkeys indexOfObject: key] != NSNotFound) {
+ // create new IFD entry
+ NSString * entry = [self createIFDElement: key
+ withFormatDict: formatdict
+ withElementData: [datadict objectForKey:key]];
+ // create the IFD entry's data block
+ NSString * data = [self createIFDElementDataWithFormat: [formatdict objectForKey:key]
+ withData: [datadict objectForKey:key]];
+ if (entry) {
+ [ifdblock addObject:entry];
+ if(!data) {
+ [ifdblock addObject:@""];
+ } else {
+ [ifddatablock addObject:data];
+ }
+ }
+ }
+ }
+
+ NSMutableString * exifstr = [[NSMutableString alloc] initWithCapacity: [ifdblock count] * 24];
+ NSMutableString * dbstr = [[NSMutableString alloc] initWithCapacity: 100];
+
+ int addr=0; // current offset/address in datablock
+ if (ifd0flag) {
+ // calculate offset to datablock based on ifd file entry count
+ addr = 14+(12*([ifddatablock count]+1)); // +1 for tag 0x8769, exifsubifd offset
+ } else {
+ // same calculation as above, but no exifsubifd offset
+ addr = 14+12*[ifddatablock count];
+ }
+
+ for (int i = 0; i < [ifdblock count]; i++) {
+ NSString * entry = [ifdblock objectAtIndex:i];
+ NSString * data = [ifddatablock objectAtIndex:i];
+
+ // check if the data fits into 4 bytes
+ if( [data length] <= 8) {
+ // concatenate the entry and the (4byte) data entry into the final IFD entry and append to exif ifd string
+ [exifstr appendFormat : @"%@%@", entry, data];
+ } else {
+ [exifstr appendFormat : @"%@%08x", entry, addr];
+ [dbstr appendFormat: @"%@", data];
+ addr+= [data length] / 2;
+ }
+ }
+
+ // calculate IFD0 terminal offset tags, currently ExifSubIFD
+ int entrycount = [ifdblock count];
+ if (ifd0flag) {
+ NSNumber * offset = [NSNumber numberWithInt:[exifstr length] / 2 + [dbstr length] / 2 ];
+
+ [self appendExifOffsetTagTo: exifstr
+ withOffset : offset];
+ entrycount++;
+ }
+ return [[NSString alloc] initWithFormat: @"%04x%@%@%@",
+ entrycount,
+ exifstr,
+ @"00000000", // offset to next IFD, 0 since there is none
+ dbstr]; // lastly, the datablock
+}
+
+// Creates an exif formatted exif information file directory entry
+- (NSString*) createIFDElement: (NSString*) elementName withFormatDict : (NSDictionary*) formatdict withElementData : (NSString*) data {
+ NSArray * fielddata = [formatdict objectForKey: elementName];// format data of desired field
+ if (fielddata) {
+ // format string @"%@%@%@%@", tag number, data format, components, value
+ NSNumber * dataformat = [fielddata objectAtIndex:1];
+ NSNumber * components = [fielddata objectAtIndex:2];
+ if([components intValue] == 0) {
+ components = [NSNumber numberWithInt: [data length] * DataTypeToWidth[[dataformat intValue]-1]];
+ }
+
+ return [[NSString alloc] initWithFormat: @"%@%@%08x",
+ [fielddata objectAtIndex:0], // the field code
+ [self formatNumberWithLeadingZeroes: dataformat withPlaces: @4], // the data type code
+ [components intValue]]; // number of components
+ }
+ return NULL;
+}
+
+/**
+ * appends exif IFD0 tag 8769 "ExifOffset" to the string provided
+ * (NSMutableString*) str - string you wish to append the 8769 tag to: APP1 or IFD0 hex data string
+ * // TAGINF(@"8769", [NSNumber numberWithInt:EDT_ULONG], @1), @"ExifOffset",
+ */
+- (void) appendExifOffsetTagTo: (NSMutableString*) str withOffset : (NSNumber*) offset {
+ NSArray * format = TAGINF(@"8769", [NSNumber numberWithInt:EDT_ULONG], @1);
+
+ NSString * entry = [self createIFDElement: @"ExifOffset"
+ withFormatDict: IFD0TagFormatDict
+ withElementData: [offset stringValue]];
+
+ NSString * data = [self createIFDElementDataWithFormat: format
+ withData: [offset stringValue]];
+ [str appendFormat:@"%@%@", entry, data];
+}
+
+// formats the Information File Directory Data to exif format
+- (NSString*) createIFDElementDataWithFormat: (NSArray*) dataformat withData: (NSString*) data {
+ NSMutableString * datastr = nil;
+ NSNumber * tmp = nil;
+ NSNumber * formatcode = [dataformat objectAtIndex:1];
+ NSNumber * num = @0;
+ NSNumber * denom = @0;
+
+ switch ([formatcode intValue]) {
+ case EDT_UBYTE:
+ break;
+ case EDT_ASCII_STRING:
+ datastr = [[NSMutableString alloc] init];
+ for (int i = 0; i < [data length]; i++) {
+ [datastr appendFormat:@"%02x",[data characterAtIndex:i]];
+ }
+ if ([datastr length] < 8) {
+ NSString * format = [NSString stringWithFormat:@"%%0%dd", 8 - [datastr length]];
+ [datastr appendFormat:format,0];
+ }
+ return datastr;
+ case EDT_USHORT:
+ return [[NSString alloc] initWithFormat : @"%@%@",
+ [self formattedHexStringFromDecimalNumber: [NSNumber numberWithInt: [data intValue]] withPlaces: @4],
+ @"00000000"];
+ case EDT_ULONG:
+ tmp = [NSNumber numberWithUnsignedLong:[data intValue]];
+ return [NSString stringWithFormat : @"%@",
+ [self formattedHexStringFromDecimalNumber: tmp withPlaces: @8]];
+ case EDT_URATIONAL:
+ return [self decimalToUnsignedRational: [NSNumber numberWithDouble:[data doubleValue]]
+ withResultNumerator: &num
+ withResultDenominator: &denom];
+ case EDT_SBYTE:
+
+ break;
+ case EDT_UNDEFINED:
+ break; // 8 bits
+ case EDT_SSHORT:
+
+ break;
+ case EDT_SLONG:
+ break; // 32bit signed integer (2's complement)
+ case EDT_SRATIONAL:
+ break; // 2 SLONGS, first long is numerator, second is denominator
+ case EDT_SINGLEFLOAT:
+ break;
+ case EDT_DOUBLEFLOAT:
+ break;
+ }
+ return datastr;
+}
+
+//======================================================================================================================
+// Utility Methods
+//======================================================================================================================
+
+// creates a formatted little endian hex string from a number and width specifier
+- (NSString*) formattedHexStringFromDecimalNumber: (NSNumber*) numb withPlaces: (NSNumber*) width {
+ NSMutableString * str = [[NSMutableString alloc] initWithCapacity:[width intValue]];
+ NSString * formatstr = [[NSString alloc] initWithFormat: @"%%%@%dx", @"0", [width intValue]];
+ [str appendFormat:formatstr, [numb intValue]];
+ return str;
+}
+
+// format number as string with leading 0's
+- (NSString*) formatNumberWithLeadingZeroes: (NSNumber *) numb withPlaces: (NSNumber *) places {
+ NSNumberFormatter * formatter = [[NSNumberFormatter alloc] init];
+ NSString *formatstr = [@"" stringByPaddingToLength:[places unsignedIntegerValue] withString:@"0" startingAtIndex:0];
+ [formatter setPositiveFormat:formatstr];
+ return [formatter stringFromNumber:numb];
+}
+
+// approximate a decimal with a rational by method of continued fraction
+// can be collasped into decimalToUnsignedRational after testing
+- (void) decimalToRational: (NSNumber *) numb
+ withResultNumerator: (NSNumber**) numerator
+ withResultDenominator: (NSNumber**) denominator {
+ NSMutableArray * fractionlist = [[NSMutableArray alloc] initWithCapacity:8];
+
+ [self continuedFraction: [numb doubleValue]
+ withFractionList: fractionlist
+ withHorizon: 8];
+
+ // simplify complex fraction represented by partial fraction list
+ [self expandContinuedFraction: fractionlist
+ withResultNumerator: numerator
+ withResultDenominator: denominator];
+
+}
+
+// approximate a decimal with an unsigned rational by method of continued fraction
+- (NSString*) decimalToUnsignedRational: (NSNumber *) numb
+ withResultNumerator: (NSNumber**) numerator
+ withResultDenominator: (NSNumber**) denominator {
+ NSMutableArray * fractionlist = [[NSMutableArray alloc] initWithCapacity:8];
+
+ // generate partial fraction list
+ [self continuedFraction: [numb doubleValue]
+ withFractionList: fractionlist
+ withHorizon: 8];
+
+ // simplify complex fraction represented by partial fraction list
+ [self expandContinuedFraction: fractionlist
+ withResultNumerator: numerator
+ withResultDenominator: denominator];
+
+ return [self formatFractionList: fractionlist];
+}
+
+// recursive implementation of decimal approximation by continued fraction
+- (void) continuedFraction: (double) val
+ withFractionList: (NSMutableArray*) fractionlist
+ withHorizon: (int) horizon {
+ int whole;
+ double remainder;
+ // 1. split term
+ [self splitDouble: val withIntComponent: &whole withFloatRemainder: &remainder];
+ [fractionlist addObject: [NSNumber numberWithInt:whole]];
+
+ // 2. calculate reciprocal of remainder
+ if (!remainder) return; // early exit, exact fraction found, avoids recip/0
+ double recip = 1 / remainder;
+
+ // 3. exit condition
+ if ([fractionlist count] > horizon) {
+ return;
+ }
+
+ // 4. recurse
+ [self continuedFraction:recip withFractionList: fractionlist withHorizon: horizon];
+
+}
+
+// expand continued fraction list, creating a single level rational approximation
+-(void) expandContinuedFraction: (NSArray*) fractionlist
+ withResultNumerator: (NSNumber**) numerator
+ withResultDenominator: (NSNumber**) denominator {
+ int i = 0;
+ int den = 0;
+ int num = 0;
+ if ([fractionlist count] == 1) {
+ *numerator = [NSNumber numberWithInt:[[fractionlist objectAtIndex:0] intValue]];
+ *denominator = @1;
+ return;
+ }
+
+ //begin at the end of the list
+ i = [fractionlist count] - 1;
+ num = 1;
+ den = [[fractionlist objectAtIndex:i] intValue];
+
+ while (i > 0) {
+ int t = [[fractionlist objectAtIndex: i-1] intValue];
+ num = t * den + num;
+ if (i==1) {
+ break;
+ } else {
+ t = num;
+ num = den;
+ den = t;
+ }
+ i--;
+ }
+ // set result parameters values
+ *numerator = [NSNumber numberWithInt: num];
+ *denominator = [NSNumber numberWithInt: den];
+}
+
+// formats expanded fraction list to string matching exif specification
+- (NSString*) formatFractionList: (NSArray *) fractionlist {
+ NSMutableString * str = [[NSMutableString alloc] initWithCapacity:16];
+
+ if ([fractionlist count] == 1){
+ [str appendFormat: @"%08x00000001", [[fractionlist objectAtIndex:0] intValue]];
+ }
+ return str;
+}
+
+// format rational as
+- (NSString*) formatRationalWithNumerator: (NSNumber*) numerator withDenominator: (NSNumber*) denominator asSigned: (Boolean) signedFlag {
+ NSMutableString * str = [[NSMutableString alloc] initWithCapacity:16];
+ if (signedFlag) {
+ long num = [numerator longValue];
+ long den = [denominator longValue];
+ [str appendFormat: @"%08lx%08lx", num >= 0 ? num : ~ABS(num) + 1, num >= 0 ? den : ~ABS(den) + 1];
+ } else {
+ [str appendFormat: @"%08lx%08lx", [numerator unsignedLongValue], [denominator unsignedLongValue]];
+ }
+ return str;
+}
+
+// split a floating point number into two integer values representing the left and right side of the decimal
+- (void) splitDouble: (double) val withIntComponent: (int*) rightside withFloatRemainder: (double*) leftside {
+ *rightside = val; // convert numb to int representation, which truncates the decimal portion
+ *leftside = val - *rightside;
+}
+
+
+//
+- (NSString*) hexStringFromData : (NSData*) data {
+ //overflow detection
+ const unsigned char *dataBuffer = [data bytes];
+ return [[NSString alloc] initWithFormat: @"%02x%02x",
+ (unsigned char)dataBuffer[0],
+ (unsigned char)dataBuffer[1]];
+}
+
+// convert a hex string to a number
+- (NSNumber*) numericFromHexString : (NSString *) hexstring {
+ NSScanner * scan = NULL;
+ unsigned int numbuf= 0;
+
+ scan = [NSScanner scannerWithString:hexstring];
+ [scan scanHexInt:&numbuf];
+ return [NSNumber numberWithInt:numbuf];
+}
+
+@end
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/CDVLocalStorage.h
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVLocalStorage.h b/lib/cordova-ios/CordovaLib/Classes/CDVLocalStorage.h
index cc6613f..dec6ab3 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVLocalStorage.h
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVLocalStorage.h
@@ -34,8 +34,8 @@
+ (void)__fixupDatabaseLocationsWithBackupType:(NSString*)backupType;
// Visible for testing.
+ (BOOL)__verifyAndFixDatabaseLocationsWithAppPlistDict:(NSMutableDictionary*)appPlistDict
- bundlePath :(NSString*)bundlePath
- fileManager :(NSFileManager*)fileManager;
+ bundlePath:(NSString*)bundlePath
+ fileManager:(NSFileManager*)fileManager;
@end
@interface CDVBackupInfo : NSObject
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/CDVLocalStorage.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVLocalStorage.m b/lib/cordova-ios/CordovaLib/Classes/CDVLocalStorage.m
index 68175f1..238d680 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVLocalStorage.m
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVLocalStorage.m
@@ -35,7 +35,7 @@
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onResignActive)
name:UIApplicationWillResignActiveNotification object:nil];
- BOOL cloudBackup = [@"cloud" isEqualToString:self.commandDelegate.settings[@"BackupWebStorage"]];
+ BOOL cloudBackup = [@"cloud" isEqualToString : self.commandDelegate.settings[@"BackupWebStorage"]];
self.backupInfo = [[self class] createBackupInfoWithCloudBackup:cloudBackup];
}
@@ -64,8 +64,8 @@
// ////////// LOCALSTORAGE
original = [targetDir stringByAppendingPathComponent:targetDirNests ? @"WebKit/LocalStorage/file__0.localstorage":@"file__0.localstorage"];
- backup = [backupDir stringByAppendingPathComponent:(backupDirNests ? @"WebKit/LocalStorage":@"")];
- backup = [backup stringByAppendingPathComponent:(rename ? @"localstorage.appdata.db":@"file__0.localstorage")];
+ backup = [backupDir stringByAppendingPathComponent:(backupDirNests ? @"WebKit/LocalStorage" : @"")];
+ backup = [backup stringByAppendingPathComponent:(rename ? @"localstorage.appdata.db" : @"file__0.localstorage")];
backupItem = [[CDVBackupInfo alloc] init];
backupItem.backup = backup;
@@ -77,8 +77,8 @@
// ////////// WEBSQL MAIN DB
original = [targetDir stringByAppendingPathComponent:targetDirNests ? @"WebKit/LocalStorage/Databases.db":@"Databases.db"];
- backup = [backupDir stringByAppendingPathComponent:(backupDirNests ? @"WebKit/LocalStorage":@"")];
- backup = [backup stringByAppendingPathComponent:(rename ? @"websqlmain.appdata.db":@"Databases.db")];
+ backup = [backupDir stringByAppendingPathComponent:(backupDirNests ? @"WebKit/LocalStorage" : @"")];
+ backup = [backup stringByAppendingPathComponent:(rename ? @"websqlmain.appdata.db" : @"Databases.db")];
backupItem = [[CDVBackupInfo alloc] init];
backupItem.backup = backup;
@@ -90,8 +90,8 @@
// ////////// WEBSQL DATABASES
original = [targetDir stringByAppendingPathComponent:targetDirNests ? @"WebKit/LocalStorage/file__0":@"file__0"];
- backup = [backupDir stringByAppendingPathComponent:(backupDirNests ? @"WebKit/LocalStorage":@"")];
- backup = [backup stringByAppendingPathComponent:(rename ? @"websqldbs.appdata.db":@"file__0")];
+ backup = [backupDir stringByAppendingPathComponent:(backupDirNests ? @"WebKit/LocalStorage" : @"")];
+ backup = [backup stringByAppendingPathComponent:(rename ? @"websqldbs.appdata.db" : @"file__0")];
backupItem = [[CDVBackupInfo alloc] init];
backupItem.backup = backup;
@@ -106,8 +106,8 @@
+ (NSMutableArray*)createBackupInfoWithCloudBackup:(BOOL)cloudBackup
{
// create backup info from backup folder to caches folder
- NSString* appLibraryFolder = [NSSearchPathForDirectoriesInDomains (NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0];
- NSString* appDocumentsFolder = [NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
+ NSString* appLibraryFolder = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0];
+ NSString* appDocumentsFolder = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString* cacheFolder = [appLibraryFolder stringByAppendingPathComponent:@"Caches"];
NSString* backupsFolder = [appDocumentsFolder stringByAppendingPathComponent:@"Backups"];
@@ -131,7 +131,7 @@
return success;
}
-+ (BOOL)copyFrom:(NSString*)src to:(NSString*)dest error:(NSError * __autoreleasing*)error
++ (BOOL)copyFrom:(NSString*)src to:(NSString*)dest error:(NSError* __autoreleasing*)error
{
NSFileManager* fileManager = [NSFileManager defaultManager];
@@ -149,7 +149,7 @@
// generate unique filepath in temp directory
CFUUIDRef uuidRef = CFUUIDCreate(kCFAllocatorDefault);
CFStringRef uuidString = CFUUIDCreateString(kCFAllocatorDefault, uuidRef);
- NSString* tempBackup = [[NSTemporaryDirectory () stringByAppendingPathComponent:(__bridge NSString*)uuidString] stringByAppendingPathExtension:@"bak"];
+ NSString* tempBackup = [[NSTemporaryDirectory() stringByAppendingPathComponent:(__bridge NSString*)uuidString] stringByAppendingPathExtension:@"bak"];
CFRelease(uuidString);
CFRelease(uuidRef);
@@ -334,8 +334,8 @@
return;
}
- NSString* appLibraryFolder = [NSSearchPathForDirectoriesInDomains (NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0];
- NSString* appDocumentsFolder = [NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
+ NSString* appLibraryFolder = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0];
+ NSString* appDocumentsFolder = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSMutableArray* backupInfo = [NSMutableArray arrayWithCapacity:0];
@@ -386,15 +386,15 @@
backgroundTaskID = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[[UIApplication sharedApplication] endBackgroundTask:backgroundTaskID];
backgroundTaskID = UIBackgroundTaskInvalid;
- NSLog (@"Background task to backup WebSQL/LocalStorage expired.");
+ NSLog(@"Background task to backup WebSQL/LocalStorage expired.");
}];
CDVLocalStorage __weak* weakSelf = self;
[self.commandDelegate runInBackground:^{
- [weakSelf backup:nil];
+ [weakSelf backup:nil];
- [[UIApplication sharedApplication] endBackgroundTask:backgroundTaskID];
- backgroundTaskID = UIBackgroundTaskInvalid;
- }];
+ [[UIApplication sharedApplication] endBackgroundTask:backgroundTaskID];
+ backgroundTaskID = UIBackgroundTaskInvalid;
+ }];
}
}
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/CDVLocation.h
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVLocation.h b/lib/cordova-ios/CordovaLib/Classes/CDVLocation.h
index 7087d43..caf0798 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVLocation.h
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVLocation.h
@@ -83,11 +83,11 @@ typedef NSUInteger CDVLocationStatus;
- (void)startLocation:(BOOL)enableHighAccuracy;
- (void)locationManager:(CLLocationManager*)manager
- didUpdateToLocation :(CLLocation*)newLocation
- fromLocation :(CLLocation*)oldLocation;
+ didUpdateToLocation:(CLLocation*)newLocation
+ fromLocation:(CLLocation*)oldLocation;
- (void)locationManager:(CLLocationManager*)manager
- didFailWithError :(NSError*)error;
+ didFailWithError:(NSError*)error;
- (BOOL)isLocationServicesEnabled;
@@ -97,7 +97,7 @@ typedef NSUInteger CDVLocationStatus;
- (void)stopHeading:(CDVInvokedUrlCommand*)command;
- (void)startHeadingWithFilter:(CLLocationDegrees)filter;
- (void)locationManager:(CLLocationManager*)manager
- didUpdateHeading :(CLHeading*)heading;
+ didUpdateHeading:(CLHeading*)heading;
- (BOOL)locationManagerShouldDisplayHeadingCalibration:(CLLocationManager*)manager;
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/CDVLocation.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVLocation.m b/lib/cordova-ios/CordovaLib/Classes/CDVLocation.m
index 07af30e..ed9ec26 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVLocation.m
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVLocation.m
@@ -591,17 +591,17 @@
- (NSString*)JSONRepresentation
{
return [NSString stringWithFormat:
- @"{ timestamp: %.00f, \
+ @"{ timestamp: %.00f, \
coords: { latitude: %f, longitude: %f, altitude: %.02f, heading: %.02f, speed: %.02f, accuracy: %.02f, altitudeAccuracy: %.02f } \
}",
- [self.timestamp timeIntervalSince1970] * 1000.0,
- self.coordinate.latitude,
- self.coordinate.longitude,
- self.altitude,
- self.course,
- self.speed,
- self.horizontalAccuracy,
- self.verticalAccuracy
+ [self.timestamp timeIntervalSince1970] * 1000.0,
+ self.coordinate.latitude,
+ self.coordinate.longitude,
+ self.altitude,
+ self.course,
+ self.speed,
+ self.horizontalAccuracy,
+ self.verticalAccuracy
];
}
@@ -614,9 +614,9 @@
- (NSString*)JSONRepresentation
{
return [NSString stringWithFormat:
- @"{ code: %d, message: '%@'}",
- self.code,
- [self localizedDescription]
+ @"{ code: %d, message: '%@'}",
+ self.code,
+ [self localizedDescription]
];
}
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/CDVNotification.h
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVNotification.h b/lib/cordova-ios/CordovaLib/Classes/CDVNotification.h
index 1eedb54..5b5b89f 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVNotification.h
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVNotification.h
@@ -26,6 +26,7 @@
- (void)alert:(CDVInvokedUrlCommand*)command;
- (void)confirm:(CDVInvokedUrlCommand*)command;
+- (void)prompt:(CDVInvokedUrlCommand*)command;
- (void)vibrate:(CDVInvokedUrlCommand*)command;
@end
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-ios/CordovaLib/Classes/CDVNotification.m
----------------------------------------------------------------------
diff --git a/lib/cordova-ios/CordovaLib/Classes/CDVNotification.m b/lib/cordova-ios/CordovaLib/Classes/CDVNotification.m
index 992239e..821cb9f 100644
--- a/lib/cordova-ios/CordovaLib/Classes/CDVNotification.m
+++ b/lib/cordova-ios/CordovaLib/Classes/CDVNotification.m
@@ -20,12 +20,24 @@
#import "CDVNotification.h"
#import "NSDictionary+Extensions.h"
+#define DIALOG_TYPE_ALERT @"alert"
+#define DIALOG_TYPE_PROMPT @"prompt"
+
@implementation CDVNotification
-- (void)showDialogWithMessage:(NSString*)message title:(NSString*)title buttons:(NSString*)buttons callbackId:(NSString*)callbackId
+/*
+ * showDialogWithMessage - Common method to instantiate the alert view for alert, confirm, and prompt notifications.
+ * Parameters:
+ * message The alert view message.
+ * title The alert view title.
+ * buttons The array of customized strings for the buttons.
+ * callbackId The commmand callback id.
+ * dialogType The type of alert view [alert | prompt].
+ */
+- (void)showDialogWithMessage:(NSString*)message title:(NSString*)title buttons:(NSArray*)buttons callbackId:(NSString*)callbackId dialogType:(NSString*)dialogType
{
CDVAlertView* alertView = [[CDVAlertView alloc]
- initWithTitle:title
+ initWithTitle:title
message:message
delegate:self
cancelButtonTitle:nil
@@ -33,11 +45,14 @@
alertView.callbackId = callbackId;
- NSArray* labels = [buttons componentsSeparatedByString:@","];
- int count = [labels count];
+ int count = [buttons count];
for (int n = 0; n < count; n++) {
- [alertView addButtonWithTitle:[labels objectAtIndex:n]];
+ [alertView addButtonWithTitle:[buttons objectAtIndex:n]];
+ }
+
+ if ([dialogType isEqualToString:DIALOG_TYPE_PROMPT]) {
+ alertView.alertViewStyle = UIAlertViewStylePlainTextInput;
}
[alertView show];
@@ -46,52 +61,54 @@
- (void)alert:(CDVInvokedUrlCommand*)command
{
NSString* callbackId = command.callbackId;
- NSArray* arguments = command.arguments;
- int argc = [arguments count];
-
- NSString* message = argc > 0 ? [arguments objectAtIndex:0] : nil;
- NSString* title = argc > 1 ? [arguments objectAtIndex:1] : nil;
- NSString* buttons = argc > 2 ? [arguments objectAtIndex:2] : nil;
-
- if (!title) {
- title = NSLocalizedString(@"Alert", @"Alert");
- }
- if (!buttons) {
- buttons = NSLocalizedString(@"OK", @"OK");
- }
+ NSString* message = [command argumentAtIndex:0];
+ NSString* title = [command argumentAtIndex:1];
+ NSString* buttons = [command argumentAtIndex:2];
- [self showDialogWithMessage:message title:title buttons:buttons callbackId:callbackId];
+ [self showDialogWithMessage:message title:title buttons:@[buttons] callbackId:callbackId dialogType:DIALOG_TYPE_ALERT];
}
- (void)confirm:(CDVInvokedUrlCommand*)command
{
NSString* callbackId = command.callbackId;
- NSArray* arguments = command.arguments;
- int argc = [arguments count];
+ NSString* message = [command argumentAtIndex:0];
+ NSString* title = [command argumentAtIndex:1];
+ NSArray* buttons = [command argumentAtIndex:2];
- NSString* message = argc > 0 ? [arguments objectAtIndex:0] : nil;
- NSString* title = argc > 1 ? [arguments objectAtIndex:1] : nil;
- NSString* buttons = argc > 2 ? [arguments objectAtIndex:2] : nil;
+ [self showDialogWithMessage:message title:title buttons:buttons callbackId:callbackId dialogType:DIALOG_TYPE_ALERT];
+}
- if (!title) {
- title = NSLocalizedString(@"Confirm", @"Confirm");
- }
- if (!buttons) {
- buttons = NSLocalizedString(@"OK,Cancel", @"OK,Cancel");
- }
+- (void)prompt:(CDVInvokedUrlCommand*)command
+{
+ NSString* callbackId = command.callbackId;
+ NSString* message = [command argumentAtIndex:0];
+ NSString* title = [command argumentAtIndex:1];
+ NSArray* buttons = [command argumentAtIndex:2];
- [self showDialogWithMessage:message title:title buttons:buttons callbackId:callbackId];
+ [self showDialogWithMessage:message title:title buttons:buttons callbackId:callbackId dialogType:DIALOG_TYPE_PROMPT];
}
/**
- Callback invoked when an alert dialog's buttons are clicked.
- Passes the index + label back to JS
- */
+ * Callback invoked when an alert dialog's buttons are clicked.
+ */
- (void)alertView:(UIAlertView*)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
CDVAlertView* cdvAlertView = (CDVAlertView*)alertView;
- CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:++buttonIndex];
-
+ CDVPluginResult* result;
+
+ // Determine what gets returned to JS based on the alert view type.
+ if (alertView.alertViewStyle == UIAlertViewStyleDefault) {
+ // For alert and confirm, return button index as int back to JS.
+ result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:buttonIndex + 1];
+ } else {
+ // For prompt, return button index and input text back to JS.
+ NSString* value0 = [[alertView textFieldAtIndex:0] text];
+ NSDictionary* info = @{
+ @"buttonIndex":@(buttonIndex + 1),
+ @"input1":(value0 ? value0 : [NSNull null])
+ };
+ result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:info];
+ }
[self.commandDelegate sendPluginResult:result callbackId:cdvAlertView.callbackId];
}
[5/6] 2.6.0rc1 used for libs now. Bumped npm version to 2.6.0. added
androids local.properties to gitignore.
Posted by fi...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/framework/src/org/apache/cordova/CordovaWebViewClient.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/CordovaWebViewClient.java b/lib/cordova-android/framework/src/org/apache/cordova/CordovaWebViewClient.java
index 8b023eb..4751fc3 100755
--- a/lib/cordova-android/framework/src/org/apache/cordova/CordovaWebViewClient.java
+++ b/lib/cordova-android/framework/src/org/apache/cordova/CordovaWebViewClient.java
@@ -18,6 +18,7 @@
*/
package org.apache.cordova;
+import java.io.ByteArrayInputStream;
import java.util.Hashtable;
import org.apache.cordova.api.CordovaInterface;
@@ -38,6 +39,7 @@ import android.util.Log;
import android.view.View;
import android.webkit.HttpAuthHandler;
import android.webkit.SslErrorHandler;
+import android.webkit.WebResourceResponse;
import android.webkit.WebView;
import android.webkit.WebViewClient;
@@ -66,7 +68,7 @@ public class CordovaWebViewClient extends WebViewClient {
/**
* Constructor.
- *
+ *
* @param cordova
* @param view
*/
@@ -77,7 +79,7 @@ public class CordovaWebViewClient extends WebViewClient {
/**
* Constructor.
- *
+ *
* @param view
*/
public void setWebView(CordovaWebView view) {
@@ -101,8 +103,8 @@ public class CordovaWebViewClient extends WebViewClient {
String callbackId = url.substring(idx3 + 1, idx4);
String jsonArgs = url.substring(idx4 + 1);
appView.pluginManager.exec(service, action, callbackId, jsonArgs);
- }
-
+ }
+
/**
* Give the host application a chance to take over the control when a new url
* is about to be loaded in the current WebView.
@@ -192,12 +194,8 @@ public class CordovaWebViewClient extends WebViewClient {
// If our app or file:, then load into a new Cordova webview container by starting a new instance of our activity.
// Our app continues to run. When BACK is pressed, our app is redisplayed.
- if (url.startsWith("file://") || url.startsWith("data:") || url.indexOf(this.appView.baseUrl) == 0 || Config.isUrlWhiteListed(url)) {
- //This will fix iFrames
- if (appView.useBrowserHistory || url.startsWith("data:"))
- return false;
- else
- this.appView.loadUrl(url);
+ if (url.startsWith("file://") || url.startsWith("data:") || Config.isUrlWhiteListed(url)) {
+ return false;
}
// If not our application, let default viewer handle
@@ -215,6 +213,34 @@ public class CordovaWebViewClient extends WebViewClient {
}
/**
+ * Check for intercepting any requests for resources.
+ * This includes images and scripts and so on, not just top-level pages.
+ * @param view The WebView.
+ * @param url The URL to be loaded.
+ * @return Either null to proceed as normal, or a WebResourceResponse.
+ */
+ @Override
+ public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
+ //If something isn't whitelisted, just send a blank response
+ if(!Config.isUrlWhiteListed(url) && (url.startsWith("http://") || url.startsWith("https://")))
+ {
+ return getWhitelistResponse();
+ }
+ if (this.appView.pluginManager != null) {
+ return this.appView.pluginManager.shouldInterceptRequest(url);
+ }
+ return null;
+ }
+
+ private WebResourceResponse getWhitelistResponse()
+ {
+ WebResourceResponse emptyResponse;
+ String empty = "";
+ ByteArrayInputStream data = new ByteArrayInputStream(empty.getBytes());
+ return new WebResourceResponse("text/plain", "UTF-8", data);
+ }
+
+ /**
* On received http auth request.
* The method reacts on all registered authentication tokens. There is one and only one authentication token for any host + realm combination
*
@@ -230,7 +256,7 @@ public class CordovaWebViewClient extends WebViewClient {
AuthenticationToken token = this.getAuthenticationToken(host, realm);
if (token != null) {
handler.proceed(token.getUserName(), token.getPassword());
- }
+ }
else {
// Handle 401 like we'd normally do!
super.onReceivedHttpAuthRequest(view, handler, host, realm);
@@ -238,22 +264,16 @@ public class CordovaWebViewClient extends WebViewClient {
}
/**
- * Notify the host application that a page has started loading.
- * This method is called once for each main frame load so a page with iframes or framesets will call onPageStarted
- * one time for the main frame. This also means that onPageStarted will not be called when the contents of an
- * embedded frame changes, i.e. clicking a link whose target is an iframe.
- *
+ * Notify the host application that a page has started loading.
+ * This method is called once for each main frame load so a page with iframes or framesets will call onPageStarted
+ * one time for the main frame. This also means that onPageStarted will not be called when the contents of an
+ * embedded frame changes, i.e. clicking a link whose target is an iframe.
+ *
* @param view The webview initiating the callback.
* @param url The url of the page.
*/
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
- // Clear history so history.back() doesn't do anything.
- // So we can reinit() native side CallbackServer & PluginManager.
- if (!this.appView.useBrowserHistory) {
- view.clearHistory();
- this.doClearHistory = true;
- }
// Flush stale messages.
this.appView.jsMessageQueue.reset();
@@ -270,7 +290,7 @@ public class CordovaWebViewClient extends WebViewClient {
/**
* Notify the host application that a page has finished loading.
* This method is called only for main frame. When onPageFinished() is called, the rendering picture may not be updated yet.
- *
+ *
*
* @param view The webview initiating the callback.
* @param url The url of the page.
@@ -359,11 +379,11 @@ public class CordovaWebViewClient extends WebViewClient {
}
/**
- * Notify the host application that an SSL error occurred while loading a resource.
- * The host application must call either handler.cancel() or handler.proceed().
- * Note that the decision may be retained for use in response to future SSL errors.
+ * Notify the host application that an SSL error occurred while loading a resource.
+ * The host application must call either handler.cancel() or handler.proceed().
+ * Note that the decision may be retained for use in response to future SSL errors.
* The default behavior is to cancel the load.
- *
+ *
* @param view The WebView that is initiating the callback.
* @param handler An SslErrorHandler object that will handle the user's response.
* @param error The SSL error object.
@@ -392,27 +412,10 @@ public class CordovaWebViewClient extends WebViewClient {
}
}
- /**
- * Notify the host application to update its visited links database.
- *
- * @param view The WebView that is initiating the callback.
- * @param url The url being visited.
- * @param isReload True if this url is being reloaded.
- */
- @Override
- public void doUpdateVisitedHistory(WebView view, String url, boolean isReload) {
- /*
- * If you do a document.location.href the url does not get pushed on the stack
- * so we do a check here to see if the url should be pushed.
- */
- if (!this.appView.peekAtUrlStack().equals(url)) {
- this.appView.pushUrl(url);
- }
- }
/**
* Sets the authentication token.
- *
+ *
* @param authenticationToken
* @param host
* @param realm
@@ -429,10 +432,10 @@ public class CordovaWebViewClient extends WebViewClient {
/**
* Removes the authentication token.
- *
+ *
* @param host
* @param realm
- *
+ *
* @return the authentication token or null if did not exist
*/
public AuthenticationToken removeAuthenticationToken(String host, String realm) {
@@ -441,16 +444,16 @@ public class CordovaWebViewClient extends WebViewClient {
/**
* Gets the authentication token.
- *
+ *
* In order it tries:
* 1- host + realm
* 2- host
* 3- realm
* 4- no host, no realm
- *
+ *
* @param host
* @param realm
- *
+ *
* @return the authentication token
*/
public AuthenticationToken getAuthenticationToken(String host, String realm) {
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/framework/src/org/apache/cordova/Device.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/Device.java b/lib/cordova-android/framework/src/org/apache/cordova/Device.java
index 5b09c13..ad399f0 100644
--- a/lib/cordova-android/framework/src/org/apache/cordova/Device.java
+++ b/lib/cordova-android/framework/src/org/apache/cordova/Device.java
@@ -38,7 +38,7 @@ import android.telephony.TelephonyManager;
public class Device extends CordovaPlugin {
public static final String TAG = "Device";
- public static String cordovaVersion = "2.5.0"; // Cordova version
+ public static String cordovaVersion = "2.6.0rc1"; // Cordova version
public static String platform = "Android"; // Device OS
public static String uuid; // Device UUID
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/framework/src/org/apache/cordova/DroidGap.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/DroidGap.java b/lib/cordova-android/framework/src/org/apache/cordova/DroidGap.java
index 9a7be4e..d4296cb 100755
--- a/lib/cordova-android/framework/src/org/apache/cordova/DroidGap.java
+++ b/lib/cordova-android/framework/src/org/apache/cordova/DroidGap.java
@@ -28,6 +28,7 @@ import org.apache.cordova.api.LOG;
import org.json.JSONException;
import org.json.JSONObject;
+import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
@@ -332,6 +333,7 @@ public class DroidGap extends Activity implements CordovaInterface {
* @param webViewClient
* @param webChromeClient
*/
+ @SuppressLint("NewApi")
public void init(CordovaWebView webView, CordovaWebViewClient webViewClient, CordovaChromeClient webChromeClient) {
LOG.d(TAG, "DroidGap.init()");
@@ -349,6 +351,12 @@ public class DroidGap extends Activity implements CordovaInterface {
ViewGroup.LayoutParams.MATCH_PARENT,
1.0F));
+ if (this.getBooleanProperty("disallowOverscroll", false)) {
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.GINGERBREAD) {
+ this.appView.setOverScrollMode(CordovaWebView.OVER_SCROLL_NEVER);
+ }
+ }
+
// Add web view but make it invisible while loading URL
this.appView.setVisibility(View.INVISIBLE);
this.root.addView(this.appView);
@@ -1054,7 +1062,8 @@ public class DroidGap extends Activity implements CordovaInterface {
{
//Get whatever has focus!
View childView = appView.getFocusedChild();
- if ((appView.isCustomViewShowing() || childView != null ) && keyCode == KeyEvent.KEYCODE_BACK) {
+ if ((appView.isCustomViewShowing() || childView != null ) &&
+ (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_MENU)) {
return appView.onKeyUp(keyCode, event);
} else {
return super.onKeyUp(keyCode, event);
@@ -1074,7 +1083,7 @@ public class DroidGap extends Activity implements CordovaInterface {
//Get whatever has focus!
View childView = appView.getFocusedChild();
//Determine if the focus is on the current view or not
- if (childView != null && keyCode == KeyEvent.KEYCODE_BACK) {
+ if (childView != null && (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_MENU)) {
return appView.onKeyDown(keyCode, event);
}
else
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/framework/src/org/apache/cordova/FileHelper.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/FileHelper.java b/lib/cordova-android/framework/src/org/apache/cordova/FileHelper.java
new file mode 100644
index 0000000..c10ed96
--- /dev/null
+++ b/lib/cordova-android/framework/src/org/apache/cordova/FileHelper.java
@@ -0,0 +1,142 @@
+/*
+ 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.
+ */
+package org.apache.cordova;
+
+import android.database.Cursor;
+import android.net.Uri;
+import android.webkit.MimeTypeMap;
+
+import org.apache.cordova.api.CordovaInterface;
+import org.apache.cordova.api.LOG;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class FileHelper {
+ private static final String LOG_TAG = "FileUtils";
+ private static final String _DATA = "_data";
+
+ /**
+ * Returns the real path of the given URI string.
+ * If the given URI string represents a content:// URI, the real path is retrieved from the media store.
+ *
+ * @param uriString the URI string of the audio/image/video
+ * @param cordova the current application context
+ * @return the full path to the file
+ */
+ @SuppressWarnings("deprecation")
+ public static String getRealPath(String uriString, CordovaInterface cordova) {
+ String realPath = null;
+
+ if (uriString.startsWith("content://")) {
+ String[] proj = { _DATA };
+ Cursor cursor = cordova.getActivity().managedQuery(Uri.parse(uriString), proj, null, null, null);
+ int column_index = cursor.getColumnIndexOrThrow(_DATA);
+ cursor.moveToFirst();
+ realPath = cursor.getString(column_index);
+ if (realPath == null) {
+ LOG.e(LOG_TAG, "Could get real path for URI string %s", uriString);
+ }
+ } else if (uriString.startsWith("file://")) {
+ realPath = uriString.substring(7);
+ if (realPath.startsWith("/android_asset/")) {
+ LOG.e(LOG_TAG, "Cannot get real path for URI string %s because it is a file:///android_asset/ URI.", uriString);
+ realPath = null;
+ }
+ } else {
+ realPath = uriString;
+ }
+
+ return realPath;
+ }
+
+ /**
+ * Returns the real path of the given URI.
+ * If the given URI is a content:// URI, the real path is retrieved from the media store.
+ *
+ * @param uri the URI of the audio/image/video
+ * @param cordova the current application context
+ * @return the full path to the file
+ */
+ public static String getRealPath(Uri uri, CordovaInterface cordova) {
+ return FileHelper.getRealPath(uri.toString(), cordova);
+ }
+
+ /**
+ * Returns an input stream based on given URI string.
+ *
+ * @param uriString the URI string from which to obtain the input stream
+ * @param cordova the current application context
+ * @return an input stream into the data at the given URI or null if given an invalid URI string
+ * @throws IOException
+ */
+ public static InputStream getInputStreamFromUriString(String uriString, CordovaInterface cordova) throws IOException {
+ if (uriString.startsWith("content")) {
+ Uri uri = Uri.parse(uriString);
+ return cordova.getActivity().getContentResolver().openInputStream(uri);
+ } else if (uriString.startsWith("file:///android_asset/")) {
+ String relativePath = uriString.substring(22);
+ return cordova.getActivity().getAssets().open(relativePath);
+ } else {
+ return new FileInputStream(getRealPath(uriString, cordova));
+ }
+ }
+
+ /**
+ * Removes the "file://" prefix from the given URI string, if applicable.
+ * If the given URI string doesn't have a "file://" prefix, it is returned unchanged.
+ *
+ * @param uriString the URI string to operate on
+ * @return a path without the "file://" prefix
+ */
+ public static String stripFileProtocol(String uriString) {
+ if (uriString.startsWith("file://")) {
+ uriString = uriString.substring(7);
+ }
+ return uriString;
+ }
+
+ /**
+ * Returns the mime type of the data specified by the given URI string.
+ *
+ * @param uriString the URI string of the data
+ * @return the mime type of the specified data
+ */
+ public static String getMimeType(String uriString, CordovaInterface cordova) {
+ String mimeType = null;
+
+ if (uriString.startsWith("content://")) {
+ Uri uri = Uri.parse(uriString);
+ mimeType = cordova.getActivity().getContentResolver().getType(uri);
+ } else {
+ // MimeTypeMap.getFileExtensionFromUrl has a bug that occurs when the filename has a space, so we encode it.
+ // We also convert the URI string to lower case to ensure compatibility with MimeTypeMap (see CB-2185).
+ String encodedUriString = uriString.replace(" ", "%20").toLowerCase();
+ String extension = MimeTypeMap.getFileExtensionFromUrl(encodedUriString);
+ if (extension.equals("3ga")) {
+ mimeType = "audio/3gpp";
+ } else {
+ mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
+ }
+ }
+
+ return mimeType;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/framework/src/org/apache/cordova/FileTransfer.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/FileTransfer.java b/lib/cordova-android/framework/src/org/apache/cordova/FileTransfer.java
index 623baf8..dba29af 100644
--- a/lib/cordova-android/framework/src/org/apache/cordova/FileTransfer.java
+++ b/lib/cordova-android/framework/src/org/apache/cordova/FileTransfer.java
@@ -18,6 +18,7 @@
*/
package org.apache.cordova;
+import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.File;
@@ -27,7 +28,9 @@ import java.io.FileOutputStream;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.InputStreamReader;
import java.io.OutputStream;
+import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
@@ -155,6 +158,25 @@ public class FileTransfer extends CordovaPlugin {
return false;
}
+ private static void addHeadersToRequest(URLConnection connection, JSONObject headers) {
+ try {
+ for (Iterator<?> iter = headers.keys(); iter.hasNext(); ) {
+ String headerKey = iter.next().toString();
+ JSONArray headerValues = headers.optJSONArray(headerKey);
+ if (headerValues == null) {
+ headerValues = new JSONArray();
+ headerValues.put(headers.getString(headerKey));
+ }
+ connection.setRequestProperty(headerKey, headerValues.getString(0));
+ for (int i = 1; i < headerValues.length(); ++i) {
+ connection.addRequestProperty(headerKey, headerValues.getString(i));
+ }
+ }
+ } catch (JSONException e1) {
+ // No headers to be manipulated!
+ }
+ }
+
/**
* Uploads the specified file to the server URL provided using an HTTP multipart request.
* @param source Full path of the file on the file system
@@ -196,7 +218,7 @@ public class FileTransfer extends CordovaPlugin {
try {
url = new URL(target);
} catch (MalformedURLException e) {
- JSONObject error = createFileTransferError(INVALID_URL_ERR, source, target, 0);
+ JSONObject error = createFileTransferError(INVALID_URL_ERR, source, target, null, 0);
Log.e(LOG_TAG, error.toString(), e);
callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error));
return;
@@ -269,22 +291,7 @@ public class FileTransfer extends CordovaPlugin {
// Handle the other headers
if (headers != null) {
- try {
- for (Iterator<?> iter = headers.keys(); iter.hasNext(); ) {
- String headerKey = iter.next().toString();
- JSONArray headerValues = headers.optJSONArray(headerKey);
- if (headerValues == null) {
- headerValues = new JSONArray();
- headerValues.put(headers.getString(headerKey));
- }
- conn.setRequestProperty(headerKey, headerValues.getString(0));
- for (int i = 1; i < headerValues.length(); ++i) {
- conn.addRequestProperty(headerKey, headerValues.getString(i));
- }
- }
- } catch (JSONException e1) {
- // No headers to be manipulated!
- }
+ addHeadersToRequest(conn, headers);
}
/*
@@ -530,18 +537,33 @@ public class FileTransfer extends CordovaPlugin {
private static JSONObject createFileTransferError(int errorCode, String source, String target, URLConnection connection) {
int httpStatus = 0;
-
+ StringBuilder bodyBuilder = new StringBuilder();
+ String body = null;
if (connection != null) {
try {
if (connection instanceof HttpURLConnection) {
httpStatus = ((HttpURLConnection)connection).getResponseCode();
+ InputStream err = ((HttpURLConnection) connection).getErrorStream();
+ if(err != null)
+ {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(err, "UTF-8"));
+ String line = reader.readLine();
+ while(line != null)
+ {
+ bodyBuilder.append(line);
+ line = reader.readLine();
+ if(line != null)
+ bodyBuilder.append('\n');
+ }
+ body = bodyBuilder.toString();
+ }
}
} catch (IOException e) {
Log.w(LOG_TAG, "Error getting HTTP status code from connection.", e);
}
}
- return createFileTransferError(errorCode, source, target, httpStatus);
+ return createFileTransferError(errorCode, source, target, body, httpStatus);
}
/**
@@ -549,13 +571,17 @@ public class FileTransfer extends CordovaPlugin {
* @param errorCode the error
* @return JSONObject containing the error
*/
- private static JSONObject createFileTransferError(int errorCode, String source, String target, Integer httpStatus) {
+ private static JSONObject createFileTransferError(int errorCode, String source, String target, String body, Integer httpStatus) {
JSONObject error = null;
try {
error = new JSONObject();
error.put("code", errorCode);
error.put("source", source);
error.put("target", target);
+ if(body != null)
+ {
+ error.put("body", body);
+ }
if (httpStatus != null) {
error.put("http_status", httpStatus);
}
@@ -594,12 +620,13 @@ public class FileTransfer extends CordovaPlugin {
final boolean trustEveryone = args.optBoolean(2);
final String objectId = args.getString(3);
+ final JSONObject headers = args.optJSONObject(4);
final URL url;
try {
url = new URL(source);
} catch (MalformedURLException e) {
- JSONObject error = createFileTransferError(INVALID_URL_ERR, source, target, 0);
+ JSONObject error = createFileTransferError(INVALID_URL_ERR, source, target, null, 0);
Log.e(LOG_TAG, error.toString(), e);
callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error));
return;
@@ -608,7 +635,7 @@ public class FileTransfer extends CordovaPlugin {
if (!Config.isUrlWhiteListed(source)) {
Log.w(LOG_TAG, "Source URL is not in white list: '" + source + "'");
- JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, 401);
+ JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, null, 401);
callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error));
return;
}
@@ -671,6 +698,11 @@ public class FileTransfer extends CordovaPlugin {
{
connection.setRequestProperty("cookie", cookie);
}
+
+ // Handle the other headers
+ if (headers != null) {
+ addHeadersToRequest(connection, headers);
+ }
connection.connect();
@@ -718,8 +750,7 @@ public class FileTransfer extends CordovaPlugin {
Log.d(LOG_TAG, "Saved file: " + target);
// create FileEntry object
- FileUtils fileUtil = new FileUtils();
- JSONObject fileEntry = fileUtil.getEntry(file);
+ JSONObject fileEntry = FileUtils.getEntry(file);
result = new PluginResult(PluginResult.Status.OK, fileEntry);
} catch (FileNotFoundException e) {
@@ -826,7 +857,7 @@ public class FileTransfer extends CordovaPlugin {
file.delete();
}
// Trigger the abort callback immediately to minimize latency between it and abort() being called.
- JSONObject error = createFileTransferError(ABORTED_ERR, context.source, context.target, -1);
+ JSONObject error = createFileTransferError(ABORTED_ERR, context.source, context.target, null, -1);
synchronized (context) {
context.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, error));
context.aborted = true;
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/framework/src/org/apache/cordova/FileUtils.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/FileUtils.java b/lib/cordova-android/framework/src/org/apache/cordova/FileUtils.java
index b461b02..2135be9 100755
--- a/lib/cordova-android/framework/src/org/apache/cordova/FileUtils.java
+++ b/lib/cordova-android/framework/src/org/apache/cordova/FileUtils.java
@@ -15,18 +15,17 @@
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-*/
+ */
package org.apache.cordova;
-import java.io.*;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLDecoder;
-import java.nio.channels.FileChannel;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Environment;
+import android.provider.MediaStore;
+import android.util.Log;
import org.apache.commons.codec.binary.Base64;
import org.apache.cordova.api.CallbackContext;
-import org.apache.cordova.api.CordovaInterface;
import org.apache.cordova.api.CordovaPlugin;
import org.apache.cordova.api.PluginResult;
import org.apache.cordova.file.EncodingException;
@@ -38,23 +37,25 @@ import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
-//import android.content.Context;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Environment;
-import android.provider.MediaStore;
-import android.webkit.MimeTypeMap;
-
-//import android.app.Activity;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.RandomAccessFile;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.nio.channels.FileChannel;
/**
* This class provides SD card file and directory services to JavaScript.
* Only files on the SD card can be accessed.
*/
public class FileUtils extends CordovaPlugin {
- @SuppressWarnings("unused")
private static final String LOG_TAG = "FileUtils";
- private static final String _DATA = "_data"; // The column name where the file path is stored
public static int NOT_FOUND_ERR = 1;
public static int SECURITY_ERR = 2;
@@ -75,9 +76,6 @@ public class FileUtils extends CordovaPlugin {
public static int RESOURCE = 2;
public static int APPLICATION = 3;
- FileReader f_in;
- FileWriter f_out;
-
/**
* Constructor.
*/
@@ -111,30 +109,29 @@ public class FileUtils extends CordovaPlugin {
callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, b));
}
else if (action.equals("readAsText")) {
- int start = 0;
- int end = Integer.MAX_VALUE;
- if (args.length() >= 3) {
- start = args.getInt(2);
- }
- if (args.length() >= 4) {
- end = args.getInt(3);
- }
+ String encoding = args.getString(1);
+ int start = args.getInt(2);
+ int end = args.getInt(3);
- String s = this.readAsText(args.getString(0), args.getString(1), start, end);
- callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, s));
+ this.readFileAs(args.getString(0), start, end, callbackContext, encoding, PluginResult.MESSAGE_TYPE_STRING);
}
else if (action.equals("readAsDataURL")) {
- int start = 0;
- int end = Integer.MAX_VALUE;
- if (args.length() >= 2) {
- start = args.getInt(1);
- }
- if (args.length() >= 3) {
- end = args.getInt(2);
- }
+ int start = args.getInt(1);
+ int end = args.getInt(2);
+
+ this.readFileAs(args.getString(0), start, end, callbackContext, null, -1);
+ }
+ else if (action.equals("readAsArrayBuffer")) {
+ int start = args.getInt(1);
+ int end = args.getInt(2);
- String s = this.readAsDataURL(args.getString(0), start, end);
- callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, s));
+ this.readFileAs(args.getString(0), start, end, callbackContext, null, PluginResult.MESSAGE_TYPE_ARRAYBUFFER);
+ }
+ else if (action.equals("readAsBinaryString")) {
+ int start = args.getInt(1);
+ int end = args.getInt(2);
+
+ this.readFileAs(args.getString(0), start, end, callbackContext, null, PluginResult.MESSAGE_TYPE_BINARYSTRING);
}
else if (action.equals("write")) {
long fileSize = this.write(args.getString(0), args.getString(1), args.getInt(2));
@@ -237,11 +234,11 @@ public class FileUtils extends CordovaPlugin {
* @param filePath the path to check
*/
private void notifyDelete(String filePath) {
- String newFilePath = getRealPathFromURI(Uri.parse(filePath), cordova);
+ String newFilePath = FileHelper.getRealPath(filePath, cordova);
try {
this.cordova.getActivity().getContentResolver().delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
- MediaStore.Images.Media.DATA + " = ?",
- new String[] { newFilePath });
+ MediaStore.Images.Media.DATA + " = ?",
+ new String[] { newFilePath });
} catch (UnsupportedOperationException t) {
// Was seeing this on the File mobile-spec tests on 4.0.3 x86 emulator.
// The ContentResolver applies only when the file was registered in the
@@ -344,8 +341,8 @@ public class FileUtils extends CordovaPlugin {
* @throws FileExistsException
*/
private JSONObject transferTo(String fileName, String newParent, String newName, boolean move) throws JSONException, NoModificationAllowedException, IOException, InvalidModificationException, EncodingException, FileExistsException {
- String newFileName = getRealPathFromURI(Uri.parse(fileName), cordova);
- newParent = getRealPathFromURI(Uri.parse(newParent), cordova);
+ String newFileName = FileHelper.getRealPath(fileName, cordova);
+ newParent = FileHelper.getRealPath(newParent, cordova);
// Check for invalid file name
if (newName != null && newName.contains(":")) {
@@ -384,14 +381,14 @@ public class FileUtils extends CordovaPlugin {
}
} else {
if (move) {
- JSONObject newFileEntry = moveFile(source, destination);
+ JSONObject newFileEntry = moveFile(source, destination);
- // If we've moved a file given its content URI, we need to clean up.
- if (fileName.startsWith("content://")) {
- notifyDelete(fileName);
- }
+ // If we've moved a file given its content URI, we need to clean up.
+ if (fileName.startsWith("content://")) {
+ notifyDelete(fileName);
+ }
- return newFileEntry;
+ return newFileEntry;
} else {
return copyFile(source, destination);
}
@@ -748,7 +745,7 @@ public class FileUtils extends CordovaPlugin {
if (fileName.startsWith("/")) {
fp = new File(fileName);
} else {
- dirPath = getRealPathFromURI(Uri.parse(dirPath), cordova);
+ dirPath = FileHelper.getRealPath(dirPath, cordova);
fp = new File(dirPath + File.separator + fileName);
}
return fp;
@@ -763,7 +760,7 @@ public class FileUtils extends CordovaPlugin {
* @throws JSONException
*/
private JSONObject getParent(String filePath) throws JSONException {
- filePath = getRealPathFromURI(Uri.parse(filePath), cordova);
+ filePath = FileHelper.getRealPath(filePath, cordova);
if (atRootDirectory(filePath)) {
return getEntry(filePath);
@@ -779,7 +776,7 @@ public class FileUtils extends CordovaPlugin {
* @return true if we are at the root, false otherwise.
*/
private boolean atRootDirectory(String filePath) {
- filePath = getRealPathFromURI(Uri.parse(filePath), cordova);
+ filePath = FileHelper.getRealPath(filePath, cordova);
if (filePath.equals(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/data/" + cordova.getActivity().getPackageName() + "/cache") ||
filePath.equals(Environment.getExternalStorageDirectory().getAbsolutePath()) ||
@@ -790,26 +787,13 @@ public class FileUtils extends CordovaPlugin {
}
/**
- * This method removes the "file://" from the passed in filePath
- *
- * @param filePath to be checked.
- * @return
- */
- public static String stripFileProtocol(String filePath) {
- if (filePath.startsWith("file://")) {
- filePath = filePath.substring(7);
- }
- return filePath;
- }
-
- /**
* Create a File object from the passed in path
*
* @param filePath
* @return
*/
private File createFileObject(String filePath) {
- filePath = getRealPathFromURI(Uri.parse(filePath), cordova);
+ filePath = FileHelper.getRealPath(filePath, cordova);
File file = new File(filePath);
return file;
@@ -849,7 +833,7 @@ public class FileUtils extends CordovaPlugin {
JSONObject metadata = new JSONObject();
metadata.put("size", file.length());
- metadata.put("type", getMimeType(filePath));
+ metadata.put("type", FileHelper.getMimeType(filePath, cordova));
metadata.put("name", file.getName());
metadata.put("fullPath", filePath);
metadata.put("lastModifiedDate", file.lastModified());
@@ -900,21 +884,21 @@ public class FileUtils extends CordovaPlugin {
}
/**
- * Returns a JSON Object representing a directory on the device's file system
+ * Returns a JSON object representing the given File.
*
- * @param path to the directory
- * @return
+ * @param file the File to convert
+ * @return a JSON representation of the given File
* @throws JSONException
*/
- public JSONObject getEntry(File file) throws JSONException {
+ public static JSONObject getEntry(File file) throws JSONException {
JSONObject entry = new JSONObject();
entry.put("isFile", file.isFile());
entry.put("isDirectory", file.isDirectory());
entry.put("name", file.getName());
entry.put("fullPath", "file://" + file.getAbsolutePath());
- // I can't add the next thing it as it would be an infinite loop
- //entry.put("filesystem", null);
+ // The file system can't be specified, as it would lead to an infinite loop.
+ // entry.put("filesystem", null);
return entry;
}
@@ -930,123 +914,83 @@ public class FileUtils extends CordovaPlugin {
return getEntry(new File(path));
}
- /**
- * Identifies if action to be executed returns a value and should be run synchronously.
- *
- * @param action The action to execute
- * @return T=returns value
- */
- public boolean isSynch(String action) {
- if (action.equals("testSaveLocationExists")) {
- return true;
- }
- else if (action.equals("getFreeDiskSpace")) {
- return true;
- }
- else if (action.equals("testFileExists")) {
- return true;
- }
- else if (action.equals("testDirectoryExists")) {
- return true;
- }
- return false;
- }
//--------------------------------------------------------------------------
// LOCAL METHODS
//--------------------------------------------------------------------------
/**
- * Read content of text file.
+ * Read the contents of a file.
+ * This is done in a background thread; the result is sent to the callback.
*
- * @param filename The name of the file.
- * @param encoding The encoding to return contents as. Typical value is UTF-8.
- * (see http://www.iana.org/assignments/character-sets)
- * @param start Start position in the file.
- * @param end End position to stop at (exclusive).
- * @return Contents of file.
- * @throws FileNotFoundException, IOException
+ * @param filename The name of the file.
+ * @param start Start position in the file.
+ * @param end End position to stop at (exclusive).
+ * @param callbackContext The context through which to send the result.
+ * @param encoding The encoding to return contents as. Typical value is UTF-8. (see http://www.iana.org/assignments/character-sets)
+ * @param resultType The desired type of data to send to the callback.
+ * @return Contents of file.
*/
- public String readAsText(String filename, String encoding, int start, int end) throws FileNotFoundException, IOException {
- int diff = end - start;
- byte[] bytes = new byte[1000];
- BufferedInputStream bis = new BufferedInputStream(getPathFromUri(filename), 1024);
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- int numRead = 0;
-
- if (start > 0) {
- bis.skip(start);
- }
-
- while ( diff > 0 && (numRead = bis.read(bytes, 0, Math.min(1000, diff))) >= 0) {
- diff -= numRead;
- bos.write(bytes, 0, numRead);
- }
-
- return new String(bos.toByteArray(), encoding);
+ public void readFileAs(final String filename, final int start, final int end, final CallbackContext callbackContext, final String encoding, final int resultType) {
+ this.cordova.getThreadPool().execute(new Runnable() {
+ public void run() {
+ try {
+ byte[] bytes = readAsBinaryHelper(filename, start, end);
+
+ PluginResult result;
+ switch (resultType) {
+ case PluginResult.MESSAGE_TYPE_STRING:
+ result = new PluginResult(PluginResult.Status.OK, new String(bytes, encoding));
+ break;
+ case PluginResult.MESSAGE_TYPE_ARRAYBUFFER:
+ result = new PluginResult(PluginResult.Status.OK, bytes);
+ break;
+ case PluginResult.MESSAGE_TYPE_BINARYSTRING:
+ result = new PluginResult(PluginResult.Status.OK, bytes, true);
+ break;
+ default: // Base64.
+ String contentType = FileHelper.getMimeType(filename, cordova);
+ byte[] base64 = Base64.encodeBase64(bytes);
+ String s = "data:" + contentType + ";base64," + new String(base64, "US-ASCII");
+ result = new PluginResult(PluginResult.Status.OK, s);
+ }
+
+ callbackContext.sendPluginResult(result);
+ } catch (FileNotFoundException e) {
+ callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, NOT_FOUND_ERR));
+ } catch (IOException e) {
+ Log.d(LOG_TAG, e.getLocalizedMessage());
+ callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, NOT_READABLE_ERR));
+ }
+ }
+ });
}
/**
- * Read content of text file and return as base64 encoded data url.
+ * Read the contents of a file as binary.
+ * This is done synchronously; the result is returned.
*
- * @param filename The name of the file.
- * @return Contents of file = data:<media type>;base64,<data>
- * @throws FileNotFoundException, IOException
+ * @param filename The name of the file.
+ * @param start Start position in the file.
+ * @param end End position to stop at (exclusive).
+ * @return Contents of the file as a byte[].
+ * @throws IOException
*/
- public String readAsDataURL(String filename, int start, int end) throws FileNotFoundException, IOException {
- int diff = end - start;
- byte[] bytes = new byte[1000];
- BufferedInputStream bis = new BufferedInputStream(getPathFromUri(filename), 1024);
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- int numRead = 0;
+ private byte[] readAsBinaryHelper(String filename, int start, int end) throws IOException {
+ int numBytesToRead = end - start;
+ byte[] bytes = new byte[numBytesToRead];
+ InputStream inputStream = FileHelper.getInputStreamFromUriString(filename, cordova);
+ int numBytesRead = 0;
if (start > 0) {
- bis.skip(start);
- }
-
- while (diff > 0 && (numRead = bis.read(bytes, 0, Math.min(1000, diff))) >= 0) {
- diff -= numRead;
- bos.write(bytes, 0, numRead);
+ inputStream.skip(start);
}
- // Determine content type from file name
- String contentType = null;
- if (filename.startsWith("content:")) {
- Uri fileUri = Uri.parse(filename);
- contentType = this.cordova.getActivity().getContentResolver().getType(fileUri);
- }
- else {
- contentType = getMimeType(filename);
+ while (numBytesToRead > 0 && (numBytesRead = inputStream.read(bytes, numBytesRead, numBytesToRead)) >= 0) {
+ numBytesToRead -= numBytesRead;
}
- byte[] base64 = Base64.encodeBase64(bos.toByteArray());
- String data = "data:" + contentType + ";base64," + new String(base64);
- return data;
- }
-
- /**
- * Looks up the mime type of a given file name.
- *
- * @param filename
- * @return a mime type
- */
- public static String getMimeType(String filename) {
- if (filename != null) {
- // Stupid bug in getFileExtensionFromUrl when the file name has a space
- // So we need to replace the space with a url encoded %20
-
- // CB-2185: Stupid bug not putting JPG extension in the mime-type map
- String url = filename.replace(" ", "%20").toLowerCase();
- MimeTypeMap map = MimeTypeMap.getSingleton();
- String extension = MimeTypeMap.getFileExtensionFromUrl(url);
- if (extension.toLowerCase().equals("3ga")) {
- return "audio/3gpp";
- } else {
- return map.getMimeTypeFromExtension(extension);
- }
- } else {
- return "";
- }
+ return bytes;
}
/**
@@ -1060,11 +1004,11 @@ public class FileUtils extends CordovaPlugin {
*/
/**/
public long write(String filename, String data, int offset) throws FileNotFoundException, IOException, NoModificationAllowedException {
- if (filename.startsWith("content://")) {
- throw new NoModificationAllowedException("Couldn't write to file given its content URI");
- }
+ if (filename.startsWith("content://")) {
+ throw new NoModificationAllowedException("Couldn't write to file given its content URI");
+ }
- filename = getRealPathFromURI(Uri.parse(filename), cordova);
+ filename = FileHelper.getRealPath(filename, cordova);
boolean append = false;
if (offset > 0) {
@@ -1093,11 +1037,11 @@ public class FileUtils extends CordovaPlugin {
* @throws NoModificationAllowedException
*/
private long truncateFile(String filename, long size) throws FileNotFoundException, IOException, NoModificationAllowedException {
- if (filename.startsWith("content://")) {
- throw new NoModificationAllowedException("Couldn't truncate file given its content URI");
- }
+ if (filename.startsWith("content://")) {
+ throw new NoModificationAllowedException("Couldn't truncate file given its content URI");
+ }
- filename = getRealPathFromURI(Uri.parse(filename), cordova);
+ filename = FileHelper.getRealPath(filename, cordova);
RandomAccessFile raf = new RandomAccessFile(filename, "rw");
try {
@@ -1112,48 +1056,4 @@ public class FileUtils extends CordovaPlugin {
raf.close();
}
}
-
- /**
- * Get an input stream based on file path or content:// uri
- *
- * @param path
- * @return an input stream
- * @throws FileNotFoundException
- */
- private InputStream getPathFromUri(String path) throws FileNotFoundException {
- if (path.startsWith("content")) {
- Uri uri = Uri.parse(path);
- return cordova.getActivity().getContentResolver().openInputStream(uri);
- }
- else {
- path = getRealPathFromURI(Uri.parse(path), cordova);
- return new FileInputStream(path);
- }
- }
-
- /**
- * Queries the media store to find out what the file path is for the Uri we supply
- *
- * @param contentUri the Uri of the audio/image/video
- * @param cordova the current application context
- * @return the full path to the file
- */
- @SuppressWarnings("deprecation")
- protected static String getRealPathFromURI(Uri contentUri, CordovaInterface cordova) {
- final String scheme = contentUri.getScheme();
-
- if (scheme == null) {
- return contentUri.toString();
- } else if (scheme.compareTo("content") == 0) {
- String[] proj = { _DATA };
- Cursor cursor = cordova.getActivity().managedQuery(contentUri, proj, null, null, null);
- int column_index = cursor.getColumnIndexOrThrow(_DATA);
- cursor.moveToFirst();
- return cursor.getString(column_index);
- } else if (scheme.compareTo("file") == 0) {
- return contentUri.getPath();
- } else {
- return contentUri.toString();
- }
- }
}
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/framework/src/org/apache/cordova/GeoBroker.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/GeoBroker.java b/lib/cordova-android/framework/src/org/apache/cordova/GeoBroker.java
index 86aa628..e7cdce0 100755
--- a/lib/cordova-android/framework/src/org/apache/cordova/GeoBroker.java
+++ b/lib/cordova-android/framework/src/org/apache/cordova/GeoBroker.java
@@ -150,7 +150,7 @@ public class GeoBroker extends CordovaPlugin {
o.put("altitude", (loc.hasAltitude() ? loc.getAltitude() : null));
o.put("accuracy", loc.getAccuracy());
o.put("heading", (loc.hasBearing() ? (loc.hasSpeed() ? loc.getBearing() : null) : null));
- o.put("speed", loc.getSpeed());
+ o.put("velocity", loc.getSpeed());
o.put("timestamp", loc.getTime());
} catch (JSONException e) {
// TODO Auto-generated catch block
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java b/lib/cordova-android/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java
index a96b242..2142714 100644
--- a/lib/cordova-android/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java
+++ b/lib/cordova-android/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java
@@ -42,7 +42,7 @@ public class IceCreamCordovaWebViewClient extends CordovaWebViewClient {
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
- if(url.contains("?") || url.contains("#")){
+ if(url.contains("?") || url.contains("#") || needsIceCreamSpaceInAssetUrlFix(url)){
return generateWebResourceResponse(url);
} else {
return super.shouldInterceptRequest(view, url);
@@ -80,4 +80,18 @@ public class IceCreamCordovaWebViewClient extends CordovaWebViewClient {
return null;
}
+ private static boolean needsIceCreamSpaceInAssetUrlFix(String url) {
+ if (!url.contains("%20")){
+ return false;
+ }
+
+ switch(android.os.Build.VERSION.SDK_INT){
+ case android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH:
+ case android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1:
+ return true;
+ default:
+ return false;
+ }
+ }
+
}
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/framework/src/org/apache/cordova/InAppBrowser.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/InAppBrowser.java b/lib/cordova-android/framework/src/org/apache/cordova/InAppBrowser.java
index 7e7f862..48e27c6 100644
--- a/lib/cordova-android/framework/src/org/apache/cordova/InAppBrowser.java
+++ b/lib/cordova-android/framework/src/org/apache/cordova/InAppBrowser.java
@@ -35,7 +35,9 @@ import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
+import android.graphics.Color;
import android.net.Uri;
+import android.os.Bundle;
import android.text.InputType;
import android.util.Log;
import android.util.TypedValue;
@@ -48,6 +50,7 @@ import android.view.WindowManager.LayoutParams;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.webkit.WebChromeClient;
+import android.webkit.GeolocationPermissions.Callback;
import android.webkit.WebSettings;
import android.webkit.WebStorage;
import android.webkit.WebView;
@@ -69,6 +72,8 @@ public class InAppBrowser extends CordovaPlugin {
private static final String EXIT_EVENT = "exit";
private static final String LOAD_START_EVENT = "loadstart";
private static final String LOAD_STOP_EVENT = "loadstop";
+ private static final String LOAD_ERROR_EVENT = "loaderror";
+ private static final String CLOSE_BUTTON_CAPTION = "closebuttoncaption";
private long MAX_QUOTA = 100 * 1024 * 1024;
private Dialog dialog;
@@ -76,6 +81,7 @@ public class InAppBrowser extends CordovaPlugin {
private EditText edittext;
private boolean showLocationBar = true;
private CallbackContext callbackContext;
+ private String buttonLabel = "Done";
/**
* Executes the request and returns PluginResult.
@@ -174,8 +180,12 @@ public class InAppBrowser extends CordovaPlugin {
option = new StringTokenizer(features.nextToken(), "=");
if (option.hasMoreElements()) {
String key = option.nextToken();
- Boolean value = option.nextToken().equals("no") ? Boolean.FALSE : Boolean.TRUE;
- map.put(key, value);
+ if (key.equalsIgnoreCase(CLOSE_BUTTON_CAPTION)) {
+ this.buttonLabel = option.nextToken();
+ } else {
+ Boolean value = option.nextToken().equals("no") ? Boolean.FALSE : Boolean.TRUE;
+ map.put(key, value);
+ }
}
}
return map;
@@ -221,6 +231,7 @@ public class InAppBrowser extends CordovaPlugin {
*/
private void closeDialog() {
try {
+ this.inAppWebView.loadUrl("about:blank");
JSONObject obj = new JSONObject();
obj.put("type", EXIT_EVENT);
@@ -289,7 +300,10 @@ public class InAppBrowser extends CordovaPlugin {
// Determine if we should hide the location bar.
showLocationBar = true;
if (features != null) {
- showLocationBar = features.get(LOCATION).booleanValue();
+ Boolean show = features.get(LOCATION);
+ if (show != null) {
+ showLocationBar = show.booleanValue();
+ }
}
final CordovaWebView thatWebView = this.webView;
@@ -405,7 +419,7 @@ public class InAppBrowser extends CordovaPlugin {
close.setLayoutParams(closeLayoutParams);
forward.setContentDescription("Close Button");
close.setId(5);
- close.setText("Done");
+ close.setText(buttonLabel);
close.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
closeDialog();
@@ -428,10 +442,18 @@ public class InAppBrowser extends CordovaPlugin {
*/
// @TODO: replace with settings.setPluginState(android.webkit.WebSettings.PluginState.ON)
settings.setPluginsEnabled(true);
- settings.setDatabaseEnabled(true);
- String databasePath = cordova.getActivity().getApplicationContext().getDir("inAppBrowserDB", Context.MODE_PRIVATE).getPath();
- settings.setDatabasePath(databasePath);
+
+ //Toggle whether this is enabled or not!
+ Bundle appSettings = cordova.getActivity().getIntent().getExtras();
+ boolean enableDatabase = appSettings.getBoolean("InAppBrowserStorageEnabled", true);
+ if(enableDatabase)
+ {
+ String databasePath = cordova.getActivity().getApplicationContext().getDir("inAppBrowserDB", Context.MODE_PRIVATE).getPath();
+ settings.setDatabasePath(databasePath);
+ settings.setDatabaseEnabled(true);
+ }
settings.setDomStorageEnabled(true);
+
inAppWebView.loadUrl(url);
inAppWebView.setId(6);
inAppWebView.getSettings().setLoadWithOverviewMode(true);
@@ -472,16 +494,24 @@ public class InAppBrowser extends CordovaPlugin {
}
/**
- * Create a new plugin result and send it back to JavaScript
+ * Create a new plugin success result and send it back to JavaScript
*
* @param obj a JSONObject contain event payload information
*/
private void sendUpdate(JSONObject obj, boolean keepCallback) {
- PluginResult result = new PluginResult(PluginResult.Status.OK, obj);
+ sendUpdate(obj, keepCallback, PluginResult.Status.OK);
+ }
+
+ /**
+ * Create a new plugin result and send it back to JavaScript
+ *
+ * @param obj a JSONObject contain event payload information
+ * @param status the status code to return to the JavaScript environment
+ */ private void sendUpdate(JSONObject obj, boolean keepCallback, PluginResult.Status status) {
+ PluginResult result = new PluginResult(status, obj);
result.setKeepCallback(keepCallback);
this.callbackContext.sendPluginResult(result);
}
-
public class InAppChromeClient extends WebChromeClient {
/**
@@ -514,6 +544,18 @@ public class InAppBrowser extends CordovaPlugin {
quotaUpdater.updateQuota(currentQuota);
}
}
+
+ /**
+ * Instructs the client to show a prompt to ask the user to set the Geolocation permission state for the specified origin.
+ *
+ * @param origin
+ * @param callback
+ */
+ @Override
+ public void onGeolocationPermissionsShowPrompt(String origin, Callback callback) {
+ super.onGeolocationPermissionsShowPrompt(origin, callback);
+ callback.invoke(origin, true, false);
+ }
}
/**
@@ -543,10 +585,62 @@ public class InAppBrowser extends CordovaPlugin {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
- String newloc;
+ String newloc = "";
if (url.startsWith("http:") || url.startsWith("https:") || url.startsWith("file:")) {
newloc = url;
- } else {
+ }
+ // If dialing phone (tel:5551212)
+ else if (url.startsWith(WebView.SCHEME_TEL)) {
+ try {
+ Intent intent = new Intent(Intent.ACTION_DIAL);
+ intent.setData(Uri.parse(url));
+ cordova.getActivity().startActivity(intent);
+ } catch (android.content.ActivityNotFoundException e) {
+ LOG.e(LOG_TAG, "Error dialing " + url + ": " + e.toString());
+ }
+ }
+
+ else if (url.startsWith("geo:") || url.startsWith(WebView.SCHEME_MAILTO) || url.startsWith("market:")) {
+ try {
+ Intent intent = new Intent(Intent.ACTION_VIEW);
+ intent.setData(Uri.parse(url));
+ cordova.getActivity().startActivity(intent);
+ } catch (android.content.ActivityNotFoundException e) {
+ LOG.e(LOG_TAG, "Error with " + url + ": " + e.toString());
+ }
+ }
+ // If sms:5551212?body=This is the message
+ else if (url.startsWith("sms:")) {
+ try {
+ Intent intent = new Intent(Intent.ACTION_VIEW);
+
+ // Get address
+ String address = null;
+ int parmIndex = url.indexOf('?');
+ if (parmIndex == -1) {
+ address = url.substring(4);
+ }
+ else {
+ address = url.substring(4, parmIndex);
+
+ // If body, then set sms body
+ Uri uri = Uri.parse(url);
+ String query = uri.getQuery();
+ if (query != null) {
+ if (query.startsWith("body=")) {
+ intent.putExtra("sms_body", query.substring(5));
+ }
+ }
+ }
+ intent.setData(Uri.parse("sms:" + address));
+ intent.putExtra("address", address);
+ intent.setType("vnd.android-dir/mms-sms");
+ cordova.getActivity().startActivity(intent);
+ } catch (android.content.ActivityNotFoundException e) {
+ LOG.e(LOG_TAG, "Error sending sms " + url + ":" + e.toString());
+ }
+ }
+ else {
newloc = "http://" + url;
}
@@ -578,5 +672,22 @@ public class InAppBrowser extends CordovaPlugin {
Log.d(LOG_TAG, "Should never happen");
}
}
+
+ public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
+ super.onReceivedError(view, errorCode, description, failingUrl);
+
+ try {
+ JSONObject obj = new JSONObject();
+ obj.put("type", LOAD_ERROR_EVENT);
+ obj.put("url", failingUrl);
+ obj.put("code", errorCode);
+ obj.put("message", description);
+
+ sendUpdate(obj, true, PluginResult.Status.ERROR);
+ } catch (JSONException ex) {
+ Log.d(LOG_TAG, "Should never happen");
+ }
+
+ }
}
}
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/framework/src/org/apache/cordova/JSONUtils.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/JSONUtils.java b/lib/cordova-android/framework/src/org/apache/cordova/JSONUtils.java
new file mode 100644
index 0000000..77df876
--- /dev/null
+++ b/lib/cordova-android/framework/src/org/apache/cordova/JSONUtils.java
@@ -0,0 +1,24 @@
+package org.apache.cordova;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+
+public class JSONUtils {
+ public static List<String> toStringList(JSONArray array) throws JSONException {
+ if(array == null) {
+ return null;
+ }
+ else {
+ List<String> list = new ArrayList<String>();
+
+ for (int i = 0; i < array.length(); i++) {
+ list.add(array.get(i).toString());
+ }
+
+ return list;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/framework/src/org/apache/cordova/NativeToJsMessageQueue.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/NativeToJsMessageQueue.java b/lib/cordova-android/framework/src/org/apache/cordova/NativeToJsMessageQueue.java
index 83e1778..ea684a4 100755
--- a/lib/cordova-android/framework/src/org/apache/cordova/NativeToJsMessageQueue.java
+++ b/lib/cordova-android/framework/src/org/apache/cordova/NativeToJsMessageQueue.java
@@ -409,6 +409,9 @@ public class NativeToJsMessageQueue {
case PluginResult.MESSAGE_TYPE_STRING: // s
ret += 1 + pluginResult.getStrMessage().length();
break;
+ case PluginResult.MESSAGE_TYPE_BINARYSTRING:
+ ret += 1 + pluginResult.getMessage().length();
+ break;
case PluginResult.MESSAGE_TYPE_ARRAYBUFFER:
ret += 1 + pluginResult.getMessage().length();
break;
@@ -451,7 +454,11 @@ public class NativeToJsMessageQueue {
sb.append('s');
sb.append(pluginResult.getStrMessage());
break;
- case PluginResult.MESSAGE_TYPE_ARRAYBUFFER:
+ case PluginResult.MESSAGE_TYPE_BINARYSTRING: // S
+ sb.append('S');
+ sb.append(pluginResult.getMessage());
+ break;
+ case PluginResult.MESSAGE_TYPE_ARRAYBUFFER: // A
sb.append('A');
sb.append(pluginResult.getMessage());
break;
@@ -473,9 +480,9 @@ public class NativeToJsMessageQueue {
.append(success)
.append(",")
.append(status)
- .append(",")
+ .append(",[")
.append(pluginResult.getMessage())
- .append(",")
+ .append("],")
.append(pluginResult.getKeepCallback())
.append(");");
}
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/framework/src/org/apache/cordova/Notification.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/Notification.java b/lib/cordova-android/framework/src/org/apache/cordova/Notification.java
index 958ab26..9d96062 100755
--- a/lib/cordova-android/framework/src/org/apache/cordova/Notification.java
+++ b/lib/cordova-android/framework/src/org/apache/cordova/Notification.java
@@ -24,6 +24,7 @@ import org.apache.cordova.api.CordovaPlugin;
import org.apache.cordova.api.PluginResult;
import org.json.JSONArray;
import org.json.JSONException;
+import org.json.JSONObject;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
@@ -32,6 +33,7 @@ import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Vibrator;
+import android.widget.EditText;
/**
* This class provides access to notifications on the device.
@@ -68,7 +70,11 @@ public class Notification extends CordovaPlugin {
return true;
}
else if (action.equals("confirm")) {
- this.confirm(args.getString(0), args.getString(1), args.getString(2), callbackContext);
+ this.confirm(args.getString(0), args.getString(1), args.getJSONArray(2), callbackContext);
+ return true;
+ }
+ else if (action.equals("prompt")) {
+ this.prompt(args.getString(0), args.getString(1), args.getJSONArray(2), callbackContext);
return true;
}
else if (action.equals("activityStart")) {
@@ -170,7 +176,7 @@ public class Notification extends CordovaPlugin {
callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, 0));
}
});
-
+
dlg.create();
dlg.show();
};
@@ -188,10 +194,9 @@ public class Notification extends CordovaPlugin {
* @param buttonLabels A comma separated list of button labels (Up to 3 buttons)
* @param callbackContext The callback context.
*/
- public synchronized void confirm(final String message, final String title, String buttonLabels, final CallbackContext callbackContext) {
+ public synchronized void confirm(final String message, final String title, final JSONArray buttonLabels, final CallbackContext callbackContext) {
final CordovaInterface cordova = this.cordova;
- final String[] fButtons = buttonLabels.split(",");
Runnable runnable = new Runnable() {
public void run() {
@@ -201,37 +206,43 @@ public class Notification extends CordovaPlugin {
dlg.setCancelable(true);
// First button
- if (fButtons.length > 0) {
- dlg.setNegativeButton(fButtons[0],
- new AlertDialog.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- dialog.dismiss();
- callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, 1));
- }
- });
+ if (buttonLabels.length() > 0) {
+ try {
+ dlg.setNegativeButton(buttonLabels.getString(0),
+ new AlertDialog.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.dismiss();
+ callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, 1));
+ }
+ });
+ } catch (JSONException e) { }
}
// Second button
- if (fButtons.length > 1) {
- dlg.setNeutralButton(fButtons[1],
- new AlertDialog.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- dialog.dismiss();
- callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, 2));
- }
- });
+ if (buttonLabels.length() > 1) {
+ try {
+ dlg.setNeutralButton(buttonLabels.getString(1),
+ new AlertDialog.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.dismiss();
+ callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, 2));
+ }
+ });
+ } catch (JSONException e) { }
}
// Third button
- if (fButtons.length > 2) {
- dlg.setPositiveButton(fButtons[2],
- new AlertDialog.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- dialog.dismiss();
- callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, 3));
- }
- }
- );
+ if (buttonLabels.length() > 2) {
+ try {
+ dlg.setPositiveButton(buttonLabels.getString(2),
+ new AlertDialog.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.dismiss();
+ callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, 3));
+ }
+ }
+ );
+ } catch (JSONException e) { }
}
dlg.setOnCancelListener(new AlertDialog.OnCancelListener() {
public void onCancel(DialogInterface dialog)
@@ -249,6 +260,104 @@ public class Notification extends CordovaPlugin {
}
/**
+ * Builds and shows a native Android prompt dialog with given title, message, buttons.
+ * This dialog only shows up to 3 buttons. Any labels after that will be ignored.
+ * The following results are returned to the JavaScript callback identified by callbackId:
+ * buttonIndex Index number of the button selected
+ * input1 The text entered in the prompt dialog box
+ *
+ * @param message The message the dialog should display
+ * @param title The title of the dialog
+ * @param buttonLabels A comma separated list of button labels (Up to 3 buttons)
+ * @param callbackContext The callback context.
+ */
+ public synchronized void prompt(final String message, final String title, final JSONArray buttonLabels, final CallbackContext callbackContext) {
+
+ final CordovaInterface cordova = this.cordova;
+ final EditText promptInput = new EditText(cordova.getActivity());
+
+ Runnable runnable = new Runnable() {
+ public void run() {
+ AlertDialog.Builder dlg = new AlertDialog.Builder(cordova.getActivity());
+ dlg.setMessage(message);
+ dlg.setTitle(title);
+ dlg.setCancelable(true);
+
+ dlg.setView(promptInput);
+
+ final JSONObject result = new JSONObject();
+
+ // First button
+ if (buttonLabels.length() > 0) {
+ try {
+ dlg.setNegativeButton(buttonLabels.getString(0),
+ new AlertDialog.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.dismiss();
+ try {
+ result.put("buttonIndex",1);
+ result.put("input1", promptInput.getText());
+ } catch (JSONException e) { e.printStackTrace(); }
+ callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, result));
+ }
+ });
+ } catch (JSONException e) { }
+ }
+
+ // Second button
+ if (buttonLabels.length() > 1) {
+ try {
+ dlg.setNeutralButton(buttonLabels.getString(1),
+ new AlertDialog.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.dismiss();
+ try {
+ result.put("buttonIndex",2);
+ result.put("input1", promptInput.getText());
+ } catch (JSONException e) { e.printStackTrace(); }
+ callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, result));
+ }
+ });
+ } catch (JSONException e) { }
+ }
+
+ // Third button
+ if (buttonLabels.length() > 2) {
+ try {
+ dlg.setPositiveButton(buttonLabels.getString(2),
+ new AlertDialog.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.dismiss();
+ try {
+ result.put("buttonIndex",3);
+ result.put("input1", promptInput.getText());
+ } catch (JSONException e) { e.printStackTrace(); }
+ callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, result));
+ }
+ }
+ );
+ } catch (JSONException e) { }
+ }
+ dlg.setOnCancelListener(new AlertDialog.OnCancelListener() {
+ public void onCancel(DialogInterface dialog)
+ {
+ dialog.dismiss();
+ try {
+ result.put("buttonIndex",0);
+ result.put("input1", promptInput.getText());
+ } catch (JSONException e) { e.printStackTrace(); }
+ callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, result));
+ }
+ });
+
+ dlg.create();
+ dlg.show();
+
+ };
+ };
+ this.cordova.getActivity().runOnUiThread(runnable);
+ }
+ /**
* Show the spinner.
*
* @param title Title of the dialog
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/framework/src/org/apache/cordova/api/CallbackContext.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/api/CallbackContext.java b/lib/cordova-android/framework/src/org/apache/cordova/api/CallbackContext.java
index 2f7b15f..a5d1255 100644
--- a/lib/cordova-android/framework/src/org/apache/cordova/api/CallbackContext.java
+++ b/lib/cordova-android/framework/src/org/apache/cordova/api/CallbackContext.java
@@ -79,6 +79,15 @@ public class CallbackContext {
public void success(byte[] message) {
sendPluginResult(new PluginResult(PluginResult.Status.OK, message));
}
+
+ /**
+ * Helper for success callbacks that just returns the Status.OK by default
+ *
+ * @param message The message to add to the success result.
+ */
+ public void success(int message) {
+ sendPluginResult(new PluginResult(PluginResult.Status.OK, message));
+ }
/**
* Helper for success callbacks that just returns the Status.OK by default
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/framework/src/org/apache/cordova/api/CordovaPlugin.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/api/CordovaPlugin.java b/lib/cordova-android/framework/src/org/apache/cordova/api/CordovaPlugin.java
index f4c785e..2b225e6 100644
--- a/lib/cordova-android/framework/src/org/apache/cordova/api/CordovaPlugin.java
+++ b/lib/cordova-android/framework/src/org/apache/cordova/api/CordovaPlugin.java
@@ -22,7 +22,12 @@ import org.apache.cordova.CordovaArgs;
import org.apache.cordova.CordovaWebView;
import org.json.JSONArray;
import org.json.JSONException;
+
+import android.annotation.TargetApi;
import android.content.Intent;
+import android.os.Build;
+import android.util.Log;
+import android.webkit.WebResourceResponse;
/**
* Plugins must extend this class and override one of the execute methods.
@@ -150,7 +155,7 @@ public class CordovaPlugin {
}
/**
- * By specifying a <url-filter> in plugins.xml you can map a URL (using startsWith atm) to this method.
+ * By specifying a <url-filter> in config.xml you can map a URL (using startsWith atm) to this method.
*
* @param url The URL that is trying to be loaded in the Cordova webview.
* @return Return true to prevent the URL from loading. Default is false.
@@ -160,6 +165,17 @@ public class CordovaPlugin {
}
/**
+ * By specifying a <url-filter> in config.xml you can map a URL prefix to this method. It applies to all resources loaded in the WebView, not just top-level navigation.
+ *
+ * @param url The URL of the resource to be loaded.
+ * @return Return a WebResourceResponse for the resource, or null to let the WebView handle it normally.
+ */
+ @TargetApi(Build.VERSION_CODES.HONEYCOMB)
+ public WebResourceResponse shouldInterceptRequest(String url) {
+ return null;
+ }
+
+ /**
* Called when the WebView does a top-level navigation or refreshes.
*
* Plugins should stop any long-running processes and clean up internal state.
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/framework/src/org/apache/cordova/api/PluginManager.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/api/PluginManager.java b/lib/cordova-android/framework/src/org/apache/cordova/api/PluginManager.java
index d0e6aef..337ef12 100755
--- a/lib/cordova-android/framework/src/org/apache/cordova/api/PluginManager.java
+++ b/lib/cordova-android/framework/src/org/apache/cordova/api/PluginManager.java
@@ -30,6 +30,8 @@ import org.xmlpull.v1.XmlPullParserException;
import android.content.Intent;
import android.content.res.XmlResourceParser;
+import android.webkit.WebResourceResponse;
+
/**
* PluginManager is exposed to JavaScript in the Cordova WebView.
*
@@ -118,7 +120,7 @@ public class PluginManager {
// System.out.println("Plugin: "+name+" => "+value);
onload = "true".equals(xml.getAttributeValue(null, "onload"));
entry = new PluginEntry(service, pluginClass, onload);
- this.addService(entry);
+ this.addService(entry);
}
//What is this?
else if (strNode.equals("url-filter")) {
@@ -367,6 +369,25 @@ public class PluginManager {
}
/**
+ * Called when the WebView is loading any resource, top-level or not.
+ *
+ * Uses the same url-filter tag as onOverrideUrlLoading.
+ *
+ * @param url The URL of the resource to be loaded.
+ * @return Return a WebResourceResponse with the resource, or null if the WebView should handle it.
+ */
+ public WebResourceResponse shouldInterceptRequest(String url) {
+ Iterator<Entry<String, String>> it = this.urlMap.entrySet().iterator();
+ while (it.hasNext()) {
+ HashMap.Entry<String, String> pairs = it.next();
+ if (url.startsWith(pairs.getKey())) {
+ return this.getPlugin(pairs.getValue()).shouldInterceptRequest(url);
+ }
+ }
+ return null;
+ }
+
+ /**
* Called when the app navigates or refreshes.
*/
public void onReset() {
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-android/framework/src/org/apache/cordova/api/PluginResult.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/api/PluginResult.java b/lib/cordova-android/framework/src/org/apache/cordova/api/PluginResult.java
index 4c1d833..a642200 100755
--- a/lib/cordova-android/framework/src/org/apache/cordova/api/PluginResult.java
+++ b/lib/cordova-android/framework/src/org/apache/cordova/api/PluginResult.java
@@ -71,11 +71,15 @@ public class PluginResult {
}
public PluginResult(Status status, byte[] data) {
+ this(status, data, false);
+ }
+
+ public PluginResult(Status status, byte[] data, boolean binaryString) {
this.status = status.ordinal();
- this.messageType = MESSAGE_TYPE_ARRAYBUFFER;
+ this.messageType = binaryString ? MESSAGE_TYPE_BINARYSTRING : MESSAGE_TYPE_ARRAYBUFFER;
this.encodedMessage = Base64.encodeToString(data, Base64.NO_WRAP);
}
-
+
public void setKeepCallback(boolean b) {
this.keepCallback = b;
}
@@ -143,6 +147,9 @@ public class PluginResult {
public static final int MESSAGE_TYPE_BOOLEAN = 4;
public static final int MESSAGE_TYPE_NULL = 5;
public static final int MESSAGE_TYPE_ARRAYBUFFER = 6;
+ // Use BINARYSTRING when your string may contain null characters.
+ // This is required to work around a bug in the platform :(.
+ public static final int MESSAGE_TYPE_BINARYSTRING = 7;
public static String[] StatusMessages = new String[] {
"No result",
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-blackberry/bin/create
----------------------------------------------------------------------
diff --git a/lib/cordova-blackberry/bin/create b/lib/cordova-blackberry/bin/create
index 870bad1..b7e719b 100755
--- a/lib/cordova-blackberry/bin/create
+++ b/lib/cordova-blackberry/bin/create
@@ -56,6 +56,19 @@ function on_error {
[ -d "$PROJECT_PATH" ] && rm -rf "$PROJECT_PATH"
}
+function replace {
+ local pattern=$1
+ local filename=$2
+ # Mac OS X requires -i argument
+ if [[ "$OSTYPE" =~ "darwin" ]]
+ then
+ /usr/bin/sed -i '' -e $pattern "$filename"
+ elif [[ "$OSTYPE" =~ "linux" ]]
+ then
+ /bin/sed -i -e $pattern "$filename"
+ fi
+}
+
# we do not want the script to silently fail
trap on_error ERR
trap on_exit EXIT
@@ -79,13 +92,13 @@ then
(cd "$BUILD_PATH" && "$ANT" create -Dproject.path="$PROJECT_PATH" &> /dev/null )
# interpolate the activity and package into config.xml
echo "Updating config.xml ..."
- sed -i '' -e "s/__NAME__/${NAME}/g" "$MANIFEST_PATH"
- sed -i '' -e "s/__PACKAGE__/${PACKAGE}/g" "$MANIFEST_PATH"
+ replace "s/__NAME__/${NAME}/g" "$MANIFEST_PATH"
+ replace "s/__PACKAGE__/${PACKAGE}/g" "$MANIFEST_PATH"
else
# copy project template if in distribution
echo "Copying assets and resources ..."
cp -r "$BUILD_PATH/sample/." "$PROJECT_PATH"
echo "Updating config.xml ..."
- sed -i '' -e "s/cordovaExample/${NAME}/g" "$MANIFEST_PATH"
- sed -i '' -e "s/org.apache.cordova.example/${PACKAGE}/g" "$MANIFEST_PATH"
+ replace "s/cordovaExample/${NAME}/g" "$MANIFEST_PATH"
+ replace "s/org.apache.cordova.example/${PACKAGE}/g" "$MANIFEST_PATH"
fi
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/37b92ff4/lib/cordova-blackberry/bin/templates/project/www/index.html
----------------------------------------------------------------------
diff --git a/lib/cordova-blackberry/bin/templates/project/www/index.html b/lib/cordova-blackberry/bin/templates/project/www/index.html
index f083790..6b53abc 100644
--- a/lib/cordova-blackberry/bin/templates/project/www/index.html
+++ b/lib/cordova-blackberry/bin/templates/project/www/index.html
@@ -18,8 +18,8 @@
under the License.
-->
<html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <head>
+ <meta charset="utf-8" />
<meta name="format-detection" content="telephone=no" />
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
<link rel="stylesheet" type="text/css" href="css/index.css" />