summaryrefslogtreecommitdiff
path: root/StoneIsland/plugins/cordova-plugin-dialogs/src
diff options
context:
space:
mode:
Diffstat (limited to 'StoneIsland/plugins/cordova-plugin-dialogs/src')
-rwxr-xr-xStoneIsland/plugins/cordova-plugin-dialogs/src/android/Notification.java483
-rw-r--r--StoneIsland/plugins/cordova-plugin-dialogs/src/blackberry10/index.js87
-rw-r--r--StoneIsland/plugins/cordova-plugin-dialogs/src/firefoxos/notification.js154
-rw-r--r--StoneIsland/plugins/cordova-plugin-dialogs/src/ios/CDVNotification.bundle/beep.wavbin0 -> 8114 bytes
-rw-r--r--StoneIsland/plugins/cordova-plugin-dialogs/src/ios/CDVNotification.h37
-rw-r--r--StoneIsland/plugins/cordova-plugin-dialogs/src/ios/CDVNotification.m221
-rw-r--r--StoneIsland/plugins/cordova-plugin-dialogs/src/ubuntu/notification.cpp85
-rw-r--r--StoneIsland/plugins/cordova-plugin-dialogs/src/ubuntu/notification.h64
-rw-r--r--StoneIsland/plugins/cordova-plugin-dialogs/src/ubuntu/notification.qml65
-rw-r--r--StoneIsland/plugins/cordova-plugin-dialogs/src/windows/NotificationProxy.js249
-rw-r--r--StoneIsland/plugins/cordova-plugin-dialogs/src/wp/Notification.cs482
-rw-r--r--StoneIsland/plugins/cordova-plugin-dialogs/src/wp/NotificationBox.xaml79
-rw-r--r--StoneIsland/plugins/cordova-plugin-dialogs/src/wp/NotificationBox.xaml.cs41
-rw-r--r--StoneIsland/plugins/cordova-plugin-dialogs/src/wp/notification-beep.wavbin0 -> 16630 bytes
14 files changed, 2047 insertions, 0 deletions
diff --git a/StoneIsland/plugins/cordova-plugin-dialogs/src/android/Notification.java b/StoneIsland/plugins/cordova-plugin-dialogs/src/android/Notification.java
new file mode 100755
index 00000000..3bc3cee6
--- /dev/null
+++ b/StoneIsland/plugins/cordova-plugin-dialogs/src/android/Notification.java
@@ -0,0 +1,483 @@
+/*
+ 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.dialogs;
+
+import org.apache.cordova.CallbackContext;
+import org.apache.cordova.CordovaInterface;
+import org.apache.cordova.CordovaPlugin;
+import org.apache.cordova.PluginResult;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import android.annotation.SuppressLint;
+import android.app.AlertDialog;
+import android.app.AlertDialog.Builder;
+import android.app.ProgressDialog;
+import android.content.DialogInterface;
+import android.media.Ringtone;
+import android.media.RingtoneManager;
+import android.net.Uri;
+import android.widget.EditText;
+import android.widget.TextView;
+
+
+/**
+ * This class provides access to notifications on the device.
+ *
+ * Be aware that this implementation gets called on
+ * navigator.notification.{alert|confirm|prompt}, and that there is a separate
+ * implementation in org.apache.cordova.CordovaChromeClient that gets
+ * called on a simple window.{alert|confirm|prompt}.
+ */
+public class Notification extends CordovaPlugin {
+
+ public int confirmResult = -1;
+ public ProgressDialog spinnerDialog = null;
+ public ProgressDialog progressDialog = null;
+
+ /**
+ * Constructor.
+ */
+ public Notification() {
+ }
+
+ /**
+ * Executes the request and returns PluginResult.
+ *
+ * @param action The action to execute.
+ * @param args JSONArray of arguments for the plugin.
+ * @param callbackContext The callback context used when calling back into JavaScript.
+ * @return True when the action was valid, false otherwise.
+ */
+ public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
+ /*
+ * Don't run any of these if the current activity is finishing
+ * in order to avoid android.view.WindowManager$BadTokenException
+ * crashing the app. Just return true here since false should only
+ * be returned in the event of an invalid action.
+ */
+ if(this.cordova.getActivity().isFinishing()) return true;
+
+ if (action.equals("beep")) {
+ this.beep(args.getLong(0));
+ }
+ else if (action.equals("alert")) {
+ this.alert(args.getString(0), args.getString(1), args.getString(2), callbackContext);
+ return true;
+ }
+ else if (action.equals("confirm")) {
+ 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), args.getString(3), callbackContext);
+ return true;
+ }
+ else if (action.equals("activityStart")) {
+ this.activityStart(args.getString(0), args.getString(1));
+ }
+ else if (action.equals("activityStop")) {
+ this.activityStop();
+ }
+ else if (action.equals("progressStart")) {
+ this.progressStart(args.getString(0), args.getString(1));
+ }
+ else if (action.equals("progressValue")) {
+ this.progressValue(args.getInt(0));
+ }
+ else if (action.equals("progressStop")) {
+ this.progressStop();
+ }
+ else {
+ return false;
+ }
+
+ // Only alert and confirm are async.
+ callbackContext.success();
+ return true;
+ }
+
+ //--------------------------------------------------------------------------
+ // LOCAL METHODS
+ //--------------------------------------------------------------------------
+
+ /**
+ * Beep plays the default notification ringtone.
+ *
+ * @param count Number of times to play notification
+ */
+ public void beep(final long count) {
+ cordova.getThreadPool().execute(new Runnable() {
+ public void run() {
+ Uri ringtone = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
+ Ringtone notification = RingtoneManager.getRingtone(cordova.getActivity().getBaseContext(), ringtone);
+
+ // If phone is not set to silent mode
+ if (notification != null) {
+ for (long i = 0; i < count; ++i) {
+ notification.play();
+ long timeout = 5000;
+ while (notification.isPlaying() && (timeout > 0)) {
+ timeout = timeout - 100;
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+ }
+ }
+ });
+ }
+
+ /**
+ * Builds and shows a native Android alert with given Strings
+ * @param message The message the alert should display
+ * @param title The title of the alert
+ * @param buttonLabel The label of the button
+ * @param callbackContext The callback context
+ */
+ public synchronized void alert(final String message, final String title, final String buttonLabel, final CallbackContext callbackContext) {
+ final CordovaInterface cordova = this.cordova;
+
+ Runnable runnable = new Runnable() {
+ public void run() {
+
+ AlertDialog.Builder dlg = createDialog(cordova); // new AlertDialog.Builder(cordova.getActivity(), AlertDialog.THEME_DEVICE_DEFAULT_LIGHT);
+ dlg.setMessage(message);
+ dlg.setTitle(title);
+ dlg.setCancelable(true);
+ dlg.setPositiveButton(buttonLabel,
+ new AlertDialog.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.dismiss();
+ callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, 0));
+ }
+ });
+ dlg.setOnCancelListener(new AlertDialog.OnCancelListener() {
+ public void onCancel(DialogInterface dialog)
+ {
+ dialog.dismiss();
+ callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, 0));
+ }
+ });
+
+ changeTextDirection(dlg);
+ };
+ };
+ this.cordova.getActivity().runOnUiThread(runnable);
+ }
+
+ /**
+ * Builds and shows a native Android confirm dialog with given title, message, buttons.
+ * This dialog only shows up to 3 buttons. Any labels after that will be ignored.
+ * The index of the button pressed will be returned to the JavaScript callback identified by callbackId.
+ *
+ * @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 confirm(final String message, final String title, final JSONArray buttonLabels, final CallbackContext callbackContext) {
+ final CordovaInterface cordova = this.cordova;
+
+ Runnable runnable = new Runnable() {
+ public void run() {
+ AlertDialog.Builder dlg = createDialog(cordova); // new AlertDialog.Builder(cordova.getActivity(), AlertDialog.THEME_DEVICE_DEFAULT_LIGHT);
+ dlg.setMessage(message);
+ dlg.setTitle(title);
+ dlg.setCancelable(true);
+
+ // First button
+ 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 (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 (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)
+ {
+ dialog.dismiss();
+ callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, 0));
+ }
+ });
+
+ changeTextDirection(dlg);
+ };
+ };
+ this.cordova.getActivity().runOnUiThread(runnable);
+ }
+
+ /**
+ * 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 String defaultText, final CallbackContext callbackContext) {
+
+ final CordovaInterface cordova = this.cordova;
+
+ Runnable runnable = new Runnable() {
+ public void run() {
+ final EditText promptInput = new EditText(cordova.getActivity());
+ promptInput.setHint(defaultText);
+ AlertDialog.Builder dlg = createDialog(cordova); // new AlertDialog.Builder(cordova.getActivity(), AlertDialog.THEME_DEVICE_DEFAULT_LIGHT);
+ 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().toString().trim().length()==0 ? defaultText : 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().toString().trim().length()==0 ? defaultText : 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().toString().trim().length()==0 ? defaultText : 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().toString().trim().length()==0 ? defaultText : promptInput.getText());
+ } catch (JSONException e) { e.printStackTrace(); }
+ callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, result));
+ }
+ });
+
+ changeTextDirection(dlg);
+ };
+ };
+ this.cordova.getActivity().runOnUiThread(runnable);
+ }
+
+ /**
+ * Show the spinner.
+ *
+ * @param title Title of the dialog
+ * @param message The message of the dialog
+ */
+ public synchronized void activityStart(final String title, final String message) {
+ if (this.spinnerDialog != null) {
+ this.spinnerDialog.dismiss();
+ this.spinnerDialog = null;
+ }
+ final Notification notification = this;
+ final CordovaInterface cordova = this.cordova;
+ Runnable runnable = new Runnable() {
+ public void run() {
+ notification.spinnerDialog = createProgressDialog(cordova); // new ProgressDialog(cordova.getActivity(), AlertDialog.THEME_DEVICE_DEFAULT_LIGHT);
+ notification.spinnerDialog.setTitle(title);
+ notification.spinnerDialog.setMessage(message);
+ notification.spinnerDialog.setCancelable(true);
+ notification.spinnerDialog.setIndeterminate(true);
+ notification.spinnerDialog.setOnCancelListener(
+ new DialogInterface.OnCancelListener() {
+ public void onCancel(DialogInterface dialog) {
+ notification.spinnerDialog = null;
+ }
+ });
+ notification.spinnerDialog.show();
+ }
+ };
+ this.cordova.getActivity().runOnUiThread(runnable);
+ }
+
+ /**
+ * Stop spinner.
+ */
+ public synchronized void activityStop() {
+ if (this.spinnerDialog != null) {
+ this.spinnerDialog.dismiss();
+ this.spinnerDialog = null;
+ }
+ }
+
+ /**
+ * Show the progress dialog.
+ *
+ * @param title Title of the dialog
+ * @param message The message of the dialog
+ */
+ public synchronized void progressStart(final String title, final String message) {
+ if (this.progressDialog != null) {
+ this.progressDialog.dismiss();
+ this.progressDialog = null;
+ }
+ final Notification notification = this;
+ final CordovaInterface cordova = this.cordova;
+ Runnable runnable = new Runnable() {
+ public void run() {
+ notification.progressDialog = createProgressDialog(cordova); // new ProgressDialog(cordova.getActivity(), AlertDialog.THEME_DEVICE_DEFAULT_LIGHT);
+ notification.progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
+ notification.progressDialog.setTitle(title);
+ notification.progressDialog.setMessage(message);
+ notification.progressDialog.setCancelable(true);
+ notification.progressDialog.setMax(100);
+ notification.progressDialog.setProgress(0);
+ notification.progressDialog.setOnCancelListener(
+ new DialogInterface.OnCancelListener() {
+ public void onCancel(DialogInterface dialog) {
+ notification.progressDialog = null;
+ }
+ });
+ notification.progressDialog.show();
+ }
+ };
+ this.cordova.getActivity().runOnUiThread(runnable);
+ }
+
+ /**
+ * Set value of progress bar.
+ *
+ * @param value 0-100
+ */
+ public synchronized void progressValue(int value) {
+ if (this.progressDialog != null) {
+ this.progressDialog.setProgress(value);
+ }
+ }
+
+ /**
+ * Stop progress dialog.
+ */
+ public synchronized void progressStop() {
+ if (this.progressDialog != null) {
+ this.progressDialog.dismiss();
+ this.progressDialog = null;
+ }
+ }
+
+ @SuppressLint("NewApi")
+ private AlertDialog.Builder createDialog(CordovaInterface cordova) {
+ int currentapiVersion = android.os.Build.VERSION.SDK_INT;
+ if (currentapiVersion >= android.os.Build.VERSION_CODES.HONEYCOMB) {
+ return new AlertDialog.Builder(cordova.getActivity(), AlertDialog.THEME_DEVICE_DEFAULT_LIGHT);
+ } else {
+ return new AlertDialog.Builder(cordova.getActivity());
+ }
+ }
+
+ @SuppressLint("InlinedApi")
+ private ProgressDialog createProgressDialog(CordovaInterface cordova) {
+ int currentapiVersion = android.os.Build.VERSION.SDK_INT;
+ if (currentapiVersion >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
+ return new ProgressDialog(cordova.getActivity(), AlertDialog.THEME_DEVICE_DEFAULT_LIGHT);
+ } else {
+ return new ProgressDialog(cordova.getActivity());
+ }
+ }
+
+ @SuppressLint("NewApi")
+ private void changeTextDirection(Builder dlg){
+ int currentapiVersion = android.os.Build.VERSION.SDK_INT;
+ dlg.create();
+ AlertDialog dialog = dlg.show();
+ if (currentapiVersion >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
+ TextView messageview = (TextView)dialog.findViewById(android.R.id.message);
+ messageview.setTextDirection(android.view.View.TEXT_DIRECTION_LOCALE);
+ }
+ }
+}
diff --git a/StoneIsland/plugins/cordova-plugin-dialogs/src/blackberry10/index.js b/StoneIsland/plugins/cordova-plugin-dialogs/src/blackberry10/index.js
new file mode 100644
index 00000000..3660f667
--- /dev/null
+++ b/StoneIsland/plugins/cordova-plugin-dialogs/src/blackberry10/index.js
@@ -0,0 +1,87 @@
+/*
+* Copyright 2013 Research In Motion Limited.
+*
+* 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.
+*/
+
+function showDialog(args, dialogType, result) {
+ //Unpack and map the args
+ var msg = JSON.parse(decodeURIComponent(args[0])),
+ title = JSON.parse(decodeURIComponent(args[1])),
+ btnLabel = JSON.parse(decodeURIComponent(args[2]));
+
+ if (!Array.isArray(btnLabel)) {
+ //Converts to array for (string) and (string,string, ...) cases
+ btnLabel = btnLabel.split(",");
+ }
+
+ if (msg && typeof msg === "string") {
+ msg = msg.replace(/^"|"$/g, "").replace(/\\"/g, '"');
+ } else {
+ result.error("message is undefined");
+ return;
+ }
+
+ var messageObj = {
+ title : title,
+ htmlmessage : msg,
+ dialogType : dialogType,
+ optionalButtons : btnLabel
+ };
+
+ //TODO replace with getOverlayWebview() when available in webplatform
+ qnx.webplatform.getWebViews()[2].dialog.show(messageObj, function (data) {
+ if (typeof data === "number") {
+ //Confirm dialog call back needs to be called with one-based indexing [1,2,3 etc]
+ result.callbackOk(++data, false);
+ } else {
+ //Prompt dialog callback expects object
+ result.callbackOk({
+ buttonIndex: data.ok ? 1 : 0,
+ input1: (data.oktext) ? decodeURIComponent(data.oktext) : ""
+ }, false);
+ }
+ });
+
+ result.noResult(true);
+}
+
+module.exports = {
+ alert: function (success, fail, args, env) {
+ var result = new PluginResult(args, env);
+
+ if (Object.keys(args).length < 3) {
+ result.error("Notification action - alert arguments not found.");
+ } else {
+ showDialog(args, "CustomAsk", result);
+ }
+ },
+ confirm: function (success, fail, args, env) {
+ var result = new PluginResult(args, env);
+
+ if (Object.keys(args).length < 3) {
+ result.error("Notification action - confirm arguments not found.");
+ } else {
+ showDialog(args, "CustomAsk", result);
+ }
+ },
+ prompt: function (success, fail, args, env) {
+ var result = new PluginResult(args, env);
+
+ if (Object.keys(args).length < 3) {
+ result.error("Notification action - prompt arguments not found.");
+ } else {
+ showDialog(args, "JavaScriptPrompt", result);
+ }
+ }
+};
diff --git a/StoneIsland/plugins/cordova-plugin-dialogs/src/firefoxos/notification.js b/StoneIsland/plugins/cordova-plugin-dialogs/src/firefoxos/notification.js
new file mode 100644
index 00000000..b6986fd0
--- /dev/null
+++ b/StoneIsland/plugins/cordova-plugin-dialogs/src/firefoxos/notification.js
@@ -0,0 +1,154 @@
+/*
+ *
+ * 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.
+ *
+*/
+
+var modulemapper = require('cordova/modulemapper');
+
+
+var origOpenFunc = modulemapper.getOriginalSymbol(window, 'window.open');
+
+
+function _empty() {}
+
+
+function modal(message, callback, title, buttonLabels, domObjects) {
+ var mainWindow = window;
+ var modalWindow = origOpenFunc();
+ var modalDocument = modalWindow.document;
+
+ modalDocument.write(
+ '<html><head>' +
+ '<link rel="stylesheet" type="text/css" href="/css/index.css" />' +
+ '<link rel="stylesheet" type="text/css" href="/css/notification.css" />' +
+ '</head><body></body></html>');
+
+ var box = modalDocument.createElement('form');
+ box.setAttribute('role', 'dialog');
+ // prepare and append empty section
+ var section = modalDocument.createElement('section');
+ box.appendChild(section);
+ // add title
+ var boxtitle = modalDocument.createElement('h1');
+ boxtitle.appendChild(modalDocument.createTextNode(title));
+ section.appendChild(boxtitle);
+ // add message
+ var boxMessage = modalDocument.createElement('p');
+ boxMessage.appendChild(modalDocument.createTextNode(message));
+ section.appendChild(boxMessage);
+ // inject what's needed
+ if (domObjects) {
+ section.appendChild(domObjects);
+ }
+ // add buttons and assign callbackButton on click
+ var menu = modalDocument.createElement('menu');
+ box.appendChild(menu);
+ for (var index = 0; index < buttonLabels.length; index++) {
+ addButton(buttonLabels[index], index, (index === 0));
+ }
+ modalDocument.body.appendChild(box);
+
+ function addButton(label, index, recommended) {
+ var thisButtonCallback = makeCallbackButton(index + 1);
+ var button = modalDocument.createElement('button');
+ button.appendChild(modalDocument.createTextNode(label));
+ button.addEventListener('click', thisButtonCallback, false);
+ if (recommended) {
+ // TODO: default one listens to Enter key
+ button.classList.add('recommend');
+ }
+ menu.appendChild(button);
+ }
+
+ // TODO: onUnload listens to the cancel key
+ function onUnload() {
+ var result = 0;
+ if (modalDocument.getElementById('prompt-input')) {
+ result = {
+ input1: '',
+ buttonIndex: 0
+ }
+ }
+ mainWindow.setTimeout(function() {
+ callback(result);
+ }, 10);
+ };
+ modalWindow.addEventListener('unload', onUnload, false);
+
+ // call callback and destroy modal
+ function makeCallbackButton(labelIndex) {
+ return function() {
+ if (modalWindow) {
+ modalWindow.removeEventListener('unload', onUnload, false);
+ modalWindow.close();
+ }
+ // checking if prompt
+ var promptInput = modalDocument.getElementById('prompt-input');
+ var response;
+ if (promptInput) {
+ response = {
+ input1: promptInput.value,
+ buttonIndex: labelIndex
+ };
+ }
+ response = response || labelIndex;
+ callback(response);
+ }
+ }
+}
+
+var Notification = {
+ vibrate: function(milliseconds) {
+ navigator.vibrate(milliseconds);
+ },
+ alert: function(successCallback, errorCallback, args) {
+ var message = args[0];
+ var title = args[1];
+ var _buttonLabels = [args[2]];
+ var _callback = (successCallback || _empty);
+ modal(message, _callback, title, _buttonLabels);
+ },
+ confirm: function(successCallback, errorCallback, args) {
+ var message = args[0];
+ var title = args[1];
+ var buttonLabels = args[2];
+ var _callback = (successCallback || _empty);
+ modal(message, _callback, title, buttonLabels);
+ },
+ prompt: function(successCallback, errorCallback, args) {
+ var message = args[0];
+ var title = args[1];
+ var buttonLabels = args[2];
+ var defaultText = args[3];
+ var inputParagraph = document.createElement('p');
+ inputParagraph.classList.add('input');
+ var inputElement = document.createElement('input');
+ inputElement.setAttribute('type', 'text');
+ inputElement.id = 'prompt-input';
+ if (defaultText) {
+ inputElement.setAttribute('placeholder', defaultText);
+ }
+ inputParagraph.appendChild(inputElement);
+ modal(message, successCallback, title, buttonLabels, inputParagraph);
+ }
+};
+
+
+module.exports = Notification;
+require('cordova/exec/proxy').add('Notification', Notification);
diff --git a/StoneIsland/plugins/cordova-plugin-dialogs/src/ios/CDVNotification.bundle/beep.wav b/StoneIsland/plugins/cordova-plugin-dialogs/src/ios/CDVNotification.bundle/beep.wav
new file mode 100644
index 00000000..05f5997f
--- /dev/null
+++ b/StoneIsland/plugins/cordova-plugin-dialogs/src/ios/CDVNotification.bundle/beep.wav
Binary files differ
diff --git a/StoneIsland/plugins/cordova-plugin-dialogs/src/ios/CDVNotification.h b/StoneIsland/plugins/cordova-plugin-dialogs/src/ios/CDVNotification.h
new file mode 100644
index 00000000..9253f6a9
--- /dev/null
+++ b/StoneIsland/plugins/cordova-plugin-dialogs/src/ios/CDVNotification.h
@@ -0,0 +1,37 @@
+/*
+ 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>
+#import <UIKit/UIKit.h>
+#import <AudioToolbox/AudioServices.h>
+#import <Cordova/CDVPlugin.h>
+
+@interface CDVNotification : CDVPlugin <UIAlertViewDelegate>{}
+
+- (void)alert:(CDVInvokedUrlCommand*)command;
+- (void)confirm:(CDVInvokedUrlCommand*)command;
+- (void)prompt:(CDVInvokedUrlCommand*)command;
+- (void)beep:(CDVInvokedUrlCommand*)command;
+
+@end
+
+@interface CDVAlertView : UIAlertView {}
+@property (nonatomic, copy) NSString* callbackId;
+
+@end
diff --git a/StoneIsland/plugins/cordova-plugin-dialogs/src/ios/CDVNotification.m b/StoneIsland/plugins/cordova-plugin-dialogs/src/ios/CDVNotification.m
new file mode 100644
index 00000000..1581ad3c
--- /dev/null
+++ b/StoneIsland/plugins/cordova-plugin-dialogs/src/ios/CDVNotification.m
@@ -0,0 +1,221 @@
+/*
+ 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 "CDVNotification.h"
+
+#define DIALOG_TYPE_ALERT @"alert"
+#define DIALOG_TYPE_PROMPT @"prompt"
+
+static void soundCompletionCallback(SystemSoundID ssid, void* data);
+
+@implementation CDVNotification
+
+/*
+ * 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.
+ * defaultText The input text for the textbox (if textbox exists).
+ * callbackId The commmand callback id.
+ * dialogType The type of alert view [alert | prompt].
+ */
+- (void)showDialogWithMessage:(NSString*)message title:(NSString*)title buttons:(NSArray*)buttons defaultText:(NSString*)defaultText callbackId:(NSString*)callbackId dialogType:(NSString*)dialogType
+{
+
+ NSUInteger count = [buttons count];
+#ifdef __IPHONE_8_0
+ if (NSClassFromString(@"UIAlertController")) {
+
+ UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
+
+ if ([[[UIDevice currentDevice] systemVersion] floatValue] < 8.3) {
+
+ CGRect alertFrame = [UIScreen mainScreen].applicationFrame;
+
+ if (UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])) {
+ // swap the values for the app frame since it is now in landscape
+ CGFloat temp = alertFrame.size.width;
+ alertFrame.size.width = alertFrame.size.height;
+ alertFrame.size.height = temp;
+ }
+
+ alertController.view.frame = alertFrame;
+ }
+
+ for (int n = 0; n < count; n++) {
+
+ UIAlertAction* action = [UIAlertAction actionWithTitle:[buttons objectAtIndex:n] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action)
+ {
+ CDVPluginResult* result;
+
+ if ([dialogType isEqualToString:DIALOG_TYPE_PROMPT]) {
+
+ NSString* value0 = [[alertController.textFields objectAtIndex:0] text];
+ NSDictionary* info = @{
+ @"buttonIndex":@(n + 1),
+ @"input1":(value0 ? value0 : [NSNull null])
+ };
+ result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:info];
+
+ } else {
+
+ result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:(int)(n + 1)];
+
+ }
+
+ [self.commandDelegate sendPluginResult:result callbackId:callbackId];
+
+ }];
+ [alertController addAction:action];
+
+ }
+
+ if ([dialogType isEqualToString:DIALOG_TYPE_PROMPT]) {
+
+ [alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) {
+ textField.text = defaultText;
+ }];
+ }
+
+
+
+ [self.viewController presentViewController:alertController animated:YES completion:nil];
+
+ } else {
+#endif
+ CDVAlertView* alertView = [[CDVAlertView alloc]
+ initWithTitle:title
+ message:message
+ delegate:self
+ cancelButtonTitle:nil
+ otherButtonTitles:nil];
+
+ alertView.callbackId = callbackId;
+
+
+
+ for (int n = 0; n < count; n++) {
+ [alertView addButtonWithTitle:[buttons objectAtIndex:n]];
+ }
+
+ if ([dialogType isEqualToString:DIALOG_TYPE_PROMPT]) {
+ alertView.alertViewStyle = UIAlertViewStylePlainTextInput;
+ UITextField* textField = [alertView textFieldAtIndex:0];
+ textField.text = defaultText;
+ }
+
+ [alertView show];
+#ifdef __IPHONE_8_0
+ }
+#endif
+
+}
+
+- (void)alert:(CDVInvokedUrlCommand*)command
+{
+ NSString* callbackId = command.callbackId;
+ NSString* message = [command argumentAtIndex:0];
+ NSString* title = [command argumentAtIndex:1];
+ NSString* buttons = [command argumentAtIndex:2];
+
+ [self showDialogWithMessage:message title:title buttons:@[buttons] defaultText:nil callbackId:callbackId dialogType:DIALOG_TYPE_ALERT];
+}
+
+- (void)confirm:(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 defaultText:nil callbackId:callbackId dialogType:DIALOG_TYPE_ALERT];
+}
+
+- (void)prompt:(CDVInvokedUrlCommand*)command
+{
+ NSString* callbackId = command.callbackId;
+ NSString* message = [command argumentAtIndex:0];
+ NSString* title = [command argumentAtIndex:1];
+ NSArray* buttons = [command argumentAtIndex:2];
+ NSString* defaultText = [command argumentAtIndex:3];
+
+ [self showDialogWithMessage:message title:title buttons:buttons defaultText:defaultText callbackId:callbackId dialogType:DIALOG_TYPE_PROMPT];
+}
+
+/**
+ * Callback invoked when an alert dialog's buttons are clicked.
+ */
+- (void)alertView:(UIAlertView*)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
+{
+ CDVAlertView* cdvAlertView = (CDVAlertView*)alertView;
+ 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:(int)(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];
+}
+
+static void playBeep(int count) {
+ SystemSoundID completeSound;
+ NSInteger cbDataCount = count;
+ NSURL* audioPath = [[NSBundle mainBundle] URLForResource:@"CDVNotification.bundle/beep" withExtension:@"wav"];
+ #if __has_feature(objc_arc)
+ AudioServicesCreateSystemSoundID((__bridge CFURLRef)audioPath, &completeSound);
+ #else
+ AudioServicesCreateSystemSoundID((CFURLRef)audioPath, &completeSound);
+ #endif
+ AudioServicesAddSystemSoundCompletion(completeSound, NULL, NULL, soundCompletionCallback, (void*)(cbDataCount-1));
+ AudioServicesPlaySystemSound(completeSound);
+}
+
+static void soundCompletionCallback(SystemSoundID ssid, void* data) {
+ int count = (int)data;
+ AudioServicesRemoveSystemSoundCompletion (ssid);
+ AudioServicesDisposeSystemSoundID(ssid);
+ if (count > 0) {
+ playBeep(count);
+ }
+}
+
+- (void)beep:(CDVInvokedUrlCommand*)command
+{
+ NSNumber* count = [command argumentAtIndex:0 withDefault:[NSNumber numberWithInt:1]];
+ playBeep([count intValue]);
+}
+
+
+@end
+
+@implementation CDVAlertView
+
+@synthesize callbackId;
+
+@end
diff --git a/StoneIsland/plugins/cordova-plugin-dialogs/src/ubuntu/notification.cpp b/StoneIsland/plugins/cordova-plugin-dialogs/src/ubuntu/notification.cpp
new file mode 100644
index 00000000..d0adf892
--- /dev/null
+++ b/StoneIsland/plugins/cordova-plugin-dialogs/src/ubuntu/notification.cpp
@@ -0,0 +1,85 @@
+/*
+ *
+ * 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.
+ */
+
+#include "notification.h"
+
+#include <QApplication>
+
+void Dialogs::beep(int scId, int ecId, int times) {
+ Q_UNUSED(scId)
+ Q_UNUSED(ecId)
+ Q_UNUSED(times)
+
+ _player.setVolume(100);
+ _player.setMedia(QUrl::fromLocalFile("/usr/share/sounds/ubuntu/stereo/bell.ogg"));
+ _player.play();
+}
+
+void Dialogs::alert(int scId, int ecId, const QString &message, const QString &title, const QString &buttonLabel) {
+ QStringList list;
+ list.append(buttonLabel);
+
+ confirm(scId, ecId, message, title, list);
+}
+
+void Dialogs::confirm(int scId, int ecId, const QString &message, const QString &title, const QStringList &buttonLabels) {
+ Q_UNUSED(ecId);
+
+ if (_alertCallback) {
+ qCritical() << "can't open second dialog";
+ return;
+ }
+ _alertCallback = scId;
+
+ QString s1, s2, s3;
+ if (buttonLabels.size() > 0)
+ s1 = buttonLabels[0];
+ if (buttonLabels.size() > 1)
+ s2 = buttonLabels[1];
+ if (buttonLabels.size() > 2)
+ s3 = buttonLabels[2];
+
+ QString path = m_cordova->get_app_dir() + "/../qml/notification.qml";
+ QString qml = QString("PopupUtils.open(%1, root, { root: root, cordova: cordova, title: %2, text: %3, promptVisible: false, button1Text: %4, button2Text: %5, button3Text: %6 })")
+ .arg(CordovaInternal::format(path)).arg(CordovaInternal::format(title)).arg(CordovaInternal::format(message))
+ .arg(CordovaInternal::format(s1)).arg(CordovaInternal::format(s2)).arg(CordovaInternal::format(s3));
+
+ m_cordova->execQML(qml);
+}
+
+void Dialogs::prompt(int scId, int ecId, const QString &message, const QString &title, const QStringList &buttonLabels, const QString &defaultText) {
+ Q_UNUSED(ecId);
+
+ if (_alertCallback) {
+ qCritical() << "can't open second dialog";
+ return;
+ }
+ _alertCallback = scId;
+
+ QString s1, s2, s3;
+ if (buttonLabels.size() > 0)
+ s1 = buttonLabels[0];
+ if (buttonLabels.size() > 1)
+ s2 = buttonLabels[1];
+ if (buttonLabels.size() > 2)
+ s3 = buttonLabels[2];
+ QString path = m_cordova->get_app_dir() + "/../qml/notification.qml";
+ QString qml = QString("PopupUtils.open(%1, root, { root: root, cordova: cordova, title: %2, text: %3, promptVisible: true, defaultPromptText: %7, button1Text: %4, button2Text: %5, button3Text: %6 })")
+ .arg(CordovaInternal::format(path)).arg(CordovaInternal::format(title)).arg(CordovaInternal::format(message))
+ .arg(CordovaInternal::format(s1)).arg(CordovaInternal::format(s2))
+ .arg(CordovaInternal::format(s3)).arg(CordovaInternal::format(defaultText));
+
+ m_cordova->execQML(qml);
+}
diff --git a/StoneIsland/plugins/cordova-plugin-dialogs/src/ubuntu/notification.h b/StoneIsland/plugins/cordova-plugin-dialogs/src/ubuntu/notification.h
new file mode 100644
index 00000000..53430738
--- /dev/null
+++ b/StoneIsland/plugins/cordova-plugin-dialogs/src/ubuntu/notification.h
@@ -0,0 +1,64 @@
+/*
+ *
+ * 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.
+ */
+
+#ifndef NOTIFICATION_H
+#define NOTIFICATION_H
+
+#include <QtQuick>
+#include <QMediaPlayer>
+#include <cplugin.h>
+#include <cordova.h>
+
+class Dialogs: public CPlugin {
+ Q_OBJECT
+public:
+ explicit Dialogs(Cordova *cordova): CPlugin(cordova), _alertCallback(0) {
+ }
+
+ virtual const QString fullName() override {
+ return Dialogs::fullID();
+ }
+
+ virtual const QString shortName() override {
+ return "Notification";
+ }
+
+ static const QString fullID() {
+ return "Notification";
+ }
+public slots:
+ void beep(int scId, int ecId, int times);
+ void alert(int scId, int ecId, const QString &message, const QString &title, const QString &buttonLabel);
+ void confirm(int scId, int ecId, const QString &message, const QString &title, const QStringList &buttonLabels);
+ void prompt(int scId, int ecId, const QString &message, const QString &title, const QStringList &buttonLabels, const QString &defaultText);
+
+ void notificationDialogButtonPressed(int buttonId, const QString &text, bool prompt) {
+ if (prompt) {
+ QVariantMap res;
+ res.insert("buttonIndex", buttonId);
+ res.insert("input1", text);
+ this->cb(_alertCallback, res);
+ } else {
+ this->cb(_alertCallback, buttonId);
+ }
+ _alertCallback = 0;
+ }
+
+private:
+ int _alertCallback;
+ QMediaPlayer _player;
+};
+
+#endif
diff --git a/StoneIsland/plugins/cordova-plugin-dialogs/src/ubuntu/notification.qml b/StoneIsland/plugins/cordova-plugin-dialogs/src/ubuntu/notification.qml
new file mode 100644
index 00000000..5fdc7d31
--- /dev/null
+++ b/StoneIsland/plugins/cordova-plugin-dialogs/src/ubuntu/notification.qml
@@ -0,0 +1,65 @@
+/*
+ *
+ * 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 QtQuick 2.0
+import Ubuntu.Components.Popups 0.1
+import Ubuntu.Components 0.1
+
+Dialog {
+ id: dialogue
+ property string button1Text
+ property string button2Text
+ property string button3Text
+ property bool promptVisible
+ property string defaultPromptText
+
+ TextField {
+ id: prompt
+ text: defaultPromptText
+ visible: promptVisible
+ focus: true
+ }
+ Button {
+ text: button1Text
+ color: "orange"
+ onClicked: {
+ root.exec("Notification", "notificationDialogButtonPressed", [1, prompt.text, promptVisible]);
+ PopupUtils.close(dialogue)
+ }
+ }
+ Button {
+ text: button2Text
+ visible: button2Text.length > 0
+ color: "orange"
+ onClicked: {
+ root.exec("Notification", "notificationDialogButtonPressed", [2, prompt.text, promptVisible]);
+ PopupUtils.close(dialogue)
+ }
+ }
+ Button {
+ text: button3Text
+ visible: button3Text.length > 0
+ onClicked: {
+ root.exec("Notification", "notificationDialogButtonPressed", [3, prompt.text, promptVisible]);
+ PopupUtils.close(dialogue)
+ }
+ }
+}
diff --git a/StoneIsland/plugins/cordova-plugin-dialogs/src/windows/NotificationProxy.js b/StoneIsland/plugins/cordova-plugin-dialogs/src/windows/NotificationProxy.js
new file mode 100644
index 00000000..d1eb3448
--- /dev/null
+++ b/StoneIsland/plugins/cordova-plugin-dialogs/src/windows/NotificationProxy.js
@@ -0,0 +1,249 @@
+/*
+ *
+ * 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.
+ *
+*/
+
+/*global Windows:true */
+
+var cordova = require('cordova');
+
+var isAlertShowing = false;
+var alertStack = [];
+
+// CB-8928: When toStaticHTML is undefined, prompt fails to run
+function _cleanHtml(html) { return html; }
+if (typeof toStaticHTML !== 'undefined') {
+ _cleanHtml = toStaticHTML;
+}
+
+// Windows does not provide native UI for promp dialog so we use some
+// simple html-based implementation until it is available
+function createPromptDialog(title, message, buttons, defaultText, callback) {
+
+ var isPhone = cordova.platformId == "windows" && WinJS.Utilities.isPhone;;
+
+ var dlgWrap = document.createElement("div");
+ dlgWrap.style.position = "absolute";
+ dlgWrap.style.width = "100%";
+ dlgWrap.style.height = "100%";
+ dlgWrap.style.backgroundColor = "rgba(0,0,0,0.25)";
+ dlgWrap.style.zIndex = "100000";
+
+ var dlg = document.createElement("div");
+ dlg.style.width = "100%";
+ dlg.style.minHeight = "180px";
+ dlg.style.height = "auto";
+ dlg.style.overflow = "auto";
+ dlg.style.backgroundColor = "white";
+ dlg.style.position = "relative";
+ dlg.style.lineHeight = "2";
+
+ if (isPhone) {
+ dlg.style.padding = "0px 5%";
+ } else {
+ dlg.style.top = "50%"; // center vertically
+ dlg.style.transform = "translateY(-50%)";
+ dlg.style.padding = "0px 30%";
+ }
+
+ // dialog layout template
+ dlg.innerHTML = _cleanHtml("<span id='lbl-title' style='font-size: 24pt'></span><br/>" // title
+ + "<span id='lbl-message'></span><br/>" // message
+ + "<input id='prompt-input' style='width: 100%'/><br/>"); // input fields
+
+ dlg.querySelector('#lbl-title').appendChild(document.createTextNode(title));
+ dlg.querySelector('#lbl-message').appendChild(document.createTextNode(message));
+ dlg.querySelector('#prompt-input').setAttribute('placeholder', defaultText);
+
+ function makeButtonCallback(idx) {
+ return function () {
+ var value = promptInput = dlg.querySelector('#prompt-input').value;
+ dlgWrap.parentNode.removeChild(dlgWrap);
+
+ if (callback) {
+ callback({ input1: value, buttonIndex: idx });
+ }
+ }
+ }
+
+ function addButton(idx, label) {
+ var button = document.createElement('button');
+ button.style.margin = "8px 0 8px 16px";
+ button.style.float = "right";
+ button.style.fontSize = "12pt";
+ button.tabIndex = idx;
+ button.onclick = makeButtonCallback(idx + 1);
+ if (idx == 0) {
+ button.style.color = "white";
+ button.style.backgroundColor = "#464646";
+ } else {
+ button.style.backgroundColor = "#cccccc";
+ }
+ button.style.border = "none";
+ button.appendChild(document.createTextNode(label));
+ dlg.appendChild(button);
+ }
+
+ // reverse order is used since we align buttons to the right
+ for (var idx = buttons.length - 1; idx >= 0; idx--) {
+ addButton(idx, buttons[idx]);
+ }
+
+ dlgWrap.appendChild(dlg);
+ document.body.appendChild(dlgWrap);
+
+ // make sure input field is under focus
+ dlg.querySelector('#prompt-input').focus();
+
+ return dlgWrap;
+}
+
+module.exports = {
+ alert:function(win, loseX, args) {
+
+ if (isAlertShowing) {
+ var later = function () {
+ module.exports.alert(win, loseX, args);
+ };
+ alertStack.push(later);
+ return;
+ }
+ isAlertShowing = true;
+
+ var message = args[0];
+ var _title = args[1];
+ var _buttonLabel = args[2];
+
+ var md = new Windows.UI.Popups.MessageDialog(message, _title);
+ md.commands.append(new Windows.UI.Popups.UICommand(_buttonLabel));
+ md.showAsync().then(function() {
+ isAlertShowing = false;
+ win && win();
+
+ if (alertStack.length) {
+ setTimeout(alertStack.shift(), 0);
+ }
+
+ });
+ },
+
+ prompt: function (win, lose, args) {
+ if (isAlertShowing) {
+ var later = function () {
+ module.exports.prompt(win, lose, args);
+ };
+ alertStack.push(later);
+ return;
+ }
+
+ isAlertShowing = true;
+
+ var message = args[0],
+ title = args[1],
+ buttons = args[2],
+ defaultText = args[3];
+
+ try {
+ createPromptDialog(title, message, buttons, defaultText, function (evt) {
+ isAlertShowing = false;
+ if (win) {
+ win(evt);
+ }
+ });
+
+ } catch (e) {
+ // set isAlertShowing flag back to false in case of exception
+ isAlertShowing = false;
+ if (alertStack.length) {
+ setTimeout(alertStack.shift(), 0);
+ }
+ // rethrow exception
+ throw e;
+ }
+ },
+
+ confirm:function(win, loseX, args) {
+
+ if (isAlertShowing) {
+ var later = function () {
+ module.exports.confirm(win, loseX, args);
+ };
+ alertStack.push(later);
+ return;
+ }
+
+ isAlertShowing = true;
+
+ try {
+ var message = args[0];
+ var _title = args[1];
+ var buttons = args[2];
+
+ var md = new Windows.UI.Popups.MessageDialog(message, _title);
+
+ buttons.forEach(function(buttonLabel) {
+ md.commands.append(new Windows.UI.Popups.UICommand(buttonLabel));
+ });
+
+ md.showAsync().then(function(res) {
+ isAlertShowing = false;
+ var result = res ? buttons.indexOf(res.label) + 1 : 0;
+ win && win(result);
+ if (alertStack.length) {
+ setTimeout(alertStack.shift(), 0);
+ }
+
+ });
+ } catch (e) {
+ // set isAlertShowing flag back to false in case of exception
+ isAlertShowing = false;
+ if (alertStack.length) {
+ setTimeout(alertStack.shift(), 0);
+ }
+ // rethrow exception
+ throw e;
+ }
+ },
+
+ beep:function(winX, loseX, args) {
+
+ // set a default args if it is not set
+ args = args && args.length ? args : ["1"];
+
+ var snd = new Audio('ms-winsoundevent:Notification.Default');
+ var count = parseInt(args[0]) || 1;
+ snd.msAudioCategory = "Alerts";
+
+ var onEvent = function () {
+ if (count > 0) {
+ snd.play();
+ } else {
+ snd.removeEventListener("ended", onEvent);
+ snd = null;
+ winX && winX(); // notification.js just sends null, but this is future friendly
+ }
+ count--;
+ };
+ snd.addEventListener("ended", onEvent);
+ onEvent();
+
+ }
+};
+
+require("cordova/exec/proxy").add("Notification",module.exports);
diff --git a/StoneIsland/plugins/cordova-plugin-dialogs/src/wp/Notification.cs b/StoneIsland/plugins/cordova-plugin-dialogs/src/wp/Notification.cs
new file mode 100644
index 00000000..b6216848
--- /dev/null
+++ b/StoneIsland/plugins/cordova-plugin-dialogs/src/wp/Notification.cs
@@ -0,0 +1,482 @@
+/*
+ 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.Windows;
+using System.Windows.Controls;
+using Microsoft.Devices;
+using System.Runtime.Serialization;
+using System.Threading;
+using System.Windows.Resources;
+using Microsoft.Phone.Controls;
+using Microsoft.Xna.Framework.Audio;
+using WPCordovaClassLib.Cordova.UI;
+using System.Diagnostics;
+
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+ public class Notification : BaseCommand
+ {
+ static ProgressBar progressBar = null;
+ const int DEFAULT_DURATION = 5;
+
+ private NotificationBox notifyBox;
+
+ private class NotifBoxData
+ {
+ public NotificationBox previous {get;set;}
+ public string callbackId { get; set; }
+ }
+
+ private PhoneApplicationPage Page
+ {
+ get
+ {
+ PhoneApplicationPage page = null;
+ PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
+ if (frame != null)
+ {
+ page = frame.Content as PhoneApplicationPage;
+ }
+ return page;
+ }
+ }
+
+ // blink api - doesn't look like there is an equivalent api we can use...
+
+ [DataContract]
+ public class AlertOptions
+ {
+ [OnDeserializing]
+ public void OnDeserializing(StreamingContext context)
+ {
+ // set defaults
+ this.message = "message";
+ this.title = "Alert";
+ this.buttonLabel = "ok";
+ }
+
+ /// <summary>
+ /// message to display in the alert box
+ /// </summary>
+ [DataMember]
+ public string message;
+
+ /// <summary>
+ /// title displayed on the alert window
+ /// </summary>
+ [DataMember]
+ public string title;
+
+ /// <summary>
+ /// text to display on the button
+ /// </summary>
+ [DataMember]
+ public string buttonLabel;
+ }
+
+ [DataContract]
+ public class PromptResult
+ {
+ [DataMember]
+ public int buttonIndex;
+
+ [DataMember]
+ public string input1;
+
+ public PromptResult(int index, string text)
+ {
+ this.buttonIndex = index;
+ this.input1 = text;
+ }
+ }
+
+ public void alert(string options)
+ {
+ string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
+ AlertOptions alertOpts = new AlertOptions();
+ alertOpts.message = args[0];
+ alertOpts.title = args[1];
+ alertOpts.buttonLabel = args[2];
+ string aliasCurrentCommandCallbackId = args[3];
+
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ PhoneApplicationPage page = Page;
+ if (page != null)
+ {
+ Grid grid = page.FindName("LayoutRoot") as Grid;
+ if (grid != null)
+ {
+ var previous = notifyBox;
+ notifyBox = new NotificationBox();
+ notifyBox.Tag = new NotifBoxData { previous = previous, callbackId = aliasCurrentCommandCallbackId };
+ notifyBox.PageTitle.Text = alertOpts.title;
+ notifyBox.SubTitle.Text = alertOpts.message;
+ Button btnOK = new Button();
+ btnOK.Content = alertOpts.buttonLabel;
+ btnOK.Click += new RoutedEventHandler(btnOK_Click);
+ btnOK.Tag = 1;
+ notifyBox.ButtonPanel.Children.Add(btnOK);
+ grid.Children.Add(notifyBox);
+
+ if (previous == null)
+ {
+ page.BackKeyPress += page_BackKeyPress;
+ }
+ }
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.INSTANTIATION_EXCEPTION));
+ }
+ });
+ }
+
+ public void prompt(string options)
+ {
+ string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
+ string message = args[0];
+ string title = args[1];
+ string buttonLabelsArray = args[2];
+ string[] buttonLabels = JSON.JsonHelper.Deserialize<string[]>(buttonLabelsArray);
+ string defaultText = args[3];
+ string aliasCurrentCommandCallbackId = args[4];
+
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ PhoneApplicationPage page = Page;
+ if (page != null)
+ {
+ Grid grid = page.FindName("LayoutRoot") as Grid;
+ if (grid != null)
+ {
+ var previous = notifyBox;
+ notifyBox = new NotificationBox();
+ notifyBox.Tag = new NotifBoxData { previous = previous, callbackId = aliasCurrentCommandCallbackId };
+ notifyBox.PageTitle.Text = title;
+ notifyBox.SubTitle.Text = message;
+
+ //TextBox textBox = new TextBox();
+ //textBox.Text = defaultText;
+ //textBox.AcceptsReturn = true;
+ //notifyBox.ContentScroller.Content = textBox;
+
+ notifyBox.InputText.Text = defaultText;
+ notifyBox.InputText.Visibility = Visibility.Visible;
+
+ for (int i = 0; i < buttonLabels.Length; ++i)
+ {
+ Button button = new Button();
+ button.Content = buttonLabels[i];
+ button.Tag = i + 1;
+ button.Click += promptBoxbutton_Click;
+ notifyBox.ButtonPanel.Orientation = Orientation.Vertical;
+ notifyBox.ButtonPanel.Children.Add(button);
+ }
+
+ grid.Children.Add(notifyBox);
+ if (previous != null)
+ {
+ page.BackKeyPress += page_BackKeyPress;
+ }
+ }
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.INSTANTIATION_EXCEPTION));
+ }
+ });
+ }
+
+ public void confirm(string options)
+ {
+ string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
+ AlertOptions alertOpts = new AlertOptions();
+ alertOpts.message = args[0];
+ alertOpts.title = args[1];
+ alertOpts.buttonLabel = args[2];
+ string aliasCurrentCommandCallbackId = args[3];
+
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ PhoneApplicationPage page = Page;
+ if (page != null)
+ {
+ Grid grid = page.FindName("LayoutRoot") as Grid;
+ if (grid != null)
+ {
+ var previous = notifyBox;
+ notifyBox = new NotificationBox();
+ notifyBox.Tag = new NotifBoxData { previous = previous, callbackId = aliasCurrentCommandCallbackId };
+ notifyBox.PageTitle.Text = alertOpts.title;
+ notifyBox.SubTitle.Text = alertOpts.message;
+
+ string[] labels = JSON.JsonHelper.Deserialize<string[]>(alertOpts.buttonLabel);
+
+ if (labels == null)
+ {
+ labels = alertOpts.buttonLabel.Split(',');
+ }
+
+ for (int n = 0; n < labels.Length; n++)
+ {
+ Button btn = new Button();
+ btn.Content = labels[n];
+ btn.Tag = n;
+ btn.Click += new RoutedEventHandler(btnOK_Click);
+ notifyBox.ButtonPanel.Children.Add(btn);
+ }
+
+ grid.Children.Add(notifyBox);
+ if (previous == null)
+ {
+ page.BackKeyPress += page_BackKeyPress;
+ }
+ }
+ }
+ else
+ {
+ DispatchCommandResult(new PluginResult(PluginResult.Status.INSTANTIATION_EXCEPTION));
+ }
+ });
+ }
+
+ void promptBoxbutton_Click(object sender, RoutedEventArgs e)
+ {
+ Button button = sender as Button;
+ FrameworkElement promptBox = null;
+ int buttonIndex = 0;
+ string callbackId = string.Empty;
+ string text = string.Empty;
+ if (button != null)
+ {
+ buttonIndex = (int)button.Tag;
+ promptBox = button.Parent as FrameworkElement;
+ while ((promptBox = promptBox.Parent as FrameworkElement) != null &&
+ !(promptBox is NotificationBox)) ;
+ }
+
+ if (promptBox != null)
+ {
+ NotificationBox box = promptBox as NotificationBox;
+
+ text = box.InputText.Text;
+
+ PhoneApplicationPage page = Page;
+ if (page != null)
+ {
+ Grid grid = page.FindName("LayoutRoot") as Grid;
+ if (grid != null)
+ {
+ grid.Children.Remove(promptBox);
+ }
+
+ NotifBoxData data = promptBox.Tag as NotifBoxData;
+ promptBox = data.previous as NotificationBox;
+ callbackId = data.callbackId as string;
+
+ if (promptBox == null)
+ {
+ page.BackKeyPress -= page_BackKeyPress;
+ }
+ }
+ }
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new PromptResult(buttonIndex, text)), callbackId);
+ }
+
+ void page_BackKeyPress(object sender, System.ComponentModel.CancelEventArgs e)
+ {
+ PhoneApplicationPage page = sender as PhoneApplicationPage;
+ string callbackId = "";
+ if (page != null && notifyBox != null)
+ {
+ Grid grid = page.FindName("LayoutRoot") as Grid;
+ if (grid != null)
+ {
+ grid.Children.Remove(notifyBox);
+ NotifBoxData notifBoxData = notifyBox.Tag as NotifBoxData;
+ notifyBox = notifBoxData.previous as NotificationBox;
+ callbackId = notifBoxData.callbackId as string;
+ }
+ if (notifyBox == null)
+ {
+ page.BackKeyPress -= page_BackKeyPress;
+ }
+ e.Cancel = true;
+ }
+
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, 0), callbackId);
+ }
+
+ void btnOK_Click(object sender, RoutedEventArgs e)
+ {
+ Button btn = sender as Button;
+ FrameworkElement notifBoxParent = null;
+ int retVal = 0;
+ string callbackId = "";
+ if (btn != null)
+ {
+ retVal = (int)btn.Tag + 1;
+
+ notifBoxParent = btn.Parent as FrameworkElement;
+ while ((notifBoxParent = notifBoxParent.Parent as FrameworkElement) != null &&
+ !(notifBoxParent is NotificationBox)) ;
+ }
+ if (notifBoxParent != null)
+ {
+ PhoneApplicationPage page = Page;
+ if (page != null)
+ {
+ Grid grid = page.FindName("LayoutRoot") as Grid;
+ if (grid != null)
+ {
+ grid.Children.Remove(notifBoxParent);
+ }
+
+ NotifBoxData notifBoxData = notifBoxParent.Tag as NotifBoxData;
+ notifyBox = notifBoxData.previous as NotificationBox;
+ callbackId = notifBoxData.callbackId as string;
+
+ if (notifyBox == null)
+ {
+ page.BackKeyPress -= page_BackKeyPress;
+ }
+ }
+
+ }
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, retVal), callbackId);
+ }
+
+
+
+ public void beep(string options)
+ {
+ string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
+ int times = int.Parse(args[0]);
+
+ string resourcePath = BaseCommand.GetBaseURL() + "Plugins/cordova-plugin-dialogs/notification-beep.wav";
+
+ StreamResourceInfo sri = Application.GetResourceStream(new Uri(resourcePath, UriKind.Relative));
+
+ if (sri != null)
+ {
+ SoundEffect effect = SoundEffect.FromStream(sri.Stream);
+ SoundEffectInstance inst = effect.CreateInstance();
+ ThreadPool.QueueUserWorkItem((o) =>
+ {
+ // cannot interact with UI !!
+ do
+ {
+ inst.Play();
+ Thread.Sleep(effect.Duration + TimeSpan.FromMilliseconds(100));
+ }
+ while (--times > 0);
+
+ });
+
+ }
+
+ // TODO: may need a listener to trigger DispatchCommandResult after the alarm has finished executing...
+ DispatchCommandResult();
+ }
+
+ // Display an indeterminate progress indicator
+ public void activityStart(string unused)
+ {
+
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
+
+ if (frame != null)
+ {
+ PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
+
+ if (page != null)
+ {
+ var temp = page.FindName("LayoutRoot");
+ Grid grid = temp as Grid;
+ if (grid != null)
+ {
+ if (progressBar != null)
+ {
+ grid.Children.Remove(progressBar);
+ }
+ progressBar = new ProgressBar();
+ progressBar.IsIndeterminate = true;
+ progressBar.IsEnabled = true;
+
+ grid.Children.Add(progressBar);
+ }
+ }
+ }
+ });
+ }
+
+
+ // Remove our indeterminate progress indicator
+ public void activityStop(string unused)
+ {
+ Deployment.Current.Dispatcher.BeginInvoke(() =>
+ {
+ if (progressBar != null)
+ {
+ progressBar.IsEnabled = false;
+ PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
+ if (frame != null)
+ {
+ PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
+ if (page != null)
+ {
+ Grid grid = page.FindName("LayoutRoot") as Grid;
+ if (grid != null)
+ {
+ grid.Children.Remove(progressBar);
+ }
+ }
+ }
+ progressBar = null;
+ }
+ });
+ }
+
+ public void vibrate(string vibrateDuration)
+ {
+
+ int msecs = 200; // set default
+
+ try
+ {
+ string[] args = JSON.JsonHelper.Deserialize<string[]>(vibrateDuration);
+
+ msecs = int.Parse(args[0]);
+ if (msecs < 1)
+ {
+ msecs = 1;
+ }
+ }
+ catch (FormatException)
+ {
+
+ }
+
+ VibrateController.Default.Start(TimeSpan.FromMilliseconds(msecs));
+
+ // TODO: may need to add listener to trigger DispatchCommandResult when the vibration ends...
+ DispatchCommandResult();
+ }
+ }
+}
diff --git a/StoneIsland/plugins/cordova-plugin-dialogs/src/wp/NotificationBox.xaml b/StoneIsland/plugins/cordova-plugin-dialogs/src/wp/NotificationBox.xaml
new file mode 100644
index 00000000..2d564fba
--- /dev/null
+++ b/StoneIsland/plugins/cordova-plugin-dialogs/src/wp/NotificationBox.xaml
@@ -0,0 +1,79 @@
+<!--
+ 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.
+-->
+<UserControl x:Class="WPCordovaClassLib.Cordova.UI.NotificationBox"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ mc:Ignorable="d"
+ FontFamily="{StaticResource PhoneFontFamilyNormal}"
+ FontSize="{StaticResource PhoneFontSizeNormal}"
+ Foreground="{StaticResource PhoneForegroundBrush}"
+ d:DesignHeight="800" d:DesignWidth="480" VerticalAlignment="Stretch">
+
+ <!--TitlePanel contains the name of the application and page title-->
+ <Grid x:Name="LayoutRoot"
+ Background="{StaticResource PhoneSemitransparentBrush}">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="*"></RowDefinition>
+ </Grid.RowDefinitions>
+
+ <Grid x:Name="TitlePanel"
+ Grid.Row="0"
+ VerticalAlignment="Top"
+ Background="{StaticResource PhoneSemitransparentBrush}">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"></RowDefinition>
+ <RowDefinition Height="*"></RowDefinition>
+ <RowDefinition Height="Auto"></RowDefinition>
+ </Grid.RowDefinitions>
+
+ <TextBlock x:Name="PageTitle"
+ Text="Title"
+ Margin="10,10"
+ Grid.Row="0"
+ Style="{StaticResource PhoneTextTitle2Style}"/>
+
+ <ScrollViewer x:Name="ContentScroller"
+ Grid.Row="1"
+ MinHeight="120"
+ Margin="10,10">
+ <StackPanel Orientation="Vertical">
+ <TextBlock x:Name="SubTitle"
+ Text="Subtitle"
+ Width="Auto"
+ TextWrapping="Wrap"
+ Style="{StaticResource PhoneTextTitle3Style}"/>
+ <TextBox x:Name="InputText"
+ Visibility="Collapsed"/>
+ </StackPanel>
+ </ScrollViewer>
+
+ <ScrollViewer HorizontalScrollBarVisibility="Auto"
+ Grid.Row="2"
+ VerticalScrollBarVisibility="Disabled">
+ <StackPanel x:Name="ButtonPanel"
+ Margin="10,10"
+ Orientation="Horizontal"/>
+ </ScrollViewer>
+
+ </Grid>
+ </Grid>
+
+</UserControl>
diff --git a/StoneIsland/plugins/cordova-plugin-dialogs/src/wp/NotificationBox.xaml.cs b/StoneIsland/plugins/cordova-plugin-dialogs/src/wp/NotificationBox.xaml.cs
new file mode 100644
index 00000000..50b2f2a8
--- /dev/null
+++ b/StoneIsland/plugins/cordova-plugin-dialogs/src/wp/NotificationBox.xaml.cs
@@ -0,0 +1,41 @@
+/*
+ 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.
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Shapes;
+
+namespace WPCordovaClassLib.Cordova.UI
+{
+ public partial class NotificationBox : UserControl
+ {
+ public NotificationBox()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/StoneIsland/plugins/cordova-plugin-dialogs/src/wp/notification-beep.wav b/StoneIsland/plugins/cordova-plugin-dialogs/src/wp/notification-beep.wav
new file mode 100644
index 00000000..d0ad085f
--- /dev/null
+++ b/StoneIsland/plugins/cordova-plugin-dialogs/src/wp/notification-beep.wav
Binary files differ