new style api

This commit is contained in:
Jaime Pillora
2013-06-03 12:28:03 +10:00
parent d0838b4c6d
commit 37631df657
3 changed files with 344 additions and 303 deletions
+124 -114
View File
@@ -5,12 +5,12 @@
(function(window,document,undefined) {
'use strict';
var Notification, className, cornerElem, createElem, getAnchorElement, hAligns, incr, inherit, insertCSS, mainPositions, opposites, parsePosition, pluginName, pluginOptions, positions, realign, styles, vAligns,
var Notification, addStyle, className, coreStyle, cornerElem, createElem, defaultStyle, defaultStyleName, getAnchorElement, hAligns, incr, inherit, insertCSS, mainPositions, opposites, options, parsePosition, pluginName, pluginOptions, positions, realign, styles, vAligns,
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
pluginName = 'notify';
className = '__' + pluginName;
className = pluginName + 'js';
positions = {
t: 'top',
@@ -49,40 +49,74 @@ parsePosition = function(str) {
return pos;
};
styles = {
core: {
html: "<div class=\"" + className + "Wrapper\">\n <div class=\"" + className + "Arrow\"></div>\n <div class=\"" + className + "Container\"></div>\n</div>",
css: "." + className + "Corner {\n position: fixed;\n top: 0;\n right: 0;\n margin: 5px;\n z-index: 1050;\n}\n\n." + className + "Corner ." + className + "Wrapper,\n." + className + "Corner ." + className + "Container {\n position: relative;\n display: block;\n height: inherit;\n width: inherit;\n}\n\n." + className + "Wrapper {\n z-index: 1;\n position: absolute;\n display: inline-block;\n height: 0;\n width: 0;\n}\n\n." + className + "Container {\n display: none;\n z-index: 1;\n position: absolute;\n cursor: pointer;\n}\n\n." + className + "Text {\n position: relative;\n}\n\n." + className + "Arrow {\n position: absolute;\n z-index: 2;\n width: 0;\n height: 0;\n}\n"
},
user: {
"default": {
html: "<div class=\"" + className + "Default\" \n data-notify-style=\"\n color: {{color}}; \n border-color: {{color}};\n \">\n <span data-notify-text></span>\n </div>",
css: "." + className + "Default {\n background: #fff;\n font-size: 11px;\n box-shadow: 0 0 6px #000;\n -moz-box-shadow: 0 0 6px #000;\n -webkit-box-shadow: 0 0 6px #000;\n padding: 4px 10px 4px 8px;\n border-radius: 6px;\n border-style: solid;\n border-width: 2px;\n -moz-border-radius: 6px;\n -webkit-border-radius: 6px;\n white-space: nowrap;\n}"
},
bootstrap: {
html: "<div class=\"alert alert-error " + className + "Bootstrap\">\n <strong data-notify-text></strong>\n</div>",
css: "." + className + "Bootstrap {\n white-space: nowrap;\n margin: 5px !important;\n padding-left: 25px !important;\n background-repeat: no-repeat;\n background-position: 3px 7px;\n 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=);\n}",
colors: {
red: '#eed3d7'
}
}
styles = {};
coreStyle = {
name: 'core',
html: "<div class=\"" + className + "-wrapper\">\n <div class=\"" + className + "-arrow\"></div>\n <div class=\"" + className + "-container\"></div>\n</div>",
css: "." + className + "-corner {\n position: fixed;\n top: 0;\n right: 0;\n margin: 5px;\n z-index: 1050;\n}\n\n." + className + "-corner ." + className + "-wrapper,\n." + className + "-corner ." + className + "-container {\n position: relative;\n display: block;\n height: inherit;\n width: inherit;\n}\n\n." + className + "-wrapper {\n z-index: 1;\n position: absolute;\n display: inline-block;\n height: 0;\n width: 0;\n}\n\n." + className + "-container {\n display: none;\n z-index: 1;\n position: absolute;\n cursor: pointer;\n}\n\n." + className + "-text {\n position: relative;\n}\n\n." + className + "-arrow {\n position: absolute;\n z-index: 2;\n width: 0;\n height: 0;\n}"
};
defaultStyleName = "bootstrap";
defaultStyle = {
html: "<div>\n <span data-notify-text></span>\n</div>",
classes: {
base: "padding: 8px 35px 8px 14px;\ntext-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);\nbackground-color: #fcf8e3;\nborder: 1px solid #fbeed5;\n-webkit-border-radius: 4px;\n-moz-border-radius: 4px;\nborder-radius: 4px;\nwhite-space: nowrap;",
error: "color: #B94A48;\nbackground-color: #F2DEDE;\nborder-color: #EED3D7;\npadding-left: 25px;\nbackground-repeat: no-repeat;\nbackground-position: 3px 7px;\nbackground-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=);",
info: "",
warn: ""
}
};
addStyle = function(name, def) {
var cssText;
if (styles[name]) {
alert("" + pluginName + ": style '" + name + "' already defined");
return;
}
def.name = name;
styles[name] = def;
if (def.cssElem) {
return;
}
cssText = "";
if (def.classes) {
$.each(def.classes, function(subClassName, css) {
return cssText += "." + className + "-" + def.name + "-" + subClassName + " {\n " + css + "\n}\n";
});
}
if (def.css) {
cssText += "/* styles for " + def.name + " */\n" + def.css;
}
if (!cssText) {
return;
}
def.cssElem = insertCSS(cssText);
return def.cssElem.attr('data-notify-style', def.name);
};
insertCSS = function(cssText) {
var elem;
elem = createElem("style");
$("head").append(elem);
try {
elem.html(cssText);
} catch (e) {
elem[0].styleSheet.cssText = cssText;
}
return elem;
};
pluginOptions = {
autoHide: false,
autoHideDelay: 2000,
arrowShow: true,
arrowSize: 5,
arrowColor: 'border',
position: 'bottom',
style: 'default',
color: 'black',
colors: {
red: '#b94a48',
green: '#33be40',
black: '#393939',
blue: '#00f'
},
style: 'bootstrap',
cls: 'error',
showAnimation: 'slideDown',
showDuration: 400,
hideAnimation: 'slideUp',
@@ -91,10 +125,6 @@ pluginOptions = {
offsetX: 0
};
createElem = function(tag) {
return $("<" + tag + "></" + tag + ">");
};
inherit = function(a, b) {
var F;
F = function() {};
@@ -102,7 +132,15 @@ inherit = function(a, b) {
return $.extend(true, new F(), b);
};
cornerElem = createElem("div").addClass("" + className + "Corner");
options = function(opts) {
return $.extend(pluginOptions, opts);
};
createElem = function(tag) {
return $("<" + tag + "></" + tag + ">");
};
cornerElem = createElem("div").addClass("" + className + "-corner");
getAnchorElement = function(element) {
var radios;
@@ -150,25 +188,6 @@ realign = function(alignment, inner, outer) {
throw "Invalid alignment";
};
insertCSS = function(style) {
var elem;
if (!(style && style.css)) {
return;
}
elem = style.cssElem;
if (elem) {
return;
}
elem = createElem("style");
$("head").append(elem);
style.cssElem = elem;
try {
return elem.html(style.css);
} catch (e) {
return elem[0].styleSheet.cssText = style.css;
}
};
Notification = (function() {
function Notification(elem, data, options) {
@@ -178,12 +197,11 @@ Notification = (function() {
};
}
this.options = inherit(pluginOptions, $.isPlainObject(options) ? options : {});
this.loadCSS();
this.loadHTML();
this.wrapper = $(styles.core.html);
this.wrapper = $(coreStyle.html);
this.wrapper.data(className, this);
this.arrow = this.wrapper.find("." + className + "Arrow");
this.container = this.wrapper.find("." + className + "Container");
this.arrow = this.wrapper.find("." + className + "-arrow");
this.container = this.wrapper.find("." + className + "-container");
this.container.append(this.userContainer);
if (elem && elem.length) {
this.elementType = elem.attr('type');
@@ -199,15 +217,6 @@ Notification = (function() {
this.run(data);
}
Notification.prototype.loadCSS = function(style) {
var name;
if (!style) {
name = this.options.style;
style = this.getStyle(name);
}
return insertCSS(style);
};
Notification.prototype.loadHTML = function() {
var style;
style = this.getStyle();
@@ -216,7 +225,7 @@ Notification = (function() {
if (this.text.length === 0) {
throw "style: " + name + " HTML is missing the: 'data-notify-text' attribute";
}
return this.text.addClass("" + className + "Text");
return this.text.addClass("" + className + "-text");
};
Notification.prototype.show = function(show, callback) {
@@ -245,7 +254,7 @@ Notification = (function() {
};
Notification.prototype.updatePosition = function() {
var arrowCss, arrowSize, color, contH, contW, css, elemH, elemIH, elemIW, elemPos, elemW, mainFull, margin, opp, oppFull, pAlign, pArrow, pMain, padding, pos, posFull, position, wrapPos, _i, _len;
var arrowCss, arrowSize, color, contH, contW, css, elemH, elemIH, elemIW, elemPos, elemW, mainFull, margin, opp, oppFull, pAlign, pArrow, pMain, padding, pos, posFull, position, style, wrapPos, _i, _len;
if (!this.elem) {
return;
}
@@ -258,6 +267,7 @@ Notification = (function() {
contH = this.container.height();
contW = this.container.width();
position = this.getPosition();
console.log(position);
pMain = position[0];
pAlign = position[1];
pArrow = position[2] || pAlign;
@@ -279,6 +289,7 @@ Notification = (function() {
}
incr(css, 'top', this.options.offsetY);
incr(css, 'left', this.options.offsetX);
style = this.getStyle();
if (!this.options.arrowShow) {
this.arrow.hide();
} else {
@@ -290,7 +301,7 @@ Notification = (function() {
if (pos === opp) {
continue;
}
color = posFull === mainFull ? this.getColor() : 'transparent';
color = posFull === mainFull ? 'black' : 'transparent';
arrowCss["border-" + posFull] = "" + arrowSize + "px solid " + color;
}
incr(css, positions[opp], arrowSize);
@@ -337,12 +348,6 @@ Notification = (function() {
throw "Not implemented";
};
Notification.prototype.getColor = function() {
var styleColors;
styleColors = this.getStyle().colors;
return (styleColors && styleColors[this.options.color]) || this.options.colors[this.options.color] || this.options.color;
};
Notification.prototype.getStyle = function(name) {
var style;
if (!name) {
@@ -351,18 +356,26 @@ Notification = (function() {
if (!name) {
name = 'default';
}
style = styles.user[name];
style = styles[name];
if (!style) {
throw "Missing style: " + name;
}
return style;
};
Notification.prototype.updateStyle = function() {
var _this = this;
return this.wrapper.find('[data-notify-style]').each(function(i, e) {
return $(e).attr('style', $(e).attr('data-notify-style').replace(/\{\{\s*color\s*\}\}/ig, _this.getColor()));
});
Notification.prototype.updateStyleClasses = function() {
var cls, style;
cls = ['base'];
if ($.isArray(this.options.cls)) {
cls = cls.concat(this.options.cls);
} else if (this.options.cls) {
cls.push(this.options.cls);
}
style = this.getStyle();
cls = $.map(cls, function(n) {
return "" + className + "-" + style.name + "-" + n;
}).join(' ');
return this.userContainer.attr('class', cls);
};
Notification.prototype.run = function(data, options) {
@@ -383,6 +396,7 @@ Notification = (function() {
} else {
this.text.empty().append(data);
}
this.updateStyleClasses();
this.updatePosition();
this.show(true);
if (this.options.autoHide) {
@@ -404,31 +418,6 @@ Notification = (function() {
})();
$(function() {
$("body").append(cornerElem);
$("link").each(function() {
var bootstrapDetected, src;
src = $(this).attr('href');
if (src.match(/bootstrap/)) {
bootstrapDetected = true;
return false;
}
});
insertCSS(styles.core);
return $(document).on('click', "." + className + "Wrapper", function() {
var inst;
inst = $(this).data(className);
if (!inst) {
return;
}
if (inst.elem) {
return inst.show(false);
} else {
return inst.destroy();
}
});
});
$[pluginName] = function(elem, data, options) {
if ((elem && elem.nodeName) || elem.jquery) {
$(elem)[pluginName](data, options);
@@ -440,16 +429,6 @@ $[pluginName] = function(elem, data, options) {
return elem;
};
$[pluginName].options = function(options) {
return $.extend(pluginOptions, options);
};
$[pluginName].styles = function(s) {
return $.extend(true, styles.user, s);
};
$[pluginName].insertCSS = insertCSS;
$.fn[pluginName] = function(data, options) {
$(this).each(function() {
var inst;
@@ -463,4 +442,35 @@ $.fn[pluginName] = function(data, options) {
return this;
};
$.extend($[pluginName], {
options: options,
addStyle: addStyle
});
$(function() {
$("body").append(cornerElem);
$("link").each(function() {
var bootstrapDetected, src;
src = $(this).attr('href');
if (src.match(/bootstrap/)) {
bootstrapDetected = true;
return false;
}
});
insertCSS(coreStyle.css).attr('data-notify-style', 'core');
$[pluginName].addStyle(defaultStyleName, defaultStyle);
return $(document).on('click', "." + className + "-wrapper", function() {
var inst;
inst = $(this).data(className);
if (!inst) {
return;
}
if (inst.elem) {
return inst.show(false);
} else {
return inst.destroy();
}
});
});
}(window,document));
+1 -1
View File
File diff suppressed because one or more lines are too long
+219 -188
View File
@@ -3,8 +3,11 @@
#plugin constants
pluginName = 'notify'
className = '__'+pluginName
className = pluginName+'js'
# ================================
# POSITIONING
# ================================
positions =
t: 'top'
@@ -32,109 +35,144 @@ parsePosition = (str) ->
pos.push w if positions[w]
pos
#built-in styles
styles =
core:
html: """
<div class="#{className}Wrapper">
<div class="#{className}Arrow"></div>
<div class="#{className}Container"></div>
</div>
# ================================
# STYLES
# ================================
styles = {}
coreStyle =
name: 'core'
html: """
<div class="#{className}-wrapper">
<div class="#{className}-arrow"></div>
<div class="#{className}-container"></div>
</div>
"""
# <div class="#{className}Debug"></div>
# .#{className}Debug {
# position: absolute;
# border: 3px solid red;
# height: 0;
# width: 0;
# }
css: """
.#{className}-corner {
position: fixed;
top: 0;
right: 0;
margin: 5px;
z-index: 1050;
}
.#{className}-corner .#{className}-wrapper,
.#{className}-corner .#{className}-container {
position: relative;
display: block;
height: inherit;
width: inherit;
}
.#{className}-wrapper {
z-index: 1;
position: absolute;
display: inline-block;
height: 0;
width: 0;
}
.#{className}-container {
display: none;
z-index: 1;
position: absolute;
cursor: pointer;
}
.#{className}-text {
position: relative;
}
.#{className}-arrow {
position: absolute;
z-index: 2;
width: 0;
height: 0;
}
"""
defaultStyleName = "bootstrap"
defaultStyle =
html: """
<div>
<span data-notify-text></span>
</div>
"""
classes:
base: """
padding: 8px 35px 8px 14px;
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
background-color: #fcf8e3;
border: 1px solid #fbeed5;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
white-space: nowrap;
"""
error: """
color: #B94A48;
background-color: #F2DEDE;
border-color: #EED3D7;
padding-left: 25px;
background-repeat: no-repeat;
background-position: 3px 7px;
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=);
"""
info: ""
warn: ""
addStyle = (name, def) ->
if styles[name]
alert "#{pluginName}: style '#{name}' already defined"
return
def.name = name
styles[name] = def
return if def.cssElem
cssText = ""
if def.classes
$.each def.classes, (subClassName, css) ->
cssText += """
.#{className}-#{def.name}-#{subClassName} {
#{css}
}\n
"""
if def.css
cssText += """
/* styles for #{def.name} */
#{def.css}
"""
# <div class="#{className}Debug"></div>
return unless cssText
def.cssElem = insertCSS cssText
def.cssElem.attr('data-notify-style', def.name)
# .#{className}Debug {
# position: absolute;
# border: 3px solid red;
# height: 0;
# width: 0;
# }
insertCSS = (cssText) ->
elem = createElem("style")
$("head").append elem
try
elem.html cssText
catch e #ie fix
elem[0].styleSheet.cssText = cssText
elem
css: """
.#{className}Corner {
position: fixed;
top: 0;
right: 0;
margin: 5px;
z-index: 1050;
}
.#{className}Corner .#{className}Wrapper,
.#{className}Corner .#{className}Container {
position: relative;
display: block;
height: inherit;
width: inherit;
}
.#{className}Wrapper {
z-index: 1;
position: absolute;
display: inline-block;
height: 0;
width: 0;
}
.#{className}Container {
display: none;
z-index: 1;
position: absolute;
cursor: pointer;
}
.#{className}Text {
position: relative;
}
.#{className}Arrow {
position: absolute;
z-index: 2;
width: 0;
height: 0;
}
"""
user:
bootstrap:
html: """
<div>
<span data-notify-text></span>
</div>
"""
classes:
base: """
padding: 8px 35px 8px 14px;
margin-bottom: 20px;
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
background-color: #fcf8e3;
border: 1px solid #fbeed5;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
"""
error:
info:
warn:
bootstrap:
html: """
<div class="alert alert-error #{className}Bootstrap">
<strong data-notify-text></strong>
</div>
"""
css: """
.#{className}Bootstrap {
white-space: nowrap;
margin: 5px !important;
padding-left: 25px !important;
background-repeat: no-repeat;
background-position: 3px 7px;
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=);
}
"""
colors:
red: '#eed3d7'
# ================================
# OPTIONS
# ================================
#overridable options
pluginOptions =
@@ -142,17 +180,11 @@ pluginOptions =
autoHideDelay: 2000
arrowShow: true
arrowSize: 5
arrowColor: 'border'
position: 'bottom'
# Default style
style: 'default'
# Default color
color: 'black'
# Color mappings
colors:
red: '#b94a48'
green: '#33be40'
black: '#393939'
blue: '#00f'
style: 'bootstrap'
cls: 'error'
showAnimation: 'slideDown'
showDuration: 400
hideAnimation: 'slideUp'
@@ -163,16 +195,25 @@ pluginOptions =
#TODO add z-index watches
#parents: { '.ui-dialog': 5001 }
# plugin helpers
createElem = (tag) ->
$ "<#{tag}></#{tag}>"
inherit = (a, b) ->
F = () ->
F.prototype = a
$.extend true, new F(), b
options = (opts) ->
$.extend pluginOptions, opts
# ================================
# DOM MANIPULATION
# ================================
# plugin helpers
createElem = (tag) ->
$ "<#{tag}></#{tag}>"
# container for element-less notifications
cornerElem = createElem("div").addClass("#{className}Corner")
cornerElem = createElem("div").addClass("#{className}-corner")
#gets first on n radios, and gets the fancy stylised input for hidden inputs
getAnchorElement = (element) ->
@@ -216,18 +257,10 @@ realign = (alignment, inner, outer) ->
outer - inner
throw "Invalid alignment"
insertCSS = (style) ->
return unless style and style.css
elem = style.cssElem
return if elem
elem = createElem("style")
$("head").append elem
style.cssElem = elem
try
elem.html style.css
catch e #ie fix
elem[0].styleSheet.cssText = style.css
# ================================
# NOTIFY CLASS
# ================================
#define plugin
class Notification
@@ -237,15 +270,13 @@ class Notification
options = {color: options} if typeof options is 'string'
@options = inherit pluginOptions, if $.isPlainObject(options) then options else {}
#load user css into dom
@loadCSS()
#load user html into @userContainer
@loadHTML()
@wrapper = $(styles.core.html)
@wrapper = $(coreStyle.html)
@wrapper.data className, @
@arrow = @wrapper.find ".#{className}Arrow"
@container = @wrapper.find ".#{className}Container"
@arrow = @wrapper.find ".#{className}-arrow"
@container = @wrapper.find ".#{className}-container"
@container.append @userContainer
if elem and elem.length
@@ -263,20 +294,13 @@ class Notification
@container.hide()
@run(data)
loadCSS: (style) ->
unless style
name = @options.style
style = @getStyle(name)
#insert
insertCSS style
loadHTML: ->
style = @getStyle()
@userContainer = $(style.html)
@text = @userContainer.find '[data-notify-text]'
if @text.length is 0
throw "style: #{name} HTML is missing the: 'data-notify-text' attribute"
@text.addClass "#{className}Text"
@text.addClass "#{className}-text"
show: (show, callback = $.noop) ->
@@ -318,6 +342,8 @@ class Notification
#get user defined position
position = @getPosition()
console.log position
pMain = position[0]
pAlign = position[1]
pArrow = position[2] or pAlign
@@ -347,6 +373,10 @@ class Notification
incr css, 'top', @options.offsetY
incr css, 'left', @options.offsetX
style = @getStyle()
# if style.css
#calculate arrow
if not @options.arrowShow
@arrow.hide()
@@ -357,7 +387,7 @@ class Notification
for pos in mainPositions
posFull = positions[pos]
continue if pos is opp
color = if posFull is mainFull then @getColor() else 'transparent'
color = if posFull is mainFull then 'black' else 'transparent'
arrowCss["border-#{posFull}"] = "#{arrowSize}px solid #{color}"
#add some room for the arrow
incr css, positions[opp], arrowSize
@@ -385,7 +415,7 @@ class Notification
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
@@ -400,27 +430,26 @@ class Notification
# return 'bottom'
throw "Not implemented"
getColor: ->
styleColors = @getStyle().colors
return (styleColors and
styleColors[@options.color]) or
@options.colors[@options.color] or
@options.color
getStyle: (name) ->
name = @options.style unless name
name = 'default' unless name
style = styles.user[name]
style = styles[name]
throw "Missing style: #{name}" unless style
style
updateStyle: ->
#update colors
@wrapper.find('[data-notify-style]').each (i,e) =>
$(e).attr 'style', $(e).attr('data-notify-style').
replace(/\{\{\s*color\s*\}\}/ig, @getColor())
# .
# replace(/\{\{\s*position\s*\}\}/ig, @getPosition())
updateStyleClasses: ->
cls = ['base']
if $.isArray @options.cls
cls = cls.concat @options.cls
else if @options.cls
cls.push @options.cls
style = @getStyle()
cls = $.map(cls, (n) -> "#{className}-#{style.name}-#{n}").join ' '
@userContainer.attr 'class', cls
#run plugin
run: (data, options) ->
@@ -443,6 +472,10 @@ class Notification
else
@text.empty().append(data)
#set styles
@updateStyleClasses()
#position
@updatePosition()
@show true
@@ -458,6 +491,34 @@ class Notification
@show false, =>
@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(className)
if inst
inst.run data, options
else
new Notification $(@), data, options
@
#extra
$.extend $[pluginName], { options, addStyle }
#when ready
$ ->
#corner notification container
@@ -470,11 +531,13 @@ $ ->
bootstrapDetected = true
return false
#add core styles
insertCSS styles.core
#insert default style
insertCSS(coreStyle.css).attr('data-notify-style', 'core')
#insert default style
$[pluginName].addStyle(defaultStyleName, defaultStyle)
#watch all notifications clicks
$(document).on 'click', ".#{className}Wrapper", ->
$(document).on 'click', ".#{className}-wrapper", ->
inst = $(@).data className
return unless inst
if inst.elem
@@ -482,35 +545,3 @@ $ ->
else
inst.destroy()
# publicise jquery plugin
# return alert "$.#{pluginName} already defined" if $[pluginName]?
# $.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
# publicise methods
$[pluginName].options = (options) ->
$.extend pluginOptions, options
$[pluginName].styles = (s) ->
$.extend true, styles.user, s
$[pluginName].insertCSS = insertCSS
# $( ... ).pluginName( { .. } ) creates a cached instance on each
$.fn[pluginName] = (data, options) ->
$(@).each ->
inst = getAnchorElement($(@)).data(className)
if inst
inst.run data, options
else
new Notification $(@), data, options
@