Files
vanillajs-seed/node_modules/pnotify/README.md
2019-04-12 20:01:07 +02:00

699 lines
26 KiB
Markdown

[![npm version](https://badge.fury.io/js/pnotify.svg)](https://www.npmjs.com/package/pnotify) [![Waffle.io - Columns and their card count](https://badge.waffle.io/sciactive/pnotify.svg?columns=all)](https://waffle.io/sciactive/pnotify) [![jsDelivr Hits](https://data.jsdelivr.com/v1/package/npm/pnotify/badge?style=rounded)](https://www.jsdelivr.com/package/npm/pnotify)
PNotify is a vanilla JavaScript notification library. PNotify can provide [desktop notifications](http://sciactive.com/pnotify/#web-notifications) based on the [Web Notifications spec](http://www.w3.org/TR/notifications/) with fall back to an in-browser notice.
<h1>Demos</h1>
* http://sciactive.com/pnotify/ for the latest release (v3)
* https://sciactive.github.io/pnotify/ for what's in development (v4-beta)
<h1>Table of Contents</h1>
<!-- TOC START min:1 max:3 link:true update:true -->
- [Whoa there!](#whoa-there)
- [Running PNotify 3 Code with the Compat Module](#running-pnotify-3-code-with-the-compat-module)
- [Getting Started](#getting-started)
- [Installation](#installation)
- [Svelte](#svelte)
- [React](#react)
- [Angular](#angular)
- [Angular (Injectable)](#angular-injectable)
- [AngularJS](#angularjs)
- [Vanilla JS (ES5)](#vanilla-js-es5)
- [Vanilla JS (ES6)](#vanilla-js-es6)
- [Styles](#styles)
- [Bright Theme](#bright-theme)
- [Material](#material)
- [Material Icons](#material-icons)
- [Bootstrap](#bootstrap)
- [Font Awesome (Icons)](#font-awesome-icons)
- [Creating Notices](#creating-notices)
- [Options](#options)
- [Changing Defaults](#changing-defaults)
- [Desktop Module](#desktop-module)
- [Buttons Module](#buttons-module)
- [NonBlock Module](#nonblock-module)
- [Mobile Module](#mobile-module)
- [Animate Module](#animate-module)
- [Confirm Module](#confirm-module)
- [History Module](#history-module)
- [Callbacks Module](#callbacks-module)
- [Static Methods and Properties](#static-methods-and-properties)
- [Instance Methods and Properties](#instance-methods-and-properties)
- [From the Svelte Component API](#from-the-svelte-component-api)
- [Events](#events)
- [Stacks](#stacks)
- [Example Stack](#example-stack)
- [Features](#features)
- [Licensing and Additional Info](#licensing-and-additional-info)
<!-- TOC END -->
# Whoa there!
Unless you're a beta tester, **none of this README applies to you!** You want to check out the **[README on the master branch](https://github.com/sciactive/pnotify/blob/master/README.md)**.
This README is for **PNotify 4**. v4 is in beta stage, but it's got some huge changes:
* **jQuery is no longer required.** v4 doesn't require any libraries, actually.
* It's built using [Svelte](http://svelte.technology), which means it compiles down to vanilla JS.
* Has an ES module build.
* Options are in camelCase instead of snake_case.
* `text_escape`/`title_escape` replaced by `textTrusted`/`titleTrusted`, and default behavior changed.
* `insert_brs` went away. (Now uses `white-space: pre-line;`.)
* Default width raised to 360px.
* NonBlock module spun off into its own project, [NonBlock.js](https://github.com/sciactive/nonblockjs).
* There is a Compat module available to allow you to run PNotify 3 code with PNotify 4.
It should be safe to use in production code, but please report any issues you run into.
## Running PNotify 3 Code with the Compat Module
You can use `PNotifyCompat` instead of `PNotify` in order to run PNotify 3 code. Check out `demo/compat-*.html` for more examples.
```js
import PNotify from 'pnotify/dist/es/PNotifyCompat';
new PNotify({
title: 'Regular Notice',
text: 'Check me out! I\'m a notice.',
text_escape: true // <-- old options work
});
```
# Getting Started
You can get PNotify using NPM. (You can also use [jsDelivr](https://www.jsdelivr.com/package/npm/pnotify) or [UNPKG](https://unpkg.com/pnotify/).)
```sh
npm install --save pnotify
# If you plan to use Material style:
npm install --save material-design-icons
# If you plan to use the Animate module:
npm install --save animate.css
# If you plan to use the NonBlock module:
npm install --save nonblockjs
```
Inside the pnotify module directory:
* `src` Svelte components and uncompressed Bright Theme CSS.
* `lib/es` uncompressed ECMAScript modules.
* `lib/umd` uncompressed UMD modules.
* `lib/iife` uncompressed IIFE scripts.
* `dist` compressed Bright Theme CSS.
* `dist/es` compressed ECMAScript modules.
* `dist/umd` compressed UMD modules.liz
* `dist/iife` compressed IIFE scripts.
# Installation
In addition to the JS, be sure to [include a PNotify style](#styles).
## Svelte
[PNotify in Svelte](https://codesandbox.io/s/nwoxqkvw6m). Import the Svelte files from `src`:
```js
import PNotify from 'pnotify/src/PNotify.html';
import PNotifyButtons from 'pnotify/src/PNotifyButtons.html';
PNotify.alert('Notice me, senpai!');
```
## React
[PNotify in React](https://codesandbox.io/s/wwqzk8472w). Import the ES modules from `dist`:
```js
import PNotify from 'pnotify/dist/es/PNotify';
import PNotifyButtons from 'pnotify/dist/es/PNotifyButtons';
PNotify.alert('Notice me, senpai!');
```
## Angular
[PNotify in Angular](https://codesandbox.io/s/l3pzkl64yq). Import the ES modules from `dist` and initiate the modules:
```ts
import PNotify from 'pnotify/dist/es/PNotify';
import PNotifyButtons from 'pnotify/dist/es/PNotifyButtons';
//...
export class WhateverComponent {
constructor() {
PNotifyButtons; // Initiate the module. Important!
PNotify.alert('Notice me, senpai!');
}
}
```
<small>For IE support, see [this issue](https://github.com/sciactive/pnotify/issues/343).</small>
## Angular (Injectable)
[PNotify in Angular](https://codesandbox.io/s/17yr520yj) as an injectable service:
```ts
// pnotify.service.ts
import { Injectable } from '@angular/core';
import PNotify from 'pnotify/dist/es/PNotify';
import PNotifyButtons from 'pnotify/dist/es/PNotifyButtons';
@Injectable()
export class PNotifyService {
getPNotify() {
PNotifyButtons; // Initiate the module. Important!
return PNotify;
}
}
// whatever.module.ts
//...
import { PNotifyService } from './pnotify.service';
@NgModule({
declarations: [...],
imports: [...],
providers: [PNotifyService],
bootstrap: [...]
})
export class WhateverModule {}
// whatever.component.ts
import { PNotifyService } from './pnotify.service';
//...
export class WhateverComponent {
pnotify = undefined;
constructor(pnotifyService: PNotifyService) {
this.pnotify = pnotifyService.getPNotify();
this.pnotify.alert('Notice me, senpai!');
}
}
```
## AngularJS
[PNotify in AngularJS](https://codesandbox.io/s/o5mp55p2p9). Import the UMD modules from `dist`:
```js
var angular = require('angular');
var PNotify = require('pnotify/dist/umd/PNotify');
var PNotifyButtons = require('pnotify/dist/umd/PNotifyButtons');
angular.module('WhateverModule', [])
.value('PNotify', PNotify)
.controller('WhateverController', ['PNotify', function(PNotify) {
PNotify.alert('Notice me, senpai!');
}]);
```
## Vanilla JS (ES5)
PNotify in vanilla ECMAScript 5. Include the IIFE scripts from `dist`:
```html
<script type="text/javascript" src="node_modules/pnotify/dist/iife/PNotify.js"></script>
<script type="text/javascript" src="node_modules/pnotify/dist/iife/PNotifyButtons.js"></script>
<script type="text/javascript">
PNotify.alert('Notice me, senpai!');
</script>
```
## Vanilla JS (ES6)
PNotify in vanilla ECMAScript 6+. Include the ES modules from `dist`:
```js
import PNotify from 'node_modules/pnotify/dist/es/PNotify.js';
import PNotifyButtons from 'node_modules/pnotify/dist/es/PNotifyButtons.js';
PNotify.alert('Notice me, senpai!');
```
# Styles
## Bright Theme
The default, standalone theme, Bright Theme. Include the CSS file in your page:
```html
<link href="node_modules/pnotify/dist/PNotifyBrightTheme.css" rel="stylesheet" type="text/css" />
```
## Material
The Material Style module. Requires [material-design-icons](https://www.npmjs.com/package/material-design-icons). Include the module in your JS, and set it as the default:
```js
import PNotifyStyleMaterial from 'pnotify/dist/es/PNotifyStyleMaterial.js';
// or
var PNotifyStyleMaterial = require('pnotify/dist/umd/PNotifyStyleMaterial.js');
// Set default styling.
PNotify.defaults.styling = 'material';
// This icon setting requires the Material Icons font. (See below.)
PNotify.defaults.icons = 'material';
```
### Material Icons
To use the Material Style icons, include the Material Design Icons Font in your page.
```sh
# The official Google package:
npm install --save material-design-icons
# OR, An unofficial package that only includes the font:
npm install --save material-design-icon-fonts
```
```html
<link rel="stylesheet" href="node_modules/material-design-icons/iconfont/material-icons.css" />
```
Alternatively, you can use the Google Fonts CDN:
```html
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Material+Icons" />
```
## Bootstrap
To set Bootstrap as the default style, include the appropriate line(s) from below after you import PNotify:
```js
PNotify.defaults.styling = 'bootstrap3'; // Bootstrap version 3
PNotify.defaults.icons = 'bootstrap3'; // glyphicons
// or
PNotify.defaults.styling = 'bootstrap4'; // Bootstrap version 4
```
## Font Awesome (Icons)
To set Font Awesome as the default icons, include the appropriate line from below after you import PNotify:
```js
PNotify.defaults.icons = 'fontawesome4'; // Font Awesome 4
// or
PNotify.defaults.icons = 'fontawesome5'; // Font Awesome 5
```
# Creating Notices
To make a notice, use the helper functions:
```js
// Manually set the type.
PNotify.alert({
text: "I'm an alert.",
type: 'notice'
});
// Automatically set the type.
PNotify.notice({
text: "I'm a notice."
});
PNotify.info({
text: "I'm an info message."
});
PNotify.success({
text: "I'm a success message."
});
PNotify.error({
text: "I'm an error message."
});
```
Or you can manually create a new notice (if you know what you're doing):
```js
new PNotify({
target: document.body,
data: {
text: "I'm an alert.",
type: 'notice'
}
});
```
# Options
PNotify options and default values.
* `title: false` - The notice's title.
* `titleTrusted: false` - Whether to trust the title or escape its contents. (Not allow HTML.)
* `text: false` - The notice's text.
* `textTrusted: false` - Whether to trust the text or escape its contents. (Not allow HTML.)
* `styling: 'brighttheme'` - What styling classes to use. (Can be 'brighttheme', 'bootstrap3', 'bootstrap4', or a styling object. See the source in PNotifyStyleMaterial.html for the properties in a style object.)
* `icons: 'brighttheme'` - What icons classes to use (Can be 'brighttheme', 'bootstrap3', 'fontawesome4', 'fontawesome5', or an icon object. See the source in PNotifyStyleMaterial.html for the properties in an icon object.)
* `addClass: ''` - Additional classes to be added to the notice. (For custom styling.)
* `cornerClass: ''` - Class to be added to the notice for corner styling.
* `autoDisplay: true` - Display the notice when it is created. Turn this off to add notifications to the history without displaying them.
* `width: '360px'` - Width of the notice.
* `minHeight: '16px'` - Minimum height of the notice. It will expand to fit content.
* `type: 'notice'` - Type of the notice. 'notice', 'info', 'success', or 'error'.
* `icon: true` - Set icon to true to use the default icon for the selected style/type, false for no icon, or a string for your own icon class.
* `animation: 'fade'` - The animation to use when displaying and hiding the notice. 'none' and 'fade' are supported through CSS. Others are supported through the Animate module and Animate.css.
* `animateSpeed: 'normal'` - Speed at which the notice animates in and out. 'slow', 'normal', or 'fast'. Respectively, 400ms, 250ms, 100ms.
* `shadow: true` - Display a drop shadow.
* `hide: true` - After a delay, close the notice.
* `delay: 8000` - Delay in milliseconds before the notice is closed.
* `mouseReset: true` - Reset the hide timer if the mouse moves over the notice.
* `remove: true` - Remove the notice's elements from the DOM after it is closed.
* `destroy: true` - Whether to remove the notice from the global array when it is closed.
* `stack: PNotify.defaultStack` - The stack on which the notices will be placed. Also controls the direction the notices stack.
* `modules: {}` - This is where options for modules should be defined.
```js
PNotify.defaultStack = {
dir1: 'down',
dir2: 'left',
firstpos1: 25,
firstpos2: 25,
spacing1: 36,
spacing2: 36,
push: 'bottom',
context: document.body
}
```
## Changing Defaults
```js
PNotify.defaults.width = '400px';
```
Changing a default for modules can be done in a couple ways.
```js
// This will change the default for every notice and is the recommended way.
PNotify.modules.History.defaults.maxInStack = 10;
// This will change the default only for notices that don't have a module option.
PNotify.defaults.modules = {
History: {
maxInStack: 10
}
};
```
## Desktop Module
`Desktop: {`
* `desktop: false` - Display the notification as a desktop notification.
* `fallback: true` - If desktop notifications are not supported or allowed, fall back to a regular notice.
* `icon: null` - The URL of the icon to display. If false, no icon will show. If null, a default icon will show.
* `tag: null` - Using a tag lets you update an existing notice, or keep from duplicating notices between tabs. If you leave tag null, one will be generated, facilitating the `update` function.
* `title: null` - Optionally display a different title for the desktop.
* `text: null` - Optionally display different text for the desktop.
* `options: {}` - Any additional options to be passed to the Notification constructor.
`}`
## Buttons Module
`Buttons: {`
* `closer: true` - Provide a button for the user to manually close the notice.
* `closerHover: true` - Only show the closer button on hover.
* `sticker: true` - Provide a button for the user to manually stick the notice.
* `stickerHover: true` - Only show the sticker button on hover.
* `labels: {close: 'Close', stick: 'Stick', unstick: 'Unstick'}` - Lets you change the displayed text, facilitating internationalization.
* `classes: {closer: null, pinUp: null, pinDown: null}` - The classes to use for button icons. Leave them null to use the classes from the styling you're using.
`}`
> :information_source: In v4, it's no longer possible to show closer/sticker buttons when the notice is nonblocking.
## NonBlock Module
Requires [NonBlock.js](https://github.com/sciactive/nonblockjs) 1.0.8 or higher.
**It is also deprecated and unnecessary in v4.** All it does is add the 'nonblock' class to your notice. You can do the same yourself with `addClass: 'nonblock'`.
`NonBlock: {`
* `nonblock: false` - Use NonBlock.js to create a non-blocking notice. It lets the user click elements underneath it.
`}`
## Mobile Module
`Mobile: {`
* `swipeDismiss: true` - Let the user swipe the notice away.
* `styling: true` - Styles the notice to look good on mobile.
`}`
## Animate Module
Requires [Animate.css](https://daneden.github.io/animate.css/).
`Animate: {`
* `animate: false` - Use animate.css to animate the notice.
* `inClass: ''` - The class to use to animate the notice in.
* `outClass: ''` - The class to use to animate the notice out.
`}`
The Animate module also creates a method, `attention`, on notices which accepts an attention grabber class and an animation completed callback.
## Confirm Module
`Confirm: {`
* `confirm: false` - Make a confirmation box.
* `prompt: false` - Make a prompt.
* `promptClass: ''` - Classes to add to the input element of the prompt.
* `promptValue: ''` - The value of the prompt. (Note that this is two-way bound to the input.)
* `promptMultiLine: false` - Whether the prompt should accept multiple lines of text.
* `align: 'right'` - Where to align the buttons. (right, center, left, justify)
```js
buttons: [
{
text: 'Ok',
textTrusted: false,
addClass: '',
primary: true,
// Whether to trigger this button when the user hits enter in a single line
// prompt. Also, focus the button if it is a modal prompt.
promptTrigger: true,
click: (notice, value) => {
notice.close();
notice.fire('pnotify.confirm', {notice, value});
}
},
{
text: 'Cancel',
textTrusted: false,
addClass: '',
click: (notice) => {
notice.close();
notice.fire('pnotify.cancel', {notice});
}
}
]
```
* The buttons to display, and their callbacks. If a button has promptTrigger set to true, it will be triggered when the user hits enter in a prompt (unless they hold shift).
`}`
Because the default buttons fire notice events on confirmation and cancellation, you can listen for them like this:
```js
const notice = PNotify.alert({
title: 'Confirmation Needed',
text: 'Are you sure?',
hide: false,
modules: {
Confirm: {
confirm: true
}
}
});
notice.on('pnotify.confirm', () => {
// User confirmed, continue here...
});
notice.on('pnotify.cancel', () => {
// User canceled, continue here...
});
```
## History Module
`History: {`
* `history: true` - Place the notice in the history.
* `maxInStack: Infinity` - Maximum number of notices to have open in its stack.
`}`
The History module also has two methods:
* `PNotify.modules.History.showLast(stack)` - Reopen the last closed notice from a stack that was placed in the history. If no stack is provided, it will use the default stack.
* `PNotify.modules.History.showAll(stack)` - Reopen all notices from a stack that were placed in the history. If no stack is provided, it will also use the default stack. If stack is `true`, it will reopen all notices from every stack.
> :information_source: In v4, the History module can no longer make a dropdown for you. But hey, it's smaller now.
## Callbacks Module
The callback options all expect the value to be a callback function. If the function returns false on the `beforeOpen` or `beforeClose` callback, that event will be canceled. `beforeInit` and `afterInit` will only work for notices created with the helper functions.
`Callbacks: {`
* `beforeInit` - Called before the notice has been initialized. Given one argument, the options object.
* `afterInit` - Called after the notice has been initialized. Given one argument, the notice object.
* `beforeOpen` - Called before the notice opens. Given one argument, the notice object.
* `afterOpen` - Called after the notice opens. Given one argument, the notice object.
* `beforeClose` - Called before the notice closes. Given one argument, the notice object.
* `afterClose` - Called after the notice closes. Given one argument, the notice object.
`}`
# Static Methods and Properties
* `PNotify.alert(options)` - Create a notice.
* `PNotify.notice(options)` - Create a notice with 'notice' type.
* `PNotify.info(options)` - Create a notice with 'info' type.
* `PNotify.success(options)` - Create a notice with 'success' type.
* `PNotify.error(options)` - Create a notice with 'error' type.
* `PNotify.closeAll()` - Close all notices.
* `PNotify.removeAll()` - Alias for closeAll(). (Deprecated)
* `PNotify.closeStack(stack)` - Close all the notices in a stack.
* `PNotify.removeStack(stack)` - Alias for closeStack(stack). (Deprecated)
* `PNotify.positionAll()` - Reposition all notices.
* `PNotify.VERSION` - PNotify version number.
* `PNotify.defaults` - Defaults for options.
* `PNotify.defaultStack` - The default stack object.
* `PNotify.notices` - An array of all active notices.
* `PNotify.modules` - This object holds all the PNotify modules.
* `PNotify.styling` - Styling objects.
# Instance Methods and Properties
* `notice.open()` - Open the notice.
* `notice.close()` - Close the notice.
* `notice.remove()` - Alias for close(). (Deprecated)
* `notice.update(options)` - Update the notice with new options.
* `notice.addModuleClass(...classNames)` - This is for modules to add classes to the notice.
* `notice.removeModuleClass(...classNames)` - This is for modules to remove classes from the notice.
* `notice.hasModuleClass(...classNames)` - This is for modules to test classes on the notice.
* `notice.refs.elem` - The notice's DOM element.
* `notice.refs.container` - The notice container DOM element.
* `notice.refs.titleContainer` - The title container DOM element.
* `notice.refs.textContainer` - The text container DOM element.
* `notice.refs.iconContainer` - The icon container DOM element.
## From the [Svelte Component API](https://svelte.technology/guide#component-api)
* `notice.get(option)` - Get the value of an option.
* `notice.set(options)` - You probably want to use `update(options)` instead. It has some special PNotify secret sauce to make sure your notice doesn't break.
* `notice.observe(key, callback[, options])` - Observe an option. See the Svelte docs for more info.
* `notice.destroy()` - Removes the component from the DOM and any observers/event listeners. You probably want to use `close()` instead. It will animate the notice out and you can open it again. Once you destroy it, you can't open it again.
## Events
* `notice.on(eventName, callback)` - Assign a callback to an event. Callback receives an `event` argument.
* `notice.fire(eventName, event)` - Fire an event.
# Stacks
A stack is an object used to determine where to position notices.
Stack properties:
* `dir1` - The primary stacking direction. Can be `'up'`, `'down'`, `'right'`, or `'left'`.
* `firstpos1` - Number of pixels from the edge of the context, relative to `dir1`, the first notice will appear. If undefined, the current position of the notice, whatever that is, will be used.
* `spacing1` - Number of pixels between notices along `dir1`. If undefined, `25` will be used.
* `dir2` - The secondary stacking direction. Should be a perpendicular direction to `dir1`. The notices will continue in this direction when they reach the edge of the viewport along `dir1`.
* `firstpos2` - Number of pixels from the edge of the context, relative to `dir2`, the first notice will appear. If undefined, the current position of the notice, whatever that is, will be used.
* `spacing2` - Number of pixels between notices along `dir2`. If undefined, `25` will be used.
* `push` - Where, in the stack, to push new notices. Can be `'top'` or `'bottom'`.
* `modal` - Whether to create a modal overlay when this stack's notices are open.
* `overlayClose` - Whether clicking on the modal overlay should close the stack's notices.
* `context` - The DOM element this stack's notices should appear in. If undefined, `document.body` will be used.
Stack behavior:
* If there is no `dir1` property, the notice will be centered in the context.
* If there is a `dir1` and no `dir2`, the notices will be centered along the axis of `dir1`.
* The `firstpos*` values are relative to an edge determined by the corresponding `dir*` value.
* `dirX === 'up'` - `firstposX` is relative to the **bottom** edge.
* `dirX === 'down'` - `firstposX` is relative to the **top** edge.
* `dirX === 'left'` - `firstposX` is relative to the **right** edge.
* `dirX === 'right'` - `firstposX` is relative to the **left** edge.
* Stacks are independent of each other, so a stack doesn't know and doesn't care if it overlaps (and blocks) another stack.
* Stack objects are used and manipulated by PNotify, and therefore, should be a variable when passed.
> :warning: Calling something like `PNotify.alert({text: 'notice', stack: {dir1: 'down', firstpos1: 25}});` may not do what you want. It will create a notice, but that notice will be in its own stack and will overlap other notices.
## Example Stack
Here is an example stack with comments to explain. You can play with it [here](https://codesandbox.io/s/2po6zq9yrr).
```js
const stackBottomModal = {
dir1: 'up', // With a dir1 of 'up', the stacks will start appearing at the bottom.
// Without a `dir2`, this stack will be horizontally centered, since the `dir1` axis is vertical.
firstpos1: 25, // The notices will appear 25 pixels from the bottom of the context.
// Without a `spacing1`, this stack's notices will be placed 25 pixels apart.
push: 'top', // Each new notice will appear at the bottom of the screen, which is where the 'top' of the stack is. Other notices will be pushed up.
modal: true, // When a notice appears in this stack, a modal overlay will be created.
overlayClose: true, // When the user clicks on the overlay, all notices in this stack will be closed.
context: document.getElementById('page-container') // The notices will be placed in the 'page-container' element.
};
```
If you just want to position a single notice programmatically, and don't want to add any other notices into the stack, you can use something like this:
```js
PNotify.alert({
text: "Notice that's positioned in its own stack.",
stack: {
dir1: 'down', dir2: 'right', // Position from the top left corner.
firstpos1: 90, firstpos2: 90 // 90px from the top, 90px from the left.
}
});
```
# Features
* Rich graphical features and effects.
* Material, Bootstrap 3/4, Font Awesome 4/5, or the stand-alone theme, Bright Theme.
* Mobile styling and swipe support.
* Timed hiding.
* Slick animations with Animate.css.
* Attention getters with Animate.css.
* Highly customizable UI.
* Sticky notices.
* Optional close and stick buttons.
* Non-blocking notices for less intrusive use.
* Notification types: notice, info, success, and error.
* Stacks allow notices to position together or independently.
* Control stack direction and push to top or bottom.
* Modal notices.
* Confirm dialogs, alert buttons, and prompts.
* RTL language support.
* Feature rich API.
* Desktop notifications based on the Web Notifications standard.
* Dynamically update existing notices.
* Put forms and other HTML in notices.
* By default, escapes text to prevent XSS attack.
* Callbacks for lifespan events.
* Notice history for reshowing old notices.
* Universally compatible.
* Works with any frontend library.
* No dependencies for most features.
# Licensing and Additional Info
PNotify is distributed under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0).
See http://sciactive.com/pnotify/ for more information, and demos.
<h2>Support on Beerpay</h2>
Hey dude! Help me out for a couple of :beers:!
[![Beerpay](https://beerpay.io/sciactive/pnotify/badge.svg?style=beer-square)](https://beerpay.io/sciactive/pnotify) [![Beerpay](https://beerpay.io/sciactive/pnotify/make-wish.svg?style=flat-square)](https://beerpay.io/sciactive/pnotify?focus=wish)