alertify-rails 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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));