1/*global module: false, define: false */ 2 3/** 4 * 'showNotification' callback. 5 * 6 * @callback ShowNotificationCallback 7 * @param {error} [error] - The error object in case of any error 8 * @param {function} [hide] - The hide notification function 9 */ 10 11/** 12 * 'requestPermission' callback. 13 * 14 * @callback PermissionsRequestCallback 15 * @param {Boolean} granted - True if permission is granted, else false 16 */ 17 18/** 19 * A simplified web notification API. 20 * 21 * @name webNotification 22 * @namespace webNotification 23 * @author Sagie Gur-Ari 24 */ 25 26/** 27 * Initializes the web notification API. 28 * 29 * @function 30 * @memberof! webNotification 31 * @alias webNotification.initWebNotification 32 * @private 33 * @param {Object} global - The root context (window/global/...) 34 * @param {function} factory - Returns a new instance of the API 35 * @returns {Object} New instance of the API 36 */ 37(function initWebNotification(global, factory) { 38 'use strict'; 39 40 /*istanbul ignore next*/ 41 const NotificationAPI = global.Notification || window.Notification; 42 43 const webNotification = factory(NotificationAPI); 44 45 /** 46 * Initializes the web notification API (only used for testing). 47 * 48 * @function 49 * @memberof! webNotification 50 * @alias webNotification.initWebNotificationFromContext 51 * @private 52 * @param {Object} context - The root context (window/global/...) 53 * @returns {Object} New instance of the API 54 */ 55 webNotification.initWebNotificationFromContext = function (context) { 56 return initWebNotification(context, factory); 57 }; 58 59 if ((typeof define === 'function') && define.amd) { 60 define(function defineLib() { 61 return webNotification; 62 }); 63 } else if ((typeof module === 'object') && module.exports) { 64 module.exports = webNotification; 65 } else { 66 global.webNotification = webNotification; 67 } 68 69 return webNotification; 70}(this, function initWebNotification(NotificationAPI) { 71 'use strict'; 72 73 let tagCounter = 0; 74 let localTag = ''; 75 76 const webNotification = {}; 77 78 /** 79 * The internal Notification library used by this library. 80 * 81 * @memberof! webNotification 82 * @alias webNotification.lib 83 * @private 84 */ 85 webNotification.lib = NotificationAPI; 86 87 /** 88 * True to enable automatic requesting of permissions if needed. 89 * 90 * @member {Boolean} 91 * @memberof! webNotification 92 * @alias webNotification.allowRequest 93 * @public 94 */ 95 webNotification.allowRequest = true; //true to enable automatic requesting of permissions if needed 96 97 /*eslint-disable func-name-matching*/ 98 Object.defineProperty(webNotification, 'permissionGranted', { 99 /** 100 * Returns the permission granted value. 101 * 102 * @function 103 * @memberof! webNotification 104 * @private 105 * @returns {Boolean} True if permission is granted, else false 106 */ 107 get: function getPermission() { 108 const permission = NotificationAPI.permission; 109 110 /** 111 * True if permission is granted, else false. 112 * 113 * @memberof! webNotification 114 * @alias webNotification.permissionGranted 115 * @public 116 */ 117 let permissionGranted = false; 118 if (permission === 'granted') { 119 permissionGranted = true; 120 } 121 122 return permissionGranted; 123 } 124 }); 125 /*eslint-enable func-name-matching*/ 126 127 /** 128 * Empty function. 129 * 130 * @function 131 * @memberof! webNotification 132 * @alias webNotification.noop 133 * @private 134 * @returns {undefined} Undefined 135 */ 136 const noop = function () { 137 return undefined; 138 }; 139 140 /** 141 * Checks if web notifications are permitted. 142 * 143 * @function 144 * @memberof! webNotification 145 * @alias webNotification.isEnabled 146 * @private 147 * @returns {Boolean} True if allowed to show web notifications 148 */ 149 const isEnabled = function () { 150 return webNotification.permissionGranted; 151 }; 152 153 /**
154 * Displays the web notification and returning a 'hide' notification function. 155 * 156 * @function 157 * @memberof! webNotification 158 * @alias webNotification.createAndDisplayNotification 159 * @private 160 * @param {String} title - The notification title text (defaulted to empty string if null is provided) 161 * @param {Object} options - Holds the notification data (web notification API spec for more info) 162 * @param {String} [options.icon=/favicon.ico] - The notification icon (defaults to the website favicon.ico) 163 * @param {Number} [options.autoClose] - Auto closes the notification after the provided amount of millies (0 or undefined for no auto close) 164 * @param {function} [options.onClick] - An optional onclick event handler 165 * @param {Object} [options.serviceWorkerRegistration] - Optional service worker registeration used to show the notification 166 * @param {ShowNotificationCallback} callback - Invoked with either an error or the hide notification function 167 */ 168 const createAndDisplayNotification = function (title, options, callback) { 169 let autoClose = 0; 170 if (options.autoClose && (typeof options.autoClose === 'number')) { 171 autoClose = options.autoClose; 172 } 173 174 //defaults the notification icon to the website favicon.ico 175 if (!options.icon) { 176 options.icon = '/Styles/Images/favicon.ico'; 177 } 178 179 const onNotification = function (notification) { 180 //add onclick handler 181 182 if (options.onClick && notification) { 183 notification.onclick = options.onClick; 184 } 185 186 const hideNotification = function () { 187 notification.close(); 188 }; 189 190 if (autoClose) { 191 setTimeout(hideNotification, autoClose); 192 } 193 194 callback(null, hideNotification); 195 }; 196 197 if (tagCounter == 1) 198 return; 199 200 console.log("Tag " +options.tag); 201 console.log("Local Tag "+localTag); 202 if (localTag && localTag === options.tag) { 203 localTag = ''; 204 return; 205 } else { 206 localTag = options.tag; 207 } 208 209 if (!options.tag) { 210 tagCounter++; 211 options.tag = 'webnotification-' + Date.now() + '-' + tagCounter; 212 } 213 214 const serviceWorkerRegistration = options.serviceWorkerRegistration; 215 if (serviceWorkerRegistration) { 216 delete options.serviceWorkerRegistration; 217 218 const tag = options.tag; 219 220 serviceWorkerRegistration.showNotification(title, options).then(function onCreate() { 221 serviceWorkerRegistration.getNotifications({ 222 tag 223 }).then(function notificationsFetched(notifications) { 224 if (notifications && notifications.length) { 225 onNotification(notifications[0]); 226 } else { 227 callback(new Error('Unable to find notification.')); 228 } 229 }).catch(callback); 230 }).catch(callback); 231 } else { 232 let instance; 233 try { 234 instance = new NotificationAPI(title, options); 235 } catch (error) { 236 callback(error); 237 } 238 239 //in case of no errors 240 if (instance) { 241 onNotification(instance); 242 } 243 } 244 }; 245 246 /** 247 * Returns an object with the show notification input. 248 * 249 * @function 250 * @memberof! webNotification 251 * @alias webNotification.parseInput 252 * @private 253 * @param {Array} argumentsArray - An array of all arguments provided to the show notification function 254 * @returns {Object} The parsed data 255 */ 256 const parseInput = function (argumentsArray) { 257 //callback is always the last argument 258 let callback = noop; 259 if (argumentsArray.length && (typeof argumentsArray[argumentsArray.length - 1] === 'function')) { 260 callback = argumentsArray.pop(); 261 } 262 263 let title = null; 264 let options = null; 265 if (argumentsArray.length === 2) { 266 title = argumentsArray[0]; 267 options = argumentsArray[1]; 268 } else if (argumentsArray.length === 1) { 269 const value = argumentsArray.pop(); 270 if (typeof value === 'string') { 271 title = value; 272 options = {}; 273 } else { 274 title = ''; 275 options = value; 276 } 277 } 278 279 //set defaults 280 title = title || ''; 281 options = options || {}; 282 283 return { 284 callback, 285 title, 286 options 287 }; 288 }; 289 290 /** 291 * Triggers the request permissions dialog in case permissions were not already granted. 292 * 293 * @function 294 * @memberof! webNotification 295 * @alias webNotification.requestPermission 296 * @public 297 * @param {PermissionsRequestCallback} callback - Called with the permissions result (true enabled, false disabled) 298 * @example 299 * ```js 300 * //manually ask for notification permissions (invoked automatically if needed and allowRequest=true) 301 * webNotification.requestPermission(function onRequest(granted) { 302 * if (granted) { 303 * console.log('Permission Granted.'); 304 * } else { 305 * console.log('Permission Not Granted.'); 306 * } 307 * }); 308 * ``` 309 */ 310 webNotification.requestPermission = function (callback) { 311 if (callback && typeof callback === 'function') { 312 if (isEnabled()) { 313 callback(true); 314 } else { 315 NotificationAPI.requestPermission(function onRequestDone() { 316 callback(isEnabled()); 317 }); 318 } 319 } 320 }; 321 322 /** 323 * Shows the notification based on the provided input.<br> 324 * The callback invoked will get an error object (in case of an error, null in 325 * case of no errors) and a 'hide' function which can be used to hide the notification. 326 * 327 * @function 328 * @memberof! webNotification 329 * @alias webNotification.showNotification 330 * @public 331 * @param {String} [title] - The notification title text (defaulted to empty string if null is provided) 332 * @param {Object} [options] - Holds the notification data (web notification API spec for more info) 333 * @param {String} [options.icon=/favicon.ico] - The notification icon (defaults to the website favicon.ico) 334 * @param {Number} [options.autoClose] - Auto closes the notification after the provided amount of millies (0 or undefined for no auto close) 335 * @param {function} [options.onClick] - An optional onclick event handler 336 * @param {Object} [options.serviceWorkerRegistration] - Optional service worker registeration used to show the notification 337 * @param {ShowNotificationCallback} [callback] - Called after the show is handled. 338 * @example 339 * ```js 340 * //show web notification when button is clicked 341 * document.querySelector('.some-button').addEventListener('click', function onClick() { 342 * webNotification.showNotification('Example Notification', { 343 * body: 'Notification Text...', 344 * icon: 'my-icon.ico', 345 * onClick: function onNotificationClicked() { 346 * console.log('Notification clicked.'); 347 * }, 348 * autoClose: 4000 //auto close the notification after 4 seconds (you can manually close it via hide function) 349 * }, function onShow(error, hide) { 350 * if (error) { 351 * window.alert('Unable to show notification: ' + error.message); 352 * } else { 353 * console.log('Notification Shown.'); 354 * 355 * setTimeout(function hideNotification() { 356 * console.log('Hiding notification....'); 357 * hide(); //manually close the notification (you can skip this if you use the autoClose option) 358 * }, 5000); 359 * } 360 * }); 361 * }); 362 * 363 * //service worker example 364 * navigator.serviceWorker.register('service-worker.js').then(function(registration) { 365 * document.querySelector('.some-button').addEventListener('click', function onClick() { 366 * webNotification.showNotification('Example Notification', { 367 * serviceWorkerRegistration: registration, 368 * body: 'Notification Text...', 369 * icon: 'my-icon.ico', 370 * actions: [ 371 * { 372 * action: 'Start', 373 * title: 'Start' 374 * }, 375 * { 376 * action: 'Stop', 377 * title: 'Stop' 378 * } 379 * ], 380 * autoClose: 4000 //auto close the notification after 4 seconds (you can manually close it via hide function) 381 * }, function onShow(error, hide) { 382 * if (error) { 383 * window.alert('Unable to show notification: ' + error.message); 384 * } else { 385 * console.log('Notification Shown.'); 386 * 387 * setTimeout(function hideNotification() { 388 * console.log('Hiding notification....'); 389 * hide(); //manually close the notification (you can skip this if you use the autoClose option) 390 * }, 5000); 391 * } 392 * }); 393 * }); 394 * }); 395 * ``` 396 */ 397 webNotification.showNotification = function () { 398 //convert to array to enable modifications 399 const argumentsArray = Array.prototype.slice.call(arguments, 0); 400 401 if ((argumentsArray.length >= 1) && (argumentsArray.length <= 3)) { 402 const data = parseInput(argumentsArray); 403 404 //get values 405 const callback = data.callback; 406 const title = data.title; 407 const options = data.options; 408 409 webNotification.requestPermission(function onRequestDone(granted) { 410 if (granted) { 411 createAndDisplayNotification(title, options, callback); 412 } else { 413 callback(new Error('Notifications are not enabled.'), null); 414 } 415 }); 416 } 417 }; 418 419 return webNotification; 420}));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.