diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..1594d12 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,16 @@ +# Contributing to Apache Cordova + +Anyone can contribute to Cordova. And we need your contributions. + +There are multiple ways to contribute: report bugs, improve the docs, and +contribute code. + +For instructions on this, start with the +[contribution overview](http://cordova.apache.org/#contribute). + +The details are explained there, but the important items are: + - Sign and submit an Apache ICLA (Contributor License Agreement). + - Have a Jira issue open that corresponds to your contribution. + - Run the tests so your patch doesn't break existing functionality. + +We look forward to your contributions! diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 2d40026..3d6cd70 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -80,5 +80,20 @@ * Removed some iOS6 Deprecations ### 0.3.3 (Mar 5, 2014) +* CB-5534 Fix video/audio does not stop playing when browser is closed * CB-6172 Fix broken install on case-sensitive file-systems + +### 0.4.0 (Apr 17, 2014) +* CB-6360: [ios] Fix for crash on iOS < 6.0 (closes #37) +* CB-3324: [WP8] Add support for back-button inappbrowser [WP8] if there is no history -> InAppBrowser is closed +* [WP] await async calls, resolve warnings +* [WP] Make InAppBrowser work with embedded files, using system behavior +* CB-6402: [WP8] pass empty string instead of null for [optional] windowFeatures string +* CB-6422: [windows8] use cordova/exec/proxy +* CB-6389 CB-3617: Add clearcache and clearsessioncache options to iOS (like Android) +* Doc update: event name and example param (closes #31) +* CB-6253: [WP] Add Network Capability to WMAppManifest.xml +* CB-6212: [iOS] fix warnings compiled under arm64 64-bit +* CB-6218: Update docs for BB10 +* CB-6460: Update license headers diff --git a/doc/index.md b/doc/index.md index e82b29b..760831a 100644 --- a/doc/index.md +++ b/doc/index.md @@ -30,6 +30,17 @@ and can't access Cordova APIs. cordova plugin add org.apache.cordova.inappbrowser +### Firefox OS + +Create __www/manifest.webapp__ as described in +[Manifest Docs](https://developer.mozilla.org/en-US/Apps/Developing/Manifest). +Add relevant permisions. + + "permissions": { + "browser": {} + } + + ## window.open Opens a URL in a new `InAppBrowser` instance, the current browser @@ -56,7 +67,7 @@ instance, or the system browser. Android only: - __closebuttoncaption__: set to a string to use as the __Done__ button's caption. - - __hidden__: set to `yes` to create the browser and load the page, but not show it. The load event fires when loading is complete. Omit or set to `no` (default) to have the browser open and load normally. + - __hidden__: set to `yes` to create the browser and load the page, but not show it. The loadstop event fires when loading is complete. Omit or set to `no` (default) to have the browser open and load normally. - __clearcache__: set to `yes` to have the browser's cookie cache cleared before the new window is opened - __clearsessioncache__: set to `yes` to have the session cookie cache cleared before the new window is opened @@ -64,7 +75,9 @@ instance, or the system browser. - __closebuttoncaption__: set to a string to use as the __Done__ button's caption. Note that you need to localize this value yourself. - __disallowoverscroll__: Set to `yes` or `no` (default is `no`). Turns on/off the UIWebViewBounce property. - - __hidden__: set to `yes` to create the browser and load the page, but not show it. The load event fires when loading is complete. Omit or set to `no` (default) to have the browser open and load normally. + - __hidden__: set to `yes` to create the browser and load the page, but not show it. The loadstop event fires when loading is complete. Omit or set to `no` (default) to have the browser open and load normally. + - __clearcache__: set to `yes` to have the browser's cookie cache cleared before the new window is opened + - __clearsessioncache__: set to `yes` to have the session cookie cache cleared before the new window is opened - __toolbar__: set to `yes` or `no` to turn the toolbar on or off for the InAppBrowser (defaults to `yes`) - __enableViewportScale__: Set to `yes` or `no` to prevent viewport scaling through a meta tag (defaults to `no`). - __mediaPlaybackRequiresUserAction__: Set to `yes` or `no` to prevent HTML5 audio or video from autoplaying (defaults to `no`). @@ -139,7 +152,7 @@ The object returned from a call to `window.open`. ### Quick Example var ref = window.open('http://apache.org', '_blank', 'location=yes'); - ref.addEventListener('loadstart', function() { alert(event.url); }); + ref.addEventListener('loadstart', function(event) { alert(event.url); }); ## removeEventListener @@ -169,7 +182,7 @@ The function is passed an `InAppBrowserEvent` object. ### Quick Example var ref = window.open('http://apache.org', '_blank', 'location=yes'); - var myCallback = function() { alert(event.url); } + var myCallback = function(event) { alert(event.url); } ref.addEventListener('loadstart', myCallback); ref.removeEventListener('loadstart', myCallback); diff --git a/plugin.xml b/plugin.xml index 932ff83..fcb1837 100644 --- a/plugin.xml +++ b/plugin.xml @@ -1,8 +1,26 @@ + + version="0.4.1-dev"> InAppBrowser Cordova InAppBrowser Plugin @@ -93,6 +111,10 @@ + + + + @@ -102,11 +124,19 @@ + + + + + + + + @@ -116,6 +146,10 @@ + + + + @@ -129,5 +163,14 @@ + + + + + + + + + diff --git a/src/amazon/InAppChromeClient.java b/src/amazon/InAppChromeClient.java index 7f2ddc3..37cf101 100644 --- a/src/amazon/InAppChromeClient.java +++ b/src/amazon/InAppChromeClient.java @@ -1,3 +1,21 @@ +/* + 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.inappbrowser; import org.apache.cordova.CordovaWebView; diff --git a/src/android/InAppChromeClient.java b/src/android/InAppChromeClient.java index f3fc741..a2145e6 100644 --- a/src/android/InAppChromeClient.java +++ b/src/android/InAppChromeClient.java @@ -1,3 +1,21 @@ +/* + 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.inappbrowser; import org.apache.cordova.CordovaWebView; diff --git a/src/blackberry10/README.md b/src/blackberry10/README.md index 0b16789..f0fa860 100644 --- a/src/blackberry10/README.md +++ b/src/blackberry10/README.md @@ -1,3 +1,21 @@ + # BlackBerry 10 In-App-Browser Plugin The in app browser functionality is entirely contained within common js. There is no native implementation required. diff --git a/src/firefoxos/InAppBrowserProxy.js b/src/firefoxos/InAppBrowserProxy.js new file mode 100644 index 0000000..8ee3736 --- /dev/null +++ b/src/firefoxos/InAppBrowserProxy.js @@ -0,0 +1,108 @@ +/* + * + * 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. + * +*/ + +// https://developer.mozilla.org/en-US/docs/WebAPI/Browser + +var cordova = require('cordova'), + channel = require('cordova/channel'), + modulemapper = require('cordova/modulemapper'); + +var origOpenFunc = modulemapper.getOriginalSymbol(window, 'window.open'); +var browserWrap; + +var IABExecs = { + + close: function (win, lose) { + if (browserWrap) { + browserWrap.parentNode.removeChild(browserWrap); + browserWrap = null; + } + }, + + /* + * Reveal browser if opened hidden + */ + show: function (win, lose) { + console.error('[FirefoxOS] show not implemented'); + }, + + open: function (win, lose, args) { + var strUrl = args[0], + target = args[1], + features = args[2], + url, + elem; + + if (target === '_system') { + origOpenFunc.apply(window, [strUrl, '_blank']); + } else if (target === '_blank') { + var browserElem = document.createElement('iframe'); + browserElem.setAttribute('mozbrowser', true); + // make this loaded in its own child process + browserElem.setAttribute('remote', true); + browserElem.setAttribute('src', strUrl); + if (browserWrap) { + document.body.removeChild(browserWrap); + } + browserWrap = document.createElement('div'); + browserWrap.style.position = 'absolute'; + browserWrap.style.backgroundColor = 'rgba(0,0,0,0.75)'; + browserWrap.style.color = 'rgba(235,235,235,1.0)'; + browserWrap.style.width = window.innerWidth + 'px'; + browserWrap.style.height = window.innerHeight + 'px'; + browserWrap.style.padding = '10px,0,0,0'; + browserElem.style.position = 'absolute'; + browserElem.style.top = '60px'; + browserElem.style.left = '0px'; + browserElem.style.height = (window.innerHeight - 60) + 'px'; + browserElem.style.width = browserWrap.style.width; + + browserWrap.addEventListener('click', function () { + setTimeout(function () { + IABExecs.close(); + }, 0); + }, false); + var p = document.createElement('p'); + p.appendChild(document.createTextNode('close')); + // TODO: make all buttons - ← → × + p.style.paddingTop = '10px'; + p.style.textAlign = 'center'; + browserWrap.appendChild(p); + browserWrap.appendChild(browserElem); + document.body.appendChild(browserWrap); + // assign browser element to browserWrap for future + // reference + browserWrap.browser = browserElem; + } else { + window.location = strUrl; + } + }, + injectScriptCode: function (code, bCB) { + console.error('[FirefoxOS] injectScriptCode not implemented'); + }, + injectScriptFile: function (file, bCB) { + console.error('[FirefoxOS] injectScriptFile not implemented'); + } +}; + +module.exports = IABExecs; + +require('cordova/firefoxos/commandProxy').add('InAppBrowser', module.exports); diff --git a/src/ios/CDVInAppBrowser.h b/src/ios/CDVInAppBrowser.h index 8e2ab12..0ba07f1 100644 --- a/src/ios/CDVInAppBrowser.h +++ b/src/ios/CDVInAppBrowser.h @@ -45,6 +45,8 @@ @property (nonatomic, assign) BOOL toolbar; @property (nonatomic, copy) NSString* closebuttoncaption; @property (nonatomic, copy) NSString* toolbarposition; +@property (nonatomic, assign) BOOL clearcache; +@property (nonatomic, assign) BOOL clearsessioncache; @property (nonatomic, copy) NSString* presentationstyle; @property (nonatomic, copy) NSString* transitionstyle; @@ -61,7 +63,7 @@ @end -@interface CDVInAppBrowserViewController : UIViewController { +@interface CDVInAppBrowserViewController : UIViewController { @private NSString* _userAgent; NSString* _prevUserAgent; @@ -90,4 +92,10 @@ - (id)initWithUserAgent:(NSString*)userAgent prevUserAgent:(NSString*)prevUserAgent browserOptions: (CDVInAppBrowserOptions*) browserOptions; +@end + +@interface CDVInAppBrowserNavigationController : UINavigationController + +@property (nonatomic, weak) id orientationDelegate; + @end \ No newline at end of file diff --git a/src/ios/CDVInAppBrowser.m b/src/ios/CDVInAppBrowser.m index 88b737c..8037a91 100644 --- a/src/ios/CDVInAppBrowser.m +++ b/src/ios/CDVInAppBrowser.m @@ -115,6 +115,29 @@ - (void)openInInAppBrowser:(NSURL*)url withOptions:(NSString*)options { CDVInAppBrowserOptions* browserOptions = [CDVInAppBrowserOptions parseOptions:options]; + + if (browserOptions.clearcache) { + NSHTTPCookie *cookie; + NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; + for (cookie in [storage cookies]) + { + if (![cookie.domain isEqual: @".^filecookies^"]) { + [storage deleteCookie:cookie]; + } + } + } + + if (browserOptions.clearsessioncache) { + NSHTTPCookie *cookie; + NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; + for (cookie in [storage cookies]) + { + if (![cookie.domain isEqual: @".^filecookies^"] && cookie.isSessionOnly) { + [storage deleteCookie:cookie]; + } + } + } + if (self.inAppBrowserViewController == nil) { NSString* originalUA = [CDVUserAgentUtil originalUserAgent]; self.inAppBrowserViewController = [[CDVInAppBrowserViewController alloc] initWithUserAgent:originalUA prevUserAgent:[self.commandDelegate userAgent] browserOptions: browserOptions]; @@ -193,13 +216,14 @@ _previousStatusBarStyle = [UIApplication sharedApplication].statusBarStyle; - UINavigationController* nav = [[UINavigationController alloc] + CDVInAppBrowserNavigationController* nav = [[CDVInAppBrowserNavigationController alloc] initWithRootViewController:self.inAppBrowserViewController]; + nav.orientationDelegate = self.inAppBrowserViewController; nav.navigationBarHidden = YES; // Run later to avoid the "took a long time" log message. dispatch_async(dispatch_get_main_queue(), ^{ if (self.inAppBrowserViewController != nil) { - [self.viewController presentModalViewController:nav animated:YES]; + [self.viewController presentViewController:nav animated:YES completion:nil]; } }); } @@ -395,7 +419,7 @@ if (self.callbackId != nil) { NSString* url = [self.inAppBrowserViewController.currentURL absoluteString]; CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR - messageAsDictionary:@{@"type":@"loaderror", @"url":url, @"code": [NSNumber numberWithInt:error.code], @"message": error.localizedDescription}]; + messageAsDictionary:@{@"type":@"loaderror", @"url":url, @"code": [NSNumber numberWithInteger:error.code], @"message": error.localizedDescription}]; [pluginResult setKeepCallback:[NSNumber numberWithBool:YES]]; [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId]; @@ -465,7 +489,6 @@ self.webView.clearsContextBeforeDrawing = YES; self.webView.clipsToBounds = YES; self.webView.contentMode = UIViewContentModeScaleToFill; - self.webView.contentStretch = CGRectFromString(@"{{0, 0}, {1, 1}}"); self.webView.multipleTouchEnabled = YES; self.webView.opaque = YES; self.webView.scalesPageToFit = NO; @@ -478,7 +501,6 @@ self.spinner.clearsContextBeforeDrawing = NO; self.spinner.clipsToBounds = NO; self.spinner.contentMode = UIViewContentModeScaleToFill; - self.spinner.contentStretch = CGRectFromString(@"{{0, 0}, {1, 1}}"); self.spinner.frame = CGRectMake(454.0, 231.0, 20.0, 20.0); self.spinner.hidden = YES; self.spinner.hidesWhenStopped = YES; @@ -506,7 +528,6 @@ self.toolbar.clearsContextBeforeDrawing = NO; self.toolbar.clipsToBounds = NO; self.toolbar.contentMode = UIViewContentModeScaleToFill; - self.toolbar.contentStretch = CGRectFromString(@"{{0, 0}, {1, 1}}"); self.toolbar.hidden = NO; self.toolbar.multipleTouchEnabled = NO; self.toolbar.opaque = NO; @@ -525,11 +546,16 @@ self.addressLabel.clearsContextBeforeDrawing = YES; self.addressLabel.clipsToBounds = YES; self.addressLabel.contentMode = UIViewContentModeScaleToFill; - self.addressLabel.contentStretch = CGRectFromString(@"{{0, 0}, {1, 1}}"); self.addressLabel.enabled = YES; self.addressLabel.hidden = NO; self.addressLabel.lineBreakMode = NSLineBreakByTruncatingTail; - self.addressLabel.minimumScaleFactor = 10.000; + + if ([self.addressLabel respondsToSelector:NSSelectorFromString(@"setMinimumScaleFactor:")]) { + [self.addressLabel setValue:@(10.0/[UIFont labelFontSize]) forKey:@"minimumScaleFactor"]; + } else if ([self.addressLabel respondsToSelector:NSSelectorFromString(@"setMinimumFontSize:")]) { + [self.addressLabel setValue:@(10.0) forKey:@"minimumFontSize"]; + } + self.addressLabel.multipleTouchEnabled = NO; self.addressLabel.numberOfLines = 1; self.addressLabel.opaque = NO; @@ -719,7 +745,7 @@ if ([self respondsToSelector:@selector(presentingViewController)]) { [[self presentingViewController] dismissViewControllerAnimated:YES completion:nil]; } else { - [[self parentViewController] dismissModalViewControllerAnimated:YES]; + [[self parentViewController] dismissViewControllerAnimated:YES completion:nil]; } }); } @@ -834,7 +860,7 @@ - (void)webView:(UIWebView*)theWebView didFailLoadWithError:(NSError*)error { // log fail message, stop spinner, update back/forward - NSLog(@"webView:didFailLoadWithError - %i: %@", error.code, [error localizedDescription]); + NSLog(@"webView:didFailLoadWithError - %ld: %@", (long)error.code, [error localizedDescription]); self.backButton.enabled = theWebView.canGoBack; self.forwardButton.enabled = theWebView.canGoForward; @@ -885,6 +911,8 @@ self.toolbar = YES; self.closebuttoncaption = nil; self.toolbarposition = kInAppBrowserToolbarBarPositionBottom; + self.clearcache = NO; + self.clearsessioncache = NO; self.enableviewportscale = NO; self.mediaplaybackrequiresuseraction = NO; @@ -935,4 +963,37 @@ return obj; } +@end + +@implementation CDVInAppBrowserNavigationController : UINavigationController + +#pragma mark CDVScreenOrientationDelegate + +- (BOOL)shouldAutorotate +{ + if ((self.orientationDelegate != nil) && [self.orientationDelegate respondsToSelector:@selector(shouldAutorotate)]) { + return [self.orientationDelegate shouldAutorotate]; + } + return YES; +} + +- (NSUInteger)supportedInterfaceOrientations +{ + if ((self.orientationDelegate != nil) && [self.orientationDelegate respondsToSelector:@selector(supportedInterfaceOrientations)]) { + return [self.orientationDelegate supportedInterfaceOrientations]; + } + + return 1 << UIInterfaceOrientationPortrait; +} + +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation +{ + if ((self.orientationDelegate != nil) && [self.orientationDelegate respondsToSelector:@selector(shouldAutorotateToInterfaceOrientation:)]) { + return [self.orientationDelegate shouldAutorotateToInterfaceOrientation:interfaceOrientation]; + } + + return YES; +} + + @end diff --git a/src/wp/InAppBrowser.cs b/src/wp/InAppBrowser.cs index 454464d..f5b7b1d 100644 --- a/src/wp/InAppBrowser.cs +++ b/src/wp/InAppBrowser.cs @@ -1,21 +1,38 @@ -using System; -using System.Net; +/* + Licensed 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. +*/ + +using System; +using System.Diagnostics; +using System.IO; +using System.Runtime.Serialization; using System.Windows; using System.Windows.Controls; -using System.Windows.Documents; -using System.Windows.Ink; -using System.Windows.Input; using System.Windows.Media; -using System.Windows.Media.Animation; -using System.Windows.Shapes; using Microsoft.Phone.Controls; -using System.Diagnostics; -using System.Runtime.Serialization; -using WPCordovaClassLib.Cordova; -using WPCordovaClassLib.Cordova.Commands; -using WPCordovaClassLib.Cordova.JSON; using Microsoft.Phone.Shell; + +#if WP8 +using System.Threading.Tasks; +using Windows.ApplicationModel; +using Windows.Storage; +using Windows.System; + +//Use alias in case Cordova File Plugin is enabled. Then the File class will be declared in both and error will occur. +using IOFile = System.IO.File; +#else using Microsoft.Phone.Tasks; +#endif namespace WPCordovaClassLib.Cordova.Commands { @@ -41,6 +58,8 @@ namespace WPCordovaClassLib.Cordova.Commands protected bool ShowLocation {get;set;} protected bool StartHidden {get;set;} + protected string NavigationCallbackId { get; set; } + public void open(string options) { // reset defaults on ShowLocation + StartHidden features @@ -52,28 +71,31 @@ namespace WPCordovaClassLib.Cordova.Commands string urlLoc = args[0]; string target = args[1]; string featString = args[2]; + this.NavigationCallbackId = args[3]; - string[] features = featString.Split(','); - foreach (string str in features) + if (!string.IsNullOrEmpty(featString)) { - try + string[] features = featString.Split(','); + foreach (string str in features) { - string[] split = str.Split('='); - switch (split[0]) + try { - case "location": - ShowLocation = split[1].ToLower().StartsWith("yes"); - break; - case "hidden": - StartHidden = split[1].ToLower().StartsWith("yes"); - break; + string[] split = str.Split('='); + switch (split[0]) + { + case "location": + ShowLocation = split[1].StartsWith("yes", StringComparison.OrdinalIgnoreCase); + break; + case "hidden": + StartHidden = split[1].StartsWith("yes", StringComparison.OrdinalIgnoreCase); + break; + } + } + catch (Exception) + { + // some sort of invalid param was passed, moving on ... } } - catch(Exception) - { - // some sort of invalid param was passed, moving on ... - } - } /* _self - opens in the Cordova WebView if url is in the white-list, else it opens in the InAppBrowser @@ -184,7 +206,6 @@ namespace WPCordovaClassLib.Cordova.Commands //throw new NotImplementedException("Windows Phone does not currently support 'insertCSS'"); } - private void ShowCordovaBrowser(string url) { Uri loc = new Uri(url, UriKind.RelativeOrAbsolute); @@ -200,7 +221,7 @@ namespace WPCordovaClassLib.Cordova.Commands if (cView != null) { WebBrowser br = cView.Browser; - br.Navigate(loc); + br.Navigate2(loc); } } @@ -208,13 +229,53 @@ namespace WPCordovaClassLib.Cordova.Commands }); } +#if WP8 + private async void ShowSystemBrowser(string url) + { + var pathUri = new Uri(url, UriKind.Absolute); + if (pathUri.Scheme == Uri.UriSchemeHttp || pathUri.Scheme == Uri.UriSchemeHttps) + { + await Launcher.LaunchUriAsync(pathUri); + return; + } + + var file = await GetFile(pathUri.AbsolutePath.Replace('/', Path.DirectorySeparatorChar)); + if (file != null) + { + await Launcher.LaunchFileAsync(file); + } + else + { + Debug.WriteLine("File not found."); + } + } + + private async Task GetFile(string fileName) + { + //first try to get the file from the isolated storage + var localFolder = ApplicationData.Current.LocalFolder; + if (IOFile.Exists(Path.Combine(localFolder.Path, fileName))) + { + return await localFolder.GetFileAsync(fileName); + } + + //if file is not found try to get it from the xap + var filePath = Path.Combine(Package.Current.InstalledLocation.Path, fileName); + if (IOFile.Exists(filePath)) + { + return await StorageFile.GetFileFromPathAsync(filePath); + } + + return null; + } +#else private void ShowSystemBrowser(string url) { WebBrowserTask webBrowserTask = new WebBrowserTask(); webBrowserTask.Uri = new Uri(url, UriKind.Absolute); webBrowserTask.Show(); } - +#endif private void ShowInAppBrowser(string url) { @@ -225,7 +286,7 @@ namespace WPCordovaClassLib.Cordova.Commands if (browser != null) { //browser.IsGeolocationEnabled = opts.isGeolocationEnabled; - browser.Navigate(loc); + browser.Navigate2(loc); } else { @@ -248,7 +309,7 @@ namespace WPCordovaClassLib.Cordova.Commands browser.Navigating += new EventHandler(browser_Navigating); browser.NavigationFailed += new System.Windows.Navigation.NavigationFailedEventHandler(browser_NavigationFailed); browser.Navigated += new EventHandler(browser_Navigated); - browser.Navigate(loc); + browser.Navigate2(loc); if (StartHidden) { @@ -287,6 +348,8 @@ namespace WPCordovaClassLib.Cordova.Commands bar.IsVisible = !StartHidden; AppBar = bar; + page.BackKeyPress += page_BackKeyPress; + } } @@ -294,6 +357,23 @@ namespace WPCordovaClassLib.Cordova.Commands }); } + void page_BackKeyPress(object sender, System.ComponentModel.CancelEventArgs e) + { +#if WP8 + if (browser.CanGoBack) + { + browser.GoBack(); + } + else + { + close(); + } + e.Cancel = true; +#else + browser.InvokeScript("execScript", "history.back();"); +#endif + } + void browser_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e) { @@ -326,7 +406,7 @@ namespace WPCordovaClassLib.Cordova.Commands { #if WP8 browser.GoBack(); -#else +#else browser.InvokeScript("execScript", "history.back();"); #endif } @@ -361,13 +441,15 @@ namespace WPCordovaClassLib.Cordova.Commands grid.Children.Remove(browser); } page.ApplicationBar = null; + page.BackKeyPress -= page_BackKeyPress; } } + browser = null; string message = "{\"type\":\"exit\"}"; PluginResult result = new PluginResult(PluginResult.Status.OK, message); result.KeepCallback = false; - this.DispatchCommandResult(result); + this.DispatchCommandResult(result, NavigationCallbackId); }); } } @@ -385,7 +467,7 @@ namespace WPCordovaClassLib.Cordova.Commands string message = "{\"type\":\"loadstop\", \"url\":\"" + e.Uri.OriginalString + "\"}"; PluginResult result = new PluginResult(PluginResult.Status.OK, message); result.KeepCallback = true; - this.DispatchCommandResult(result); + this.DispatchCommandResult(result, NavigationCallbackId); } void browser_NavigationFailed(object sender, System.Windows.Navigation.NavigationFailedEventArgs e) @@ -393,7 +475,7 @@ namespace WPCordovaClassLib.Cordova.Commands string message = "{\"type\":\"error\",\"url\":\"" + e.Uri.OriginalString + "\"}"; PluginResult result = new PluginResult(PluginResult.Status.ERROR, message); result.KeepCallback = true; - this.DispatchCommandResult(result); + this.DispatchCommandResult(result, NavigationCallbackId); } void browser_Navigating(object sender, NavigatingEventArgs e) @@ -401,8 +483,33 @@ namespace WPCordovaClassLib.Cordova.Commands string message = "{\"type\":\"loadstart\",\"url\":\"" + e.Uri.OriginalString + "\"}"; PluginResult result = new PluginResult(PluginResult.Status.OK, message); result.KeepCallback = true; - this.DispatchCommandResult(result); + this.DispatchCommandResult(result, NavigationCallbackId); } } + + internal static class WebBrowserExtensions + { + /// + /// Improved method to initiate request to the provided URI. Supports 'data:text/html' urls. + /// + /// The browser instance + /// The requested uri + internal static void Navigate2(this WebBrowser browser, Uri uri) + { + // IE10 does not support data uri so we use NavigateToString method instead + if (uri.Scheme == "data") + { + // we should remove the scheme identifier and unescape the uri + string uriString = Uri.UnescapeDataString(uri.AbsoluteUri); + // format is 'data:text/html, ...' + string html = new System.Text.RegularExpressions.Regex("^data:text/html,").Replace(uriString, ""); + browser.NavigateToString(html); + } + else + { + browser.Navigate(uri); + } + } + } } diff --git a/www/inappbrowser.js b/www/inappbrowser.js index ebcfa24..3535b6f 100644 --- a/www/inappbrowser.js +++ b/www/inappbrowser.js @@ -90,6 +90,8 @@ module.exports = function(strUrl, strWindowName, strWindowFeatures) { iab._eventHandler(eventname); }; + strWindowFeatures = strWindowFeatures || ""; + exec(cb, cb, "InAppBrowser", "open", [strUrl, strWindowName, strWindowFeatures]); return iab; }; diff --git a/www/windows8/InAppBrowserProxy.js b/www/windows8/InAppBrowserProxy.js index d173778..944284e 100644 --- a/www/windows8/InAppBrowserProxy.js +++ b/www/windows8/InAppBrowserProxy.js @@ -108,4 +108,4 @@ var IAB = { module.exports = IAB; -require("cordova/windows8/commandProxy").add("InAppBrowser", module.exports); +require("cordova/exec/proxy").add("InAppBrowser", module.exports);