diff --git a/package.json b/package.json index 66cb704..d6e0f9a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cordova-plugin-hostedwebapp", - "version": "0.2.1", + "version": "0.3.0", "description": "Hosted Web App Plugin", "cordova": { "id": "cordova-plugin-hostedwebapp", diff --git a/plugin.xml b/plugin.xml index 9cf7482..7b5d021 100644 --- a/plugin.xml +++ b/plugin.xml @@ -1,7 +1,7 @@ + version="0.3.0"> HostedWebApp Hosted Web App Plugin MIT License @@ -24,9 +24,9 @@ - - - + + + diff --git a/readme.md b/readme.md index 8fc8999..ce642c9 100644 --- a/readme.md +++ b/readme.md @@ -147,7 +147,19 @@ To inject scripts into the hosted web content: The following [wiki article](https://github.com/manifoldjs/ManifoldJS/wiki/Using-Cordova-Plugins-in-Hosted-Web-Apps) provides additional information about these features. ### Offline Feature -The plugin implements a basic offline feature that will show an offline page whenever network connectivity is lost. By default, the page shows a suitable message alerting the user about the loss of connectivity. To customize the offline experience, a page named **offline.html** can be placed in the **www** folder of the application and it will be used instead. +The plugin implements an offline feature that will show an offline page whenever network connectivity is lost. + +The feature is enabled by default, but can be disabled with the following property in the manifest.json file. + +``` +{ + ... + "mjs_offline_feature": false + ... +} +``` + +By default, the page shows a suitable message informing the user about the loss of connectivity. To customize the offline experience, a page named **offline.html** can be placed in the **www** folder of the application and it will be used instead. 1. To test the offline feature, interrupt the network connection to show the offline page and reconnect it to hide it. diff --git a/scripts/updateConfigurationBeforePrepare.js b/scripts/updateConfigurationBeforePrepare.js index 3a0534e..7f3e212 100644 --- a/scripts/updateConfigurationBeforePrepare.js +++ b/scripts/updateConfigurationBeforePrepare.js @@ -587,11 +587,12 @@ module.exports = function (context) { var manifestPath = path.join(projectRoot, 'manifest.json'); fs.readFile(manifestPath, function (err, data) { if (err) { - logger.error('Failed to read manifest at \'' + manifestPath + '\'.'); - return task.reject(err); + logger.warn('Failed to read manifest at \'' + manifestPath + '\'. Proceeding to point config.xml to sample url of https://www.npmjs.com/package/cordova-plugin-hostedwebapp.'); + data = JSON.stringify({ 'start_url': 'https://www.npmjs.com/package/cordova-plugin-hostedwebapp', 'short_name' : 'PlaceholderSite'}); } var manifestJson = data.toString().replace(/^\uFEFF/, ''); + var appManifestPath = path.join(projectRoot, 'www', 'manifest.json'); fs.writeFile(appManifestPath, manifestJson, function (err) { if (err) { diff --git a/src/android/HostedWebApp.java b/src/android/HostedWebApp.java index de2211b..f4cd9e5 100644 --- a/src/android/HostedWebApp.java +++ b/src/android/HostedWebApp.java @@ -47,7 +47,7 @@ public class HostedWebApp extends CordovaPlugin { private LinearLayout rootLayout; private WebView offlineWebView; - private boolean offlineOverlayEnabled; + private boolean offlineOverlayEnabled = true; private boolean isConnectionError = false; @@ -69,6 +69,11 @@ public void pluginInitialize() { this.loadingManifest = false; + if (!this.manifestObject.optBoolean("mjs_offline_feature", true)) { + this.offlineOverlayEnabled = false; + // Do not initialize offline overlay + return; + } // Initialize offline overlay this.activity.runOnUiThread(new Runnable() { @Override @@ -547,7 +552,7 @@ public void run() { evaluateJavaScriptMethod.invoke(webView, scriptToInject, resultCallback); } catch (Exception e) { Log.v(LOG_TAG, String.format("WARNING: Webview does not support 'evaluateJavascript' method. Webview type: '%s'", webView.getClass().getName())); - me.webView.getEngine().loadUrl("javascript:" + Uri.encode(scriptToInject), false); + me.webView.getEngine().loadUrl("javascript:" + scriptToInject, false); if (resultCallback != null) { resultCallback.onReceiveValue(null); diff --git a/src/ios/CDVHostedWebApp.m b/src/ios/CDVHostedWebApp.m index db3018f..635df4a 100644 --- a/src/ios/CDVHostedWebApp.m +++ b/src/ios/CDVHostedWebApp.m @@ -1,5 +1,6 @@ #import "CDVHostedWebApp.h" #import +#import #import "CDVConnection.h" static NSString* const IOS_PLATFORM = @"ios"; @@ -54,9 +55,6 @@ - (void)pluginInitialize { [super pluginInitialize]; - // creates the UI to show offline mode - [self createOfflineView]; - // observe notifications from network-information plugin to detect when device is offline [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateConnectivityStatus:) @@ -92,8 +90,16 @@ - (void)pluginInitialize // set the webview delegate to notify navigation events notificationDelegate = [[CVDWebViewNotificationDelegate alloc] init]; - notificationDelegate.wrappedDelegate = self.webView.delegate; - [self.webView setDelegate:notificationDelegate]; + notificationDelegate.wrappedDelegate = ((UIWebView*)self.webView).delegate; + [(UIWebView*)self.webView setDelegate:notificationDelegate]; + + id offlineFeature = [manifest objectForKey:@"mjs_offline_feature"]; + if (offlineFeature != nil && [offlineFeature boolValue] == NO) { + self.enableOfflineSupport = NO; + } else { + // creates the UI to show offline mode + [self createOfflineView]; + } } // loads the specified W3C manifest @@ -216,7 +222,7 @@ -(BOOL) injectScripts:(NSArray *)scriptList { } } - return[self.webView stringByEvaluatingJavaScriptFromString:content] != nil; + return[(UIWebView*)self.webView stringByEvaluatingJavaScriptFromString:content] != nil; } - (BOOL) isCordovaEnabled @@ -299,7 +305,7 @@ -(BOOL) isMatchingRuleForPage:(NSDictionary*) rule withPlatformCheck: (BOOL) che if (match != nil) { CDVWhitelist *whitelist = [[CDVWhitelist alloc] initWithArray:match]; - NSURL* url = self.webView.request.URL; + NSURL* url = ((UIWebView*)self.webView).request.URL; isURLMatch = [whitelist URLIsAllowed:url]; } } @@ -356,7 +362,7 @@ - (void)updateConnectivityStatus:(NSNotification*)notification } else { if (self.failedURL) { - [self.webView loadRequest: [NSURLRequest requestWithURL: self.failedURL]]; + [(UIWebView*)self.webView loadRequest: [NSURLRequest requestWithURL: self.failedURL]]; } else { [self.offlineView setHidden:YES]; @@ -412,7 +418,7 @@ - (void)webViewDidFinishLoad:(NSNotification*)notification } NSString* javascript = [NSString stringWithFormat:@"window.hostedWebApp = { 'platform': '%@', 'pluginMode': '%@', 'cordovaBaseUrl': '%@'};", IOS_PLATFORM, pluginMode, cordovaBaseUrl]; - [self.webView stringByEvaluatingJavaScriptFromString:javascript]; + [(UIWebView*)self.webView stringByEvaluatingJavaScriptFromString:javascript]; NSMutableArray* scripts = [[NSMutableArray alloc] init]; if ([pluginMode isEqualToString:@"client"]) @@ -468,6 +474,7 @@ - (void)didWebViewFailLoadWithError:(NSNotification*)notification } } +#ifndef __CORDOVA_4_0_0 - (BOOL) shouldOverrideLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType { NSURL* url = [request URL]; @@ -483,6 +490,7 @@ - (BOOL) shouldOverrideLoadWithRequest:(NSURLRequest*)request navigationType:(UI return NO; } +#endif -(BOOL) shouldAllowNavigation:(NSURL*) url { diff --git a/src/windows/HostedWebAppPluginProxy.js b/src/windows/HostedWebAppPluginProxy.js index a83d2da..ee79e09 100644 --- a/src/windows/HostedWebAppPluginProxy.js +++ b/src/windows/HostedWebAppPluginProxy.js @@ -438,7 +438,11 @@ cordova.commandProxy.add('HostedWebApp', module.exports); module.exports.loadManifest( function (manifest) { - configureOfflineSupport('offline.html'); + if (manifest.mjs_offline_feature === false) { + _enableOfflineSupport = false; + } else { + configureOfflineSupport('offline.html'); + } configureWhiteList(manifest); _mainView = configureHost(manifest ? manifest.start_url : 'about:blank', _zIndex); _mainView.addEventListener("MSWebViewDOMContentLoaded", domContentLoadedEvent, false); diff --git a/www/hostedapp-bridge.js b/www/hostedapp-bridge.js index 1efcc65..3e79791 100644 --- a/www/hostedapp-bridge.js +++ b/www/hostedapp-bridge.js @@ -40,9 +40,14 @@ } // change bridge mode in iOS to avoid Content Security Policy (CSP) issues with 'gap://' frame origin + // Note that all bridge modes except IFRAME_NAV were dropped starting from cordova-ios@4.0.0 (see + // https://issues.apache.org/jira/browse/CB-9883), so plugins will *not* work correctly in pages that + // restrict the gap:// origin if (platform === 'ios') { var exec = cordova.require('cordova/exec'); - exec.setJsToNativeBridgeMode(exec.jsToNativeModes.XHR_OPTIONAL_PAYLOAD); + if (exec.setJsToNativeBridgeMode && exec.jsToNativeModes && exec.jsToNativeModes.XHR_OPTIONAL_PAYLOAD) { + exec.setJsToNativeBridgeMode(exec.jsToNativeModes.XHR_OPTIONAL_PAYLOAD); + } } // override plugin loader to handle script injection