alertify-rails 0.0.1 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md CHANGED
@@ -1,24 +1,38 @@
1
- # Alertify::Rails
1
+ # alertify-rails
2
2
 
3
- TODO: Write a gem description
3
+ This gem provides [alertify.js](http://fabien-d.github.com/alertify.js) (v0.2.12) for Rails.
4
4
 
5
- ## Installation
6
5
 
7
- Add this line to your application's Gemfile:
6
+ ## Installation
8
7
 
9
- gem 'alertify-rails'
8
+ In your Gemfile:
10
9
 
11
- And then execute:
10
+ ```ruby
11
+ gem 'alertify-rails'
12
+ ```
12
13
 
13
- $ bundle
14
+ or system wide:
14
15
 
15
- Or install it yourself as:
16
+ ```console
17
+ $ gem install alertify-rails
18
+ ```
16
19
 
17
- $ gem install alertify-rails
18
20
 
19
21
  ## Usage
20
22
 
21
- TODO: Write usage instructions here
23
+ The alertify files will be added to the asset pipeline and available for you to use. Add the following line to `app/assets/javascripts/application.js`
24
+
25
+ ```javascript
26
+ //= require alertify
27
+ ```
28
+
29
+ In order to get the CSS, add the following line to `app/assets/stylesheets/application.css.scss`
30
+
31
+ ```css
32
+ /*
33
+ *= require alertify
34
+ */
35
+ ```
22
36
 
23
37
  ## Contributing
24
38
 
@@ -27,3 +41,6 @@ TODO: Write usage instructions here
27
41
  3. Commit your changes (`git commit -am 'Add some feature'`)
28
42
  4. Push to the branch (`git push origin my-new-feature`)
29
43
  5. Create new Pull Request
44
+
45
+ Copyright © 2012 Rudolf Schmidt, released under the MIT license
46
+
@@ -1,7 +1,7 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
  lib = File.expand_path('../lib', __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'alertify/version'
4
+ require 'alertify/rails/version'
5
5
 
6
6
  Gem::Specification.new do |gem|
7
7
  gem.name = "alertify-rails"
@@ -9,7 +9,7 @@ Gem::Specification.new do |gem|
9
9
  gem.authors = ["Rudolf Schmidt"]
10
10
 
11
11
  gem.description = %q{Use Alertify.js with Rails 3}
12
- gem.summary = %q{This gem provides the Alertify.js deiver for Rails 3 applications}
12
+ gem.summary = %q{This gem provides the Alertify.js driver for Rails 3 applications}
13
13
  gem.homepage = ""
14
14
 
15
15
  gem.files = `git ls-files`.split($/)
@@ -1,7 +1,2 @@
1
- require 'alertify/engine' if ::Rails.version >= '3.1'
2
- require 'alertify/railtie'
3
- require 'alertify/version'
4
-
5
- module Alertify #:nodoc:
6
- end
1
+ require 'alertify/rails'
7
2
 
@@ -0,0 +1,9 @@
1
+ require 'alertify/rails/engine' if ::Rails.version >= '3.1'
2
+ require 'alertify/rails/railtie'
3
+ require 'alertify/rails/version'
4
+
5
+ module Alertify #:nodoc:
6
+ module Rails #:nodoc:
7
+ end
8
+ end
9
+
@@ -0,0 +1,9 @@
1
+ module Alertify #:nodoc:
2
+ module Rails #:nodoc:
3
+
4
+ class Engine < ::Rails::Engine
5
+ end
6
+
7
+ end
8
+ end
9
+
@@ -0,0 +1,14 @@
1
+ module Alertify #:nodoc:
2
+ module Rails #:nodoc:
3
+
4
+ class Railtie < ::Rails::Railtie
5
+ config.before_configuration do
6
+ if config.action_view.javascript_expansions
7
+ config.action_view.javascript_expansions[:defaults] << 'alertify'
8
+ end
9
+ end
10
+ end
11
+
12
+ end
13
+ end
14
+
@@ -0,0 +1,8 @@
1
+ module Alertify #:nodoc:
2
+ module Rails #:nodoc:
3
+ VERSION = "0.1.0"
4
+ ALERTIFY_VERSION = "0.2.12"
5
+
6
+ end
7
+ end
8
+
@@ -1,393 +1,467 @@
1
1
  /**
2
- * Alertify
2
+ * alertify
3
3
  * An unobtrusive customizable JavaScript notification system
4
4
  *
5
5
  * @author Fabien Doiron <fabien.doiron@gmail.com>
6
6
  * @copyright Fabien Doiron 2012
7
- * @license The MIT License (MIT) <http://opensource.org/licenses/mit-license.php>
7
+ * @license MIT <http://opensource.org/licenses/mit-license.php>
8
8
  * @link http://www.github.com/fabien-d
9
- * @module Alertify
10
- * @version 0.1a1
9
+ * @module alertify
10
+ * @version 0.2.12
11
11
  */
12
12
 
13
- ;(function( window, undefined ) {
14
-
15
- var
16
- // Use the correct document accordingly with window argument (sandbox)
17
- document = window.document,
18
-
19
- // The ready event handler and self cleanup method
20
- DOMContentLoaded = function() {
21
- if ( document.addEventListener ) {
22
- document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
23
-
24
- window.alertify = new Alertify();
25
- } else if ( document.readyState === "complete" ) {
26
- // we're here because readyState === "complete" in oldIE
27
- // which is good enough for us to call the dom ready!
28
- document.detachEvent( "onreadystatechange", DOMContentLoaded );
29
-
30
- window.alertify = new Alertify();
31
- }
32
- },
33
-
34
- // sandboxed Alertify
35
- Alertify = function () {
36
-
37
- var init, addListeners, bind, unbind, build, close, extend, hide, notify, setup, alert, confirm, log, prompt,
38
- $, cover, element, logElement,
39
- dialogs = {},
40
- delay = 5000,
41
- keys = {},
42
- labels = {},
43
- queue = [],
44
- isopen = false;
45
-
46
- keys = {
47
- ENTER : 13,
48
- ESC : 27
49
- };
50
-
51
- labels = {
52
- ok : "OK",
53
- cancel : "Cancel"
54
- };
55
-
56
- dialogs = {
57
- buttons : {
58
- holder : "<nav class=\"alertify-buttons\">{{buttons}}</nav>",
59
- ok : "<a href=\"#\" class=\"alertify-button alertify-button-ok\" id=\"aOK\">{{ok}}</a>",
60
- cancel : "<a href=\"#\" class=\"alertify-button alertify-button-cancel\" id=\"aCancel\">{{cancel}}</a>"
61
- },
62
- input : "<input type=\"text\" class=\"alertify-text\" id=\"aText\">",
63
- message : "<p class=\"alertify-message\">{{message}}</p>",
64
- log : "<article class=\"alertify-log{{class}}\">{{message}}</article>"
65
- };
66
-
67
- /**
68
- * Shorthand for document.getElementById()
69
- *
70
- * @param {String} id A specific element ID
71
-
72
- * @return {Object} HTML element
73
- */
74
- $ = function (id) {
75
- return document.getElementById(id);
76
- };
77
-
78
- /**
79
- * Initialize Alertify
80
- * Create the 2 main elements
81
- *
82
- * @return {undefined}
83
- */
84
- init = function () {
85
- // ensure legacy browsers support html5 tags
86
- document.createElement("nav");
87
- document.createElement("article");
88
- document.createElement("section");
89
- // cover
90
- cover = document.createElement("div");
91
- cover.setAttribute("id", "alertifycover");
92
- cover.className = "alertify-cover alertify-hidden";
93
- document.body.appendChild(cover);
94
- // main element
95
- element = document.createElement("section");
96
- element.setAttribute("id", "alertify");
97
- element.className = "alertify alertify-hidden";
98
- document.body.appendChild(element);
99
- // main element
100
- logElement = document.createElement("section");
101
- logElement.setAttribute("id", "alertifylogs");
102
- logElement.className = "alertify-logs";
103
- document.body.appendChild(logElement);
104
- };
105
-
106
- /**
107
- * Set the proper button click events
108
- *
109
- * @param {Function} fn [Optional] Callback function
110
- *
111
- * @return {undefined}
112
- */
113
- addListeners = function (fn) {
114
- var btnOK = $("aOK") || undefined,
115
- btnCancel = $("aCancel") || undefined,
116
- input = $("aText") || undefined,
117
- val = "",
118
- ok, cancel, common, key;
119
-
120
- // ok event handler
121
- ok = function (event) {
122
- common(event);
123
- if (typeof input !== "undefined") val = input.value;
124
- if (typeof fn === "function") fn(true, val);
125
- if (typeof event.preventDefault !== "undefined") event.preventDefault();
126
- };
127
-
128
- // cancel event handler
129
- cancel = function (event) {
130
- common(event);
131
- if (typeof fn === "function") fn(false);
132
- if (typeof event.preventDefault !== "undefined") event.preventDefault();
133
- };
134
-
135
- // common event handler (keyup, ok and cancel)
136
- common = function (event) {
137
- hide();
138
- unbind(document.body, "keyup", key);
139
- };
140
-
141
- // keyup handler
142
- key = function (event) {
143
- var keyCode = event.keyCode;
144
- if (keyCode === keys.ENTER && typeof btnOK !== "undefined") ok(event);
145
- else if (keyCode === keys.ESC && typeof btnCancel !== "undefined") cancel(event);
146
- };
147
-
148
- // handle OK click
149
- if (typeof btnOK !== "undefined") bind(btnOK, "click", ok);
150
- // handle Cancel click
151
- if (typeof btnCancel !== "undefined") bind(btnCancel, "click", cancel);
152
-
153
- // clear focus off activeElement element to ensure
154
- // the ENTER key triggers the correct behaviour
155
- // Firefox has an issue if this isn't done and the current
156
- // focus is an anchor
157
- document.activeElement.blur();
158
- // listen for keys, OK => ENTER, Cancel => ESC
159
- bind(document.body, "keyup", key);
160
- };
161
-
162
- /**
163
- * Bind events to elements
164
- *
165
- * @param {Object} el HTML Object
166
- * @param {Event} event Event to attach to element
167
- * @param {Function} fn Callback function
168
- *
169
- * @return {undefined}
170
- */
171
- bind = function (el, event, fn) {
172
- if (typeof el.addEventListener === "function") {
173
- el.addEventListener(event, fn, false);
174
- } else if (el.attachEvent) {
175
- el.attachEvent("on" + event, fn);
176
- }
177
- };
178
-
179
- /**
180
- * Unbind events to elements
181
- *
182
- * @param {Object} el HTML Object
183
- * @param {Event} event Event to detach to element
184
- * @param {Function} fn Callback function
185
- *
186
- * @return {undefined}
187
- */
188
- unbind = function (el, event, fn) {
189
- if (typeof el.removeEventListener === "function") {
190
- el.removeEventListener(event, fn, false);
191
- } else if (el.detachEvent) {
192
- el.detachEvent("on" + event, fn);
193
- }
194
- };
195
-
196
- /**
197
- * Build the proper message box
198
- *
199
- * @param {Object} item Current object in the queue
200
- * @return {String} An HTML string of the message box
201
- */
202
- build = function (item) {
203
- var html = "",
204
- type = item.type,
205
- message = item.message;
206
-
207
- html += "<div class=\"alertify-dialog\">";
208
- html += "<article class=\"alertify-inner\">";
209
- html += dialogs.message.replace("{{message}}", message);
210
-
211
- if (type === "prompt") { html += dialogs.input; }
212
-
213
- html += dialogs.buttons.holder;
214
- html += "</article>";
215
- html += "</div>";
216
-
217
- switch (type) {
218
- case "confirm":
219
- case "prompt":
220
- html = html.replace("{{buttons}}", dialogs.buttons.cancel + dialogs.buttons.ok);
221
- html = html.replace("{{ok}}", labels.ok).replace("{{cancel}}", labels.cancel);
222
- break;
223
- case "alert":
224
- html = html.replace("{{buttons}}", dialogs.buttons.ok);
225
- html = html.replace("{{ok}}", labels.ok);
226
- break;
227
- default:
228
- break;
229
- }
230
-
231
- element.className = "alertify alertify-show alertify-" + type;
232
- cover.className = "alertify-cover";
233
- return html;
234
- };
235
-
236
- /**
237
- * Close the log messages
238
- *
239
- * @return {undefined}
240
- */
241
- close = function () {
242
- setTimeout(function () {
243
- var child = logElement.childNodes[logElement.childNodes.length - 1];
244
- if (typeof child !== "undefined") logElement.removeChild(child);
245
- }, delay);
246
- };
247
-
248
- /**
249
- * Extend the log method to create custom methods
250
- *
251
- * @param {String} type Custom method name
252
- * @return {Function}
253
- */
254
- extend = function (type) {
255
- return function (message) { log(message, type); };
256
- };
257
-
258
- /**
259
- * Add new log message
260
- * If a type is passed, a class name "alertify-log-{type}" will get added.
261
- * This allows for custom look and feel for various types of notifications.
262
- *
263
- * @param {String} message The message passed from the callee
264
- * @param {String} type [Optional] Type of log message
265
- *
266
- * @return {undefined}
267
- */
268
- notify = function (message, type) {
269
- var log = document.createElement("article");
270
- log.className = "alertify-log" + ((typeof type === "string" && type !== "") ? " alertify-log-" + type : "");
271
- log.innerHTML = message;
272
- // prepend child
273
- logElement.insertBefore(log, logElement.firstChild);
274
- // triggers the CSS animation
275
- setTimeout(function() { log.className = log.className + " alertify-log-show"; }, 50);
276
- close();
277
- };
278
-
279
- /**
280
- * Hide the dialog and rest to defaults
281
- *
282
- * @return {undefined}
283
- */
284
- hide = function () {
285
- // remove reference from queue
286
- queue.splice(0,1);
287
- // if items remaining in the queue
288
- if (queue.length > 0) setup();
289
- else {
290
- isopen = false;
291
- element.className = "alertify alertify-hide alertify-hidden";
292
- cover.className = "alertify-cover alertify-hidden";
293
- }
294
- };
295
-
296
- /**
297
- * Initiate all the required pieces for the dialog box
298
- *
299
- * @return {undefined}
300
- */
301
- setup = function () {
302
- var item = queue[0];
303
-
304
- isopen = true;
305
- element.innerHTML = build(item);
306
- addListeners(item.callback);
307
- };
308
-
309
- /**
310
- * Create an alert dialog box
311
- *
312
- * @param {String} message The message passed from the callee
313
- * @param {Function} fn [Optional] Callback function
314
- *
315
- * @return {Object}
316
- */
317
- alert = function (message, fn) {
318
- queue.push({ type: "alert", message: message, callback: fn });
319
- if (!isopen) setup();
320
-
321
- return this;
322
- };
323
-
324
- /**
325
- * Create a confirm dialog box
326
- *
327
- * @param {String} message The message passed from the callee
328
- * @param {Function} fn [Optional] Callback function
329
- *
330
- * @return {Object}
331
- */
332
- confirm = function (message, fn) {
333
- queue.push({ type: "confirm", message: message, callback: fn });
334
- if (!isopen) setup();
335
-
336
- return this;
337
- };
338
-
339
- /**
340
- * Show a new log message box
341
- *
342
- * @param {String} message The message passed from the callee
343
- * @param {String} type [Optional] Optional type of log message
344
- *
345
- * @return {Object}
346
- */
347
- log = function (message, type) {
348
- notify(message, type);
349
- return this;
350
- };
351
-
352
- /**
353
- * Create a prompt dialog box
354
- *
355
- * @param {String} message The message passed from the function
356
- * @param {Function} fn [Optional] Callback function
357
- *
358
- * @return {Object}
359
- */
360
- prompt = function (message, fn) {
361
- queue.push({ type: "prompt", message: message, callback: fn });
362
- if (!isopen) setup();
363
-
364
- return this;
365
- };
366
-
367
- // Bootstrap
368
- init();
369
-
370
- return {
371
- alert : alert,
372
- confirm : confirm,
373
- log : log,
374
- prompt : prompt,
375
- success : function (message) { log(message, "success"); },
376
- error : function (message) { log(message, "error"); },
377
- extend : extend,
378
-
379
- labels : labels,
380
- delay : delay
381
- };
382
- };
383
-
384
- /*
385
- * Trigger DOMContentLoaded function when DOM is ready
386
- */
387
- if (window.addEventListener) { // W3C standard
388
- window.addEventListener('load', DOMContentLoaded, false);
389
- } else if (window.attachEvent) { // Microsoft
390
- window.attachEvent('onload', DOMContentLoaded);
391
- };
392
-
393
- })( window );
13
+ /*global define*/
14
+ (function (global, undefined) {
15
+ "use strict";
16
+
17
+ var document = global.document,
18
+ Alertify;
19
+
20
+ Alertify = function () {
21
+
22
+ var _alertify = {},
23
+ dialogs = {},
24
+ isopen = false,
25
+ keys = { ENTER: 13, ESC: 27, SPACE: 32 },
26
+ queue = [],
27
+ $, elCallee, elCover, elDialog, elLog;
28
+
29
+ /**
30
+ * Markup pieces
31
+ * @type {Object}
32
+ */
33
+ dialogs = {
34
+ buttons : {
35
+ holder : "<nav class=\"alertify-buttons\">{{buttons}}</nav>",
36
+ submit : "<button type=\"submit\" class=\"alertify-button alertify-button-ok\" id=\"alertify-ok\" />{{ok}}</button>",
37
+ ok : "<a href=\"#\" class=\"alertify-button alertify-button-ok\" id=\"alertify-ok\">{{ok}}</a>",
38
+ cancel : "<a href=\"#\" class=\"alertify-button alertify-button-cancel\" id=\"alertify-cancel\">{{cancel}}</a>"
39
+ },
40
+ input : "<input type=\"text\" class=\"alertify-text\" id=\"alertify-text\">",
41
+ message : "<p class=\"alertify-message\">{{message}}</p>",
42
+ log : "<article class=\"alertify-log{{class}}\">{{message}}</article>"
43
+ };
44
+
45
+ /**
46
+ * Shorthand for document.getElementById()
47
+ *
48
+ * @param {String} id A specific element ID
49
+ * @return {Object} HTML element
50
+ */
51
+ $ = function (id) {
52
+ return document.getElementById(id);
53
+ };
54
+
55
+ /**
56
+ * Alertify private object
57
+ * @type {Object}
58
+ */
59
+ _alertify = {
60
+
61
+ /**
62
+ * Labels object
63
+ * @type {Object}
64
+ */
65
+ labels : {
66
+ ok : "OK",
67
+ cancel : "Cancel"
68
+ },
69
+
70
+ /**
71
+ * Delay number
72
+ * @type {Number}
73
+ */
74
+ delay : 5000,
75
+
76
+ /**
77
+ * Set the proper button click events
78
+ *
79
+ * @param {Function} fn [Optional] Callback function
80
+ *
81
+ * @return {undefined}
82
+ */
83
+ addListeners : function (fn) {
84
+ var btnReset = $("alertify-resetFocus"),
85
+ btnOK = $("alertify-ok") || undefined,
86
+ btnCancel = $("alertify-cancel") || undefined,
87
+ input = $("alertify-text") || undefined,
88
+ form = $("alertify-form") || undefined,
89
+ hasOK = (typeof btnOK !== "undefined"),
90
+ hasCancel = (typeof btnCancel !== "undefined"),
91
+ hasInput = (typeof input !== "undefined"),
92
+ val = "",
93
+ self = this,
94
+ ok, cancel, common, key, reset;
95
+
96
+ // ok event handler
97
+ ok = function (event) {
98
+ if (typeof event.preventDefault !== "undefined") event.preventDefault();
99
+ common(event);
100
+ if (typeof input !== "undefined") val = input.value;
101
+ if (typeof fn === "function") fn(true, val);
102
+ };
103
+
104
+ // cancel event handler
105
+ cancel = function (event) {
106
+ if (typeof event.preventDefault !== "undefined") event.preventDefault();
107
+ common(event);
108
+ if (typeof fn === "function") fn(false);
109
+ };
110
+
111
+ // common event handler (keyup, ok and cancel)
112
+ common = function (event) {
113
+ self.hide();
114
+ self.unbind(document.body, "keyup", key);
115
+ self.unbind(btnReset, "focus", reset);
116
+ if (hasInput) self.unbind(form, "submit", ok);
117
+ if (hasOK) self.unbind(btnOK, "click", ok);
118
+ if (hasCancel) self.unbind(btnCancel, "click", cancel);
119
+ };
120
+
121
+ // keyup handler
122
+ key = function (event) {
123
+ var keyCode = event.keyCode;
124
+ if (keyCode === keys.SPACE && !hasInput) ok(event);
125
+ if (keyCode === keys.ESC && hasCancel) cancel(event);
126
+ };
127
+
128
+ // reset focus to first item in the dialog
129
+ reset = function (event) {
130
+ if (hasInput) input.focus();
131
+ else if (hasCancel) btnCancel.focus();
132
+ else btnOK.focus();
133
+ };
134
+
135
+ // handle reset focus link
136
+ // this ensures that the keyboard focus does not
137
+ // ever leave the dialog box until an action has
138
+ // been taken
139
+ this.bind(btnReset, "focus", reset);
140
+ // handle OK click
141
+ if (hasOK) this.bind(btnOK, "click", ok);
142
+ // handle Cancel click
143
+ if (hasCancel) this.bind(btnCancel, "click", cancel);
144
+ // listen for keys, Cancel => ESC
145
+ this.bind(document.body, "keyup", key);
146
+ // bind form submit
147
+ if (hasInput) this.bind(form, "submit", ok);
148
+ // set focus on OK button or the input text
149
+ global.setTimeout(function () {
150
+ if (input) {
151
+ input.focus();
152
+ input.select();
153
+ }
154
+ else btnOK.focus();
155
+ }, 50);
156
+ },
157
+
158
+ /**
159
+ * Bind events to elements
160
+ *
161
+ * @param {Object} el HTML Object
162
+ * @param {Event} event Event to attach to element
163
+ * @param {Function} fn Callback function
164
+ *
165
+ * @return {undefined}
166
+ */
167
+ bind : function (el, event, fn) {
168
+ if (typeof el.addEventListener === "function") {
169
+ el.addEventListener(event, fn, false);
170
+ } else if (el.attachEvent) {
171
+ el.attachEvent("on" + event, fn);
172
+ }
173
+ },
174
+
175
+ /**
176
+ * Build the proper message box
177
+ *
178
+ * @param {Object} item Current object in the queue
179
+ *
180
+ * @return {String} An HTML string of the message box
181
+ */
182
+ build : function (item) {
183
+ var html = "",
184
+ type = item.type,
185
+ message = item.message;
186
+
187
+ html += "<div class=\"alertify-dialog\">";
188
+
189
+ if (type === "prompt") html += "<form id=\"alertify-form\">";
190
+
191
+ html += "<article class=\"alertify-inner\">";
192
+ html += dialogs.message.replace("{{message}}", message);
193
+
194
+ if (type === "prompt") html += dialogs.input;
195
+
196
+ html += dialogs.buttons.holder;
197
+ html += "</article>";
198
+
199
+ if (type === "prompt") html += "</form>";
200
+
201
+ html += "<a id=\"alertify-resetFocus\" class=\"alertify-resetFocus\" href=\"#\">Reset Focus</a>";
202
+ html += "</div>";
203
+
204
+ switch (type) {
205
+ case "confirm":
206
+ html = html.replace("{{buttons}}", dialogs.buttons.cancel + dialogs.buttons.ok);
207
+ html = html.replace("{{ok}}", this.labels.ok).replace("{{cancel}}", this.labels.cancel);
208
+ break;
209
+ case "prompt":
210
+ html = html.replace("{{buttons}}", dialogs.buttons.cancel + dialogs.buttons.submit);
211
+ html = html.replace("{{ok}}", this.labels.ok).replace("{{cancel}}", this.labels.cancel);
212
+ break;
213
+ case "alert":
214
+ html = html.replace("{{buttons}}", dialogs.buttons.ok);
215
+ html = html.replace("{{ok}}", this.labels.ok);
216
+ break;
217
+ default:
218
+ break;
219
+ }
220
+
221
+ elDialog.className = "alertify alertify-show alertify-" + type;
222
+ elCover.className = "alertify-cover";
223
+ return html;
224
+ },
225
+
226
+ /**
227
+ * Close the log messages
228
+ *
229
+ * @param {Object} elem HTML Element of log message to close
230
+ * @param {Number} wait [optional] Time (in ms) to wait before automatically hiding the message
231
+ *
232
+ * @return {undefined}
233
+ */
234
+ close : function (elem, wait) {
235
+ var timer = (wait && !isNaN(wait)) ? +wait : this.delay; // Unary Plus: +"2" === 2
236
+ this.bind(elem, "click", function () {
237
+ elLog.removeChild(elem);
238
+ });
239
+ setTimeout(function () {
240
+ if (typeof elem !== "undefined" && elem.parentNode === elLog) elLog.removeChild(elem);
241
+ }, timer);
242
+ },
243
+
244
+ /**
245
+ * Create a dialog box
246
+ *
247
+ * @param {String} message The message passed from the callee
248
+ * @param {String} type Type of dialog to create
249
+ * @param {Function} fn [Optional] Callback function
250
+ * @param {String} placeholder [Optional] Default value for prompt input field
251
+ *
252
+ * @return {Object}
253
+ */
254
+ dialog : function (message, type, fn, placeholder) {
255
+ // set the current active element
256
+ // this allows the keyboard focus to be resetted
257
+ // after the dialog box is closed
258
+ elCallee = document.activeElement;
259
+ // check to ensure the alertify dialog element
260
+ // has been successfully created
261
+ var check = function () {
262
+ if (elDialog && elDialog.scrollTop !== null) return;
263
+ else check();
264
+ };
265
+ // error catching
266
+ if (typeof message !== "string") throw new Error("message must be a string");
267
+ if (typeof type !== "string") throw new Error("type must be a string");
268
+ if (typeof fn !== "undefined" && typeof fn !== "function") throw new Error("fn must be a function");
269
+ // initialize alertify if it hasn't already been done
270
+ if (typeof this.init === "function") {
271
+ this.init();
272
+ check();
273
+ }
274
+
275
+ queue.push({ type: type, message: message, callback: fn, placeholder: placeholder });
276
+ if (!isopen) this.setup();
277
+
278
+ return this;
279
+ },
280
+
281
+ /**
282
+ * Extend the log method to create custom methods
283
+ *
284
+ * @param {String} type Custom method name
285
+ *
286
+ * @return {Function}
287
+ */
288
+ extend : function (type) {
289
+ return function (message, wait) { this.log(message, type, wait); };
290
+ },
291
+
292
+ /**
293
+ * Hide the dialog and rest to defaults
294
+ *
295
+ * @return {undefined}
296
+ */
297
+ hide : function () {
298
+ // remove reference from queue
299
+ queue.splice(0,1);
300
+ // if items remaining in the queue
301
+ if (queue.length > 0) this.setup();
302
+ else {
303
+ isopen = false;
304
+ elDialog.className = "alertify alertify-hide alertify-hidden";
305
+ elCover.className = "alertify-cover alertify-hidden";
306
+ // set focus to the last element or body
307
+ // after the dialog is closed
308
+ elCallee.focus();
309
+ }
310
+ },
311
+
312
+ /**
313
+ * Initialize Alertify
314
+ * Create the 2 main elements
315
+ *
316
+ * @return {undefined}
317
+ */
318
+ init : function () {
319
+ // ensure legacy browsers support html5 tags
320
+ document.createElement("nav");
321
+ document.createElement("article");
322
+ document.createElement("section");
323
+ // cover
324
+ elCover = document.createElement("div");
325
+ elCover.setAttribute("id", "alertify-cover");
326
+ elCover.className = "alertify-cover alertify-hidden";
327
+ document.body.appendChild(elCover);
328
+ // main element
329
+ elDialog = document.createElement("section");
330
+ elDialog.setAttribute("id", "alertify");
331
+ elDialog.className = "alertify alertify-hidden";
332
+ document.body.appendChild(elDialog);
333
+ // log element
334
+ elLog = document.createElement("section");
335
+ elLog.setAttribute("id", "alertify-logs");
336
+ elLog.className = "alertify-logs";
337
+ document.body.appendChild(elLog);
338
+ // set tabindex attribute on body element
339
+ // this allows script to give it focus
340
+ // after the dialog is closed
341
+ document.body.setAttribute("tabindex", "0");
342
+ // clean up init method
343
+ delete this.init;
344
+ },
345
+
346
+ /**
347
+ * Show a new log message box
348
+ *
349
+ * @param {String} message The message passed from the callee
350
+ * @param {String} type [Optional] Optional type of log message
351
+ * @param {Number} wait [Optional] Time (in ms) to wait before auto-hiding the log
352
+ *
353
+ * @return {Object}
354
+ */
355
+ log : function (message, type, wait) {
356
+ // check to ensure the alertify dialog element
357
+ // has been successfully created
358
+ var check = function () {
359
+ if (elLog && elLog.scrollTop !== null) return;
360
+ else check();
361
+ };
362
+ // initialize alertify if it hasn't already been done
363
+ if (typeof this.init === "function") {
364
+ this.init();
365
+ check();
366
+ }
367
+ this.notify(message, type, wait);
368
+ return this;
369
+ },
370
+
371
+ /**
372
+ * Add new log message
373
+ * If a type is passed, a class name "alertify-log-{type}" will get added.
374
+ * This allows for custom look and feel for various types of notifications.
375
+ *
376
+ * @param {String} message The message passed from the callee
377
+ * @param {String} type [Optional] Type of log message
378
+ * @param {Number} wait [Optional] Time (in ms) to wait before auto-hiding
379
+ *
380
+ * @return {undefined}
381
+ */
382
+ notify : function (message, type, wait) {
383
+ var log = document.createElement("article");
384
+ log.className = "alertify-log" + ((typeof type === "string" && type !== "") ? " alertify-log-" + type : "");
385
+ log.innerHTML = message;
386
+ // prepend child
387
+ elLog.insertBefore(log, elLog.firstChild);
388
+ // triggers the CSS animation
389
+ setTimeout(function() { log.className = log.className + " alertify-log-show"; }, 50);
390
+ this.close(log, wait);
391
+ },
392
+
393
+ /**
394
+ * Set properties
395
+ *
396
+ * @param {Object} args Passing parameters
397
+ *
398
+ * @return {undefined}
399
+ */
400
+ set : function (args) {
401
+ var k;
402
+ // error catching
403
+ if (typeof args !== "object" && args instanceof Array) throw new Error("args must be an object");
404
+ // set parameters
405
+ for (k in args) {
406
+ if (args.hasOwnProperty(k)) {
407
+ this[k] = args[k];
408
+ }
409
+ }
410
+ },
411
+
412
+ /**
413
+ * Initiate all the required pieces for the dialog box
414
+ *
415
+ * @return {undefined}
416
+ */
417
+ setup : function () {
418
+ var item = queue[0];
419
+
420
+ isopen = true;
421
+ elDialog.innerHTML = this.build(item);
422
+ if (typeof item.placeholder === "string") $("alertify-text").value = item.placeholder;
423
+ this.addListeners(item.callback);
424
+ },
425
+
426
+ /**
427
+ * Unbind events to elements
428
+ *
429
+ * @param {Object} el HTML Object
430
+ * @param {Event} event Event to detach to element
431
+ * @param {Function} fn Callback function
432
+ *
433
+ * @return {undefined}
434
+ */
435
+ unbind : function (el, event, fn) {
436
+ if (typeof el.removeEventListener === "function") {
437
+ el.removeEventListener(event, fn, false);
438
+ } else if (el.detachEvent) {
439
+ el.detachEvent("on" + event, fn);
440
+ }
441
+ }
442
+ };
443
+
444
+ return {
445
+ alert : function (message, fn) { _alertify.dialog(message, "alert", fn); return this; },
446
+ confirm : function (message, fn) { _alertify.dialog(message, "confirm", fn); return this; },
447
+ extend : _alertify.extend,
448
+ init : _alertify.init,
449
+ log : function (message, type, wait) { _alertify.log(message, type, wait); return this; },
450
+ prompt : function (message, fn, placeholder) { _alertify.dialog(message, "prompt", fn, placeholder); return this; },
451
+ success : function (message, wait) { _alertify.log(message, "success", wait); return this; },
452
+ error : function (message, wait) { _alertify.log(message, "error", wait); return this; },
453
+ set : function (args) { _alertify.set(args); },
454
+ labels : _alertify.labels
455
+ };
456
+ };
457
+
458
+ // AMD and window support
459
+ if (typeof define === "function") {
460
+ define([], function () { return new Alertify(); });
461
+ } else {
462
+ if (typeof global.alertify === "undefined") {
463
+ global.alertify = new Alertify();
464
+ }
465
+ }
466
+
467
+ }(this));