summaryrefslogtreecommitdiff
path: root/StoneIsland/plugins/cordova-plugin-customurlscheme/src
diff options
context:
space:
mode:
authorJules Laplace <jules@okfoc.us>2016-11-08 12:37:03 -0500
committerJules Laplace <jules@okfoc.us>2016-11-08 12:37:03 -0500
commitef4f212fc1482136dba1e690ec589b315b4a377f (patch)
tree0b7e16d72567fafcfd3e08d7c5c591ad07a63458 /StoneIsland/plugins/cordova-plugin-customurlscheme/src
parent5fa81da81260d65113f57a293b6256d334fe8e2d (diff)
build 0.7.0
Diffstat (limited to 'StoneIsland/plugins/cordova-plugin-customurlscheme/src')
-rw-r--r--StoneIsland/plugins/cordova-plugin-customurlscheme/src/android/nl/xservices/plugins/LaunchMyApp.java49
-rw-r--r--StoneIsland/plugins/cordova-plugin-customurlscheme/src/windows/hooks/prepare-manifest.js30
-rw-r--r--StoneIsland/plugins/cordova-plugin-customurlscheme/src/wp8/CompositeUriMapper.cs46
-rw-r--r--StoneIsland/plugins/cordova-plugin-customurlscheme/src/wp8/CustomUriMapperCommand.cs9
-rw-r--r--StoneIsland/plugins/cordova-plugin-customurlscheme/src/wp8/ICustomUriMapper.cs7
-rw-r--r--StoneIsland/plugins/cordova-plugin-customurlscheme/src/wp8/hooks/add-uri-mapper.js80
6 files changed, 215 insertions, 6 deletions
diff --git a/StoneIsland/plugins/cordova-plugin-customurlscheme/src/android/nl/xservices/plugins/LaunchMyApp.java b/StoneIsland/plugins/cordova-plugin-customurlscheme/src/android/nl/xservices/plugins/LaunchMyApp.java
index 9d3f3d63..3a52d287 100644
--- a/StoneIsland/plugins/cordova-plugin-customurlscheme/src/android/nl/xservices/plugins/LaunchMyApp.java
+++ b/StoneIsland/plugins/cordova-plugin-customurlscheme/src/android/nl/xservices/plugins/LaunchMyApp.java
@@ -4,6 +4,8 @@ import android.content.Intent;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaActivity;
import org.apache.cordova.CordovaPlugin;
+import org.apache.cordova.CordovaInterface;
+import org.apache.cordova.CordovaWebView;
import org.apache.cordova.PluginResult;
import org.json.JSONArray;
import org.json.JSONException;
@@ -16,19 +18,52 @@ import java.util.Locale;
public class LaunchMyApp extends CordovaPlugin {
private static final String ACTION_CHECKINTENT = "checkIntent";
+ private static final String ACTION_CLEARINTENT = "clearIntent";
+ private static final String ACTION_GETLASTINTENT = "getLastIntent";
+
+ private String lastIntentString = null;
+
+ /**
+ * We don't want to interfere with other plugins requiring the intent data,
+ * but in case of a multi-page app your app may receive the same intent data
+ * multiple times, that's why you'll get an option to reset it (null it).
+ *
+ * Add this to config.xml to enable that behaviour (default false):
+ * <preference name="CustomURLSchemePluginClearsAndroidIntent" value="true"/>
+ */
+ private boolean resetIntent;
+
+ @Override
+ public void initialize(final CordovaInterface cordova, CordovaWebView webView){
+ this.resetIntent = preferences.getBoolean("resetIntent", false) ||
+ preferences.getBoolean("CustomURLSchemePluginClearsAndroidIntent", false);
+ }
@Override
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
- if (ACTION_CHECKINTENT.equalsIgnoreCase(action)) {
+ if (ACTION_CLEARINTENT.equalsIgnoreCase(action)) {
+ final Intent intent = ((CordovaActivity) this.webView.getContext()).getIntent();
+ if (resetIntent){
+ intent.setData(null);
+ }
+ return true;
+ } else if (ACTION_CHECKINTENT.equalsIgnoreCase(action)) {
final Intent intent = ((CordovaActivity) this.webView.getContext()).getIntent();
final String intentString = intent.getDataString();
- if (intentString != null && intentString.contains("://") && intent.getScheme() != null) {
+ if (intentString != null && intent.getScheme() != null) {
+ lastIntentString = intentString;
callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, intent.getDataString()));
- intent.setData(null);
} else {
callbackContext.error("App was not started via the launchmyapp URL scheme. Ignoring this errorcallback is the best approach.");
}
return true;
+ } else if (ACTION_GETLASTINTENT.equalsIgnoreCase(action)) {
+ if(lastIntentString != null) {
+ callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, lastIntentString));
+ } else {
+ callbackContext.error("No intent received so far.");
+ }
+ return true;
} else {
callbackContext.error("This plugin only responds to the " + ACTION_CHECKINTENT + " action.");
return false;
@@ -38,8 +73,10 @@ public class LaunchMyApp extends CordovaPlugin {
@Override
public void onNewIntent(Intent intent) {
final String intentString = intent.getDataString();
- if (intentString != null && intentString.contains("://") && intent.getScheme() != null) {
- intent.setData(null);
+ if (intentString != null && intent.getScheme() != null) {
+ if (resetIntent){
+ intent.setData(null);
+ }
try {
StringWriter writer = new StringWriter(intentString.length() * 2);
escapeJavaStyleString(writer, intentString, true, false);
@@ -133,4 +170,4 @@ public class LaunchMyApp extends CordovaPlugin {
private static String hex(char ch) {
return Integer.toHexString(ch).toUpperCase(Locale.ENGLISH);
}
-} \ No newline at end of file
+}
diff --git a/StoneIsland/plugins/cordova-plugin-customurlscheme/src/windows/hooks/prepare-manifest.js b/StoneIsland/plugins/cordova-plugin-customurlscheme/src/windows/hooks/prepare-manifest.js
new file mode 100644
index 00000000..06e237f7
--- /dev/null
+++ b/StoneIsland/plugins/cordova-plugin-customurlscheme/src/windows/hooks/prepare-manifest.js
@@ -0,0 +1,30 @@
+module.exports = function(context) {
+ var fs = context.requireCordovaModule('fs'),
+ et = context.requireCordovaModule('elementtree'),
+ path = context.requireCordovaModule('path'),
+ xml= context.requireCordovaModule('cordova-common').xmlHelpers,
+ projectRoot = path.join(context.opts.projectRoot, "platforms", "windows");
+
+ var MANIFEST_WINDOWS = 'package.windows.appxmanifest',
+ MANIFEST_PHONE = 'package.phone.appxmanifest',
+ MANIFEST_WINDOWS10 = 'package.windows10.appxmanifest',
+ MANIFEST_WINDOWS80 = 'package.windows80.appxmanifest';
+
+ function updateManifestFile(manifestPath) {
+ var doc = xml.parseElementtreeSync(manifestPath);
+ var root = doc.getroot();
+ var app = root.find('./Applications/Application');
+ if (!app) {
+ throw new Error(manifestPath + ' has incorrect XML structure.');
+ }
+ if (!app.find('./Extensions')) {
+ app.append(new et.Element('Extensions'));
+ }
+ fs.writeFileSync(manifestPath, doc.write({indent: 4}), 'utf-8');
+ }
+
+ [MANIFEST_PHONE, MANIFEST_WINDOWS80, MANIFEST_WINDOWS, MANIFEST_WINDOWS10]
+ .forEach(function(manifestFile) {
+ updateManifestFile(path.join(projectRoot, manifestFile));
+ });
+}
diff --git a/StoneIsland/plugins/cordova-plugin-customurlscheme/src/wp8/CompositeUriMapper.cs b/StoneIsland/plugins/cordova-plugin-customurlscheme/src/wp8/CompositeUriMapper.cs
new file mode 100644
index 00000000..8db593b8
--- /dev/null
+++ b/StoneIsland/plugins/cordova-plugin-customurlscheme/src/wp8/CompositeUriMapper.cs
@@ -0,0 +1,46 @@
+using System;
+using System.Linq;
+using System.Windows.Navigation;
+
+internal class CompositeUriMapper : UriMapperBase
+{
+ public static string launchUrl;
+
+ public override Uri MapUri(Uri uri)
+ {
+ string launchUri = uri.ToString();
+ if (launchUri.StartsWith("/Protocol?encodedLaunchUri="))
+ {
+ int launchUrlIndex = launchUri.IndexOf("encodedLaunchUri=");
+ launchUrl = System.Net.HttpUtility.UrlDecode(launchUri.Substring(launchUrlIndex+17));
+ return new Uri("/MainPage.xaml", UriKind.Relative);
+ }
+ var assemblies = AppDomain.CurrentDomain.GetAssemblies();
+ var types = assemblies.SelectMany(a =>
+ {
+ try
+ {
+ return a.ExportedTypes.Where(et => typeof(ICustomUriMapper).IsAssignableFrom(et));
+ }
+ catch
+ {
+ return Enumerable.Empty<Type>();
+ }
+ });
+
+ foreach (var type in types)
+ {
+ if (type != typeof(ICustomUriMapper))
+ {
+ var worker = (ICustomUriMapper)Activator.CreateInstance(type);
+ var mappedUri = worker.CustomMapUri(uri);
+ if (mappedUri != null)
+ {
+ return mappedUri;
+ }
+ }
+ }
+
+ return uri;
+ }
+} \ No newline at end of file
diff --git a/StoneIsland/plugins/cordova-plugin-customurlscheme/src/wp8/CustomUriMapperCommand.cs b/StoneIsland/plugins/cordova-plugin-customurlscheme/src/wp8/CustomUriMapperCommand.cs
new file mode 100644
index 00000000..2004f2ec
--- /dev/null
+++ b/StoneIsland/plugins/cordova-plugin-customurlscheme/src/wp8/CustomUriMapperCommand.cs
@@ -0,0 +1,9 @@
+using System;
+using WPCordovaClassLib.Cordova.Commands;
+
+namespace Cordova.Extension.Commands
+{
+ public class CustomUriMapperCommand : BaseCommand
+ {
+ }
+} \ No newline at end of file
diff --git a/StoneIsland/plugins/cordova-plugin-customurlscheme/src/wp8/ICustomUriMapper.cs b/StoneIsland/plugins/cordova-plugin-customurlscheme/src/wp8/ICustomUriMapper.cs
new file mode 100644
index 00000000..2cc31e5c
--- /dev/null
+++ b/StoneIsland/plugins/cordova-plugin-customurlscheme/src/wp8/ICustomUriMapper.cs
@@ -0,0 +1,7 @@
+using System;
+using System.Linq;
+
+public interface ICustomUriMapper
+{
+ Uri CustomMapUri(Uri uri);
+}
diff --git a/StoneIsland/plugins/cordova-plugin-customurlscheme/src/wp8/hooks/add-uri-mapper.js b/StoneIsland/plugins/cordova-plugin-customurlscheme/src/wp8/hooks/add-uri-mapper.js
new file mode 100644
index 00000000..1c1db69c
--- /dev/null
+++ b/StoneIsland/plugins/cordova-plugin-customurlscheme/src/wp8/hooks/add-uri-mapper.js
@@ -0,0 +1,80 @@
+module.exports = function (context) {
+ var deferred = context.requireCordovaModule('q').defer(),
+ fs = context.requireCordovaModule('fs'),
+ path = context.requireCordovaModule('path'),
+ projectRoot = context.opts.projectRoot;
+
+ // While on AppBuilder this may work, the Cordova CLI doesn't like it
+ // (or at least not all versions of it).
+ var appXaml = path.join(projectRoot, "App.xaml.cs");
+ var mainPageXaml = path.join(projectRoot, "MainPage.xaml.cs");
+ try {
+ fs.statSync(appXaml);
+ fs.statSync(mainPageXaml);
+ } catch (err) {
+ appXaml = path.join(projectRoot, "platforms", "wp8", "App.xaml.cs");
+ mainPageXaml = path.join(projectRoot, "platforms", "wp8", "MainPage.xaml.cs");
+ try {
+ fs.statSync(appXaml);
+ fs.statSync(mainPageXaml);
+ } catch (err2) {
+ console.error("Custom URL Scheme plugin couldn't find your App's xaml file! Try to adjust the file manually according to the 'add-uri-mapper.js' hook.");
+ return;
+ }
+ }
+
+ fs.readFile(appXaml, 'utf8', function (err,data) {
+ if (err) {
+ console.error("Error while configuring the Custom URL Scheme: " + err);
+ deferred.reject(err);
+ return;
+ }
+
+ var result = data.replace(/^(\s*?)(RootFrame.NavigationFailed\s*?\+=\s*?RootFrame_NavigationFailed;)/gm,
+ "$1$2\n\n$1// Assign the URI-mapper class to the application frame\n$1RootFrame.UriMapper = new CompositeUriMapper();");
+
+ fs.writeFile(appXaml, result, 'utf8', function (err) {
+ if (err){
+ deferred.reject(err);
+ } else{
+ deferred.resolve();
+ }
+ });
+ });
+
+ fs.readFile(mainPageXaml, 'utf8', function (err,data) {
+ if (err) {
+ console.error("Error while configuring the Custom URL Scheme: " + err);
+ deferred.reject(err);
+ return;
+ }
+
+ // first add a line to refer to a new method
+ var result = data.replace(/^(\s*?)(this.CordovaView.Loaded\s*?\+=\s*?CordovaView_Loaded;)/gm,
+ "$1$2\n\n$1// Wire a handler so we can check for our custom scheme\n$1this.CordovaView.Browser.LoadCompleted += CordovaBrowser_LoadCompleted;");
+
+ // now add that new method
+ result = result.replace(/^(\s*?)(\/\/ Constructor)/gm,
+ "$1void CordovaBrowser_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e) {\n"+
+ "$1\tif (CompositeUriMapper.launchUrl != null) {\n" +
+ "$1\t\tstring handleOpenURL = string.Format(\"(function() {{ document.addEventListener('deviceready', function() {{ if (typeof handleOpenURL === 'function') {{ handleOpenURL(\\\"{0}\\\"); }} }}); }})()\", CompositeUriMapper.launchUrl);\n" +
+ "$1\t\ttry {\n" +
+ "$1\t\t\tthis.CordovaView.CordovaBrowser.InvokeScript(\"eval\", new string[] { handleOpenURL });\n" +
+ "$1\t\t} catch (Exception) {}\n" +
+ "$1\t\tCompositeUriMapper.launchUrl = null;\n" +
+ "$1\t}\n" +
+ "$1\tthis.CordovaView.Browser.LoadCompleted -= CordovaBrowser_LoadCompleted;\n" +
+ "$1}\n\n" +
+ "$1$2");
+
+ fs.writeFile(mainPageXaml, result, 'utf8', function (err) {
+ if (err){
+ deferred.reject(err);
+ } else{
+ deferred.resolve();
+ }
+ });
+ });
+
+ return deferred.promise;
+} \ No newline at end of file