<commit_before>import angular from 'angular'
import angularAnimate from 'angular-animate'
import angularNotifyToaster from 'angular-notify-toaster'

const {isString} = angular

// ===================================================================

// High level integration of XO API in xo-web.
export default angular.module('xo-notify', [
  angularAnimate,
  angularNotifyToaster
])
  .service('xoNotify', (toaster) => {
    function makeNotifier (level) {
      return function notifier (options) {
        if (isString(options)) {
          options = { message: options }
        } else if (!options.message) {
          throw new Error('missing message')
        }

        toaster.pop(
          level,
          options.title || 'Xen-Orchestra',
          options.message
        )
      }
    }

    return {
      warning: makeNotifier('warning'),
      error: makeNotifier('error'),
      info: makeNotifier('info')
      // TODO: It is probably a bad design to have notification for
      // successful operations.
      // success: makeNotifier 'success'
    }
  })
  .name<commit_msg>Use desktop notification when avilable and when the browser is minified without jquery, and using angular $window and $document<commit_after>import angular from 'angular'
import angularAnimate from 'angular-animate'
import angularNotifyToaster from 'angular-notify-toaster'

const {isString} = angular

// ===================================================================

// High level integration of XO API in xo-web.
export default angular.module('xo-notify', [
  angularAnimate,
  angularNotifyToaster
])
  .service('xoNotify', (toaster, $window, $document) => {
    const Notification = $window.Notification ||
    /* Chrome & ff-html5notifications plugin */$window.webkitNotifications ||
    /* Firefox Mobile */ navigator.mozNotification /* useless on mobile since page should be in front */ ||
      {
        permission: 'not capable',
        requestPermission: function () {
        }
      }

    // Set the name of the hidden property and the change event for visibility
    let hidden_property, visibility_change_event, is_document_hidden
    is_document_hidden = false
    if (typeof $document.prop('hidden') !== 'undefined') { // Opera 12.10 and Firefox 18 and later support
      hidden_property = 'hidden'
      visibility_change_event = 'visibilitychange'
    } else if (typeof $document.prop('mozHidden') !== 'undefined') {
      hidden_property = 'mozHidden'
      visibility_change_event = 'mozvisibilitychange'
    } else if (typeof $document.prop('msHidden') !== 'undefined') {
      hidden_property = 'msHidden'
      visibility_change_event = 'msvisibilitychange'
    } else if (typeof $document.prop('webkitHidden') !== 'undefined') {
      hidden_property = 'webkitHidden'
      visibility_change_event = 'webkitvisibilitychange'
    }

    if (typeof $document.prop(hidden_property) !== 'undefined') {
      is_document_hidden = $document.prop(hidden_property)
      $document.on(visibility_change_event, function () {
        is_document_hidden = $document.prop(hidden_property)
      })
    }

    $document.ready(function () { // some browser allow to ask for permission
      Notification.requestPermission(function (permission) {
        if (!('permission' in Notification)) {
          Notification.permission = permission
        }
      })
    })

    $document.on('click', function () { // other force us to wit for a user interaction
      Notification.requestPermission(function (permission) {
        if (!('permission' in Notification)) {
          Notification.permission = permission
        }
      })
    })

    function makeNotifier (level) {
      return function notifier (options) {
        if (isString(options)) {
          options = { message: options }
        } else if (!options.message) {
          throw new Error('missing message')
        }
        if (Notification.permission === 'granted' && is_document_hidden) {
          const n = new Notification(options.title || 'Xen-Orchestra', {
            body: options.message,
            icon: 'images/logo_small.png'// ,
            // tag: model.get('tag')
          })
          n.onclose = function () {
            /* should I do something when notif is closed ? */
          }
          n.onshow = function () {
            setTimeout(function () {
              if (n) {
                n.close()
              }
            }, 5000)
          }
        } else {
          toaster.pop(
            level,
            options.title || 'Xen-Orchestra',
            options.message
          )
        }
      }
    }

    return {
      warning: makeNotifier('warning'),
      error: makeNotifier('error'),
      info: makeNotifier('info')
      // TODO: It is probably a bad design to have notification for
      // successful operations.
      // success: makeNotifier 'success'
    }
  })
  .name
{'fraction_non_alphanumeric': 0.1353827361563518, 'fraction_numerical': 0.002239413680781759, 'mean_word_length': 2.5345323741007193, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4114798', 'n_tokens_mistral': 1305, 'n_tokens_neox': 1258, 'n_words': 339}