Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
36ee2b8298 | ||
|
|
7a30b52ad6 | ||
|
|
8a89efc74a | ||
|
|
2edc584359 | ||
|
|
dfd0df0a59 | ||
|
|
3e98e714c6 |
@@ -0,0 +1,3 @@
|
||||
2015-10-20 v0.3.3
|
||||
|
||||
ECARROLL- Updated to remove Grunt, and coffeescript stuff.
|
||||
@@ -1,65 +0,0 @@
|
||||
fs = require("fs")
|
||||
|
||||
#global module:false
|
||||
module.exports = (grunt) ->
|
||||
|
||||
# Project configuration.
|
||||
grunt.initConfig
|
||||
pkg: grunt.file.readJSON('package.json')
|
||||
banner:
|
||||
"/** <%= pkg.title || pkg.name %> - v<%= pkg.version %> - <%= grunt.template.today(\"yyyy/mm/dd\") %>\n"+
|
||||
" * <%= pkg.homepage %>\n" +
|
||||
" * Copyright (c) <%= grunt.template.today(\"yyyy\") %> <%= pkg.author.name %> - MIT\n"+
|
||||
" */\n"
|
||||
|
||||
coffee:
|
||||
options:
|
||||
bare: true
|
||||
compile:
|
||||
expand: true,
|
||||
flatten: false,
|
||||
cwd: 'src',
|
||||
src: ['**/*.coffee'],
|
||||
dest: 'dist/',
|
||||
ext: '.js'
|
||||
|
||||
wrap:
|
||||
dist:
|
||||
src: 'dist/<%= pkg.name %>.js'
|
||||
dest: '.'
|
||||
wrapper: [
|
||||
"<%= banner %>(function(window,document,$,undefined) {\n"
|
||||
"\n}(window,document,jQuery));"
|
||||
]
|
||||
|
||||
concat:
|
||||
combined:
|
||||
src: ['dist/<%= pkg.name %>.js', 'dist/styles/bootstrap/<%= pkg.name %>-bootstrap.js']
|
||||
dest: 'dist/<%= pkg.name %>-combined.js'
|
||||
|
||||
uglify:
|
||||
options:
|
||||
stripBanners: true
|
||||
banner: '<%= banner %>'
|
||||
|
||||
dist:
|
||||
src: "dist/<%= pkg.name %>.js"
|
||||
dest: "dist/<%= pkg.name %>.min.js"
|
||||
|
||||
combined:
|
||||
src: "dist/<%= pkg.name %>-combined.js"
|
||||
dest: "dist/<%= pkg.name %>-combined.min.js"
|
||||
|
||||
watch:
|
||||
scripts:
|
||||
files: 'src/**/*.coffee'
|
||||
tasks: 'default'
|
||||
|
||||
grunt.loadNpmTasks "grunt-contrib-concat"
|
||||
grunt.loadNpmTasks "grunt-contrib-watch"
|
||||
grunt.loadNpmTasks "grunt-contrib-uglify"
|
||||
grunt.loadNpmTasks "grunt-contrib-coffee"
|
||||
grunt.loadNpmTasks "grunt-wrap"
|
||||
|
||||
# Default task.
|
||||
grunt.registerTask "default", "coffee wrap concat uglify".split(' ')
|
||||
@@ -0,0 +1,66 @@
|
||||
var fs = require("fs");
|
||||
var process = require("process");
|
||||
|
||||
|
||||
console.log("This file is now deprecated.. We no longer have a build system because we're not using coffee script.");
|
||||
process.exit();
|
||||
|
||||
module.exports = function(grunt) {
|
||||
grunt.initConfig({
|
||||
pkg: grunt.file.readJSON('package.json'),
|
||||
banner: "/** <%= pkg.title || pkg.name %> - v<%= pkg.version %> - <%= grunt.template.today(\"yyyy/mm/dd\") %>\n" + " * <%= pkg.homepage %>\n" + " * Copyright (c) <%= grunt.template.today(\"yyyy\") %> <%= pkg.author.name %> - MIT\n" + " */\n",
|
||||
coffee: {
|
||||
options: {
|
||||
bare: true
|
||||
},
|
||||
compile: {
|
||||
expand: true,
|
||||
flatten: false,
|
||||
cwd: 'src',
|
||||
src: ['**/*.coffee'],
|
||||
dest: 'dist/',
|
||||
ext: '.js'
|
||||
}
|
||||
},
|
||||
wrap: {
|
||||
dist: {
|
||||
src: 'dist/<%= pkg.name %>.js',
|
||||
dest: '.',
|
||||
wrapper: ["<%= banner %>(function(window,document,$,undefined) {\n", "\n}(window,document,jQuery));"]
|
||||
}
|
||||
},
|
||||
concat: {
|
||||
combined: {
|
||||
src: ['dist/<%= pkg.name %>.js', 'dist/styles/bootstrap/<%= pkg.name %>-bootstrap.js'],
|
||||
dest: 'dist/<%= pkg.name %>-combined.js'
|
||||
}
|
||||
},
|
||||
uglify: {
|
||||
options: {
|
||||
stripBanners: true,
|
||||
banner: '<%= banner %>'
|
||||
},
|
||||
dist: {
|
||||
src: "dist/<%= pkg.name %>.js",
|
||||
dest: "dist/<%= pkg.name %>.min.js"
|
||||
},
|
||||
combined: {
|
||||
src: "dist/<%= pkg.name %>-combined.js",
|
||||
dest: "dist/<%= pkg.name %>-combined.min.js"
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
scripts: {
|
||||
files: 'src/**/*.coffee',
|
||||
tasks: 'default'
|
||||
}
|
||||
}
|
||||
});
|
||||
grunt.loadNpmTasks("grunt-contrib-concat");
|
||||
grunt.loadNpmTasks("grunt-contrib-watch");
|
||||
grunt.loadNpmTasks("grunt-contrib-uglify");
|
||||
grunt.loadNpmTasks("grunt-contrib-coffee");
|
||||
grunt.loadNpmTasks("grunt-wrap");
|
||||
return grunt.registerTask("default", "coffee wrap concat uglify".split(' '));
|
||||
};
|
||||
|
||||
Vendored
-4
@@ -1,7 +1,3 @@
|
||||
/** Notify.js - v0.3.1 - 2014/06/29
|
||||
* http://notifyjs.com/
|
||||
* Copyright (c) 2014 Jaime Pillora - MIT
|
||||
*/
|
||||
(function(window,document,$,undefined) {
|
||||
'use strict';
|
||||
|
||||
|
||||
Vendored
+3
-3
File diff suppressed because one or more lines are too long
-469
@@ -1,469 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Notify.js</title>
|
||||
<meta name="description" content="Notify.js - A simple, versatile notification library">
|
||||
<meta name="author" content="Jaime Pillora <dev@jpillora.com>">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||
<link rel="stylesheet" href="docs/css/app.css">
|
||||
<link href="http://fonts.googleapis.com/css?family=Merriweather+Sans:400,300,700,800" rel="stylesheet" type="text/css"><!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
|
||||
</head>
|
||||
<body><a href="https://github.com/jpillora/notifyjs"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_green_007200.png" alt="Fork me on GitHub"></a>
|
||||
<div class="main container">
|
||||
<div class="eight columns">
|
||||
<h1 class="title">Notify.js</h1>
|
||||
</div>
|
||||
<div class="eight columns right"><span>
|
||||
<iframe src="http://ghbtns.com/github-btn.html?user=jpillora&type=follow" allowtransparency="true" frameborder="0" scrolling="0" width="130" height="20"></iframe></span><span>
|
||||
<iframe src="http://ghbtns.com/github-btn.html?user=jpillora&repo=notifyjs&type=watch&count=true" allowtransparency="true" frameborder="0" scrolling="0" width="80" height="20"></iframe></span><span><a href="https://twitter.com/share" data-url="http://notifyjs.com" data-text="Notify.js - A simple, versatile notification library" data-hashtags="notifyjs" class="twitter-share-button">Tweet</a>
|
||||
<script>
|
||||
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");
|
||||
|
||||
</script></span></div>
|
||||
<hr>
|
||||
<div class="eight columns summary">
|
||||
<h3>Summary</h3>
|
||||
<p>
|
||||
Notify.js is a jQuery plugin to provide simple yet fully customisable notifications.
|
||||
The javascript code snippets in this documentation with the <code>green</code> edge are runnable by clicking them.
|
||||
</p>
|
||||
<p>
|
||||
<pre class="prettyprint runnable">$.notify("Hello World");</pre>
|
||||
</p><img src="docs/img/pointer.png" class="demo-mouse">
|
||||
</div>
|
||||
<div class="eight columns">
|
||||
<h3>Download</h3>
|
||||
<p>Download pre-packaged with the Bootstrap notification style:<br><a href="dist/notify-combined.min.js" data-download data-name="notify.min">
|
||||
<button>Download notify.min.js</button></a><a href="dist/notify-combined.js" data-download data-name="notify">
|
||||
<button>Download notify.js</button></a></p>
|
||||
<p>Or, create a custom build with your own style<br>
|
||||
<button disabled="disabled" class="build-tool-loading">Loading...</button>
|
||||
<button class="build-tool-toggle">Build a custom notify.js</button>
|
||||
</p>
|
||||
</div>
|
||||
<div ng-app ng-controller="BuildController" class="sixteen columns build-tool">
|
||||
<p class="center">Notify.js Core
|
||||
<button disabled="disabled" class="active">Include</button>
|
||||
</p>
|
||||
<hr>
|
||||
<p><span class="bold">Styles </span><br>
|
||||
<div ng-repeat="style in styles" class="build-tool-style">
|
||||
<div>
|
||||
<textarea ng-model="style.code" class="code"></textarea>
|
||||
</div>
|
||||
<div class="right">
|
||||
<button ng-click="active(style,'active')" ng-class="style.active && 'active'">Include</button>
|
||||
<button ng-click="useDefault(style)" ng-class="settings.default == style && 'active'">Default</button>
|
||||
<button ng-click="test($event,style)" class="test">Test</button>
|
||||
<button ng-click="delete($index)">Delete</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="build-tool-controls center">
|
||||
<button ng-click="addStyle()">Add Style</button>
|
||||
<select ng-options="p.name for p in premadeStyles" ng-model="toLoad"></select>
|
||||
<button ng-click="loadStyle()">Load Style</button><span class="italic">Contribute more styles !</span>
|
||||
</div>
|
||||
</p>
|
||||
<hr>
|
||||
<p class="center">Minify
|
||||
<button ng-click="active(settings,'minify')" ng-class="settings.minify && 'active'">Minify this build</button>
|
||||
</p>
|
||||
<hr>
|
||||
<p class="center">
|
||||
<button ng-click="build()" ng-bind="building && 'Building...' || 'Download this build'"></button><span class="italic indent2">Made with <a href="https://github.com/jpillora/compilejs" target="_blank">Compile.js</a></span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="sixteen columns">
|
||||
<h3>Basic Usage</h3>
|
||||
</div>
|
||||
<div class="eight columns">
|
||||
<h4>Element Notifications</h4>
|
||||
<p>You can place notifications on any element:</p>
|
||||
<p>
|
||||
<pre class="prettyprint runnable">$(".elem-demo").notify("Hello Box");</pre>
|
||||
</p>
|
||||
<p class="center">Like this <span class="box elem-demo">box</span></p>
|
||||
</div>
|
||||
<div class="eight columns">
|
||||
<h4>Global Notifications</h4>
|
||||
<p>
|
||||
|
||||
If you don't specify an element, notification
|
||||
will appear in the top left (unless you specify a
|
||||
different position - See <a data-highlight>Positioning</a>)
|
||||
</p>
|
||||
<p>
|
||||
<pre class="prettyprint runnable">$.notify("I'm over here !");</pre>
|
||||
</p>
|
||||
</div>
|
||||
<div class="sixteen columns">
|
||||
<h4>Notification Styles</h4>
|
||||
<p>
|
||||
Each style may define a set of classes to use to substyle the notification.
|
||||
The pre-packaged version includes a bootstrap notification style (see more below in Styling).
|
||||
These classes include:
|
||||
|
||||
</p>
|
||||
<div><span>Success</span>
|
||||
<pre class="prettyprint runnable indent1">$.notify("Access granted", "success");</pre><span>Info</span>
|
||||
<pre class="prettyprint runnable indent1">$.notify("Do not press this button", "info");</pre><span>Warning</span>
|
||||
<pre class="prettyprint runnable indent1">$.notify("Warning: Self-destruct in 3.. 2..", "warn");</pre><span>Error</span>
|
||||
<pre class="prettyprint runnable indent1">$.notify("BOOM!", "error");</pre>
|
||||
</div>
|
||||
<p style="margin-top:10px" class="italic">Note: This page has set the default class to<code>"success"</code> with<code>$.notify.defaults({ className: "success" });</code>.</p>
|
||||
</div>
|
||||
<div id="position" class="sixteen columns">
|
||||
<h3>Positioning</h3>
|
||||
<p>
|
||||
Element notifications and Global notifications can
|
||||
be vertically repositioned to: <code>"top"</code>, <code>"middle" </code>or <code>"bottom" </code>and horozontally repositioned to: <code>"left"</code>, <code>"center" </code>or <code>"right" </code>.
|
||||
</p>
|
||||
<p>
|
||||
<pre class="prettyprint runnable">$(".pos-demo").notify(
|
||||
"I'm left of the box",
|
||||
{ position:"left" }
|
||||
);</pre>
|
||||
</p>
|
||||
<p class="center">We can position the notification around this <span class="box pos-demo">box</span></p>
|
||||
<p style="padding-top: 30px">Use this positioning tool to see all possible position combinations </p>
|
||||
<div style="padding: 30px;">
|
||||
<label for="pos-elem" class="inline">Element</label>
|
||||
<input type="radio" id="pos-elem" value="elem" name="pos-type" checked="checked">
|
||||
<label for="pos-glob" class="inline">Global</label>
|
||||
<input type="radio" id="pos-glob" value="glob" name="pos-type">
|
||||
</div>
|
||||
<div style="margin-left: 60px">
|
||||
<input data-thickness=".3" data-width="100" data-height="100" data-max="12" data-cursor="true" data-fgColor="#080" data-displayInput="false" data-angleOffset="-15" data-linecap="round" class="pos-chooser">
|
||||
</div>
|
||||
<p class="center"><span>An awesome cool </span><span class="box pos-chooser-demo">larrrggggeeee box</span></p>
|
||||
</div>
|
||||
<div class="sixteen columns">
|
||||
<h3>API</h3>
|
||||
<div class="entry">
|
||||
<h5><code class="black">$.notify( </code><code>string|object</code><code class="black">, [ </code><code>options</code><code class="black"> ])</code></h5>
|
||||
<p class="indent1"><code>string|object</code> - global notification data<br><code>options</code> - an options object or class name string </p>
|
||||
</div>
|
||||
<div class="entry">
|
||||
<h5><code class="black">$.notify( </code><code>element</code><code class="black">, </code><code>string|object</code><code class="black">, [ </code><code>options</code><code class="black"> ])</code></h5>
|
||||
<p class="indent1"><code>element</code> - a jquery element<br><code>string|object</code> - element notification data<br><code>options</code> - an options object or class name string </p>
|
||||
</div>
|
||||
<div class="entry">
|
||||
<h5><code class="black">$( </code><code>selector</code><code class="black"> ).notify( </code><code>string|object</code><code class="black">, [ </code><code>options</code><code class="black"> ])</code></h5>
|
||||
<p class="indent1"><code>selector</code> - jquery selector<br><code>string|object</code> - element notification data<br><code>options</code> - an options object or class name string </p>
|
||||
</div>
|
||||
<div class="entry">
|
||||
<h5><code class="black">$.notify.addStyle( </code><code>styleName</code><code class="black">, </code><code>styleDefinition</code><code class="black"> )</code></h5>
|
||||
<p class="indent1"><code>styleName</code> - string (the <b>style</b> option references this name)<br> <code>styleDefinition</code> - style definition object (see <b>Styling</b> below)</p>
|
||||
</div>
|
||||
<div class="entry">
|
||||
<h5><code class="black">$.notify.defaults( </code><code>options</code><code class="black"> )</code></h5>
|
||||
<p class="indent1"><code>options</code> - an options object (updates the defaults listed below) </p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sixteen columns">
|
||||
<h3>Options</h3>
|
||||
<p>
|
||||
|
||||
The options object listed above are in the form below.
|
||||
This object below is the actual used to check option
|
||||
validity and set defaults.
|
||||
</p>
|
||||
<pre class="prettyprint">{
|
||||
// whether to hide the notification on click
|
||||
clickToHide: true,
|
||||
// whether to auto-hide the notification
|
||||
autoHide: true,
|
||||
// if autoHide, hide after milliseconds
|
||||
autoHideDelay: 5000,
|
||||
// show the arrow pointing at the element
|
||||
arrowShow: true,
|
||||
// arrow size in pixels
|
||||
arrowSize: 5,
|
||||
// default positions
|
||||
elementPosition: 'bottom left',
|
||||
globalPosition: 'top right',
|
||||
// default style
|
||||
style: 'bootstrap',
|
||||
// default class (string or [string])
|
||||
className: 'error',
|
||||
// show animation
|
||||
showAnimation: 'slideDown',
|
||||
// show animation duration
|
||||
showDuration: 400,
|
||||
// hide animation
|
||||
hideAnimation: 'slideUp',
|
||||
// hide animation duration
|
||||
hideDuration: 200,
|
||||
// padding between element and notification
|
||||
gap: 2
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
<div class="sixteen columns">
|
||||
<div class="section">
|
||||
<h3>Custom Styling Guide</h3>
|
||||
<p>You can add your own styles to Notify.js with the<code>$.notify.addStyle </code>method. See <a data-highlight>API</a>.</p>
|
||||
<p>Style definition objects are in the form:</p>
|
||||
<pre class="prettyprint">{
|
||||
//required html representing each notification
|
||||
html: "",
|
||||
//optional object to be converted to css
|
||||
classes: {
|
||||
<className>: {
|
||||
<propertyName>: <value>
|
||||
},
|
||||
<className>: {
|
||||
...
|
||||
},
|
||||
...
|
||||
},
|
||||
//optional css to be inserted onto the page
|
||||
css: ""
|
||||
}
|
||||
</pre>
|
||||
<p>
|
||||
<h5 class="inline">html</h5> - If you only have HTML element that you need to modify per
|
||||
notification then you should give this element an attribute of <code>data-notify-text</code> or <code>data-notify-html</code>. Use <code>data-notify-html</code> if you wish to display arbitrary HTML inside the notification,
|
||||
otherwise, use <code>data-notify-text</code> as it is more secure.<br> Otherwise, if you wish to modify multiple HTML elements per
|
||||
notification then you'll need to give each element one of the two
|
||||
attributes above <b>as well as a value</b>. For an example of this see the Advanced Example below.
|
||||
</p>
|
||||
<p>
|
||||
<h5 class="inline">classes</h5> - This object will be used to construct css. It must be in the form described above and there is an example below.
|
||||
</p>
|
||||
<p>
|
||||
<h5 class="inline">css</h5> - This string is simply raw css. Use this property if you want to keep your style definition inside
|
||||
your js files.
|
||||
</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<h4>Class naming convention</h4>
|
||||
<p>
|
||||
When each notification is constructed, it's container
|
||||
(outer most element defined in your style html) will automatically
|
||||
apply the class:
|
||||
</p>
|
||||
<p><code>notifyjs-<style name>-base</code></p>
|
||||
<p>
|
||||
|
||||
When you use the class name option (<code>className</code>) the class:
|
||||
</p>
|
||||
<p><code>notifyjs-<style name>-<class name></code></p>
|
||||
<p>
|
||||
will be applied. So if you define your styles in an external CSS file or in the style's css
|
||||
property, you must define your CSS rules using this naming convention.
|
||||
|
||||
</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<h4>Simple Example</h4>
|
||||
<p>If you were to define the style:</p>
|
||||
<pre class="prettyprint auto-run happyblue-example">$.notify.addStyle('happyblue', {
|
||||
html: "<div>☺<span data-notify-text/>☺</div>",
|
||||
classes: {
|
||||
base: {
|
||||
"white-space": "nowrap",
|
||||
"background-color": "lightblue",
|
||||
"padding": "5px"
|
||||
},
|
||||
superblue: {
|
||||
"color": "white",
|
||||
"background-color": "blue"
|
||||
}
|
||||
}
|
||||
});
|
||||
</pre>
|
||||
<p>Upon running this code, the <code>classes</code> object in this example will be converted the following css:</p>
|
||||
<pre class="prettyprint lang-css">.notifyjs-happyblue-base {
|
||||
white-space: nowrap;
|
||||
background-color: lightblue;
|
||||
padding: 5px;
|
||||
}
|
||||
.notifyjs-happyblue-superblue {
|
||||
color: white;
|
||||
background-color: blue;
|
||||
}</pre>
|
||||
<p:i>You can confirm this now by inspecting the DOM (look for the tagged style element in the head)</p:i>
|
||||
<p>You can now use your new style with:</p>
|
||||
<pre class="prettyprint runnable">$.notify('hello !!', {
|
||||
style: 'happyblue'
|
||||
});
|
||||
</pre>
|
||||
<p>
|
||||
|
||||
and you can use the <code>superblue</code> class with:
|
||||
</p>
|
||||
<pre class="prettyprint runnable">$.notify('HELLO !!!!', {
|
||||
style: 'happyblue',
|
||||
className: 'superblue'
|
||||
});
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section">
|
||||
<h4>Advanced Example</h4>
|
||||
<p>Say you wanted to use buttons in your notifications then you could do something like:</p>
|
||||
<pre class="prettyprint auto-run button-js-example">//add a new style 'foo'
|
||||
$.notify.addStyle('foo', {
|
||||
html:
|
||||
"<div>" +
|
||||
"<div class='clearfix'>" +
|
||||
"<div class='title' data-notify-html='title'/>" +
|
||||
"<div class='buttons'>" +
|
||||
"<button class='no'>Cancel</button>" +
|
||||
"<button class='yes' data-notify-text='button'></button>" +
|
||||
"</div>" +
|
||||
"</div>" +
|
||||
"</div>"
|
||||
});
|
||||
|
||||
//listen for click events from this style
|
||||
$(document).on('click', '.notifyjs-foo-base .no', function() {
|
||||
//programmatically trigger propogating hide event
|
||||
$(this).trigger('notify-hide');
|
||||
});
|
||||
$(document).on('click', '.notifyjs-foo-base .yes', function() {
|
||||
//show button text
|
||||
alert($(this).text() + " clicked!");
|
||||
//hide notification
|
||||
$(this).trigger('notify-hide');
|
||||
});
|
||||
</pre>
|
||||
<p>
|
||||
|
||||
Notice there is no <code>classes</code> property defined above. Since the CSS in this example is non-trivial, we'll use an exteral CSS file instead:
|
||||
</p>
|
||||
<p class="italic">Note: you could also convert this CSS code to a JavaScript string and use it with the <code>css</code> property. It's not very readable though it's better for distribution.</p>
|
||||
<pre class="prettyprint auto-add foo-css-example lang-css">.notifyjs-foo-base {
|
||||
opacity: 0.85;
|
||||
width: 200px;
|
||||
background: #F5F5F5;
|
||||
padding: 5px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.notifyjs-foo-base .title {
|
||||
width: 100px;
|
||||
float: left;
|
||||
margin: 10px 0 0 10px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.notifyjs-foo-base .buttons {
|
||||
width: 70px;
|
||||
float: right;
|
||||
font-size: 9px;
|
||||
padding: 5px;
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
.notifyjs-foo-base button {
|
||||
font-size: 9px;
|
||||
padding: 5px;
|
||||
margin: 2px;
|
||||
width: 60px;
|
||||
}
|
||||
</pre>
|
||||
<p>You can now use this style with:</p>
|
||||
<pre class="prettyprint runnable">$.notify({
|
||||
title: 'Would you like some Foo ?',
|
||||
button: 'Confirm'
|
||||
}, {
|
||||
style: 'foo',
|
||||
autoHide: false,
|
||||
clickToHide: false
|
||||
});
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section">
|
||||
<h4>Extra Example</h4>
|
||||
<p>
|
||||
If using the above methods still don't provide you
|
||||
with what you need then you can, pass jQuery objects
|
||||
straight into the notification (provided that the
|
||||
element has the <code>data-notify-html</code> attribute):
|
||||
|
||||
</p>
|
||||
<pre class="prettyprint runnable">var h5 = $("<h5/>").append("You MUST have some Foo !")
|
||||
|
||||
$.notify({
|
||||
title: h5,
|
||||
button: 'YES !'
|
||||
}, {
|
||||
style: 'foo',
|
||||
autoHide: false,
|
||||
clickToHide: false
|
||||
});
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section">
|
||||
<h4>Style List</h4>
|
||||
<p><span>Currently there is only one style available</span>
|
||||
<ul class="square">
|
||||
<li><a href="../../notifyjs/dist/styles/notify-bootstrap.js" target="_blank">notify-bootstrap.js</a></li>
|
||||
</ul>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sixteen columns">
|
||||
<h3>Contributing More Styles </h3>
|
||||
<p>
|
||||
|
||||
Contributing more styles is easy!
|
||||
<ol>
|
||||
<li>Click <a href="https://github.com/jpillora/notifyjs/new/master/src/styles" target="_blank">this</a> link</li>
|
||||
<li>Sign into GitHub (if you're not already)</li>
|
||||
<li>Click 'Fork'</li>
|
||||
<li>Enter your new style</li>
|
||||
<li>Click 'Commit New File'</li>
|
||||
<li>Click 'Send Pull Request'!</li>
|
||||
</ol>
|
||||
</p>
|
||||
<p>To get people started with some styles ideas, checkout this <a href="http://mac.appstorm.net/roundups/utilities-roundups/36-sweet-growl-styles-to-keep-your-notifications-snappy/" target="_blank">post on various Growl styles</a>.</p>
|
||||
<p class="italic">
|
||||
Note: If you wish to contribute to the library by fixing bugs or adding features,
|
||||
see the <b>src</b> folder. Also, the source is in CoffeeScript, however, new styles can be either JavaScript or CoffeeScript.
|
||||
I'm using <a href="https://gruntjs.com" target="_blank">Grunt </a> to compile, minify and concat the builds, you can do so with:
|
||||
<ol>
|
||||
<li>Fork <a href="https://github.com/jpillora/notifyjs">https://github.com/jpillora/notifyjs</a></li>
|
||||
<li><code>cd notifyjs</code></li>
|
||||
<li><code>npm install -g grunt-cli</code></li>
|
||||
<li><code>npm install</code></li>
|
||||
<li><code>grunt</code></li>
|
||||
<li>Pull-request ! </li>
|
||||
</ol>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<script src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.js"></script>
|
||||
<script src="dist/notify.js"></script>
|
||||
<script src="dist/styles/notify-bootstrap.js" id="bootstrap-style"></script>
|
||||
<script src="docs/js/app.js"></script>
|
||||
<script defered src="http://jpillora.com/compilejs/dist/compile.js"></script>
|
||||
<script defered src="http://jpillora.com/compilejs/dist/tasks/compile.uglify.js"></script>
|
||||
<script defered src="//ajax.googleapis.com/ajax/libs/angularjs/1.1.4/angular.min.js"></script>
|
||||
<script>
|
||||
//async fonts
|
||||
WebFontConfig = { google: { families: [ 'Droid+Sans+Mono::latin' ] } };
|
||||
(function() {
|
||||
var wf = document.createElement('script');
|
||||
wf.src = ('https:' == document.location.protocol ? 'https' : 'http') +
|
||||
'://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js';
|
||||
wf.type = 'text/javascript';
|
||||
wf.async = 'true';
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(wf, s);
|
||||
})();
|
||||
//ga
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
||||
ga('create', 'UA-38709761-6', 'notifyjs.com');
|
||||
ga('send', 'pageview');
|
||||
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
+4
-2
@@ -969,17 +969,19 @@ PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\f\r ]+/,null," \t\r\
|
||||
$(".prettyprint.auto-run").each(runSnippet);
|
||||
$(".prettyprint.auto-add").each(addCSS);
|
||||
$.notify.addStyle('gswg', {
|
||||
html: "<div>\n <div class=\"content clearfix\">\n <div class=\"cover\"></div>\n <div class=\"text\">\n <div>Read my book:</div>\n <div class=\"title\">Getting Started with Grunt: The JavaScript Task Runner</div>\n <div>Get the first chapter for free!</div>\n <div>\n <a target=\"_blank\" href=\"http://gswg.io\">\n <button data-notify-text></button>\n </a>\n <button>No thanks</button>\n </div>\n </div>\n </div>\n</div>"
|
||||
html: "<div>\n <div class=\"content clearfix\">\n <div class=\"cover\"></div>\n <div class=\"text\">\n <div>Checkout</div>\n <div class=\"title\">Getting Started with Grunt: The JavaScript Task Runner</div>\n <div>Get the first chapter for free!</div>\n <div>\n <a target=\"_blank\" href=\"http://gswg.io\">\n <button data-notify-text></button>\n </a>\n <button>No thanks</button>\n </div>\n </div>\n </div>\n</div>"
|
||||
});
|
||||
$(document).on('click', '.notifyjs-gswg-base button', function() {
|
||||
return $(this).trigger('notify-hide');
|
||||
});
|
||||
return setTimeout(function() {
|
||||
return $.notify("http://gswg.io", {
|
||||
position: 'b r',
|
||||
style: 'gswg',
|
||||
autoHide: false,
|
||||
autoHideDelay: 10 * 1000,
|
||||
clickToHide: false
|
||||
});
|
||||
}, 15 * 1000);
|
||||
};
|
||||
|
||||
App = App || {};
|
||||
|
||||
@@ -42,7 +42,7 @@ App.codeRunner = ->
|
||||
<div class="content clearfix">
|
||||
<div class="cover"></div>
|
||||
<div class="text">
|
||||
<div>Read my book:</div>
|
||||
<div>Checkout</div>
|
||||
<div class="title">Getting Started with Grunt: The JavaScript Task Runner</div>
|
||||
<div>Get the first chapter for free!</div>
|
||||
<div>
|
||||
@@ -59,7 +59,6 @@ App.codeRunner = ->
|
||||
$(document).on 'click', '.notifyjs-gswg-base button', ->
|
||||
$(this).trigger('notify-hide')
|
||||
|
||||
$.notify("http://gswg.io", {position:'b r', style: 'gswg', autoHide: false, clickToHide: false})
|
||||
|
||||
|
||||
|
||||
setTimeout ->
|
||||
$.notify("http://gswg.io", {position:'b r', style: 'gswg', autoHideDelay: 10*1000, clickToHide: false})
|
||||
, 15*1000
|
||||
|
||||
@@ -16,7 +16,7 @@ html(lang='en')
|
||||
|
||||
body
|
||||
|
||||
a(href="https://github.com/jpillora/notifyjs")
|
||||
a(href="https://github.com/notifyjs/notifyjs")
|
||||
img(style="position: absolute; top: 0; right: 0; border: 0;",
|
||||
src="https://s3.amazonaws.com/github/ribbons/forkme_right_green_007200.png",
|
||||
alt="Fork me on GitHub")
|
||||
@@ -28,10 +28,8 @@ html(lang='en')
|
||||
h1.title Notify.js
|
||||
|
||||
.eight.columns.right
|
||||
span: iframe(src="http://ghbtns.com/github-btn.html?user=jpillora&type=follow",
|
||||
allowtransparency="true",frameborder="0",scrolling="0",width="130",height="20")
|
||||
span: iframe(src="http://ghbtns.com/github-btn.html?user=jpillora&repo=notifyjs&type=watch&count=true",
|
||||
allowtransparency="true",frameborder="0",scrolling="0",width="80",height="20")
|
||||
span: iframe(src="http://ghbtns.com/github-btn.html?user=notifyjs&repo=notifyjs&type=watch&count=true",
|
||||
allowtransparency="true",frameborder="0",scrolling="0",width="120",height="20")
|
||||
span
|
||||
a.twitter-share-button(href='https://twitter.com/share', data-url='http://notifyjs.com', data-text='Notify.js - A simple, versatile notification library', data-hashtags='notifyjs') Tweet
|
||||
script.
|
||||
@@ -56,8 +54,8 @@ html(lang='en')
|
||||
script(src="docs/js/app.js")
|
||||
|
||||
//- build tool scripts
|
||||
script(defered, src="#{false ? '../' : 'http://jpillora.com/'}compilejs/dist/compile.js")
|
||||
script(defered, src="#{false ? '../' : 'http://jpillora.com/'}compilejs/dist/tasks/compile.uglify.js")
|
||||
script(defered, src="http://jpillora.com/compilejs/dist/compile.js")
|
||||
script(defered, src="http://jpillora.com/compilejs/dist/tasks/compile.uglify.js")
|
||||
script(defered, src="//ajax.googleapis.com/ajax/libs/angularjs/1.1.4/angular.min.js")
|
||||
|
||||
script.
|
||||
@@ -79,5 +77,3 @@ html(lang='en')
|
||||
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
||||
ga('create', 'UA-38709761-6', 'notifyjs.com');
|
||||
ga('send', 'pageview');
|
||||
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
| Contributing more styles is easy!
|
||||
ol
|
||||
li.
|
||||
Click <a href="https://github.com/jpillora/notifyjs/new/gh-pages/src/styles" target="_blank">this</a> link
|
||||
Click <a href="https://github.com/notifyjs/notifyjs/new/gh-pages/src/styles" target="_blank">this</a> link
|
||||
li Sign into GitHub (if you're not already)
|
||||
li Click 'Fork'
|
||||
li Enter your new style
|
||||
@@ -31,7 +31,7 @@
|
||||
ol
|
||||
li
|
||||
| Fork
|
||||
a(href="https://github.com/jpillora/notifyjs") https://github.com/jpillora/notifyjs
|
||||
a(href="https://github.com/notifyjs/notifyjs") https://github.com/notifyjs/notifyjs
|
||||
li: code cd notifyjs
|
||||
li: code npm install -g grunt-cli
|
||||
li: code npm install
|
||||
|
||||
@@ -249,7 +249,7 @@
|
||||
|
||||
p
|
||||
ul.square
|
||||
li: a(href="https://github.com/jpillora/notifyjs/tree/gh-pages/dist/styles/bootstrap", target="_blank") bootstrap
|
||||
li: a(href="https://github.com/notifyjs/notifyjs/tree/gh-pages/dist/styles/bootstrap", target="_blank") bootstrap
|
||||
ul.square
|
||||
li: a(href="https://github.com/jpillora/notifyjs/tree/gh-pages/dist/styles/metro", target="_blank") metro
|
||||
li: a(href="https://github.com/notifyjs/notifyjs/tree/gh-pages/dist/styles/metro", target="_blank") metro
|
||||
|
||||
|
||||
+6
-9
@@ -13,14 +13,13 @@
|
||||
|
||||
-->
|
||||
</head>
|
||||
<body><a href="https://github.com/jpillora/notifyjs"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_green_007200.png" alt="Fork me on GitHub"></a>
|
||||
<body><a href="https://github.com/notifyjs/notifyjs"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_green_007200.png" alt="Fork me on GitHub"></a>
|
||||
<div class="main container">
|
||||
<div class="eight columns">
|
||||
<h1 class="title">Notify.js</h1>
|
||||
</div>
|
||||
<div class="eight columns right"><span>
|
||||
<iframe src="http://ghbtns.com/github-btn.html?user=jpillora&type=follow" allowtransparency="true" frameborder="0" scrolling="0" width="130" height="20"></iframe></span><span>
|
||||
<iframe src="http://ghbtns.com/github-btn.html?user=jpillora&repo=notifyjs&type=watch&count=true" allowtransparency="true" frameborder="0" scrolling="0" width="80" height="20"></iframe></span><span><a href="https://twitter.com/share" data-url="http://notifyjs.com" data-text="Notify.js - A simple, versatile notification library" data-hashtags="notifyjs" class="twitter-share-button">Tweet</a>
|
||||
<iframe src="http://ghbtns.com/github-btn.html?user=notifyjs&repo=notifyjs&type=watch&count=true" allowtransparency="true" frameborder="0" scrolling="0" width="120" height="20"></iframe></span><span><a href="https://twitter.com/share" data-url="http://notifyjs.com" data-text="Notify.js - A simple, versatile notification library" data-hashtags="notifyjs" class="twitter-share-button">Tweet</a>
|
||||
<script>
|
||||
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");
|
||||
|
||||
@@ -394,10 +393,10 @@ $.notify({
|
||||
<h4>Style List</h4>
|
||||
<p>
|
||||
<ul class="square">
|
||||
<li><a href="https://github.com/jpillora/notifyjs/tree/gh-pages/dist/styles/bootstrap" target="_blank">bootstrap</a></li>
|
||||
<li><a href="https://github.com/notifyjs/notifyjs/tree/gh-pages/dist/styles/bootstrap" target="_blank">bootstrap</a></li>
|
||||
</ul>
|
||||
<ul class="square">
|
||||
<li><a href="https://github.com/jpillora/notifyjs/tree/gh-pages/dist/styles/metro" target="_blank">metro</a></li>
|
||||
<li><a href="https://github.com/notifyjs/notifyjs/tree/gh-pages/dist/styles/metro" target="_blank">metro</a></li>
|
||||
</ul>
|
||||
</p>
|
||||
</div>
|
||||
@@ -406,7 +405,7 @@ $.notify({
|
||||
<h3>Contributing More Styles </h3>
|
||||
<p>Contributing more styles is easy!
|
||||
<ol>
|
||||
<li>Click <a href="https://github.com/jpillora/notifyjs/new/gh-pages/src/styles" target="_blank">this</a> link</li>
|
||||
<li>Click <a href="https://github.com/notifyjs/notifyjs/new/gh-pages/src/styles" target="_blank">this</a> link</li>
|
||||
<li>Sign into GitHub (if you're not already)</li>
|
||||
<li>Click 'Fork'</li>
|
||||
<li>Enter your new style</li>
|
||||
@@ -420,7 +419,7 @@ $.notify({
|
||||
see the <b>src</b> folder. Also, the source is in CoffeeScript, however, new styles can be either JavaScript or CoffeeScript.
|
||||
I'm using <a href="https://gruntjs.com" target="_blank">Grunt </a> to compile, minify and concat the builds, you can do so with:
|
||||
<ol>
|
||||
<li>Fork <a href="https://github.com/jpillora/notifyjs">https://github.com/jpillora/notifyjs</a></li>
|
||||
<li>Fork <a href="https://github.com/notifyjs/notifyjs">https://github.com/notifyjs/notifyjs</a></li>
|
||||
<li><code>cd notifyjs</code></li>
|
||||
<li><code>npm install -g grunt-cli</code></li>
|
||||
<li><code>npm install</code></li>
|
||||
@@ -456,8 +455,6 @@ $.notify({
|
||||
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
||||
ga('create', 'UA-38709761-6', 'notifyjs.com');
|
||||
ga('send', 'pageview');
|
||||
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
+9
-13
@@ -1,22 +1,18 @@
|
||||
{
|
||||
"title": "Notify.js",
|
||||
"name": "notify",
|
||||
"version": "0.3.2",
|
||||
"version": "0.3.3",
|
||||
"author": {
|
||||
"name": "Jaime Pillora"
|
||||
},
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Evan Carroll"
|
||||
, "url": "http://www.evancarroll.com"
|
||||
, "email": "me@evancarroll.com"
|
||||
}
|
||||
],
|
||||
"homepage": "http://notifyjs.com/",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"grunt": "~0.4.x",
|
||||
"grunt-contrib-watch": "~0.1.4",
|
||||
"grunt-contrib-uglify": "~0.1.1rc6",
|
||||
"grunt-contrib-jshint": "~0.1.0",
|
||||
"grunt-contrib-concat": "~0.1.1",
|
||||
"grunt-contrib-coffee": "~0.4.0rc7",
|
||||
"grunt-wrap": "~0.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"grunt-contrib-concat": "~0.3.0"
|
||||
}
|
||||
"main": "dist/notify.js"
|
||||
}
|
||||
|
||||
@@ -1,571 +0,0 @@
|
||||
|
||||
'use strict'
|
||||
|
||||
#plugin constants
|
||||
pluginName = 'notify'
|
||||
pluginClassName = pluginName+'js'
|
||||
blankFieldName = pluginName+"!blank"
|
||||
|
||||
# ================================
|
||||
# POSITIONING
|
||||
# ================================
|
||||
|
||||
positions =
|
||||
t: 'top'
|
||||
m: 'middle'
|
||||
b: 'bottom'
|
||||
l: 'left'
|
||||
c: 'center'
|
||||
r: 'right'
|
||||
hAligns = ['l','c','r']
|
||||
vAligns = ['t','m','b']
|
||||
mainPositions = ['t','b','l','r']
|
||||
#positions mapped to opposites
|
||||
opposites =
|
||||
t: 'b'
|
||||
m: null
|
||||
b: 't'
|
||||
l: 'r'
|
||||
c: null
|
||||
r: 'l'
|
||||
|
||||
parsePosition = (str) ->
|
||||
pos = []
|
||||
$.each str.split(/\W+/), (i,word) ->
|
||||
w = word.toLowerCase().charAt(0)
|
||||
pos.push w if positions[w]
|
||||
pos
|
||||
|
||||
# ================================
|
||||
# STYLES
|
||||
# ================================
|
||||
styles = {}
|
||||
|
||||
coreStyle =
|
||||
name: 'core'
|
||||
html: """
|
||||
<div class="#{pluginClassName}-wrapper">
|
||||
<div class="#{pluginClassName}-arrow"></div>
|
||||
<div class="#{pluginClassName}-container"></div>
|
||||
</div>
|
||||
"""
|
||||
# <div class="#{pluginClassName}-debug"></div>
|
||||
# .#{pluginClassName}-debug {
|
||||
# position: absolute;
|
||||
# border: 3px solid red;
|
||||
# height: 0;
|
||||
# width: 0;
|
||||
# }
|
||||
css: """
|
||||
.#{pluginClassName}-corner {
|
||||
position: fixed;
|
||||
margin: 5px;
|
||||
z-index: 1050;
|
||||
}
|
||||
|
||||
.#{pluginClassName}-corner .#{pluginClassName}-wrapper,
|
||||
.#{pluginClassName}-corner .#{pluginClassName}-container {
|
||||
position: relative;
|
||||
display: block;
|
||||
height: inherit;
|
||||
width: inherit;
|
||||
margin: 3px;
|
||||
}
|
||||
|
||||
.#{pluginClassName}-wrapper {
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
height: 0;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.#{pluginClassName}-container {
|
||||
display: none;
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.#{pluginClassName}-hidable {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
[data-notify-text],[data-notify-html] {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.#{pluginClassName}-arrow {
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
"""
|
||||
|
||||
stylePrefixes =
|
||||
"border-radius": ["-webkit-", "-moz-"]
|
||||
|
||||
getStyle = (name) ->
|
||||
styles[name]
|
||||
|
||||
addStyle = (name, def) ->
|
||||
|
||||
unless name
|
||||
throw "Missing Style name"
|
||||
unless def
|
||||
throw "Missing Style definition"
|
||||
unless def.html
|
||||
throw "Missing Style HTML"
|
||||
|
||||
if styles[name]?.cssElem
|
||||
if window.console
|
||||
console.warn "#{pluginName}: overwriting style '#{name}'"
|
||||
styles[name].cssElem.remove()
|
||||
|
||||
def.name = name
|
||||
styles[name] = def
|
||||
|
||||
cssText = ""
|
||||
if def.classes
|
||||
$.each def.classes, (className, props) ->
|
||||
cssText += ".#{pluginClassName}-#{def.name}-#{className} {\n"
|
||||
$.each props, (name, val) ->
|
||||
#vendor prefixes
|
||||
if stylePrefixes[name]
|
||||
$.each stylePrefixes[name], (i, prefix) ->
|
||||
cssText += " #{prefix}#{name}: #{val};\n"
|
||||
#add prop
|
||||
cssText += " #{name}: #{val};\n"
|
||||
cssText += "}\n"
|
||||
if def.css
|
||||
cssText += """
|
||||
/* styles for #{def.name} */
|
||||
#{def.css}
|
||||
"""
|
||||
|
||||
if cssText
|
||||
def.cssElem = insertCSS cssText
|
||||
def.cssElem.attr('id', "notify-#{def.name}")
|
||||
|
||||
#precompute usable text fields
|
||||
fields = {}
|
||||
elem = $(def.html)
|
||||
findFields 'html', elem, fields
|
||||
findFields 'text', elem, fields
|
||||
def.fields = fields
|
||||
|
||||
insertCSS = (cssText) ->
|
||||
|
||||
elem = createElem("style")
|
||||
elem.attr 'type', 'text/css'
|
||||
$("head").append elem
|
||||
try
|
||||
elem.html cssText
|
||||
catch e #ie fix
|
||||
elem[0].styleSheet.cssText = cssText
|
||||
elem
|
||||
|
||||
# style.html helper
|
||||
findFields = (type, elem, fields) ->
|
||||
type = 'text' if type isnt 'html'
|
||||
attr = "data-notify-#{type}"
|
||||
find(elem,"[#{attr}]").each ->
|
||||
name = $(@).attr attr
|
||||
name = blankFieldName unless name
|
||||
fields[name] = type
|
||||
|
||||
find = (elem, selector) ->
|
||||
if elem.is(selector) then elem else elem.find selector
|
||||
|
||||
# ================================
|
||||
# OPTIONS
|
||||
# ================================
|
||||
|
||||
#overridable options
|
||||
pluginOptions =
|
||||
clickToHide: true
|
||||
autoHide: true
|
||||
autoHideDelay: 5000
|
||||
arrowShow: true
|
||||
arrowSize: 5
|
||||
breakNewLines: true
|
||||
# autoReposition: true
|
||||
elementPosition: 'bottom'
|
||||
globalPosition: 'top right'
|
||||
style: 'bootstrap'
|
||||
className: 'error'
|
||||
showAnimation: 'slideDown'
|
||||
showDuration: 400
|
||||
hideAnimation: 'slideUp'
|
||||
hideDuration: 200
|
||||
gap: 5
|
||||
|
||||
inherit = (a, b) ->
|
||||
F = () ->
|
||||
F.prototype = a
|
||||
$.extend true, new F(), b
|
||||
|
||||
defaults = (opts) ->
|
||||
$.extend pluginOptions, opts
|
||||
|
||||
# ================================
|
||||
# DOM MANIPULATION
|
||||
# ================================
|
||||
|
||||
# plugin helpers
|
||||
createElem = (tag) ->
|
||||
$ "<#{tag}></#{tag}>"
|
||||
|
||||
# references to global anchor positions
|
||||
globalAnchors = {}
|
||||
|
||||
#gets first on n radios, and gets the fancy stylised input for hidden inputs
|
||||
getAnchorElement = (element) ->
|
||||
#choose the first of n radios
|
||||
if element.is('[type=radio]')
|
||||
radios = element.parents('form:first').find('[type=radio]').filter (i, e) ->
|
||||
$(e).attr('name') is element.attr('name')
|
||||
element = radios.first()
|
||||
#custom-styled inputs - find thier real element
|
||||
element
|
||||
|
||||
incr = (obj, pos, val) ->
|
||||
# console.log "incr ---- #{pos} #{val} (#{typeof val})"
|
||||
if typeof val is 'string'
|
||||
val = parseInt val, 10
|
||||
else if typeof val isnt 'number'
|
||||
return
|
||||
|
||||
return if isNaN val
|
||||
|
||||
opp = positions[opposites[pos.charAt(0)]]
|
||||
temp = pos
|
||||
|
||||
#use the opposite if exists
|
||||
if obj[opp] isnt `undefined`
|
||||
pos = positions[opp.charAt(0)]
|
||||
val = -val
|
||||
|
||||
if obj[pos] is `undefined`
|
||||
obj[pos] = val
|
||||
else
|
||||
obj[pos] += val
|
||||
null
|
||||
|
||||
realign = (alignment, inner, outer) ->
|
||||
return if alignment in ['l','t']
|
||||
0
|
||||
else if alignment in ['c','m']
|
||||
outer/2 - inner/2
|
||||
else if alignment in ['r','b']
|
||||
outer - inner
|
||||
throw "Invalid alignment"
|
||||
|
||||
encode = (text) ->
|
||||
encode.e = encode.e or createElem "div"
|
||||
encode.e.text(text).html()
|
||||
|
||||
# ================================
|
||||
# NOTIFY CLASS
|
||||
# ================================
|
||||
|
||||
#define plugin
|
||||
class Notification
|
||||
|
||||
#setup instance variables
|
||||
constructor: (elem, data, options) ->
|
||||
options = {className: options} if typeof options is 'string'
|
||||
@options = inherit pluginOptions, if $.isPlainObject(options) then options else {}
|
||||
|
||||
#load style html into @userContainer
|
||||
@loadHTML()
|
||||
|
||||
@wrapper = $(coreStyle.html)
|
||||
@wrapper.addClass "#{pluginClassName}-hidable" if @options.clickToHide
|
||||
@wrapper.data pluginClassName, @
|
||||
@arrow = @wrapper.find ".#{pluginClassName}-arrow"
|
||||
@container = @wrapper.find ".#{pluginClassName}-container"
|
||||
@container.append @userContainer
|
||||
|
||||
if elem and elem.length
|
||||
@elementType = elem.attr('type')
|
||||
@originalElement = elem
|
||||
@elem = getAnchorElement(elem)
|
||||
@elem.data pluginClassName, @
|
||||
# add into dom above elem
|
||||
@elem.before @wrapper
|
||||
|
||||
@container.hide()
|
||||
@run(data)
|
||||
|
||||
loadHTML: ->
|
||||
style = @getStyle()
|
||||
@userContainer = $(style.html)
|
||||
@userFields = style.fields
|
||||
|
||||
show: (show, userCallback) ->
|
||||
|
||||
callback = =>
|
||||
@destroy() if not show and not @elem
|
||||
userCallback() if userCallback
|
||||
|
||||
hidden = @container.parent().parents(':hidden').length > 0
|
||||
|
||||
elems = @container.add @arrow
|
||||
args = []
|
||||
|
||||
if hidden and show
|
||||
fn = 'show'
|
||||
else if hidden and not show
|
||||
fn = 'hide'
|
||||
else if not hidden and show
|
||||
fn = @options.showAnimation
|
||||
args.push @options.showDuration
|
||||
else if not hidden and not show
|
||||
fn = @options.hideAnimation
|
||||
args.push @options.hideDuration
|
||||
else
|
||||
return callback()
|
||||
|
||||
args.push callback
|
||||
|
||||
elems[fn].apply elems, args
|
||||
|
||||
|
||||
setGlobalPosition: () ->
|
||||
[pMain, pAlign] = @getPosition()
|
||||
|
||||
main = positions[pMain]
|
||||
align = positions[pAlign]
|
||||
|
||||
key = pMain+"|"+pAlign
|
||||
anchor = globalAnchors[key]
|
||||
unless anchor
|
||||
anchor = globalAnchors[key] = createElem("div")
|
||||
css = {}
|
||||
css[main] = 0
|
||||
if align is 'middle'
|
||||
css.top = '45%'
|
||||
else if align is 'center'
|
||||
css.left = '45%'
|
||||
else
|
||||
css[align] = 0
|
||||
anchor.css(css).addClass("#{pluginClassName}-corner")
|
||||
$("body").append anchor
|
||||
|
||||
anchor.prepend @wrapper
|
||||
|
||||
setElementPosition: () ->
|
||||
position = @getPosition()
|
||||
|
||||
[pMain, pAlign, pArrow] = position
|
||||
|
||||
#grab some dimensions
|
||||
elemPos = @elem.position()
|
||||
elemH = @elem.outerHeight()
|
||||
elemW = @elem.outerWidth()
|
||||
elemIH = @elem.innerHeight()
|
||||
elemIW = @elem.innerWidth()
|
||||
wrapPos = @wrapper.position()
|
||||
contH = @container.height()
|
||||
contW = @container.width()
|
||||
|
||||
|
||||
#start calculations
|
||||
mainFull = positions[pMain]
|
||||
opp = opposites[pMain]
|
||||
oppFull = positions[opp]
|
||||
#initial positioning
|
||||
css = {}
|
||||
css[oppFull] = if pMain is 'b'
|
||||
elemH
|
||||
else if pMain is 'r'
|
||||
elemW
|
||||
else
|
||||
0
|
||||
|
||||
#correct for elem-wrapper offset
|
||||
# unless navigator.userAgent.match /MSIE/
|
||||
incr css, 'top', elemPos.top - wrapPos.top
|
||||
incr css, 'left', elemPos.left - wrapPos.left
|
||||
|
||||
#correct for margins
|
||||
for pos in ['top', 'left']
|
||||
margin = parseInt @elem.css("margin-#{pos}"), 10
|
||||
incr css, pos, margin if margin
|
||||
#correct for paddings (only for inline)
|
||||
# if /^inline/.test @elem.css('display')
|
||||
# padding = parseInt @elem.css("padding-#{pos}"), 10
|
||||
# incr css, pos, -padding if padding
|
||||
|
||||
#add gap
|
||||
gap = Math.max 0, @options.gap - if @options.arrowShow then arrowSize else 0
|
||||
incr css, oppFull, gap
|
||||
|
||||
#calculate arrow
|
||||
if not @options.arrowShow
|
||||
@arrow.hide()
|
||||
else
|
||||
arrowSize = @options.arrowSize
|
||||
arrowCss = $.extend {}, css
|
||||
arrowColor = @userContainer.css("border-color") or
|
||||
@userContainer.css("background-color") or
|
||||
'white'
|
||||
#build arrow
|
||||
for pos in mainPositions
|
||||
posFull = positions[pos]
|
||||
continue if pos is opp
|
||||
color = if posFull is mainFull then arrowColor else 'transparent'
|
||||
arrowCss["border-#{posFull}"] = "#{arrowSize}px solid #{color}"
|
||||
#add some room for the arrow
|
||||
incr css, positions[opp], arrowSize
|
||||
incr arrowCss, positions[pAlign], arrowSize*2 if pAlign in mainPositions
|
||||
|
||||
#calculate container alignment
|
||||
if pMain in vAligns
|
||||
incr css, 'left', realign(pAlign, contW, elemW)
|
||||
incr arrowCss, 'left', realign(pAlign, arrowSize, elemIW) if arrowCss
|
||||
else if pMain in hAligns
|
||||
incr css, 'top', realign(pAlign, contH, elemH)
|
||||
incr arrowCss, 'top', realign(pAlign, arrowSize, elemIH) if arrowCss
|
||||
|
||||
css.display = 'block' if @container.is(":visible")
|
||||
#apply css
|
||||
@container.removeAttr('style').css css
|
||||
@arrow.removeAttr('style').css(arrowCss) if arrowCss
|
||||
|
||||
getPosition: ->
|
||||
|
||||
text = @options.position or if @elem then @options.elementPosition else @options.globalPosition
|
||||
|
||||
pos = parsePosition text
|
||||
|
||||
#validate position
|
||||
pos[0] = 'b' if pos.length is 0
|
||||
if pos[0] not in mainPositions
|
||||
throw "Must be one of [#{mainPositions}]"
|
||||
|
||||
#validate alignment
|
||||
if pos.length is 1 or
|
||||
(pos[0] in vAligns and pos[1] not in hAligns) or
|
||||
(pos[0] in hAligns and pos[1] not in vAligns)
|
||||
pos[1] = if pos[0] in hAligns then 'm' else 'l'
|
||||
|
||||
if pos.length is 2
|
||||
pos[2] = pos[1]
|
||||
|
||||
return pos
|
||||
|
||||
getStyle: (name) ->
|
||||
name = @options.style unless name
|
||||
name = 'default' unless name
|
||||
style = styles[name]
|
||||
throw "Missing style: #{name}"unless style
|
||||
style
|
||||
|
||||
updateClasses: ->
|
||||
classes = ['base']
|
||||
|
||||
if $.isArray @options.className
|
||||
classes = classes.concat @options.className
|
||||
else if @options.className
|
||||
classes.push @options.className
|
||||
|
||||
style = @getStyle()
|
||||
classes = $.map(classes, (n) -> "#{pluginClassName}-#{style.name}-#{n}").join ' '
|
||||
|
||||
@userContainer.attr 'class', classes
|
||||
|
||||
#run plugin
|
||||
run: (data, options) ->
|
||||
#update options
|
||||
if $.isPlainObject(options)
|
||||
$.extend @options, options
|
||||
#shortcut special case
|
||||
else if $.type(options) is 'string'
|
||||
@options.className = options
|
||||
|
||||
if @container and not data
|
||||
@show false
|
||||
return
|
||||
else if not @container and not data
|
||||
return
|
||||
|
||||
datas = {}
|
||||
if $.isPlainObject data
|
||||
datas = data
|
||||
else
|
||||
datas[blankFieldName] = data
|
||||
|
||||
for name, d of datas
|
||||
type = @userFields[name]
|
||||
continue unless type
|
||||
if type is 'text'
|
||||
#escape
|
||||
d = encode(d)
|
||||
d = d.replace(/\n/g,'<br/>') if @options.breakNewLines
|
||||
#update content
|
||||
value = if name is blankFieldName then '' else '='+name
|
||||
find(@userContainer,"[data-notify-#{type}#{value}]").html(d)
|
||||
|
||||
#set styles
|
||||
@updateClasses()
|
||||
|
||||
#positioning
|
||||
if @elem
|
||||
@setElementPosition()
|
||||
else
|
||||
@setGlobalPosition()
|
||||
|
||||
@show true
|
||||
|
||||
#autohide
|
||||
if @options.autoHide
|
||||
clearTimeout @autohideTimer
|
||||
@autohideTimer = setTimeout =>
|
||||
@show false
|
||||
, @options.autoHideDelay
|
||||
|
||||
destroy: ->
|
||||
@wrapper.remove()
|
||||
|
||||
|
||||
# ================================
|
||||
# API
|
||||
# ================================
|
||||
|
||||
# $.pluginName( { ... } ) changes options for all instances
|
||||
$[pluginName] = (elem, data, options) ->
|
||||
if (elem and elem.nodeName) or elem.jquery
|
||||
$(elem)[pluginName](data, options)
|
||||
else
|
||||
options = data
|
||||
data = elem
|
||||
new Notification null, data, options
|
||||
elem
|
||||
|
||||
# $( ... ).pluginName( { .. } ) creates a cached instance on each
|
||||
$.fn[pluginName] = (data, options) ->
|
||||
$(@).each ->
|
||||
inst = getAnchorElement($(@)).data(pluginClassName)
|
||||
if inst
|
||||
inst.run data, options
|
||||
else
|
||||
new Notification $(@), data, options
|
||||
@
|
||||
|
||||
#extra methods
|
||||
$.extend $[pluginName], { defaults, addStyle, pluginOptions, getStyle, insertCSS }
|
||||
|
||||
#when ready
|
||||
$ ->
|
||||
#insert default style
|
||||
insertCSS(coreStyle.css).attr('id', 'core-notify')
|
||||
|
||||
#watch all notifications clicks
|
||||
$(document).on 'click', ".#{pluginClassName}-hidable", (e) ->
|
||||
$(@).trigger 'notify-hide'
|
||||
|
||||
$(document).on 'notify-hide', ".#{pluginClassName}-wrapper", (e) ->
|
||||
$(@).data(pluginClassName)?.show false
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
* Styles in CoffeeScript go here, which will be compiled into `dist/styles`
|
||||
* Styles in JavaScript can go straight in `dist/styles/`
|
||||
@@ -1,40 +0,0 @@
|
||||
|
||||
$.notify.addStyle "bootstrap",
|
||||
html: """
|
||||
<div>
|
||||
<span data-notify-text></span>
|
||||
</div>
|
||||
"""
|
||||
classes:
|
||||
base:
|
||||
"font-weight": "bold"
|
||||
"padding": "8px 15px 8px 14px"
|
||||
"text-shadow": "0 1px 0 rgba(255, 255, 255, 0.5)"
|
||||
"background-color": "#fcf8e3"
|
||||
"border": "1px solid #fbeed5"
|
||||
"border-radius": "4px"
|
||||
"white-space": "nowrap"
|
||||
#for background-image
|
||||
"padding-left": "25px"
|
||||
"background-repeat": "no-repeat"
|
||||
"background-position": "3px 7px"
|
||||
error:
|
||||
"color": "#B94A48"
|
||||
"background-color": "#F2DEDE"
|
||||
"border-color": "#EED3D7"
|
||||
"background-image": "url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAtRJREFUeNqkVc1u00AQHq+dOD+0poIQfkIjalW0SEGqRMuRnHos3DjwAH0ArlyQeANOOSMeAA5VjyBxKBQhgSpVUKKQNGloFdw4cWw2jtfMOna6JOUArDTazXi/b3dm55socPqQhFka++aHBsI8GsopRJERNFlY88FCEk9Yiwf8RhgRyaHFQpPHCDmZG5oX2ui2yilkcTT1AcDsbYC1NMAyOi7zTX2Agx7A9luAl88BauiiQ/cJaZQfIpAlngDcvZZMrl8vFPK5+XktrWlx3/ehZ5r9+t6e+WVnp1pxnNIjgBe4/6dAysQc8dsmHwPcW9C0h3fW1hans1ltwJhy0GxK7XZbUlMp5Ww2eyan6+ft/f2FAqXGK4CvQk5HueFz7D6GOZtIrK+srupdx1GRBBqNBtzc2AiMr7nPplRdKhb1q6q6zjFhrklEFOUutoQ50xcX86ZlqaZpQrfbBdu2R6/G19zX6XSgh6RX5ubyHCM8nqSID6ICrGiZjGYYxojEsiw4PDwMSL5VKsC8Yf4VRYFzMzMaxwjlJSlCyAQ9l0CW44PBADzXhe7xMdi9HtTrdYjFYkDQL0cn4Xdq2/EAE+InCnvADTf2eah4Sx9vExQjkqXT6aAERICMewd/UAp/IeYANM2joxt+q5VI+ieq2i0Wg3l6DNzHwTERPgo1ko7XBXj3vdlsT2F+UuhIhYkp7u7CarkcrFOCtR3H5JiwbAIeImjT/YQKKBtGjRFCU5IUgFRe7fF4cCNVIPMYo3VKqxwjyNAXNepuopyqnld602qVsfRpEkkz+GFL1wPj6ySXBpJtWVa5xlhpcyhBNwpZHmtX8AGgfIExo0ZpzkWVTBGiXCSEaHh62/PoR0p/vHaczxXGnj4bSo+G78lELU80h1uogBwWLf5YlsPmgDEd4M236xjm+8nm4IuE/9u+/PH2JXZfbwz4zw1WbO+SQPpXfwG/BBgAhCNZiSb/pOQAAAAASUVORK5CYII=)"
|
||||
success:
|
||||
"color": "#468847"
|
||||
"background-color": "#DFF0D8"
|
||||
"border-color": "#D6E9C6"
|
||||
"background-image": "url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAutJREFUeNq0lctPE0Ecx38zu/RFS1EryqtgJFA08YCiMZIAQQ4eRG8eDGdPJiYeTIwHTfwPiAcvXIwXLwoXPaDxkWgQ6islKlJLSQWLUraPLTv7Gme32zoF9KSTfLO7v53vZ3d/M7/fIth+IO6INt2jjoA7bjHCJoAlzCRw59YwHYjBnfMPqAKWQYKjGkfCJqAF0xwZjipQtA3MxeSG87VhOOYegVrUCy7UZM9S6TLIdAamySTclZdYhFhRHloGYg7mgZv1Zzztvgud7V1tbQ2twYA34LJmF4p5dXF1KTufnE+SxeJtuCZNsLDCQU0+RyKTF27Unw101l8e6hns3u0PBalORVVVkcaEKBJDgV3+cGM4tKKmI+ohlIGnygKX00rSBfszz/n2uXv81wd6+rt1orsZCHRdr1Imk2F2Kob3hutSxW8thsd8AXNaln9D7CTfA6O+0UgkMuwVvEFFUbbAcrkcTA8+AtOk8E6KiQiDmMFSDqZItAzEVQviRkdDdaFgPp8HSZKAEAL5Qh7Sq2lIJBJwv2scUqkUnKoZgNhcDKhKg5aH+1IkcouCAdFGAQsuWZYhOjwFHQ96oagWgRoUov1T9kRBEODAwxM2QtEUl+Wp+Ln9VRo6BcMw4ErHRYjH4/B26AlQoQQTRdHWwcd9AH57+UAXddvDD37DmrBBV34WfqiXPl61g+vr6xA9zsGeM9gOdsNXkgpEtTwVvwOklXLKm6+/p5ezwk4B+j6droBs2CsGa/gNs6RIxazl4Tc25mpTgw/apPR1LYlNRFAzgsOxkyXYLIM1V8NMwyAkJSctD1eGVKiq5wWjSPdjmeTkiKvVW4f2YPHWl3GAVq6ymcyCTgovM3FzyRiDe2TaKcEKsLpJvNHjZgPNqEtyi6mZIm4SRFyLMUsONSSdkPeFtY1n0mczoY3BHTLhwPRy9/lzcziCw9ACI+yql0VLzcGAZbYSM5CCSZg1/9oc/nn7+i8N9p/8An4JMADxhH+xHfuiKwAAAABJRU5ErkJggg==)"
|
||||
info:
|
||||
"color": "#3A87AD"
|
||||
"background-color": "#D9EDF7"
|
||||
"border-color": "#BCE8F1"
|
||||
"background-image": "url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QYFAhkSsdes/QAAA8dJREFUOMvVlGtMW2UYx//POaWHXg6lLaW0ypAtw1UCgbniNOLcVOLmAjHZolOYlxmTGXVZdAnRfXQm+7SoU4mXaOaiZsEpC9FkiQs6Z6bdCnNYruM6KNBw6YWewzl9z+sHImEWv+vz7XmT95f/+3/+7wP814v+efDOV3/SoX3lHAA+6ODeUFfMfjOWMADgdk+eEKz0pF7aQdMAcOKLLjrcVMVX3xdWN29/GhYP7SvnP0cWfS8caSkfHZsPE9Fgnt02JNutQ0QYHB2dDz9/pKX8QjjuO9xUxd/66HdxTeCHZ3rojQObGQBcuNjfplkD3b19Y/6MrimSaKgSMmpGU5WevmE/swa6Oy73tQHA0Rdr2Mmv/6A1n9w9suQ7097Z9lM4FlTgTDrzZTu4StXVfpiI48rVcUDM5cmEksrFnHxfpTtU/3BFQzCQF/2bYVoNbH7zmItbSoMj40JSzmMyX5qDvriA7QdrIIpA+3cdsMpu0nXI8cV0MtKXCPZev+gCEM1S2NHPvWfP/hL+7FSr3+0p5RBEyhEN5JCKYr8XnASMT0xBNyzQGQeI8fjsGD39RMPk7se2bd5ZtTyoFYXftF6y37gx7NeUtJJOTFlAHDZLDuILU3j3+H5oOrD3yWbIztugaAzgnBKJuBLpGfQrS8wO4FZgV+c1IxaLgWVU0tMLEETCos4xMzEIv9cJXQcyagIwigDGwJgOAtHAwAhisQUjy0ORGERiELgG4iakkzo4MYAxcM5hAMi1WWG1yYCJIcMUaBkVRLdGeSU2995TLWzcUAzONJ7J6FBVBYIggMzmFbvdBV44Corg8vjhzC+EJEl8U1kJtgYrhCzgc/vvTwXKSib1paRFVRVORDAJAsw5FuTaJEhWM2SHB3mOAlhkNxwuLzeJsGwqWzf5TFNdKgtY5qHp6ZFf67Y/sAVadCaVY5YACDDb3Oi4NIjLnWMw2QthCBIsVhsUTU9tvXsjeq9+X1d75/KEs4LNOfcdf/+HthMnvwxOD0wmHaXr7ZItn2wuH2SnBzbZAbPJwpPx+VQuzcm7dgRCB57a1uBzUDRL4bfnI0RE0eaXd9W89mpjqHZnUI5Hh2l2dkZZUhOqpi2qSmpOmZ64Tuu9qlz/SEXo6MEHa3wOip46F1n7633eekV8ds8Wxjn37Wl63VVa+ej5oeEZ/82ZBETJjpJ1Rbij2D3Z/1trXUvLsblCK0XfOx0SX2kMsn9dX+d+7Kf6h8o4AIykuffjT8L20LU+w4AZd5VvEPY+XpWqLV327HR7DzXuDnD8r+ovkBehJ8i+y8YAAAAASUVORK5CYII=)"
|
||||
warn:
|
||||
"color": "#C09853"
|
||||
"background-color": "#FCF8E3"
|
||||
"border-color": "#FBEED5"
|
||||
"background-image": "url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAMAAAC6V+0/AAABJlBMVEXr6eb/2oD/wi7/xjr/0mP/ykf/tQD/vBj/3o7/uQ//vyL/twebhgD/4pzX1K3z8e349vK6tHCilCWbiQymn0jGworr6dXQza3HxcKkn1vWvV/5uRfk4dXZ1bD18+/52YebiAmyr5S9mhCzrWq5t6ufjRH54aLs0oS+qD751XqPhAybhwXsujG3sm+Zk0PTwG6Shg+PhhObhwOPgQL4zV2nlyrf27uLfgCPhRHu7OmLgAafkyiWkD3l49ibiAfTs0C+lgCniwD4sgDJxqOilzDWowWFfAH08uebig6qpFHBvH/aw26FfQTQzsvy8OyEfz20r3jAvaKbhgG9q0nc2LbZxXanoUu/u5WSggCtp1anpJKdmFz/zlX/1nGJiYmuq5Dx7+sAAADoPUZSAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfdBgUBGhh4aah5AAAAlklEQVQY02NgoBIIE8EUcwn1FkIXM1Tj5dDUQhPU502Mi7XXQxGz5uVIjGOJUUUW81HnYEyMi2HVcUOICQZzMMYmxrEyMylJwgUt5BljWRLjmJm4pI1hYp5SQLGYxDgmLnZOVxuooClIDKgXKMbN5ggV1ACLJcaBxNgcoiGCBiZwdWxOETBDrTyEFey0jYJ4eHjMGWgEAIpRFRCUt08qAAAAAElFTkSuQmCC)"
|
||||
Reference in New Issue
Block a user