change pnotify with noty

This commit is contained in:
s2
2020-06-08 11:51:45 +02:00
parent 27635904a6
commit 51c66fc3cb
200 changed files with 6503 additions and 23902 deletions

419
node_modules/noty/src/api.js generated vendored Normal file
View File

@@ -0,0 +1,419 @@
import * as Utils from 'utils'
export let PageHidden = false
export let DocModalCount = 0
const DocTitleProps = {
originalTitle: null,
count: 0,
changed: false,
timer: -1
}
export const docTitle = {
increment: () => {
DocTitleProps.count++
docTitle._update()
},
decrement: () => {
DocTitleProps.count--
if (DocTitleProps.count <= 0) {
docTitle._clear()
return
}
docTitle._update()
},
_update: () => {
let title = document.title
if (!DocTitleProps.changed) {
DocTitleProps.originalTitle = title
document.title = `(${DocTitleProps.count}) ${title}`
DocTitleProps.changed = true
} else {
document.title = `(${DocTitleProps.count}) ${DocTitleProps.originalTitle}`
}
},
_clear: () => {
if (DocTitleProps.changed) {
DocTitleProps.count = 0
document.title = DocTitleProps.originalTitle
DocTitleProps.changed = false
}
}
}
export const DefaultMaxVisible = 5
export const Queues = {
global: {
maxVisible: DefaultMaxVisible,
queue: []
}
}
export const Store = {}
export let Defaults = {
type: 'alert',
layout: 'topRight',
theme: 'mint',
text: '',
timeout: false,
progressBar: true,
closeWith: ['click'],
animation: {
open: 'noty_effects_open',
close: 'noty_effects_close'
},
id: false,
force: false,
killer: false,
queue: 'global',
container: false,
buttons: [],
callbacks: {
beforeShow: null,
onShow: null,
afterShow: null,
onClose: null,
afterClose: null,
onClick: null,
onHover: null,
onTemplate: null
},
sounds: {
sources: [],
volume: 1,
conditions: []
},
titleCount: {
conditions: []
},
modal: false,
visibilityControl: false
}
/**
* @param {string} queueName
* @return {object}
*/
export function getQueueCounts (queueName = 'global') {
let count = 0
let max = DefaultMaxVisible
if (Queues.hasOwnProperty(queueName)) {
max = Queues[queueName].maxVisible
Object.keys(Store).forEach(i => {
if (Store[i].options.queue === queueName && !Store[i].closed) count++
})
}
return {
current: count,
maxVisible: max
}
}
/**
* @param {Noty} ref
* @return {void}
*/
export function addToQueue (ref) {
if (!Queues.hasOwnProperty(ref.options.queue)) {
Queues[ref.options.queue] = {maxVisible: DefaultMaxVisible, queue: []}
}
Queues[ref.options.queue].queue.push(ref)
}
/**
* @param {Noty} ref
* @return {void}
*/
export function removeFromQueue (ref) {
if (Queues.hasOwnProperty(ref.options.queue)) {
const queue = []
Object.keys(Queues[ref.options.queue].queue).forEach(i => {
if (Queues[ref.options.queue].queue[i].id !== ref.id) {
queue.push(Queues[ref.options.queue].queue[i])
}
})
Queues[ref.options.queue].queue = queue
}
}
/**
* @param {string} queueName
* @return {void}
*/
export function queueRender (queueName = 'global') {
if (Queues.hasOwnProperty(queueName)) {
const noty = Queues[queueName].queue.shift()
if (noty) noty.show()
}
}
/**
* @return {void}
*/
export function queueRenderAll () {
Object.keys(Queues).forEach(queueName => {
queueRender(queueName)
})
}
/**
* @param {Noty} ref
* @return {void}
*/
export function ghostFix (ref) {
const ghostID = Utils.generateID('ghost')
let ghost = document.createElement('div')
ghost.setAttribute('id', ghostID)
Utils.css(ghost, {
height: Utils.outerHeight(ref.barDom) + 'px'
})
ref.barDom.insertAdjacentHTML('afterend', ghost.outerHTML)
Utils.remove(ref.barDom)
ghost = document.getElementById(ghostID)
Utils.addClass(ghost, 'noty_fix_effects_height')
Utils.addListener(ghost, Utils.animationEndEvents, () => {
Utils.remove(ghost)
})
}
/**
* @param {Noty} ref
* @return {void}
*/
export function build (ref) {
findOrCreateContainer(ref)
const markup = `<div class="noty_body">${ref.options.text}</div>${buildButtons(ref)}<div class="noty_progressbar"></div>`
ref.barDom = document.createElement('div')
ref.barDom.setAttribute('id', ref.id)
Utils.addClass(
ref.barDom,
`noty_bar noty_type__${ref.options.type} noty_theme__${ref.options.theme}`
)
ref.barDom.innerHTML = markup
fire(ref, 'onTemplate')
}
/**
* @param {Noty} ref
* @return {boolean}
*/
export function hasButtons (ref) {
return !!(ref.options.buttons && Object.keys(ref.options.buttons).length)
}
/**
* @param {Noty} ref
* @return {string}
*/
function buildButtons (ref) {
if (hasButtons(ref)) {
let buttons = document.createElement('div')
Utils.addClass(buttons, 'noty_buttons')
Object.keys(ref.options.buttons).forEach(key => {
buttons.appendChild(ref.options.buttons[key].dom)
})
ref.options.buttons.forEach(btn => {
buttons.appendChild(btn.dom)
})
return buttons.outerHTML
}
return ''
}
/**
* @param {Noty} ref
* @return {void}
*/
export function handleModal (ref) {
if (ref.options.modal) {
if (DocModalCount === 0) {
createModal(ref)
}
DocModalCount++
}
}
/**
* @param {Noty} ref
* @return {void}
*/
export function handleModalClose (ref) {
if (ref.options.modal && DocModalCount > 0) {
DocModalCount--
if (DocModalCount <= 0) {
const modal = document.querySelector('.noty_modal')
if (modal) {
Utils.removeClass(modal, 'noty_modal_open')
Utils.addClass(modal, 'noty_modal_close')
Utils.addListener(modal, Utils.animationEndEvents, () => {
Utils.remove(modal)
})
}
}
}
}
/**
* @return {void}
*/
function createModal () {
const body = document.querySelector('body')
const modal = document.createElement('div')
Utils.addClass(modal, 'noty_modal')
body.insertBefore(modal, body.firstChild)
Utils.addClass(modal, 'noty_modal_open')
Utils.addListener(modal, Utils.animationEndEvents, () => {
Utils.removeClass(modal, 'noty_modal_open')
})
}
/**
* @param {Noty} ref
* @return {void}
*/
function findOrCreateContainer (ref) {
if (ref.options.container) {
ref.layoutDom = document.querySelector(ref.options.container)
return
}
const layoutID = `noty_layout__${ref.options.layout}`
ref.layoutDom = document.querySelector(`div#${layoutID}`)
if (!ref.layoutDom) {
ref.layoutDom = document.createElement('div')
ref.layoutDom.setAttribute('id', layoutID)
ref.layoutDom.setAttribute('role', 'alert')
ref.layoutDom.setAttribute('aria-live', 'polite')
Utils.addClass(ref.layoutDom, 'noty_layout')
document.querySelector('body').appendChild(ref.layoutDom)
}
}
/**
* @param {Noty} ref
* @return {void}
*/
export function queueClose (ref) {
if (ref.options.timeout) {
if (ref.options.progressBar && ref.progressDom) {
Utils.css(ref.progressDom, {
transition: `width ${ref.options.timeout}ms linear`,
width: '0%'
})
}
clearTimeout(ref.closeTimer)
ref.closeTimer = setTimeout(
() => {
ref.close()
},
ref.options.timeout
)
}
}
/**
* @param {Noty} ref
* @return {void}
*/
export function dequeueClose (ref) {
if (ref.options.timeout && ref.closeTimer) {
clearTimeout(ref.closeTimer)
ref.closeTimer = -1
if (ref.options.progressBar && ref.progressDom) {
Utils.css(ref.progressDom, {
transition: 'width 0ms linear',
width: '100%'
})
}
}
}
/**
* @param {Noty} ref
* @param {string} eventName
* @return {void}
*/
export function fire (ref, eventName) {
if (ref.listeners.hasOwnProperty(eventName)) {
ref.listeners[eventName].forEach(cb => {
if (typeof cb === 'function') {
cb.apply(ref)
}
})
}
}
/**
* @param {Noty} ref
* @return {void}
*/
export function openFlow (ref) {
fire(ref, 'afterShow')
queueClose(ref)
Utils.addListener(ref.barDom, 'mouseenter', () => {
dequeueClose(ref)
})
Utils.addListener(ref.barDom, 'mouseleave', () => {
queueClose(ref)
})
}
/**
* @param {Noty} ref
* @return {void}
*/
export function closeFlow (ref) {
delete Store[ref.id]
ref.closing = false
fire(ref, 'afterClose')
Utils.remove(ref.barDom)
if (
ref.layoutDom.querySelectorAll('.noty_bar').length === 0 &&
!ref.options.container
) {
Utils.remove(ref.layoutDom)
}
if (
Utils.inArray('docVisible', ref.options.titleCount.conditions) ||
Utils.inArray('docHidden', ref.options.titleCount.conditions)
) {
docTitle.decrement()
}
queueRender(ref.options.queue)
}

16
node_modules/noty/src/button.js generated vendored Normal file
View File

@@ -0,0 +1,16 @@
import * as Utils from 'utils'
export class NotyButton {
constructor (html, classes, cb, attributes = {}) {
this.dom = document.createElement('button')
this.dom.innerHTML = html
this.id = (attributes.id = attributes.id || Utils.generateID('button'))
this.cb = cb
Object.keys(attributes).forEach(propertyName => {
this.dom.setAttribute(propertyName, attributes[propertyName])
})
Utils.addClass(this.dom, classes || 'noty_btn')
return this
}
}

493
node_modules/noty/src/index.js generated vendored Normal file
View File

@@ -0,0 +1,493 @@
/* global VERSION */
import 'noty.scss'
import Promise from 'es6-promise'
import * as Utils from 'utils'
import * as API from 'api'
import { NotyButton } from 'button'
import { Push } from 'push'
export default class Noty {
/**
* @param {object} options
* @return {Noty}
*/
constructor (options = {}) {
this.options = Utils.deepExtend({}, API.Defaults, options)
if (API.Store[this.options.id]) {
return API.Store[this.options.id]
}
this.id = this.options.id || Utils.generateID('bar')
this.closeTimer = -1
this.barDom = null
this.layoutDom = null
this.progressDom = null
this.showing = false
this.shown = false
this.closed = false
this.closing = false
this.killable = this.options.timeout || this.options.closeWith.length > 0
this.hasSound = this.options.sounds.sources.length > 0
this.soundPlayed = false
this.listeners = {
beforeShow: [],
onShow: [],
afterShow: [],
onClose: [],
afterClose: [],
onClick: [],
onHover: [],
onTemplate: []
}
this.promises = {
show: null,
close: null
}
this.on('beforeShow', this.options.callbacks.beforeShow)
this.on('onShow', this.options.callbacks.onShow)
this.on('afterShow', this.options.callbacks.afterShow)
this.on('onClose', this.options.callbacks.onClose)
this.on('afterClose', this.options.callbacks.afterClose)
this.on('onClick', this.options.callbacks.onClick)
this.on('onHover', this.options.callbacks.onHover)
this.on('onTemplate', this.options.callbacks.onTemplate)
return this
}
/**
* @param {string} eventName
* @param {function} cb
* @return {Noty}
*/
on (eventName, cb = () => {}) {
if (typeof cb === 'function' && this.listeners.hasOwnProperty(eventName)) {
this.listeners[eventName].push(cb)
}
return this
}
/**
* @return {Noty}
*/
show () {
if (this.showing || this.shown) {
return this // preventing multiple show
}
if (this.options.killer === true) {
Noty.closeAll()
} else if (typeof this.options.killer === 'string') {
Noty.closeAll(this.options.killer)
}
let queueCounts = API.getQueueCounts(this.options.queue)
if (
queueCounts.current >= queueCounts.maxVisible ||
(API.PageHidden && this.options.visibilityControl)
) {
API.addToQueue(this)
if (
API.PageHidden &&
this.hasSound &&
Utils.inArray('docHidden', this.options.sounds.conditions)
) {
Utils.createAudioElements(this)
}
if (
API.PageHidden &&
Utils.inArray('docHidden', this.options.titleCount.conditions)
) {
API.docTitle.increment()
}
return this
}
API.Store[this.id] = this
API.fire(this, 'beforeShow')
this.showing = true
if (this.closing) {
this.showing = false
return this
}
API.build(this)
API.handleModal(this)
if (this.options.force) {
this.layoutDom.insertBefore(this.barDom, this.layoutDom.firstChild)
} else {
this.layoutDom.appendChild(this.barDom)
}
if (
this.hasSound &&
!this.soundPlayed &&
Utils.inArray('docVisible', this.options.sounds.conditions)
) {
Utils.createAudioElements(this)
}
if (Utils.inArray('docVisible', this.options.titleCount.conditions)) {
API.docTitle.increment()
}
this.shown = true
this.closed = false
// bind button events if any
if (API.hasButtons(this)) {
Object.keys(this.options.buttons).forEach(key => {
const btn = this.barDom.querySelector(
`#${this.options.buttons[key].id}`
)
Utils.addListener(btn, 'click', e => {
Utils.stopPropagation(e)
this.options.buttons[key].cb(this)
})
})
}
this.progressDom = this.barDom.querySelector('.noty_progressbar')
if (Utils.inArray('click', this.options.closeWith)) {
Utils.addClass(this.barDom, 'noty_close_with_click')
Utils.addListener(
this.barDom,
'click',
e => {
Utils.stopPropagation(e)
API.fire(this, 'onClick')
this.close()
},
false
)
}
Utils.addListener(
this.barDom,
'mouseenter',
() => {
API.fire(this, 'onHover')
},
false
)
if (this.options.timeout) Utils.addClass(this.barDom, 'noty_has_timeout')
if (this.options.progressBar) {
Utils.addClass(this.barDom, 'noty_has_progressbar')
}
if (Utils.inArray('button', this.options.closeWith)) {
Utils.addClass(this.barDom, 'noty_close_with_button')
const closeButton = document.createElement('div')
Utils.addClass(closeButton, 'noty_close_button')
closeButton.innerHTML = '×'
this.barDom.appendChild(closeButton)
Utils.addListener(
closeButton,
'click',
e => {
Utils.stopPropagation(e)
this.close()
},
false
)
}
API.fire(this, 'onShow')
if (this.options.animation.open === null) {
this.promises.show = new Promise(resolve => {
resolve()
})
} else if (typeof this.options.animation.open === 'function') {
this.promises.show = new Promise(this.options.animation.open.bind(this))
} else {
Utils.addClass(this.barDom, this.options.animation.open)
this.promises.show = new Promise(resolve => {
Utils.addListener(this.barDom, Utils.animationEndEvents, () => {
Utils.removeClass(this.barDom, this.options.animation.open)
resolve()
})
})
}
this.promises.show.then(() => {
const _t = this
setTimeout(
() => {
API.openFlow(_t)
},
100
)
})
return this
}
/**
* @return {Noty}
*/
stop () {
API.dequeueClose(this)
return this
}
/**
* @return {Noty}
*/
resume () {
API.queueClose(this)
return this
}
/**
* @param {int|boolean} ms
* @return {Noty}
*/
setTimeout (ms) {
this.stop()
this.options.timeout = ms
if (this.barDom) {
if (this.options.timeout) {
Utils.addClass(this.barDom, 'noty_has_timeout')
} else {
Utils.removeClass(this.barDom, 'noty_has_timeout')
}
const _t = this
setTimeout(
function () {
// ugly fix for progressbar display bug
_t.resume()
},
100
)
}
return this
}
/**
* @param {string} html
* @param {boolean} optionsOverride
* @return {Noty}
*/
setText (html, optionsOverride = false) {
if (this.barDom) {
this.barDom.querySelector('.noty_body').innerHTML = html
}
if (optionsOverride) this.options.text = html
return this
}
/**
* @param {string} type
* @param {boolean} optionsOverride
* @return {Noty}
*/
setType (type, optionsOverride = false) {
if (this.barDom) {
let classList = Utils.classList(this.barDom).split(' ')
classList.forEach(c => {
if (c.substring(0, 11) === 'noty_type__') {
Utils.removeClass(this.barDom, c)
}
})
Utils.addClass(this.barDom, `noty_type__${type}`)
}
if (optionsOverride) this.options.type = type
return this
}
/**
* @param {string} theme
* @param {boolean} optionsOverride
* @return {Noty}
*/
setTheme (theme, optionsOverride = false) {
if (this.barDom) {
let classList = Utils.classList(this.barDom).split(' ')
classList.forEach(c => {
if (c.substring(0, 12) === 'noty_theme__') {
Utils.removeClass(this.barDom, c)
}
})
Utils.addClass(this.barDom, `noty_theme__${theme}`)
}
if (optionsOverride) this.options.theme = theme
return this
}
/**
* @return {Noty}
*/
close () {
if (this.closed) return this
if (!this.shown) {
// it's in the queue
API.removeFromQueue(this)
return this
}
API.fire(this, 'onClose')
this.closing = true
if (this.options.animation.close === null || this.options.animation.close === false) {
this.promises.close = new Promise(resolve => {
resolve()
})
} else if (typeof this.options.animation.close === 'function') {
this.promises.close = new Promise(
this.options.animation.close.bind(this)
)
} else {
Utils.addClass(this.barDom, this.options.animation.close)
this.promises.close = new Promise(resolve => {
Utils.addListener(this.barDom, Utils.animationEndEvents, () => {
if (this.options.force) {
Utils.remove(this.barDom)
} else {
API.ghostFix(this)
}
resolve()
})
})
}
this.promises.close.then(() => {
API.closeFlow(this)
API.handleModalClose(this)
})
this.closed = true
return this
}
// API functions
/**
* @param {boolean|string} queueName
* @return {Noty}
*/
static closeAll (queueName = false) {
Object.keys(API.Store).forEach(id => {
if (queueName) {
if (
API.Store[id].options.queue === queueName && API.Store[id].killable
) {
API.Store[id].close()
}
} else if (API.Store[id].killable) {
API.Store[id].close()
}
})
return this
}
/**
* @param {string} queueName
* @return {Noty}
*/
static clearQueue (queueName = 'global') {
if (API.Queues.hasOwnProperty(queueName)) {
API.Queues[queueName].queue = []
}
return this
}
/**
* @return {API.Queues}
*/
static get Queues () {
return API.Queues
}
/**
* @return {API.PageHidden}
*/
static get PageHidden () {
return API.PageHidden
}
/**
* @param {Object} obj
* @return {Noty}
*/
static overrideDefaults (obj) {
API.Defaults = Utils.deepExtend({}, API.Defaults, obj)
return this
}
/**
* @param {int} amount
* @param {string} queueName
* @return {Noty}
*/
static setMaxVisible (amount = API.DefaultMaxVisible, queueName = 'global') {
if (!API.Queues.hasOwnProperty(queueName)) {
API.Queues[queueName] = {maxVisible: amount, queue: []}
}
API.Queues[queueName].maxVisible = amount
return this
}
/**
* @param {string} innerHtml
* @param {String} classes
* @param {Function} cb
* @param {Object} attributes
* @return {NotyButton}
*/
static button (innerHtml, classes = null, cb, attributes = {}) {
return new NotyButton(innerHtml, classes, cb, attributes)
}
/**
* @return {string}
*/
static version () {
return VERSION
}
/**
* @param {String} workerPath
* @return {Push}
*/
static Push (workerPath) {
return new Push(workerPath)
}
}
// Document visibility change controller
if (typeof window !== 'undefined') {
Utils.visibilityChangeFlow()
}

228
node_modules/noty/src/noty.scss generated vendored Normal file
View File

@@ -0,0 +1,228 @@
$noty-primary-color: #333;
$noty-default-width: 325px;
$noty-corner-space: 20px;
.noty_layout_mixin {
position: fixed;
margin: 0;
padding: 0;
z-index: 9999999;
transform: translateZ(0) scale(1.0, 1.0);
backface-visibility: hidden;
-webkit-font-smoothing: subpixel-antialiased;
filter: blur(0);
-webkit-filter: blur(0);
max-width: 90%;
}
#noty_layout__top {
@extend .noty_layout_mixin;
top: 0;
left: 5%;
width: 90%;
}
#noty_layout__topLeft {
@extend .noty_layout_mixin;
top: $noty-corner-space;
left: $noty-corner-space;
width: $noty-default-width;
}
#noty_layout__topCenter {
@extend .noty_layout_mixin;
top: 5%;
left: 50%;
width: $noty-default-width;
transform: translate(calc(-50% - .5px)) translateZ(0) scale(1.0, 1.0);
}
#noty_layout__topRight {
@extend .noty_layout_mixin;
top: $noty-corner-space;
right: $noty-corner-space;
width: $noty-default-width;
}
#noty_layout__bottom {
@extend .noty_layout_mixin;
bottom: 0;
left: 5%;
width: 90%;
}
#noty_layout__bottomLeft {
@extend .noty_layout_mixin;
bottom: $noty-corner-space;
left: $noty-corner-space;
width: $noty-default-width;
}
#noty_layout__bottomCenter {
@extend .noty_layout_mixin;
bottom: 5%;
left: 50%;
width: $noty-default-width;
transform: translate(calc(-50% - .5px)) translateZ(0) scale(1.0, 1.0);
}
#noty_layout__bottomRight {
@extend .noty_layout_mixin;
bottom: $noty-corner-space;
right: $noty-corner-space;
width: $noty-default-width;
}
#noty_layout__center {
@extend .noty_layout_mixin;
top: 50%;
left: 50%;
width: $noty-default-width;
transform: translate(calc(-50% - .5px), calc(-50% - .5px)) translateZ(0) scale(1.0, 1.0);
}
#noty_layout__centerLeft {
@extend .noty_layout_mixin;
top: 50%;
left: $noty-corner-space;
width: $noty-default-width;
transform: translate(0, calc(-50% - .5px)) translateZ(0) scale(1.0, 1.0);
}
#noty_layout__centerRight {
@extend .noty_layout_mixin;
top: 50%;
right: $noty-corner-space;
width: $noty-default-width;
transform: translate(0, calc(-50% - .5px)) translateZ(0) scale(1, 1);
}
.noty_progressbar {
display: none;
}
.noty_has_timeout.noty_has_progressbar .noty_progressbar {
display: block;
position: absolute;
left: 0;
bottom: 0;
height: 3px;
width: 100%;
background-color: #646464;
opacity: 0.2;
filter: alpha(opacity=10)
}
.noty_bar {
-webkit-backface-visibility: hidden;
-webkit-transform: translate(0, 0) translateZ(0) scale(1.0, 1.0);
transform: translate(0, 0) scale(1.0, 1.0);
-webkit-font-smoothing: subpixel-antialiased;
overflow: hidden;
}
.noty_effects_open {
opacity: 0;
transform: translate(50%);
animation: noty_anim_in .5s cubic-bezier(0.68, -0.55, 0.265, 1.55);
animation-fill-mode: forwards;
}
.noty_effects_close {
animation: noty_anim_out .5s cubic-bezier(0.68, -0.55, 0.265, 1.55);
animation-fill-mode: forwards;
}
.noty_fix_effects_height {
animation: noty_anim_height 75ms ease-out;
}
.noty_close_with_click {
cursor: pointer;
}
.noty_close_button {
position: absolute;
top: 2px;
right: 2px;
font-weight: bold;
width: 20px;
height: 20px;
text-align: center;
line-height: 20px;
background-color: rgba(0, 0, 0, .05);
border-radius: 2px;
cursor: pointer;
transition: all .2s ease-out;
}
.noty_close_button:hover {
background-color: rgba(0, 0, 0, .1);
}
.noty_modal {
position: fixed;
width: 100%;
height: 100%;
background-color: #000;
z-index: 10000;
opacity: .3;
left: 0;
top: 0;
}
.noty_modal.noty_modal_open {
opacity: 0;
animation: noty_modal_in .3s ease-out;
}
.noty_modal.noty_modal_close {
animation: noty_modal_out .3s ease-out;
animation-fill-mode: forwards;
}
@keyframes noty_modal_in {
100% {
opacity: .3;
}
}
@keyframes noty_modal_out {
100% {
opacity: 0;
}
}
@keyframes noty_modal_out {
100% {
opacity: 0;
}
}
@keyframes noty_anim_in {
100% {
transform: translate(0);
opacity: 1;
}
}
@keyframes noty_anim_out {
100% {
transform: translate(50%);
opacity: 0;
}
}
@keyframes noty_anim_height {
100% {
height: 0;
}
}
//@import "themes/relax";
//@import "themes/metroui";
//@import "themes/mint";
//@import "themes/sunset";
//@import "themes/bootstrap-v3";
//@import "themes/bootstrap-v4";
//@import "themes/semanticui";
//@import "themes/nest";
//@import "themes/light";

204
node_modules/noty/src/push.js generated vendored Normal file
View File

@@ -0,0 +1,204 @@
export class Push {
constructor (workerPath = '/service-worker.js') {
this.subData = {}
this.workerPath = workerPath
this.listeners = {
onPermissionGranted: [],
onPermissionDenied: [],
onSubscriptionSuccess: [],
onSubscriptionCancel: [],
onWorkerError: [],
onWorkerSuccess: [],
onWorkerNotSupported: []
}
return this
}
/**
* @param {string} eventName
* @param {function} cb
* @return {Push}
*/
on (eventName, cb = () => {}) {
if (typeof cb === 'function' && this.listeners.hasOwnProperty(eventName)) {
this.listeners[eventName].push(cb)
}
return this
}
fire (eventName, params = []) {
if (this.listeners.hasOwnProperty(eventName)) {
this.listeners[eventName].forEach(cb => {
if (typeof cb === 'function') {
cb.apply(this, params)
}
})
}
}
create () {
console.log('NOT IMPLEMENTED YET')
}
/**
* @return {boolean}
*/
isSupported () {
let result = false
try {
result = window.Notification ||
window.webkitNotifications ||
navigator.mozNotification ||
(window.external && window.external.msIsSiteMode() !== undefined)
} catch (e) {}
return result
}
/**
* @return {string}
*/
getPermissionStatus () {
let perm = 'default'
if (window.Notification && window.Notification.permissionLevel) {
perm = window.Notification.permissionLevel
} else if (
window.webkitNotifications && window.webkitNotifications.checkPermission
) {
switch (window.webkitNotifications.checkPermission()) {
case 1:
perm = 'default'
break
case 0:
perm = 'granted'
break
default:
perm = 'denied'
}
} else if (window.Notification && window.Notification.permission) {
perm = window.Notification.permission
} else if (navigator.mozNotification) {
perm = 'granted'
} else if (
window.external && window.external.msIsSiteMode() !== undefined
) {
perm = window.external.msIsSiteMode() ? 'granted' : 'default'
}
return perm.toString().toLowerCase()
}
/**
* @return {string}
*/
getEndpoint (subscription) {
let endpoint = subscription.endpoint
const subscriptionId = subscription.subscriptionId
// fix for Chrome < 45
if (subscriptionId && endpoint.indexOf(subscriptionId) === -1) {
endpoint += '/' + subscriptionId
}
return endpoint
}
/**
* @return {boolean}
*/
isSWRegistered () {
try {
return navigator.serviceWorker.controller.state === 'activated'
} catch (e) {
return false
}
}
/**
* @return {void}
*/
unregisterWorker () {
const self = this
if ('serviceWorker' in navigator) {
navigator.serviceWorker.getRegistrations().then(function (registrations) {
for (let registration of registrations) {
registration.unregister()
self.fire('onSubscriptionCancel')
}
})
}
}
/**
* @return {void}
*/
requestSubscription (userVisibleOnly = true) {
const self = this
const current = this.getPermissionStatus()
const cb = result => {
if (result === 'granted') {
this.fire('onPermissionGranted')
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register(this.workerPath).then(function () {
navigator.serviceWorker.ready.then(
function (serviceWorkerRegistration) {
self.fire('onWorkerSuccess')
serviceWorkerRegistration.pushManager
.subscribe({
userVisibleOnly: userVisibleOnly
})
.then(function (subscription) {
const key = subscription.getKey('p256dh')
const token = subscription.getKey('auth')
self.subData = {
endpoint: self.getEndpoint(subscription),
p256dh: key
? window.btoa(
String.fromCharCode.apply(null, new Uint8Array(key))
)
: null,
auth: token
? window.btoa(
String.fromCharCode.apply(
null,
new Uint8Array(token)
)
)
: null
}
self.fire('onSubscriptionSuccess', [self.subData])
})
.catch(function (err) {
self.fire('onWorkerError', [err])
})
}
)
})
} else {
self.fire('onWorkerNotSupported')
}
} else if (result === 'denied') {
this.fire('onPermissionDenied')
this.unregisterWorker()
}
}
if (current === 'default') {
if (window.Notification && window.Notification.requestPermission) {
window.Notification.requestPermission(cb)
} else if (
window.webkitNotifications && window.webkitNotifications.checkPermission
) {
window.webkitNotifications.requestPermission(cb)
}
} else {
cb(current)
}
}
}

64
node_modules/noty/src/themes/bootstrap-v3.scss generated vendored Normal file
View File

@@ -0,0 +1,64 @@
.noty_theme__bootstrap-v3.noty_bar {
margin: 4px 0;
overflow: hidden;
position: relative;
border: 1px solid transparent;
border-radius: 4px;
.noty_body {
padding: 15px;
}
.noty_buttons {
padding: 10px;
}
.noty_close_button {
font-size: 21px;
font-weight: 700;
line-height: 1;
color: #000;
text-shadow: 0 1px 0 #fff;
filter: alpha(opacity=20);
opacity: .2;
background: transparent;
}
.noty_close_button:hover {
background: transparent;
text-decoration: none;
cursor: pointer;
filter: alpha(opacity=50);
opacity: .5;
}
}
.noty_theme__bootstrap-v3.noty_type__alert,
.noty_theme__bootstrap-v3.noty_type__notification {
background-color: #fff;
color: inherit;
}
.noty_theme__bootstrap-v3.noty_type__warning {
background-color: #fcf8e3;
color: #8a6d3b;
border-color: #faebcc;
}
.noty_theme__bootstrap-v3.noty_type__error {
background-color: #f2dede;
color: #a94442;
border-color: #ebccd1;
}
.noty_theme__bootstrap-v3.noty_type__info,
.noty_theme__bootstrap-v3.noty_type__information {
background-color: #d9edf7;
color: #31708f;
border-color: #bce8f1;
}
.noty_theme__bootstrap-v3.noty_type__success {
background-color: #dff0d8;
color: #3c763d;
border-color: #d6e9c6;
}

65
node_modules/noty/src/themes/bootstrap-v4.scss generated vendored Normal file
View File

@@ -0,0 +1,65 @@
.noty_theme__bootstrap-v4.noty_bar {
margin: 4px 0;
overflow: hidden;
position: relative;
border: 1px solid transparent;
border-radius: .25rem;
.noty_body {
padding: .75rem 1.25rem;
}
.noty_buttons {
padding: 10px;
}
.noty_close_button {
font-size: 1.5rem;
font-weight: 700;
line-height: 1;
color: #000;
text-shadow: 0 1px 0 #fff;
filter: alpha(opacity=20);
opacity: .5;
background: transparent;
}
.noty_close_button:hover {
background: transparent;
text-decoration: none;
cursor: pointer;
filter: alpha(opacity=50);
opacity: .75;
}
}
.noty_theme__bootstrap-v4.noty_type__alert,
.noty_theme__bootstrap-v4.noty_type__notification {
background-color: #fff;
color: inherit;
}
.noty_theme__bootstrap-v4.noty_type__warning {
background-color: #fcf8e3;
color: #8a6d3b;
border-color: #faebcc;
}
.noty_theme__bootstrap-v4.noty_type__error {
background-color: #f2dede;
color: #a94442;
border-color: #ebccd1;
}
.noty_theme__bootstrap-v4.noty_type__info,
.noty_theme__bootstrap-v4.noty_type__information {
background-color: #d9edf7;
color: #31708f;
border-color: #bce8f1;
}
.noty_theme__bootstrap-v4.noty_type__success {
background-color: #dff0d8;
color: #3c763d;
border-color: #d6e9c6;
}

63
node_modules/noty/src/themes/light.scss generated vendored Normal file
View File

@@ -0,0 +1,63 @@
.noty_theme__light.noty_bar {
margin: 4px 0;
overflow: hidden;
border-radius: 2px;
position: relative;
.noty_body {
padding: 10px;
}
.noty_buttons {
border-top: 1px solid #e7e7e7;
padding: 5px 10px;
}
}
.noty_theme__light.noty_type__alert,
.noty_theme__light.noty_type__notification {
background-color: #fff;
border: 1px solid #dedede;
color: #444;
}
.noty_theme__light.noty_type__warning {
background-color: #FFEAA8;
border: 1px solid #FFC237;
color: #826200;
.noty_buttons {
border-color: #dfaa30;
}
}
.noty_theme__light.noty_type__error {
background-color: #ED7000;
border: 1px solid #e25353;
color: #FFF;
.noty_buttons {
border-color: darkred;
}
}
.noty_theme__light.noty_type__info,
.noty_theme__light.noty_type__information {
background-color: #78C5E7;
border: 1px solid #3badd6;
color: #FFF;
.noty_buttons {
border-color: #0B90C4;
}
}
.noty_theme__light.noty_type__success {
background-color: #57C880;
border: 1px solid #7cdd77;
color: darkgreen;
.noty_buttons {
border-color: #50C24E;
}
}

53
node_modules/noty/src/themes/metroui.scss generated vendored Normal file
View File

@@ -0,0 +1,53 @@
.noty_theme__metroui.noty_bar {
margin: 4px 0;
overflow: hidden;
position: relative;
box-shadow: rgba(0, 0, 0, 0.298039) 0 0 5px 0;
.noty_progressbar {
position: absolute;
left: 0;
bottom: 0;
height: 3px;
width: 100%;
background-color: #000;
opacity: 0.2;
filter: alpha(opacity=20)
}
.noty_body {
padding: 1.25em;
font-size: 14px;
}
.noty_buttons {
padding: 0 10px .5em 10px;
}
}
.noty_theme__metroui.noty_type__alert,
.noty_theme__metroui.noty_type__notification {
background-color: #fff;
color: #1d1d1d;
}
.noty_theme__metroui.noty_type__warning {
background-color: #FA6800;
color: #fff;
}
.noty_theme__metroui.noty_type__error {
background-color: #CE352C;
color: #FFF;
}
.noty_theme__metroui.noty_type__info,
.noty_theme__metroui.noty_type__information {
background-color: #1BA1E2;
color: #FFF;
}
.noty_theme__metroui.noty_type__success {
background-color: #60A917;
color: #fff;
}

47
node_modules/noty/src/themes/mint.scss generated vendored Normal file
View File

@@ -0,0 +1,47 @@
.noty_theme__mint.noty_bar {
margin: 4px 0;
overflow: hidden;
border-radius: 2px;
position: relative;
.noty_body {
padding: 10px;
font-size: 14px;
}
.noty_buttons {
padding: 10px;
}
}
.noty_theme__mint.noty_type__alert,
.noty_theme__mint.noty_type__notification {
background-color: #fff;
border-bottom: 1px solid #D1D1D1;
color: #2F2F2F;
}
.noty_theme__mint.noty_type__warning {
background-color: #FFAE42;
border-bottom: 1px solid #E89F3C;
color: #fff;
}
.noty_theme__mint.noty_type__error {
background-color: #DE636F;
border-bottom: 1px solid #CA5A65;
color: #fff;
}
.noty_theme__mint.noty_type__info,
.noty_theme__mint.noty_type__information {
background-color: #7F7EFF;
border-bottom: 1px solid #7473E8;
color: #fff;
}
.noty_theme__mint.noty_type__success {
background-color: #AFC765;
border-bottom: 1px solid #A0B55C;
color: #fff;
}

146
node_modules/noty/src/themes/nest.scss generated vendored Normal file
View File

@@ -0,0 +1,146 @@
.noty_theme__nest.noty_bar {
margin: 0 0 15px 0;
overflow: hidden;
border-radius: 2px;
position: relative;
box-shadow: rgba(0, 0, 0, 0.098039) 5px 4px 10px 0;
.noty_body {
padding: 10px;
font-size: 14px;
text-shadow: 1px 1px 1px rgba(0, 0, 0, .1);
}
.noty_buttons {
padding: 10px;
}
}
.noty_layout .noty_theme__nest.noty_bar {
z-index: 5;
}
.noty_layout .noty_theme__nest.noty_bar:nth-child(2) {
position: absolute;
top: 0;
margin-top: 4px;
margin-right: -4px;
margin-left: 4px;
z-index: 4;
width: 100%;
}
.noty_layout .noty_theme__nest.noty_bar:nth-child(3) {
position: absolute;
top: 0;
margin-top: 8px;
margin-right: -8px;
margin-left: 8px;
z-index: 3;
width: 100%;
}
.noty_layout .noty_theme__nest.noty_bar:nth-child(4) {
position: absolute;
top: 0;
margin-top: 12px;
margin-right: -12px;
margin-left: 12px;
z-index: 2;
width: 100%;
}
.noty_layout .noty_theme__nest.noty_bar:nth-child(5) {
position: absolute;
top: 0;
margin-top: 16px;
margin-right: -16px;
margin-left: 16px;
z-index: 1;
width: 100%;
}
.noty_layout .noty_theme__nest.noty_bar:nth-child(n+6) {
position: absolute;
top: 0;
margin-top: 20px;
margin-right: -20px;
margin-left: 20px;
z-index: -1;
width: 100%;
}
// left corner stacks
#noty_layout__bottomLeft .noty_theme__nest.noty_bar:nth-child(2),
#noty_layout__topLeft .noty_theme__nest.noty_bar:nth-child(2) {
margin-top: 4px;
margin-left: -4px;
margin-right: 4px;
}
#noty_layout__bottomLeft .noty_theme__nest.noty_bar:nth-child(3),
#noty_layout__topLeft .noty_theme__nest.noty_bar:nth-child(3) {
margin-top: 8px;
margin-left: -8px;
margin-right: 8px;
}
#noty_layout__bottomLeft .noty_theme__nest.noty_bar:nth-child(4),
#noty_layout__topLeft .noty_theme__nest.noty_bar:nth-child(4) {
margin-top: 12px;
margin-left: -12px;
margin-right: 12px;
}
#noty_layout__bottomLeft .noty_theme__nest.noty_bar:nth-child(5),
#noty_layout__topLeft .noty_theme__nest.noty_bar:nth-child(5) {
margin-top: 16px;
margin-left: -16px;
margin-right: 16px;
}
#noty_layout__bottomLeft .noty_theme__nest.noty_bar:nth-child(n+6),
#noty_layout__topLeft .noty_theme__nest.noty_bar:nth-child(n+6) {
margin-top: 20px;
margin-left: -20px;
margin-right: 20px;
}
.noty_theme__nest.noty_type__alert,
.noty_theme__nest.noty_type__notification {
background-color: #073B4C;
color: #fff;
.noty_progressbar {
background-color: #fff;
}
}
.noty_theme__nest.noty_type__warning {
background-color: #FFD166;
color: #fff;
}
.noty_theme__nest.noty_type__error {
background-color: #EF476F;
color: #fff;
.noty_progressbar {
opacity: .4;
}
}
.noty_theme__nest.noty_type__info,
.noty_theme__nest.noty_type__information {
background-color: #118AB2;
color: #fff;
.noty_progressbar {
opacity: .6;
}
}
.noty_theme__nest.noty_type__success {
background-color: #06D6A0;
color: #fff;
}

63
node_modules/noty/src/themes/relax.scss generated vendored Normal file
View File

@@ -0,0 +1,63 @@
.noty_theme__relax.noty_bar {
margin: 4px 0;
overflow: hidden;
border-radius: 2px;
position: relative;
.noty_body {
padding: 10px;
}
.noty_buttons {
border-top: 1px solid #e7e7e7;
padding: 5px 10px;
}
}
.noty_theme__relax.noty_type__alert,
.noty_theme__relax.noty_type__notification {
background-color: #fff;
border: 1px solid #dedede;
color: #444;
}
.noty_theme__relax.noty_type__warning {
background-color: #FFEAA8;
border: 1px solid #FFC237;
color: #826200;
.noty_buttons {
border-color: #dfaa30;
}
}
.noty_theme__relax.noty_type__error {
background-color: #FF8181;
border: 1px solid #e25353;
color: #FFF;
.noty_buttons {
border-color: darkred;
}
}
.noty_theme__relax.noty_type__info,
.noty_theme__relax.noty_type__information {
background-color: #78C5E7;
border: 1px solid #3badd6;
color: #FFF;
.noty_buttons {
border-color: #0B90C4;
}
}
.noty_theme__relax.noty_type__success {
background-color: #BCF5BC;
border: 1px solid #7cdd77;
color: darkgreen;
.noty_buttons {
border-color: #50C24E;
}
}

53
node_modules/noty/src/themes/semanticui.scss generated vendored Normal file
View File

@@ -0,0 +1,53 @@
.noty_theme__semanticui.noty_bar {
margin: 4px 0;
overflow: hidden;
position: relative;
border: 1px solid transparent;
font-size: 1em;
border-radius: .28571429rem;
box-shadow: 0 0 0 1px rgba(34,36,38,.22) inset, 0 0 0 0 transparent;
.noty_body {
padding: 1em 1.5em;
line-height: 1.4285em;
}
.noty_buttons {
padding: 10px;
}
}
.noty_theme__semanticui.noty_type__alert,
.noty_theme__semanticui.noty_type__notification {
background-color: #f8f8f9;
color: rgba(0,0,0,.87);
}
.noty_theme__semanticui.noty_type__warning {
background-color: #fffaf3;
color: #573a08;
box-shadow: 0 0 0 1px #c9ba9b inset, 0 0 0 0 transparent;
}
.noty_theme__semanticui.noty_type__error {
background-color: #fff6f6;
color: #9f3a38;
box-shadow: 0 0 0 1px #e0b4b4 inset, 0 0 0 0 transparent;
}
.noty_theme__semanticui.noty_type__info,
.noty_theme__semanticui.noty_type__information {
background-color: #f8ffff;
color: #276f86;
box-shadow: 0 0 0 1px #a9d5de inset, 0 0 0 0 transparent;
}
.noty_theme__semanticui.noty_type__success {
background-color: #fcfff5;
color: #2c662d;
box-shadow: 0 0 0 1px #a3c293 inset, 0 0 0 0 transparent;
}

55
node_modules/noty/src/themes/sunset.scss generated vendored Normal file
View File

@@ -0,0 +1,55 @@
.noty_theme__sunset.noty_bar {
margin: 4px 0;
overflow: hidden;
border-radius: 2px;
position: relative;
.noty_body {
padding: 10px;
font-size: 14px;
text-shadow: 1px 1px 1px rgba(0, 0, 0, .1);
}
.noty_buttons {
padding: 10px;
}
}
.noty_theme__sunset.noty_type__alert,
.noty_theme__sunset.noty_type__notification {
background-color: #073B4C;
color: #fff;
.noty_progressbar {
background-color: #fff;
}
}
.noty_theme__sunset.noty_type__warning {
background-color: #FFD166;
color: #fff;
}
.noty_theme__sunset.noty_type__error {
background-color: #EF476F;
color: #fff;
.noty_progressbar {
opacity: .4;
}
}
.noty_theme__sunset.noty_type__info,
.noty_theme__sunset.noty_type__information {
background-color: #118AB2;
color: #fff;
.noty_progressbar {
opacity: .6;
}
}
.noty_theme__sunset.noty_type__success {
background-color: #06D6A0;
color: #fff;
}

295
node_modules/noty/src/utils.js generated vendored Normal file
View File

@@ -0,0 +1,295 @@
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]
}