var ui = {}; ;(function(exports){ /** * Expose `Emitter`. */ exports.Emitter = Emitter; /** * Initialize a new `Emitter`. * * @api public */ function Emitter() { this.callbacks = {}; }; /** * Listen on the given `event` with `fn`. * * @param {String} event * @param {Function} fn * @return {Emitter} * @api public */ Emitter.prototype.on = function(event, fn){ (this.callbacks[event] = this.callbacks[event] || []) .push(fn); return this; }; /** * Adds an `event` listener that will be invoked a single * time then automatically removed. * * @param {String} event * @param {Function} fn * @return {Emitter} * @api public */ Emitter.prototype.once = function(event, fn){ var self = this; function on() { self.off(event, on); fn.apply(this, arguments); } this.on(event, on); return this; }; /** * Remove the given callback for `event` or all * registered callbacks. * * @param {String} event * @param {Function} fn * @return {Emitter} * @api public */ Emitter.prototype.off = function(event, fn){ var callbacks = this.callbacks[event]; if (!callbacks) return this; // remove all handlers if (1 == arguments.length) { delete this.callbacks[event]; return this; } // remove specific handler var i = callbacks.indexOf(fn); callbacks.splice(i, 1); return this; }; /** * Emit `event` with the given args. * * @param {String} event * @param {Mixed} ... * @return {Emitter} */ Emitter.prototype.emit = function(event){ var args = [].slice.call(arguments, 1) , callbacks = this.callbacks[event]; if (callbacks) { for (var i = 0, len = callbacks.length; i < len; ++i) { callbacks[i].apply(this, args) } } return this; }; })(ui); ;(function(exports, html){ /** * Active dialog. */ var active; /** * Expose `Dialog`. */ exports.Dialog = Dialog; /** * Return a new `Dialog` with the given * (optional) `title` and `msg`. * * @param {String} title or msg * @param {String} msg * @return {Dialog} * @api public */ exports.dialog = function(title, msg){ switch (arguments.length) { case 2: return new Dialog({ title: title, message: msg }); case 1: return new Dialog({ message: title }); } }; /** * Initialize a new `Dialog`. * * Options: * * - `title` dialog title * - `message` a message to display * * Emits: * * - `show` when visible * - `hide` when hidden * * @param {Object} options * @api public */ function Dialog(options) { ui.Emitter.call(this); options = options || {}; this.template = html; this.el = $(this.template); this.render(options); if (active) active.hide(); if (Dialog.effect) this.effect(Dialog.effect); active = this; }; /** * Inherit from `Emitter.prototype`. */ Dialog.prototype = new ui.Emitter; /** * Render with the given `options`. * * @param {Object} options * @api public */ Dialog.prototype.render = function(options){ var el = this.el , title = options.title , msg = options.message , self = this; el.find('.close').click(function(){ self.emit('close'); self.hide(); return false; }); el.find('h1').text(title); if (!title) el.find('h1').remove(); // message if ('string' == typeof msg) { el.find('p').text(msg); } else if (msg) { el.find('p').replaceWith(msg.el || msg); } setTimeout(function(){ el.removeClass('hide'); }, 0); }; /** * Enable the dialog close link. * * @return {Dialog} for chaining * @api public */ Dialog.prototype.closable = function(){ this.el.addClass('closable'); return this; }; /** * Set the effect to `type`. * * @param {String} type * @return {Dialog} for chaining * @api public */ Dialog.prototype.effect = function(type){ this._effect = type; this.el.addClass(type); return this; }; /** * Make it modal! * * @return {Dialog} for chaining * @api public */ Dialog.prototype.modal = function(){ this._overlay = ui.overlay(); return this; }; /** * Add an overlay. * * @return {Dialog} for chaining * @api public */ Dialog.prototype.overlay = function(){ var self = this; this._overlay = ui .overlay({ closable: true }) .on('hide', function(){ self.closedOverlay = true; self.hide(); }); return this; }; /** * Show the dialog. * * Emits "show" event. * * @return {Dialog} for chaining * @api public */ Dialog.prototype.show = function(){ this.emit('show'); if (this._overlay) { this._overlay.show(); this.el.addClass('modal'); } this.el.appendTo('body'); this.el.css({ marginLeft: -(this.el.width() / 2) + 'px' }); return this; }; /** * Hide the dialog with optional delay of `ms`, * otherwise the dialog is removed immediately. * * Emits "hide" event. * * @return {Number} ms * @return {Dialog} for chaining * @api public */ Dialog.prototype.hide = function(ms){ var self = this; this.emit('hide'); // duration if (ms) { setTimeout(function(){ self.hide(); }, ms); return this; } // hide / remove this.el.addClass('hide'); if (this._effect) { setTimeout(function(self){ self.remove(); }, 500, this); } else { self.remove(); } // modal if (this._overlay && !self.closedOverlay) this._overlay.hide(); return this; }; /** * Hide the dialog without potential animation. * * @return {Dialog} for chaining * @api public */ Dialog.prototype.remove = function(){ this.el.remove(); return this; }; })(ui, "
\n
\n

Title

\n ×\n

Message

\n
\n
"); ;(function(exports, html){ /** * Expose `Overlay`. */ exports.Overlay = Overlay; /** * Return a new `Overlay` with the given `options`. * * @param {Object} options * @return {Overlay} * @api public */ exports.overlay = function(options){ return new Overlay(options); }; /** * Initialize a new `Overlay`. * * @param {Object} options * @api public */ function Overlay(options) { ui.Emitter.call(this); var self = this; options = options || {}; this.closable = options.closable; this.el = $(html); this.el.appendTo('body'); if (this.closable) { this.el.click(function(){ self.hide(); }); } } /** * Inherit from `Emitter.prototype`. */ Overlay.prototype = new ui.Emitter; /** * Show the overlay. * * Emits "show" event. * * @return {Overlay} for chaining * @api public */ Overlay.prototype.show = function(){ this.emit('show'); this.el.removeClass('hide'); return this; }; /** * Hide the overlay. * * Emits "hide" event. * * @return {Overlay} for chaining * @api public */ Overlay.prototype.hide = function(){ var self = this; this.emit('hide'); this.el.addClass('hide'); setTimeout(function(){ self.el.remove(); }, 2000); return this; }; })(ui, "
"); ;(function(exports, html){ /** * Expose `Confirmation`. */ exports.Confirmation = Confirmation; /** * Return a new `Confirmation` dialog with the given * `title` and `msg`. * * @param {String} title or msg * @param {String} msg * @return {Dialog} * @api public */ exports.confirm = function(title, msg){ switch (arguments.length) { case 2: return new Confirmation({ title: title, message: msg }); case 1: return new Confirmation({ message: title }); } }; /** * Initialize a new `Confirmation` dialog. * * Options: * * - `title` dialog title * - `message` a message to display * * Emits: * * - `cancel` the user pressed cancel or closed the dialog * - `ok` the user clicked ok * - `show` when visible * - `hide` when hidden * * @param {Object} options * @api public */ function Confirmation(options) { ui.Dialog.call(this, options); }; /** * Inherit from `Dialog.prototype`. */ Confirmation.prototype = new ui.Dialog; /** * Change "cancel" button `text`. * * @param {String} text * @return {Confirmation} * @api public */ Confirmation.prototype.cancel = function(text){ this.el.find('.cancel').text(text); return this; }; /** * Change "ok" button `text`. * * @param {String} text * @return {Confirmation} * @api public */ Confirmation.prototype.ok = function(text){ this.el.find('.ok').text(text); return this; }; /** * Show the confirmation dialog and invoke `fn(ok)`. * * @param {Function} fn * @return {Confirmation} for chaining * @api public */ Confirmation.prototype.show = function(fn){ ui.Dialog.prototype.show.call(this); this.callback = fn || function(){}; return this; }; /** * Render with the given `options`. * * Emits "cancel" event. * Emits "ok" event. * * @param {Object} options * @api public */ Confirmation.prototype.render = function(options){ ui.Dialog.prototype.render.call(this, options); var self = this , actions = $(html); this.el.addClass('confirmation'); this.el.append(actions); this.on('close', function(){ self.emit('cancel'); self.callback(false); }); actions.find('.cancel').click(function(){ self.emit('cancel'); self.callback(false); self.hide(); }); actions.find('.ok').click(function(){ self.emit('ok'); self.callback(true); self.hide(); }); }; })(ui, "
\n \n \n
"); ;(function(exports, html){ /** * Expose `ColorPicker`. */ exports.ColorPicker = ColorPicker; /** * RGB util. */ function rgb(r,g,b) { return 'rgb(' + r + ', ' + g + ', ' + b + ')'; } /** * RGBA util. */ function rgba(r,g,b,a) { return 'rgba(' + r + ', ' + g + ', ' + b + ', ' + a + ')'; } /** * Initialize a new `ColorPicker`. * * Emits: * * - `change` with the given color object * * @api public */ function ColorPicker() { ui.Emitter.call(this); this._colorPos = {}; this.el = $(html); this.main = this.el.find('.main').get(0); this.spectrum = this.el.find('.spectrum').get(0); $(this.main).bind('selectstart', function(e){ e.preventDefault() }); $(this.spectrum).bind('selectstart', function(e){ e.preventDefault() }); this.hue(rgb(255, 0, 0)); this.spectrumEvents(); this.mainEvents(); this.w = 180; this.h = 180; this.render(); } /** * Inherit from `Emitter.prototype`. */ ColorPicker.prototype = new ui.Emitter; /** * Set width / height to `n`. * * @param {Number} n * @return {ColorPicker} for chaining * @api public */ ColorPicker.prototype.size = function(n){ return this .width(n) .height(n); }; /** * Set width to `n`. * * @param {Number} n * @return {ColorPicker} for chaining * @api public */ ColorPicker.prototype.width = function(n){ this.w = n; this.render(); return this; }; /** * Set height to `n`. * * @param {Number} n * @return {ColorPicker} for chaining * @api public */ ColorPicker.prototype.height = function(n){ this.h = n; this.render(); return this; }; /** * Spectrum related events. * * @api private */ ColorPicker.prototype.spectrumEvents = function(){ var self = this , canvas = $(this.spectrum) , down; function update(e) { var color = self.hueAt(e.offsetY - 4); self.hue(color.toString()); self.emit('change', color); self._huePos = e.offsetY; self.render(); } canvas.mousedown(function(e){ e.preventDefault(); down = true; update(e); }); canvas.mousemove(function(e){ if (down) update(e); }); canvas.mouseup(function(){ down = false; }); }; /** * Hue / lightness events. * * @api private */ ColorPicker.prototype.mainEvents = function(){ var self = this , canvas = $(this.main) , down; function update(e) { var color = self.colorAt(e.offsetX, e.offsetY); self.color(color.toString()); self.emit('change', color); self._colorPos = e; self.render(); } canvas.mousedown(function(e){ down = true; update(e); }); canvas.mousemove(function(e){ if (down) update(e); }); canvas.mouseup(function(){ down = false; }); }; /** * Get the RGB color at `(x, y)`. * * @param {Number} x * @param {Number} y * @return {Object} * @api private */ ColorPicker.prototype.colorAt = function(x, y){ var data = this.main.getContext('2d').getImageData(x, y, 1, 1).data; return { r: data[0] , g: data[1] , b: data[2] , toString: function(){ return rgb(this.r, this.g, this.b); } }; }; /** * Get the RGB value at `y`. * * @param {Type} name * @return {Type} * @api private */ ColorPicker.prototype.hueAt = function(y){ var data = this.spectrum.getContext('2d').getImageData(0, y, 1, 1).data; return { r: data[0] , g: data[1] , b: data[2] , toString: function(){ return rgb(this.r, this.g, this.b); } }; }; /** * Get or set `color`. * * @param {String} color * @return {String|ColorPicker} * @api public */ ColorPicker.prototype.color = function(color){ // TODO: update pos if (0 == arguments.length) return this._color; this._color = color; return this; }; /** * Get or set hue `color`. * * @param {String} color * @return {String|ColorPicker} * @api public */ ColorPicker.prototype.hue = function(color){ // TODO: update pos if (0 == arguments.length) return this._hue; this._hue = color; return this; }; /** * Render with the given `options`. * * @param {Object} options * @api public */ ColorPicker.prototype.render = function(options){ options = options || {}; this.renderMain(options); this.renderSpectrum(options); }; /** * Render spectrum. * * @api private */ ColorPicker.prototype.renderSpectrum = function(options){ var el = this.el , canvas = this.spectrum , ctx = canvas.getContext('2d') , pos = this._huePos , w = this.w * .12 , h = this.h; canvas.width = w; canvas.height = h; var grad = ctx.createLinearGradient(0, 0, 0, h); grad.addColorStop(0, rgb(255, 0, 0)); grad.addColorStop(.15, rgb(255, 0, 255)); grad.addColorStop(.33, rgb(0, 0, 255)); grad.addColorStop(.49, rgb(0, 255, 255)); grad.addColorStop(.67, rgb(0, 255, 0)); grad.addColorStop(.84, rgb(255, 255, 0)); grad.addColorStop(1, rgb(255, 0, 0)); ctx.fillStyle = grad; ctx.fillRect(0, 0, w, h); // pos if (!pos) return; ctx.fillStyle = rgba(0,0,0, .3); ctx.fillRect(0, pos, w, 1); ctx.fillStyle = rgba(255,255,255, .3); ctx.fillRect(0, pos + 1, w, 1); }; /** * Render hue/luminosity canvas. * * @api private */ ColorPicker.prototype.renderMain = function(options){ var el = this.el , canvas = this.main , ctx = canvas.getContext('2d') , w = this.w , h = this.h , x = (this._colorPos.offsetX || w) + .5 , y = (this._colorPos.offsetY || 0) + .5; canvas.width = w; canvas.height = h; var grad = ctx.createLinearGradient(0, 0, w, 0); grad.addColorStop(0, rgb(255, 255, 255)); grad.addColorStop(1, this._hue); ctx.fillStyle = grad; ctx.fillRect(0, 0, w, h); grad = ctx.createLinearGradient(0, 0, 0, h); grad.addColorStop(0, rgba(255, 255, 255, 0)); grad.addColorStop(1, rgba(0, 0, 0, 1)); ctx.fillStyle = grad; ctx.fillRect(0, 0, w, h); // pos var rad = 10; ctx.save(); ctx.beginPath(); ctx.lineWidth = 1; // outer dark ctx.strokeStyle = rgba(0,0,0,.5); ctx.arc(x, y, rad / 2, 0, Math.PI * 2, false); ctx.stroke(); // outer light ctx.strokeStyle = rgba(255,255,255,.5); ctx.arc(x, y, rad / 2 - 1, 0, Math.PI * 2, false); ctx.stroke(); ctx.beginPath(); ctx.restore(); }; })(ui, "
\n \n \n
"); ;(function(exports, html){ /** * Notification list. */ var list; /** * Expose `Notification`. */ exports.Notification = Notification; // list $(function(){ list = $('