UNPKG

noty

Version:

Noty is a dependency-free notification library that makes it easy to create alert - success - error - warning - information - confirmation messages as an alternative the standard alert dialog. Each notification is added to a queue. (Optional)

296 lines (243 loc) 6.87 kB
import * as API from 'api' export const animationEndEvents = 'webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend' export function inArray (needle, haystack, argStrict) { let key let strict = !!argStrict if (strict) { for (key in haystack) { if (haystack.hasOwnProperty(key) && haystack[key] === needle) { return true } } } else { for (key in haystack) { if (haystack.hasOwnProperty(key) && haystack[key] === needle) { return true } } } return false } export function stopPropagation (evt) { evt = evt || window.event if (typeof evt.stopPropagation !== 'undefined') { evt.stopPropagation() } else { evt.cancelBubble = true } } export const deepExtend = function (out) { out = out || {} for (let i = 1; i < arguments.length; i++) { let obj = arguments[i] if (!obj) continue for (let key in obj) { if (obj.hasOwnProperty(key)) { if (Array.isArray(obj[key])) { out[key] = obj[key] } else if (typeof obj[key] === 'object' && obj[key] !== null) { out[key] = deepExtend(out[key], obj[key]) } else { out[key] = obj[key] } } } } return out } export function generateID (prefix = '') { let id = `noty_${prefix}_` id += 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { let r = Math.random() * 16 | 0 let v = c === 'x' ? r : r & 0x3 | 0x8 return v.toString(16) }) return id } export function outerHeight (el) { let height = el.offsetHeight let style = window.getComputedStyle(el) height += parseInt(style.marginTop) + parseInt(style.marginBottom) return height } export let css = (function () { let cssPrefixes = ['Webkit', 'O', 'Moz', 'ms'] let cssProps = {} function camelCase (string) { return string .replace(/^-ms-/, 'ms-') .replace(/-([\da-z])/gi, function (match, letter) { return letter.toUpperCase() }) } function getVendorProp (name) { let style = document.body.style if (name in style) return name let i = cssPrefixes.length let capName = name.charAt(0).toUpperCase() + name.slice(1) let vendorName while (i--) { vendorName = cssPrefixes[i] + capName if (vendorName in style) return vendorName } return name } function getStyleProp (name) { name = camelCase(name) return cssProps[name] || (cssProps[name] = getVendorProp(name)) } function applyCss (element, prop, value) { prop = getStyleProp(prop) element.style[prop] = value } return function (element, properties) { let args = arguments let prop let value if (args.length === 2) { for (prop in properties) { if (properties.hasOwnProperty(prop)) { value = properties[prop] if (value !== undefined && properties.hasOwnProperty(prop)) { applyCss(element, prop, value) } } } } else { applyCss(element, args[1], args[2]) } } })() export function addListener (el, events, cb, useCapture = false) { events = events.split(' ') for (let i = 0; i < events.length; i++) { if (document.addEventListener) { el.addEventListener(events[i], cb, useCapture) } else if (document.attachEvent) { el.attachEvent('on' + events[i], cb) } } } export function hasClass (element, name) { let list = typeof element === 'string' ? element : classList(element) return list.indexOf(' ' + name + ' ') >= 0 } export function addClass (element, name) { let oldList = classList(element) let newList = oldList + name if (hasClass(oldList, name)) return // Trim the opening space. element.className = newList.substring(1) } export function removeClass (element, name) { let oldList = classList(element) let newList if (!hasClass(element, name)) return // Replace the class name. newList = oldList.replace(' ' + name + ' ', ' ') // Trim the opening and closing spaces. element.className = newList.substring(1, newList.length - 1) } export function remove (element) { if (element.parentNode) { element.parentNode.removeChild(element) } } export function classList (element) { return (' ' + ((element && element.className) || '') + ' ').replace( /\s+/gi, ' ' ) } export function visibilityChangeFlow () { let hidden let visibilityChange if (typeof document.hidden !== 'undefined') { // Opera 12.10 and Firefox 18 and later support hidden = 'hidden' visibilityChange = 'visibilitychange' } else if (typeof document.msHidden !== 'undefined') { hidden = 'msHidden' visibilityChange = 'msvisibilitychange' } else if (typeof document.webkitHidden !== 'undefined') { hidden = 'webkitHidden' visibilityChange = 'webkitvisibilitychange' } function onVisibilityChange () { API.PageHidden = document[hidden] handleVisibilityChange() } function onBlur () { API.PageHidden = true handleVisibilityChange() } function onFocus () { API.PageHidden = false handleVisibilityChange() } function handleVisibilityChange () { if (API.PageHidden) stopAll() else resumeAll() } function stopAll () { setTimeout( function () { Object.keys(API.Store).forEach(id => { if (API.Store.hasOwnProperty(id)) { if (API.Store[id].options.visibilityControl) { API.Store[id].stop() } } }) }, 100 ) } function resumeAll () { setTimeout( function () { Object.keys(API.Store).forEach(id => { if (API.Store.hasOwnProperty(id)) { if (API.Store[id].options.visibilityControl) { API.Store[id].resume() } } }) API.queueRenderAll() }, 100 ) } if (visibilityChange) { addListener(document, visibilityChange, onVisibilityChange) } addListener(window, 'blur', onBlur) addListener(window, 'focus', onFocus) } export function createAudioElements (ref) { if (ref.hasSound) { const audioElement = document.createElement('audio') ref.options.sounds.sources.forEach(s => { const source = document.createElement('source') source.src = s source.type = `audio/${getExtension(s)}` audioElement.appendChild(source) }) if (ref.barDom) { ref.barDom.appendChild(audioElement) } else { document.querySelector('body').appendChild(audioElement) } audioElement.volume = ref.options.sounds.volume if (!ref.soundPlayed) { audioElement.play() ref.soundPlayed = true } audioElement.onended = function () { remove(audioElement) } } } function getExtension (fileName) { return fileName.match(/\.([^.]+)$/)[1] }