PlanHubMe/PlanHub

View on GitHub
public/js/notify.js

Summary

Maintainability
A
3 hrs
Test Coverage
/*
 * Author: Alex Gibson
 * https://github.com/alexgibson/notify.js
 * License: MIT license
 */

(function(global, factory) {
    'use strict';

    if (typeof define === 'function' && define.amd) {
        // AMD environment
        define(function() {
            return factory(global, global.document);
        });
    } else if (typeof module !== 'undefined' && module.exports) {
        // CommonJS environment
        module.exports = factory(global, global.document);
    } else {
        // Browser environment
        global.Notify = factory(global, global.document);
    }
} (typeof window !== 'undefined' ? window : this, function (w, d) {
    'use strict';

    var N = w.Notification;

    function isFunction(item) {
        return typeof item === 'function';
    }

    function Notify(title, options) {

        if (typeof title !== 'string') {
            throw new Error('Notify(): first arg (title) must be a string.');
        }

        this.title = title;

        this.options = {
            icon: '',
            body: '',
            tag: '',
            lang: 'en',
            notifyShow: null,
            notifyClose: null,
            notifyClick: null,
            notifyError: null,
            timeout: null,
            requireInteraction: false,
            closeOnClick: false,
            silent: false
        };

        this.permission = null;

        //User defined options for notification content
        if (typeof options === 'object') {

            for (var i in options) {
                if (options.hasOwnProperty(i)) {
                    this.options[i] = options[i];
                }
            }

            //callback when notification is displayed
            if (isFunction(this.options.notifyShow)) {
                this.onShowCallback = this.options.notifyShow;
            }

            //callback when notification is closed
            if (isFunction(this.options.notifyClose)) {
                this.onCloseCallback = this.options.notifyClose;
            }

            //callback when notification is clicked
            if (isFunction(this.options.notifyClick)) {
                this.onClickCallback = this.options.notifyClick;
            }

            //callback when notification throws error
            if (isFunction(this.options.notifyError)) {
                this.onErrorCallback = this.options.notifyError;
            }
        }
    }

    // returns true if the browser supports Web Notifications
    // https://developers.google.com/web/updates/2015/05/Notifying-you-of-notificiation-changes
    // @param {perm} for test purposes only
    Notify.isSupported = function(perm) {
        if (!N || !N.requestPermission) {
            return false;
        }

        if (perm === 'granted' || N.permission === 'granted') {
            throw new Error('You must only call this before calling Notification.requestPermission(), otherwise this feature detect would trigger an actual notification!');
        }

        try {
            new N('');
        } catch (e) {
            if (e.name === 'TypeError') {
                return false;
            }
        }
        return true;
    };

    // true if the permission is not granted
    Notify.needsPermission = (N && N.permission && N.permission === 'granted') ? false : true;

    // asks the user for permission to display notifications.  Then calls the callback functions is supplied.
    Notify.requestPermission = function(onPermissionGrantedCallback, onPermissionDeniedCallback) {
        N.requestPermission(function(perm) {
            switch (perm) {
                case 'granted':
                    Notify.needsPermission = false;
                    if (isFunction(onPermissionGrantedCallback)) {
                        onPermissionGrantedCallback();
                    }
                    break;
                case 'denied':
                    Notify.needsPermission = true;
                    if (isFunction(onPermissionDeniedCallback)) {
                        onPermissionDeniedCallback();
                    }
                    break;
            }
        });
    };


    Notify.prototype.show = function() {
        this.myNotify = new N(this.title, {
            'body': this.options.body,
            'tag': this.options.tag,
            'icon': this.options.icon,
            'lang': this.options.lang,
            'requireInteraction': this.options.requireInteraction,
            'silent': this.options.silent,
            'closeOnClick': this.options.closeOnClick
        });

        if (!this.options.requireInteraction && this.options.timeout && !isNaN(this.options.timeout)) {
            setTimeout(this.close.bind(this), this.options.timeout * 1000);
        }

        this.myNotify.addEventListener('show', this, false);
        this.myNotify.addEventListener('error', this, false);
        this.myNotify.addEventListener('close', this, false);
        this.myNotify.addEventListener('click', this, false);
    };

    Notify.prototype.onShowNotification = function(e) {
        if (this.onShowCallback) {
            this.onShowCallback(e);
        }
    };

    Notify.prototype.onCloseNotification = function(e) {
        if (this.onCloseCallback) {
            this.onCloseCallback(e);
        }
        this.destroy();
    };

    Notify.prototype.onClickNotification = function(e) {
        if (this.onClickCallback) {
            this.onClickCallback(e);
        }

        if (this.options.closeOnClick) {
            this.close();
        }
    };

    Notify.prototype.onErrorNotification = function(e) {
        if (this.onErrorCallback) {
            this.onErrorCallback(e);
        }
        this.destroy();
    };

    Notify.prototype.destroy = function() {
        this.myNotify.removeEventListener('show', this, false);
        this.myNotify.removeEventListener('error', this, false);
        this.myNotify.removeEventListener('close', this, false);
        this.myNotify.removeEventListener('click', this, false);
    };

    Notify.prototype.close = function() {
        this.myNotify.close();
    };

    Notify.prototype.handleEvent = function(e) {
        switch (e.type) {
        case 'show':
            this.onShowNotification(e);
            break;
        case 'close':
            this.onCloseNotification(e);
            break;
        case 'click':
            this.onClickNotification(e);
            break;
        case 'error':
            this.onErrorNotification(e);
            break;
        }
    };

    return Notify;
}));