From 03f263f50a706bb1c779eb0458e2fa46e484e7ad Mon Sep 17 00:00:00 2001 From: Peter Dave Hello Date: Thu, 23 Oct 2014 22:59:53 +0800 Subject: [PATCH] add noti.js, close #3940 --- ajax/libs/noti.js/0.9-beta.5/noti.js | 281 +++++++++++++++++++++++ ajax/libs/noti.js/0.9-beta.5/noti.min.js | 10 + ajax/libs/noti.js/package.json | 42 ++++ 3 files changed, 333 insertions(+) create mode 100644 ajax/libs/noti.js/0.9-beta.5/noti.js create mode 100644 ajax/libs/noti.js/0.9-beta.5/noti.min.js create mode 100644 ajax/libs/noti.js/package.json diff --git a/ajax/libs/noti.js/0.9-beta.5/noti.js b/ajax/libs/noti.js/0.9-beta.5/noti.js new file mode 100644 index 000000000..282cb2882 --- /dev/null +++ b/ajax/libs/noti.js/0.9-beta.5/noti.js @@ -0,0 +1,281 @@ +/** +* noti.js +* https://github.com/j-l-n/noti.js/ +* +* @author: j-l-n (https://github.com/j-l-n) +* @version: 0.9-beta.5 +* @lastModified: 17/10/2014 (DD/MM/YYYY) +*/ + + +(function(window){ + "use strict"; + + + //helper function to check if document has focus + var isFocused; + isFocused = function isFocused(){ + var hasFocus; + if(typeof window.opera !== "undefined"){ //Opera does not support document.hasFocus() (more information: http://caniuse.com/#feat=pagevisibility) + if(typeof document.hidden !== "undefined"){ //Opera 12.1 and ≥ 20 support the standard Page Visibility API + hasFocus = !document.hidden; + } + else if(typeof document.webkitHidden !== "undefined"){ //Opera 15-19: Page Visibility API supported with prefix "webkit" + hasFocus = !document.webkitHidden; + } + } + else{ + hasFocus = document.hasFocus(); + } + return hasFocus; + }; + + + var noti; + noti = { + checkSupport: function(){ + var notificationsSupported; + if(window.Notification){ + notificationsSupported = true; + } + else { + notificationsSupported = false; + } + return notificationsSupported; + }, + askForPermission: function(){ + if(noti.checkSupport() === true){ + if(window.Notification.permission === "default"){ + console.log("Asking for notification permission..."); + window.Notification.requestPermission(function(){ + if(window.Notification.permission === "granted"){ + console.info("Permission for web notifications granted."); + } + else if(window.Notification.permission === "denied"){ + console.warn("Permission for web notifications denied."); + } + }); + } + else if(window.Notification.permission === "granted"){ + console.info("Permission for web notifications granted."); + } + else { + console.warn("Permission for web notifications denied."); + } + } + }, + create: function(notificationArguments){ + if(typeof notificationArguments !== "object"){ + throw new Error("No arguments were passed to function."); + } + else if(typeof notificationArguments.title !== "string" || typeof notificationArguments.message !== "string"){ + throw new Error("Title or content of notification is undefined."); + } + var debugMode; + debugMode = false; + if(notificationArguments.debug_alwaysFallback === true){ + debugMode = true; + } + var changeTitle, createAudio, callback, fallbackNotification, showNotification; + changeTitle = function(){ + var interval; + if(notificationArguments.changeTitle_interval){ + interval = notificationArguments.changeTitle_interval * 1000; + } + else { + interval = 1500; //default interval: change title all 1.5s + } + var originalTitle; + originalTitle = document.title; + var titleChangingInterval; + titleChangingInterval = setInterval(function(){ + if(isFocused()){ + clearInterval(titleChangingInterval); + document.title = originalTitle; + } + else { + var newTitle; + if(document.title === originalTitle){ + if(notificationArguments.changeTitle_prefix){ + newTitle = notificationArguments.changeTitle_prefix + " " + originalTitle; + } + else { + newTitle = notificationArguments.title + " - " + originalTitle; + } + } + else { + newTitle = originalTitle; + } + document.title = newTitle; + } + }, interval); + }; + createAudio = function(ogg, mp3){ + var audio, audioSource; + audio = document.createElement("audio"); + audio.preload = "auto"; + audioSource = document.createElement("source"); //browser with support for ogg + audioSource.type = "audio/ogg"; + audioSource.src = ogg; + audio.appendChild(audioSource); + audioSource = document.createElement("source"); //browser with support for mp3 + audioSource.type = "audio/mpeg"; + audioSource.src = mp3; + audio.appendChild(audioSource); + return audio; + }; + callback = function(id){ //this function is called when user closes notification + console.log("Closed notification " + id); + if(typeof notificationArguments.callback === "function"){ //if user defined callback, call that function + notificationArguments.callback(); + } + }; + fallbackNotification = function(notificationTitle, notificationMessage, notificationId){ + changeTitle(); + if(playAudio){ + var sound; + sound = createAudio(notificationArguments.oggSoundFile, notificationArguments.mp3SoundFile); + sound.onloadeddata = function(){ + sound.play(); + }; + } + if(notificationArguments.dontShowAlert){ + var showAlertActive; + showAlertActive = false; + if(notificationArguments.dontShowAlert !== true){ + var showAlertAfter; + if(notificationArguments.showAlertAfter){ + showAlertAfter = notificationArguments.showAlertAfter * 1000; + } + else { + showAlertAfter = 60000; //default: 60 seconds + } + showAlertActive = setTimeout(function(){ //show alert after specified time in order to get focus and thus users attention + window.focus(); //opens minimized window in IE + alert(notificationTitle + "\n\n" + notificationMessage); + }, showAlertAfter); + } + var checkFocus; + checkFocus = setInterval(function(){ + if(isFocused()){ + if(showAlertActive !== false){ + clearTimeout(showAlertActive); + } + clearInterval(checkFocus); + callback(notificationId); + } + }, 100); + } + }; + showNotification = function(title, options){ + changeTitle(); + var notification, checkFocus; + notification = new window.Notification(title, options); + checkFocus = setInterval(function(){ //auto close notification if tab gets focus back + if(isFocused()){ + notification.close(); + clearInterval(checkFocus); + } + }, 100); + if(typeof window.mozInnerScreenX !== "undefined"){ //if browser is Firefox + //workaround for bug 875114 ("Web notifications should optionally be permanent, not automatically close after 4 seconds" + //more information: https://bugzilla.mozilla.org/show_bug.cgi?id=875114 + notification.onshow = function(){ + console.log("Showing notification " + notification.tag); + var showAgain = setTimeout(function(){ + notification.onclose = function(){}; //remove event listener so that close event is not fired if notification closed by script + notification.close(); //close notification and... + showNotification(title, options); //...create new + }, 3700); + notification.onclose = function(){ //close event is fired (closed by user) + clearTimeout(showAgain); //stop continually sending the notification again + clearInterval(checkFocus); + callback(notification.tag); + }; + }; + } + else { //other browser with support for web notification + notification.onshow = function(){ + console.log("Showing notification " + notification.tag); + }; + notification.onclose = function(){ + clearInterval(checkFocus); + callback(notification.tag); + }; + } + }; + //play sound during notification? + var playAudio, canPlayAudio; + playAudio = false; + canPlayAudio = typeof document.createElement("audio").play; + if(canPlayAudio === "function"){ //browser can play HTML5 audio + if(notificationArguments.playSound === true){ + if(notificationArguments.oggSoundFile && notificationArguments.mp3SoundFile){ + var oggSoundFile, mp3SoundFile; + oggSoundFile = notificationArguments.oggSoundFile; + mp3SoundFile = notificationArguments.mp3SoundFile; + playAudio = true; + } + else if(notificationArguments.oggSoundFile || notificationArguments.mp3SoundFile){ + throw new Error("If sound file should be played during notification, it must be present both in ogg format and in mp3."); + } + else { + throw new Error("No sound file defined."); + } + } + } + else { + console.warn("Browser does not support HTML5 audio."); + } + //set up notification + var notificationTitle, notificationMessage, notificationId; + notificationTitle = notificationArguments.title; + notificationMessage = notificationArguments.message; + notificationId = new Date().getTime(); + if(noti.checkSupport() === true && debugMode === false){ + if(window.Notification.permission === "granted"){ + var notificationOptions; + notificationOptions = { + dir: "auto", + lang: "de", + body: notificationMessage, + tag: notificationId + }; + if(notificationArguments.icon){ + NotificationOptions.icon = notificationArguments.icon; + } + if(playAudio){ + var sound; + sound = createAudio(notificationArguments.oggSoundFile, notificationArguments.mp3SoundFile); + sound.onloadeddata = function(){ + showNotification(notificationTitle, notificationOptions); + sound.play(); + }; + } + else{ + showNotification(notificationTitle, notificationOptions); + } + } + else{ //if permission for web notifications denied + console.info("Permission for web notification denied. Falling back to alert."); + fallbackNotification(notificationTitle, notificationMessage, notificationId); + } + } + else{ //if web notifications are not supported + console.info("Your browser does not support web notifications! Falling back to alert."); + fallbackNotification(notificationTitle, notificationMessage, notificationId); + } + return notificationId; + } + }; + + + if(noti.checkSupport() === true){ + noti.askForPermission(); + } + + + window.noti = noti; //make accessible in global namespace + + +})(window); diff --git a/ajax/libs/noti.js/0.9-beta.5/noti.min.js b/ajax/libs/noti.js/0.9-beta.5/noti.min.js new file mode 100644 index 000000000..a0ba9a9c7 --- /dev/null +++ b/ajax/libs/noti.js/0.9-beta.5/noti.min.js @@ -0,0 +1,10 @@ +/** +* noti.js +* https://github.com/j-l-n/noti.js/ +* +* @author: j-l-n (https://github.com/j-l-n) +* @version: 0.9-beta.5 (minified) +* @lastModified: 17/10/2014 (DD/MM/YYYY) +*/ + +(function(e){"use strict";var t;t=function(){var n;if(typeof e.opera!=="undefined"){if(typeof document.hidden!=="undefined"){n=!document.hidden}else if(typeof document.webkitHidden!=="undefined"){n=!document.webkitHidden}}else{n=document.hasFocus()}return n};var n;n={checkSupport:function(){var t;if(e.Notification){t=true}else{t=false}return t},askForPermission:function(){if(n.checkSupport()===true){if(e.Notification.permission==="default"){console.log("Asking for notification permission...");e.Notification.requestPermission(function(){if(e.Notification.permission==="granted"){console.info("Permission for web notifications granted.")}else if(e.Notification.permission==="denied"){console.warn("Permission for web notifications denied.")}})}else if(e.Notification.permission==="granted"){console.info("Permission for web notifications granted.")}else{console.warn("Permission for web notifications denied.")}}},create:function(r){if(typeof r!=="object"){throw new Error("No arguments were passed to function.")}else if(typeof r.title!=="string"||typeof r.message!=="string"){throw new Error("Title or content of notification is undefined.")}var i;i=false;if(r.debug_alwaysFallback===true){i=true}var s,o,u,a,f;s=function(){var e;if(r.changeTitle_interval){e=r.changeTitle_interval*1e3}else{e=1500}var n;n=document.title;var i;i=setInterval(function(){if(t()){clearInterval(i);document.title=n}else{var e;if(document.title===n){if(r.changeTitle_prefix){e=r.changeTitle_prefix+" "+n}else{e=r.title+" - "+n}}else{e=n}document.title=e}},e)};o=function(e,t){var n,r;n=document.createElement("audio");n.preload="auto";r=document.createElement("source");r.type="audio/ogg";r.src=e;n.appendChild(r);r=document.createElement("source");r.type="audio/mpeg";r.src=t;n.appendChild(r);return n};u=function(e){console.log("Closed notification "+e);if(typeof r.callback==="function"){r.callback()}};a=function(n,i,a){s();if(l){var f;f=o(r.oggSoundFile,r.mp3SoundFile);f.onloadeddata=function(){f.play()}}if(r.dontShowAlert){var c;c=false;if(r.dontShowAlert!==true){var h;if(r.showAlertAfter){h=r.showAlertAfter*1e3}else{h=6e4}c=setTimeout(function(){e.focus();alert(n+"\n\n"+i)},h)}var p;p=setInterval(function(){if(t()){if(c!==false){clearTimeout(c)}clearInterval(p);u(a)}},100)}};f=function(n,r){s();var i,o;i=new e.Notification(n,r);o=setInterval(function(){if(t()){i.close();clearInterval(o)}},100);if(typeof e.mozInnerScreenX!=="undefined"){i.onshow=function(){console.log("Showing notification "+i.tag);var e=setTimeout(function(){i.onclose=function(){};i.close();f(n,r)},3700);i.onclose=function(){clearTimeout(e);clearInterval(o);u(i.tag)}}}else{i.onshow=function(){console.log("Showing notification "+i.tag)};i.onclose=function(){clearInterval(o);u(i.tag)}}};var l,c;l=false;c=typeof document.createElement("audio").play;if(c==="function"){if(r.playSound===true){if(r.oggSoundFile&&r.mp3SoundFile){var h,p;h=r.oggSoundFile;p=r.mp3SoundFile;l=true}else if(r.oggSoundFile||r.mp3SoundFile){throw new Error("If sound file should be played during notification, it must be present both in ogg format and in mp3.")}else{throw new Error("No sound file defined.")}}}else{console.warn("Browser does not support HTML5 audio.")}var d,v,m;d=r.title;v=r.message;m=(new Date).getTime();if(n.checkSupport()===true&&i===false){if(e.Notification.permission==="granted"){var g;g={dir:"auto",lang:"de",body:v,tag:m};if(r.icon){NotificationOptions.icon=r.icon}if(l){var y;y=o(r.oggSoundFile,r.mp3SoundFile);y.onloadeddata=function(){f(d,g);y.play()}}else{f(d,g)}}else{console.info("Permission for web notification denied. Falling back to alert.");a(d,v,m)}}else{console.info("Your browser does not support web notifications! Falling back to alert.");a(d,v,m)}return m}};if(n.checkSupport()===true){n.askForPermission()}e.noti=n})(window) diff --git a/ajax/libs/noti.js/package.json b/ajax/libs/noti.js/package.json new file mode 100644 index 000000000..8eb80de42 --- /dev/null +++ b/ajax/libs/noti.js/package.json @@ -0,0 +1,42 @@ +{ + "name": "noti.js", + "description": "easy create cross-browser web notifications, with fallback for non-supporting browsers and other features", + "filename": "noti.min.js", + "version": "0.9-beta.5", + "author": "j-l-n (https://github.com/j-l-n)", + "homepage": "https://github.com/j-l-n/noti.js/", + "main": "noti.min.js", + "licenses": [ + { + "type": "GNU GPL v2", + "url": "http://www.gnu.org/licenses/gpl-2.0.txt" + } + ], + "keywords": [ + "noti.js", + "notification", + "notifications", + "web notification", + "web notifications", + "html5 notification", + "html5 notifications" + ], + "repositories": [ + { + "type": "git", + "url": "https://github.com/j-l-n/noti.js.git" + } + ], + "autoupdate": { + "source": "git", + "target": "git://github.com/j-l-n/noti.js", + "basePath": "", + "files": [ + "noti.js", + "noti.min.js" + ] + }, + "bugs": { + "url": "https://github.com/j-l-n/noti.js/issues" + } +}