UNPKG

8.32 kBJavaScriptView Raw
1/*
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 */
21
22/* global Windows:true, WinJS, toStaticHTML */
23
24var cordova = require('cordova');
25var urlutil = require('cordova/urlutil');
26
27var isAlertShowing = false;
28var alertStack = [];
29
30function createCSSElem (fileName) {
31 var elemId = fileName.substr(0, fileName.lastIndexOf('.')) + '-plugin-style';
32 // If the CSS element exists, don't recreate it.
33 if (document.getElementById(elemId)) {
34 return false;
35 }
36
37 // Create CSS and append it to DOM.
38 var $elem = document.createElement('link');
39 $elem.id = elemId;
40 $elem.rel = 'stylesheet';
41 $elem.type = 'text/css';
42 $elem.href = urlutil.makeAbsolute('/www/css/' + fileName);
43
44 document.head.appendChild($elem);
45 return true;
46}
47
48// CB-8928: When toStaticHTML is undefined, prompt fails to run
49var _cleanHtml = function (html) { return html; };
50if (typeof toStaticHTML !== 'undefined') {
51 _cleanHtml = toStaticHTML;
52}
53
54// Windows does not provide native UI for promp dialog so we use some
55// simple html-based implementation until it is available
56function createPromptDialog (title, message, buttons, defaultText, callback) {
57
58 var isPhone = cordova.platformId === 'windows' && WinJS.Utilities.isPhone;
59 var isWindows = !!cordova.platformId.match(/windows/);
60
61 createCSSElem('notification.css');
62
63 var dlgWrap = document.createElement('div');
64 dlgWrap.className = 'dlgWrap';
65
66 var dlg = document.createElement('div');
67 dlg.className = 'dlgContainer';
68
69 if (isWindows) {
70 dlg.className += ' dlgContainer-windows';
71 } else if (isPhone) {
72 dlg.className += ' dlgContainer-phone';
73 }
74
75 // dialog layout template
76 dlg.innerHTML = _cleanHtml("<span id='lbl-title'></span><br/>" + // title
77 "<span id='lbl-message'></span><br/>" + // message
78 "<input id='prompt-input'/><br/>"); // input fields
79
80 dlg.querySelector('#lbl-title').appendChild(document.createTextNode(title));
81 dlg.querySelector('#lbl-message').appendChild(document.createTextNode(message));
82 dlg.querySelector('#prompt-input').setAttribute('placeholder', defaultText);
83 dlg.querySelector('#prompt-input').setAttribute('value', defaultText);
84
85 function makeButtonCallback (idx) {
86 return function () {
87 var value = dlg.querySelector('#prompt-input').value || defaultText;
88 dlgWrap.parentNode.removeChild(dlgWrap);
89
90 if (callback) {
91 callback({ input1: value, buttonIndex: idx }); // eslint-disable-line standard/no-callback-literal
92 }
93 };
94 }
95
96 function addButton (idx, label) {
97 var button = document.createElement('button');
98 button.className = 'dlgButton';
99 button.tabIndex = idx;
100 button.onclick = makeButtonCallback(idx + 1);
101 if (idx === 0) {
102 button.className += ' dlgButtonFirst';
103 }
104 button.appendChild(document.createTextNode(label));
105 dlg.appendChild(button);
106 }
107
108 // reverse order is used since we align buttons to the right
109 for (var idx = buttons.length - 1; idx >= 0; idx--) {
110 addButton(idx, buttons[idx]);
111 }
112
113 dlgWrap.appendChild(dlg);
114 document.body.appendChild(dlgWrap);
115
116 // make sure input field is under focus
117 dlg.querySelector('#prompt-input').select();
118 // add Enter/Return key handling
119 var defaultButton = dlg.querySelector('.dlgButtonFirst');
120 dlg.addEventListener('keypress', function (e) {
121 if (e.keyCode === 13) { // enter key
122 if (defaultButton) {
123 defaultButton.click();
124 }
125 }
126 });
127
128 return dlgWrap;
129}
130
131module.exports = {
132 alert: function (win, loseX, args) {
133
134 if (isAlertShowing) {
135 var later = function () {
136 module.exports.alert(win, loseX, args);
137 };
138 alertStack.push(later);
139 return;
140 }
141 isAlertShowing = true;
142
143 var message = args[0];
144 var _title = args[1];
145 var _buttonLabel = args[2];
146
147 var md = new Windows.UI.Popups.MessageDialog(message, _title);
148 md.commands.append(new Windows.UI.Popups.UICommand(_buttonLabel));
149 md.showAsync().then(function () {
150 isAlertShowing = false;
151 if (win) {
152 win();
153 }
154
155 if (alertStack.length) {
156 setTimeout(alertStack.shift(), 0);
157 }
158
159 });
160 },
161
162 prompt: function (win, lose, args) {
163 if (isAlertShowing) {
164 var later = function () {
165 module.exports.prompt(win, lose, args);
166 };
167 alertStack.push(later);
168 return;
169 }
170
171 isAlertShowing = true;
172
173 var message = args[0];
174 var title = args[1];
175 var buttons = args[2];
176 var defaultText = args[3];
177
178 try {
179 createPromptDialog(title, message, buttons, defaultText, function (evt) {
180 isAlertShowing = false;
181 if (win) {
182 win(evt);
183 }
184 });
185
186 } catch (e) {
187 // set isAlertShowing flag back to false in case of exception
188 isAlertShowing = false;
189 if (alertStack.length) {
190 setTimeout(alertStack.shift(), 0);
191 }
192 // rethrow exception
193 throw e;
194 }
195 },
196
197 confirm: function (win, loseX, args) {
198
199 if (isAlertShowing) {
200 var later = function () {
201 module.exports.confirm(win, loseX, args);
202 };
203 alertStack.push(later);
204 return;
205 }
206
207 isAlertShowing = true;
208
209 try {
210 var message = args[0];
211 var _title = args[1];
212 var buttons = args[2];
213
214 var md = new Windows.UI.Popups.MessageDialog(message, _title);
215
216 buttons.forEach(function (buttonLabel) {
217 md.commands.append(new Windows.UI.Popups.UICommand(buttonLabel));
218 });
219
220 md.showAsync().then(function (res) {
221 isAlertShowing = false;
222 var result = res ? buttons.indexOf(res.label) + 1 : 0;
223 if (win) {
224 win(result);
225 }
226 if (alertStack.length) {
227 setTimeout(alertStack.shift(), 0);
228 }
229
230 });
231 } catch (e) {
232 // set isAlertShowing flag back to false in case of exception
233 isAlertShowing = false;
234 if (alertStack.length) {
235 setTimeout(alertStack.shift(), 0);
236 }
237 // rethrow exception
238 throw e;
239 }
240 },
241
242 beep: function (winX, loseX, args) {
243
244 // set a default args if it is not set
245 args = args && args.length ? args : ['1'];
246
247 var snd = new Audio('ms-winsoundevent:Notification.Default'); // eslint-disable-line no-undef
248 var count = parseInt(args[0]) || 1;
249 snd.msAudioCategory = 'Alerts';
250
251 var onEvent = function () {
252 if (count > 0) {
253 snd.play();
254 } else {
255 snd.removeEventListener('ended', onEvent);
256 snd = null;
257 if (winX) {
258 winX(); // notification.js just sends null, but this is future friendly
259 }
260 }
261 count--;
262 };
263 snd.addEventListener('ended', onEvent);
264 onEvent();
265
266 }
267};
268
269require('cordova/exec/proxy').add('Notification', module.exports);