diff --git a/dist/notify.js b/dist/notify.js
index d1e5203..5406083 100644
--- a/dist/notify.js
+++ b/dist/notify.js
@@ -1,11 +1,11 @@
-/** Notify.js - v0.0.1 - 2013/04/04
+/** Notify.js - v0.0.1 - 2013/04/05
* http://notifyjs.com/
* Copyright (c) 2013 Jaime Pillora - MIT
*/
(function(window,document,undefined) {
'use strict';
-var Notification, Options, arrowDirs, className, cornerElem, create, getAnchorElement, pluginName, pluginOptions, styles;
+var Notification, arrowDirs, bootstrapDetected, className, cornerElem, create, getAnchorElement, inherit, insertCSS, pluginName, pluginOptions, styles;
pluginName = 'notify';
@@ -20,8 +20,8 @@ arrowDirs = {
styles = {
core: {
- html: "
",
- 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\n." + className + "Wrapper {\n z-index: 1;\n position: absolute;\n display: inline-block;\n height: 0;\n width: 0;\n opacity: 0.85;\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}"
+ html: "",
+ 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 opacity: 0.85;\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 margin-top: " + (2 + (document.documentMode === 5 ? size * -4 : 0)) + ";\n position: absolute;\n z-index: 2;\n margin-left: 10px;\n width: 0;\n height: 0;\n}\n"
},
user: {
"default": {
@@ -29,8 +29,8 @@ styles = {
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: "\n Warning! \n
",
- css: "." + className + "Bootstrap {\n white-space: nowrap;\n}",
+ html: "\n \n
",
+ css: "." + className + "Bootstrap {\n white-space: nowrap;\n margin-bottom: 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'
}
@@ -38,13 +38,15 @@ styles = {
}
};
+bootstrapDetected = false;
+
pluginOptions = {
autoHide: false,
autoHideDelay: 2000,
arrowShow: true,
arrowSize: 5,
- arrowPosition: 'top',
- style: 'default',
+ position: null,
+ style: null,
color: 'red',
colors: {
red: '#b94a48',
@@ -53,22 +55,24 @@ pluginOptions = {
blue: '#00f'
},
showAnimation: 'slideDown',
- showDuration: 200,
+ showDuration: 400,
hideAnimation: 'slideUp',
- hideDuration: 600,
- gap: 2
+ hideDuration: 200,
+ offsetY: 2,
+ offsetX: 0
};
create = function(tag) {
return $(document.createElement(tag));
};
-Options = function(options) {
- return $.extend(this, options);
+inherit = function(a, b) {
+ var F;
+ F = function() {};
+ F.prototype = a;
+ return $.extend(true, new F(), b);
};
-Options.prototype = pluginOptions;
-
cornerElem = create("div").addClass("" + className + "Corner");
getAnchorElement = function(element) {
@@ -86,19 +90,35 @@ getAnchorElement = function(element) {
return element;
};
+insertCSS = function(style) {
+ var elem;
+ if (!(style && style.css)) {
+ return;
+ }
+ elem = style.cssElem;
+ if (elem) {
+ return elem.html(style.css);
+ } else {
+ elem = create("style").attr('type', 'text/css').html(style.css);
+ $("head").append(elem);
+ return style.cssElem = elem;
+ }
+};
+
Notification = (function() {
function Notification(elem, data, options) {
- if ($.type(options) === 'string') {
+ if (typeof options === 'string') {
options = {
color: options
};
}
- this.options = new Options($.isPlainObject(options) ? options : {});
+ this.options = inherit(pluginOptions, $.isPlainObject(options) ? options : {});
this.loadCSS();
this.loadHTML();
this.wrapper = $(styles.core.html);
this.wrapper.data(pluginName, this);
+ this.arrow = this.wrapper.find("." + className + "Arrow");
this.container = this.wrapper.find("." + className + "Container");
this.container.append(this.userContainer);
if (elem && elem.length) {
@@ -107,7 +127,6 @@ Notification = (function() {
this.elem = getAnchorElement(elem);
this.elem.data(pluginName, this);
this.elem.before(this.wrapper);
- this.container.css(this.calculateCSS());
} else {
this.options.arrowShow = false;
cornerElem.prepend(this.wrapper);
@@ -117,17 +136,12 @@ Notification = (function() {
}
Notification.prototype.loadCSS = function(style) {
- var elem, name;
- name = this.options.style;
- style = this.getStyle(name);
- elem = style.cssElem;
- if (elem) {
- return elem.html(style.css);
- } else {
- elem = create("style").attr('id', "" + name + "-styles").html(style.css);
- $("head").append(elem);
- return style.cssElem = elem;
+ var name;
+ if (!style) {
+ name = this.options.style;
+ style = this.getStyle(name);
}
+ return insertCSS(style);
};
Notification.prototype.loadHTML = function(style) {
@@ -140,33 +154,6 @@ Notification = (function() {
return this.text.addClass("" + className + "Text");
};
- Notification.prototype.buildArrow = function() {
- var alt, d, dir, showArrow, size;
- dir = this.options.arrowPosition;
- size = this.options.arrowSize;
- alt = arrowDirs[dir];
- this.arrow = create("div");
- this.arrow.addClass(className + 'Arrow').css({
- 'margin-top': 2 + (document.documentMode === 5 ? size * -4 : 0),
- 'position': 'relative',
- 'z-index': '2',
- 'margin-left': 10,
- 'width': 0,
- 'height': 0
- }).css('border-' + alt, size + 'px solid ' + this.getColor());
- for (d in arrowDirs) {
- if (d !== dir && d !== alt) {
- this.arrow.css('border-' + d, size + 'px solid transparent');
- }
- }
- showArrow = this.options.arrowShow && this.elementType !== 'radio';
- if (showArrow) {
- return this.arrow.show();
- } else {
- return this.arrow.hide();
- }
- };
-
Notification.prototype.show = function(show) {
var hidden;
hidden = this.container.parent().parents(':hidden').length > 0;
@@ -184,19 +171,67 @@ Notification = (function() {
}
};
- Notification.prototype.calculateCSS = function() {
- var elementPosition, height, left, mainPosition;
+ Notification.prototype.updatePosition = function() {
+ var arrowPosition, elementPosition, height, left, mainPosition, position;
+ if (!this.elem) {
+ return;
+ }
elementPosition = this.elem.position();
- mainPosition = this.container.parent().position();
- height = this.elem.outerHeight();
- left = elementPosition.left - mainPosition.left;
+ mainPosition = this.wrapper.position();
+ position = this.getPosition();
+ arrowPosition = this.updateArrow(position);
+ left = 0;
+ height = 0;
+ switch (position) {
+ case 'bottom':
+ height = this.elem.outerHeight();
+ break;
+ case 'right':
+ left = this.elem.width();
+ break;
+ default:
+ throw "Unknown position: " + position;
+ }
+ left += elementPosition.left - mainPosition.left;
if (!navigator.userAgent.match(/MSIE/)) {
height += elementPosition.top - mainPosition.top;
}
- return {
- top: height + this.options.gap,
- left: left
+ return this.container.css({
+ top: height + this.options.offsetY + arrowPosition.top,
+ left: left + this.options.offsetX + arrowPosition.left
+ });
+ };
+
+ Notification.prototype.updateArrow = function(position) {
+ var d, dir, offsets, size;
+ offsets = {
+ top: 0,
+ left: 0
};
+ if (!(this.options.arrowShow && this.elementType !== 'radio')) {
+ this.arrow.hide();
+ return offsets;
+ }
+ dir = arrowDirs[position];
+ size = this.options.arrowSize;
+ this.arrow.css('border-' + position, size + 'px solid ' + this.getColor());
+ for (d in arrowDirs) {
+ if (d !== dir && d !== position) {
+ this.arrow.css('border-' + d, size + 'px solid transparent');
+ }
+ }
+ this.arrow.show();
+ return offsets;
+ };
+
+ Notification.prototype.getPosition = function() {
+ if (this.options.position) {
+ return this.options.position;
+ }
+ if (this.elem.position().left + this.elem.width() + this.wrapper.width() < $(window).width()) {
+ return 'right';
+ }
+ return 'bottom';
};
Notification.prototype.getColor = function() {
@@ -210,6 +245,12 @@ Notification = (function() {
if (!name) {
name = this.options.style;
}
+ if (bootstrapDetected && !name) {
+ name = 'bootstrap';
+ }
+ if (!name) {
+ name = 'default';
+ }
style = styles.user[name];
if (!style) {
throw "Missing style: " + name;
@@ -217,8 +258,15 @@ Notification = (function() {
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()).replace(/\{\{\s*position\s*\}\}/ig, _this.getPosition()));
+ });
+ };
+
Notification.prototype.run = function(data, options) {
- var autohideTimer, color,
+ var autohideTimer,
_this = this;
if ($.isPlainObject(options)) {
$.extend(this.options, options);
@@ -236,17 +284,7 @@ Notification = (function() {
} else {
this.text.empty().append(data);
}
- color = this.getColor();
- this.container.find('[data-notify-style]').each(function() {
- var s;
- s = $(this).attr('data-notify-style');
- return $(this).attr('style', s.replace(/\{\{\s*color\s*\}\}/ig, color));
- });
- if (this.arrow) {
- this.arrow.remove();
- }
- this.buildArrow();
- this.container.prepend(this.arrow);
+ this.updatePosition();
this.show(true);
if (this.options.autoHide) {
clearTimeout(this.autohideTimer);
@@ -266,13 +304,11 @@ $(function() {
var src;
src = $(this).attr('href');
if (src.match(/bootstrap[^\/]*\.css/)) {
- $[pluginName].options({
- style: 'bootstrap'
- });
+ bootstrapDetected = true;
return false;
}
});
- $("head").append(create("style").html(styles.core.css));
+ insertCSS(styles.core);
return $(document).on('click', "." + className + "Wrapper", function() {
var inst;
inst = $(this).data(pluginName);
diff --git a/dist/notify.min.js b/dist/notify.min.js
index b260ea1..bb59c8d 100644
--- a/dist/notify.min.js
+++ b/dist/notify.min.js
@@ -1,4 +1,4 @@
-/** Notify.js - v0.0.1 - 2013/04/04
+/** Notify.js - v0.0.1 - 2013/04/05
* http://notifyjs.com/
* Copyright (c) 2013 Jaime Pillora - MIT
- */(function(t,n){"use strict";var i,e,o,r,s,a,h,p,d,l;p="notify",r="__"+p,o={top:"bottom",bottom:"top",left:"right",right:"left"},l={core:{html:'',css:"."+r+"Corner {\n position: fixed;\n top: 0;\n right: 0;\n margin: 5px;\n z-index: 1050;\n}\n\n."+r+"Corner ."+r+"Wrapper,\n."+r+"Corner ."+r+"Container {\n position: relative;\n display: block;\n height: inherit;\n width: inherit;\n\n}\n\n."+r+"Wrapper {\n z-index: 1;\n position: absolute;\n display: inline-block;\n height: 0;\n width: 0;\n opacity: 0.85;\n}\n\n."+r+"Container {\n display: none;\n z-index: 1;\n position: absolute;\n cursor: pointer;\n}\n\n."+r+"Text {\n position: relative;\n}"},user:{"default":{html:'\n \n
',css:"."+r+"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:'\n Warning! \n
',css:"."+r+"Bootstrap {\n white-space: nowrap;\n}",colors:{red:"#eed3d7"}}}},d={autoHide:!1,autoHideDelay:2e3,arrowShow:!0,arrowSize:5,arrowPosition:"top",style:"default",color:"red",colors:{red:"#b94a48",green:"#33be40",black:"#393939",blue:"#00f"},showAnimation:"slideDown",showDuration:200,hideAnimation:"slideUp",hideDuration:600,gap:2},a=function(t){return $(n.createElement(t))},e=function(t){return $.extend(this,t)},e.prototype=d,s=a("div").addClass(""+r+"Corner"),h=function(t){var n,i;return t.is("[type=radio]")&&(i=t.parents("form:first").find("[type=radio]").filter(function(n,i){return $(i).attr("name")===t.attr("name")}),t=i.first()),n=t.prev(),n.is("span.styled,span.OBS_checkbox")&&(t=n),t},i=function(){function t(t,n,i){"string"===$.type(i)&&(i={color:i}),this.options=new e($.isPlainObject(i)?i:{}),this.loadCSS(),this.loadHTML(),this.wrapper=$(l.core.html),this.wrapper.data(p,this),this.container=this.wrapper.find("."+r+"Container"),this.container.append(this.userContainer),t&&t.length?(this.elementType=t.attr("type"),this.originalElement=t,this.elem=h(t),this.elem.data(p,this),this.elem.before(this.wrapper),this.container.css(this.calculateCSS())):(this.options.arrowShow=!1,s.prepend(this.wrapper)),this.container.hide(),this.run(n)}return t.prototype.loadCSS=function(t){var n,i;return i=this.options.style,t=this.getStyle(i),n=t.cssElem,n?n.html(t.css):(n=a("style").attr("id",""+i+"-styles").html(t.css),$("head").append(n),t.cssElem=n)},t.prototype.loadHTML=function(t){if(t=this.getStyle(name),this.userContainer=$(t.html),this.text=this.userContainer.find("[data-notify=text]"),0===this.text.length)throw"style: "+name+" HTML is missing the: data-notify='text' attribute";return this.text.addClass(""+r+"Text")},t.prototype.buildArrow=function(){var t,i,e,s,h;e=this.options.arrowPosition,h=this.options.arrowSize,t=o[e],this.arrow=a("div"),this.arrow.addClass(r+"Arrow").css({"margin-top":2+(5===n.documentMode?-4*h:0),position:"relative","z-index":"2","margin-left":10,width:0,height:0}).css("border-"+t,h+"px solid "+this.getColor());for(i in o)i!==e&&i!==t&&this.arrow.css("border-"+i,h+"px solid transparent");return s=this.options.arrowShow&&"radio"!==this.elementType,s?this.arrow.show():this.arrow.hide()},t.prototype.show=function(t){var n;return n=this.container.parent().parents(":hidden").length>0,n&&t&&this.container.show(),n&&!t&&this.container.hide(),!n&&t&&this.container[this.options.showAnimation](this.options.showDuration),n||t?undefined:this.container[this.options.hideAnimation](this.options.hideDuration)},t.prototype.calculateCSS=function(){var t,n,i,e;return t=this.elem.position(),e=this.container.parent().position(),n=this.elem.outerHeight(),i=t.left-e.left,navigator.userAgent.match(/MSIE/)||(n+=t.top-e.top),{top:n+this.options.gap,left:i}},t.prototype.getColor=function(){var t;return t=this.getStyle().colors,t&&t[this.options.color]||this.options.colors[this.options.color]||this.options.color},t.prototype.getStyle=function(t){var n;if(t||(t=this.options.style),n=l.user[t],!n)throw"Missing style: "+t;return n},t.prototype.run=function(t,n){var i,e,o=this;return $.isPlainObject(n)?$.extend(this.options,n):"string"===$.type(n)&&(this.options.color=n),this.container&&!t?(this.show(!1),undefined):this.container||t?("string"===$.type(t)?this.text.html(t.replace("\n","
")):this.text.empty().append(t),e=this.getColor(),this.container.find("[data-notify-style]").each(function(){var t;return t=$(this).attr("data-notify-style"),$(this).attr("style",t.replace(/\{\{\s*color\s*\}\}/gi,e))}),this.arrow&&this.arrow.remove(),this.buildArrow(),this.container.prepend(this.arrow),this.show(!0),this.options.autoHide?(clearTimeout(this.autohideTimer),i=setTimeout(function(){return o.show(!1)},this.options.autoHideDelay)):undefined):undefined},t}(),$(function(){return $("body").append(s),$("link").each(function(){var t;return t=$(this).attr("href"),t.match(/bootstrap[^\/]*\.css/)?($[p].options({style:"bootstrap"}),!1):undefined}),$("head").append(a("style").html(l.core.css)),$(n).on("click","."+r+"Wrapper",function(){var t;return t=$(this).data(p),t?t.show(!1):undefined})}),$[p]=function(t,n,e){return t instanceof HTMLElement||t.jquery?$(t)[p](n,e):(e=n,n=t,new i(null,n,e))},$[p].options=function(t){return $.extend(d,t)},$[p].addStyle=function(t){return $.extend(!0,l.user,t)},$.fn[p]=function(t,n){return $(this).each(function(){var e;return e=h($(this)).data(p),e?e.run(t,n):new i($(this),t,n)})}})(window,document);
\ No newline at end of file
+ */(function(t,n){"use strict";var i,o,e,r,s,a,p,h,d,l,u,c;l="notify",r="__"+l,o={top:"bottom",bottom:"top",left:"right",right:"left"},c={core:{html:'',css:"."+r+"Corner {\n position: fixed;\n top: 0;\n right: 0;\n margin: 5px;\n z-index: 1050;\n}\n\n."+r+"Corner ."+r+"Wrapper,\n."+r+"Corner ."+r+"Container {\n position: relative;\n display: block;\n height: inherit;\n width: inherit;\n}\n\n."+r+"Wrapper {\n z-index: 1;\n position: absolute;\n display: inline-block;\n height: 0;\n width: 0;\n opacity: 0.85;\n}\n\n."+r+"Container {\n display: none;\n z-index: 1;\n position: absolute;\n cursor: pointer;\n}\n\n."+r+"Text {\n position: relative;\n}\n\n."+r+"Arrow {\n margin-top: "+(2+(5===n.documentMode?-4*size:0))+";\n position: absolute;\n z-index: 2;\n margin-left: 10px;\n width: 0;\n height: 0;\n}\n"},user:{"default":{html:'\n \n
',css:"."+r+"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:'\n \n
',css:"."+r+"Bootstrap {\n white-space: nowrap;\n margin-bottom: 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"}}}},e=!1,u={autoHide:!1,autoHideDelay:2e3,arrowShow:!0,arrowSize:5,position:null,style:null,color:"red",colors:{red:"#b94a48",green:"#33be40",black:"#393939",blue:"#00f"},showAnimation:"slideDown",showDuration:400,hideAnimation:"slideUp",hideDuration:200,offsetY:2,offsetX:0},a=function(t){return $(n.createElement(t))},h=function(t,n){var i;return i=function(){},i.prototype=t,$.extend(!0,new i,n)},s=a("div").addClass(""+r+"Corner"),p=function(t){var n,i;return t.is("[type=radio]")&&(i=t.parents("form:first").find("[type=radio]").filter(function(n,i){return $(i).attr("name")===t.attr("name")}),t=i.first()),n=t.prev(),n.is("span.styled,span.OBS_checkbox")&&(t=n),t},d=function(t){var n;if(t&&t.css)return n=t.cssElem,n?n.html(t.css):(n=a("style").attr("type","text/css").html(t.css),$("head").append(n),t.cssElem=n)},i=function(){function n(t,n,i){"string"==typeof i&&(i={color:i}),this.options=h(u,$.isPlainObject(i)?i:{}),this.loadCSS(),this.loadHTML(),this.wrapper=$(c.core.html),this.wrapper.data(l,this),this.arrow=this.wrapper.find("."+r+"Arrow"),this.container=this.wrapper.find("."+r+"Container"),this.container.append(this.userContainer),t&&t.length?(this.elementType=t.attr("type"),this.originalElement=t,this.elem=p(t),this.elem.data(l,this),this.elem.before(this.wrapper)):(this.options.arrowShow=!1,s.prepend(this.wrapper)),this.container.hide(),this.run(n)}return n.prototype.loadCSS=function(t){var n;return t||(n=this.options.style,t=this.getStyle(n)),d(t)},n.prototype.loadHTML=function(t){if(t=this.getStyle(name),this.userContainer=$(t.html),this.text=this.userContainer.find("[data-notify=text]"),0===this.text.length)throw"style: "+name+" HTML is missing the: data-notify='text' attribute";return this.text.addClass(""+r+"Text")},n.prototype.show=function(t){var n;return n=this.container.parent().parents(":hidden").length>0,n&&t&&this.container.show(),n&&!t&&this.container.hide(),!n&&t&&this.container[this.options.showAnimation](this.options.showDuration),n||t?undefined:this.container[this.options.hideAnimation](this.options.hideDuration)},n.prototype.updatePosition=function(){var t,n,i,o,e,r;if(this.elem){switch(n=this.elem.position(),e=this.wrapper.position(),r=this.getPosition(),t=this.updateArrow(r),o=0,i=0,r){case"bottom":i=this.elem.outerHeight();break;case"right":o=this.elem.width();break;default:throw"Unknown position: "+r}return o+=n.left-e.left,navigator.userAgent.match(/MSIE/)||(i+=n.top-e.top),this.container.css({top:i+this.options.offsetY+t.top,left:o+this.options.offsetX+t.left})}},n.prototype.updateArrow=function(t){var n,i,e,r;if(e={top:0,left:0},!this.options.arrowShow||"radio"===this.elementType)return this.arrow.hide(),e;i=o[t],r=this.options.arrowSize,this.arrow.css("border-"+t,r+"px solid "+this.getColor());for(n in o)n!==i&&n!==t&&this.arrow.css("border-"+n,r+"px solid transparent");return this.arrow.show(),e},n.prototype.getPosition=function(){return this.options.position?this.options.position:this.elem.position().left+this.elem.width()+this.wrapper.width()<$(t).width()?"right":"bottom"},n.prototype.getColor=function(){var t;return t=this.getStyle().colors,t&&t[this.options.color]||this.options.colors[this.options.color]||this.options.color},n.prototype.getStyle=function(t){var n;if(t||(t=this.options.style),e&&!t&&(t="bootstrap"),t||(t="default"),n=c.user[t],!n)throw"Missing style: "+t;return n},n.prototype.updateStyle=function(){var t=this;return this.wrapper.find("[data-notify-style]").each(function(n,i){return $(i).attr("style",$(i).attr("data-notify-style").replace(/\{\{\s*color\s*\}\}/gi,t.getColor()).replace(/\{\{\s*position\s*\}\}/gi,t.getPosition()))})},n.prototype.run=function(t,n){var i,o=this;return $.isPlainObject(n)?$.extend(this.options,n):"string"===$.type(n)&&(this.options.color=n),this.container&&!t?(this.show(!1),undefined):this.container||t?("string"===$.type(t)?this.text.html(t.replace("\n","
")):this.text.empty().append(t),this.updatePosition(),this.show(!0),this.options.autoHide?(clearTimeout(this.autohideTimer),i=setTimeout(function(){return o.show(!1)},this.options.autoHideDelay)):undefined):undefined},n}(),$(function(){return $("body").append(s),$("link").each(function(){var t;return t=$(this).attr("href"),t.match(/bootstrap[^\/]*\.css/)?(e=!0,!1):undefined}),d(c.core),$(n).on("click","."+r+"Wrapper",function(){var t;return t=$(this).data(l),t?t.show(!1):undefined})}),$[l]=function(t,n,o){return t instanceof HTMLElement||t.jquery?$(t)[l](n,o):(o=n,n=t,new i(null,n,o))},$[l].options=function(t){return $.extend(u,t)},$[l].addStyle=function(t){return $.extend(!0,c.user,t)},$.fn[l]=function(t,n){return $(this).each(function(){var o;return o=p($(this)).data(l),o?o.run(t,n):new i($(this),t,n)})}})(window,document);
\ No newline at end of file
diff --git a/src/notify.coffee b/src/notify.coffee
index fc713e0..fba37d8 100644
--- a/src/notify.coffee
+++ b/src/notify.coffee
@@ -15,8 +15,8 @@ styles =
core:
html: """
"""
css: """
@@ -34,7 +34,6 @@ styles =
display: block;
height: inherit;
width: inherit;
-
}
.#{className}Wrapper {
@@ -56,6 +55,16 @@ styles =
.#{className}Text {
position: relative;
}
+
+ .#{className}Arrow {
+ margin-top: #{2 + (if document.documentMode is 5 then (size*-4) else 0)};
+ position: absolute;
+ z-index: 2;
+ margin-left: 10px;
+ width: 0;
+ height: 0;
+ }
+
"""
user:
default:
@@ -88,26 +97,33 @@ styles =
bootstrap:
html: """
- Warning!
+
"""
css: """
.#{className}Bootstrap {
white-space: nowrap;
+ margin-bottom: 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'
+
+bootstrapDetected = false
#overridable options
pluginOptions =
autoHide: false
autoHideDelay: 2000
arrowShow: true
arrowSize: 5
- arrowPosition: 'top'
+ position: null
# Default style
- style: 'default'
+ style: null
# Default color
color: 'red'
# Color mappings
@@ -117,11 +133,12 @@ pluginOptions =
black: '#393939'
blue: '#00f'
showAnimation: 'slideDown'
- showDuration: 200
+ showDuration: 400
hideAnimation: 'slideUp'
- hideDuration: 600
+ hideDuration: 200
# Gap between main and element
- gap: 2
+ offsetY: 2
+ offsetX: 0
#TODO add z-index watches
#parents: { '.ui-dialog': 5001 }
@@ -129,9 +146,10 @@ pluginOptions =
create = (tag) ->
$ document.createElement(tag)
-# inherit plugin options
-Options = (options) -> $.extend @, options
-Options:: = pluginOptions
+inherit = (a, b) ->
+ F = () ->
+ F.prototype = a
+ $.extend true, new F(), b
# container for element-less notifications
cornerElem = create("div").addClass("#{className}Corner")
@@ -148,13 +166,23 @@ getAnchorElement = (element) ->
element = fBefore if fBefore.is('span.styled,span.OBS_checkbox')
element
+insertCSS = (style) ->
+ return unless style and style.css
+ elem = style.cssElem
+ if elem
+ elem.html style.css
+ else
+ elem = create("style").attr('type','text/css').html style.css
+ $("head").append elem
+ style.cssElem = elem
+
#define plugin
class Notification
#setup instance variables
constructor: (elem, data, options) ->
- options = {color: options} if $.type(options) is 'string'
- @options = new Options if $.isPlainObject(options) then options else {}
+ options = {color: options} if typeof options is 'string'
+ @options = inherit pluginOptions, if $.isPlainObject(options) then options else {}
#load user css into dom
@loadCSS()
@@ -163,6 +191,7 @@ class Notification
@wrapper = $(styles.core.html)
@wrapper.data pluginName, @
+ @arrow = @wrapper.find ".#{className}Arrow"
@container = @wrapper.find ".#{className}Container"
@container.append @userContainer
@@ -173,7 +202,6 @@ class Notification
@elem.data pluginName, @
# add into dom above elem
@elem.before @wrapper
- @container.css @calculateCSS()
else
# @options.autoHide = true
@options.arrowShow = false
@@ -183,15 +211,11 @@ class Notification
@run(data)
loadCSS: (style) ->
- name = @options.style
- style = @getStyle(name)
- elem = style.cssElem
- if elem
- elem.html style.css
- else
- elem = create("style").attr('id', "#{name}-styles").html style.css
- $("head").append elem
- style.cssElem = elem
+ unless style
+ name = @options.style
+ style = @getStyle(name)
+ #insert
+ insertCSS style
loadHTML: (style) ->
style = @getStyle(name)
@@ -201,27 +225,6 @@ class Notification
throw "style: #{name} HTML is missing the: data-notify='text' attribute"
@text.addClass "#{className}Text"
- buildArrow: ->
- dir = @options.arrowPosition
- size = @options.arrowSize
- alt = arrowDirs[dir]
- @arrow = create("div")
- @arrow.addClass(className + 'Arrow').css(
- 'margin-top': 2 + (if document.documentMode is 5 then (size*-4) else 0)
- 'position': 'relative'
- 'z-index': '2'
- 'margin-left': 10
- 'width': 0
- 'height': 0
- ).css(
- 'border-' + alt, size + 'px solid ' + @getColor()
- )
- for d of arrowDirs
- @arrow.css 'border-' + d, size + 'px solid transparent' if d isnt dir and d isnt alt
-
- showArrow = @options.arrowShow and @elementType isnt 'radio'
- if showArrow then @arrow.show() else @arrow.hide()
-
show: (show) ->
hidden = @container.parent().parents(':hidden').length > 0
@container.show() if hidden and show
@@ -229,16 +232,61 @@ class Notification
@container[@options.showAnimation] @options.showDuration if not hidden and show
@container[@options.hideAnimation] @options.hideDuration if not hidden and not show
- calculateCSS: () ->
+ updatePosition: ->
+ return unless @elem
+ #
elementPosition = @elem.position()
- mainPosition = @container.parent().position()
- height = @elem.outerHeight()
- left = elementPosition.left - mainPosition.left
+ mainPosition = @wrapper.position()
+
+ #
+ position = @getPosition()
+ arrowPosition = @updateArrow(position)
+
+ #start calculations
+ left = 0
+ height = 0
+ switch position
+ when 'bottom'
+ height = @elem.outerHeight()
+ when 'right'
+ left = @elem.width()
+ else
+ throw "Unknown position: #{position}"
+
+ #elem vs wrapper corrections
+ left += elementPosition.left - mainPosition.left
height += (elementPosition.top - mainPosition.top) unless navigator.userAgent.match /MSIE/
- return {
- top: height + @options.gap
- left: left
- }
+
+ #set with user offset, with arrow offet
+ @container.css
+ top: height + @options.offsetY + arrowPosition.top
+ left: left + @options.offsetX + arrowPosition.left
+
+ updateArrow: (position) ->
+
+ offsets = {top: 0, left: 0}
+
+ unless @options.arrowShow and @elementType isnt 'radio'
+ @arrow.hide()
+ return offsets
+
+ dir = arrowDirs[position]
+ size = @options.arrowSize
+
+ @arrow.css 'border-' + position, size + 'px solid ' + @getColor()
+ for d of arrowDirs
+ if d isnt dir and d isnt position
+ @arrow.css 'border-' + d, size + 'px solid transparent'
+
+ @arrow.show()
+ offsets
+
+
+ getPosition: ->
+ return @options.position if @options.position
+ if @elem.position().left + @elem.width() + @wrapper.width() < $(window).width()
+ return 'right'
+ return 'bottom'
getColor: ->
styleColors = @getStyle().colors
@@ -249,10 +297,19 @@ class Notification
getStyle: (name) ->
name = @options.style unless name
+ name = 'bootstrap' if bootstrapDetected and not name
+ name = 'default' unless name
style = styles.user[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())
+
#run plugin
run: (data, options) ->
#update options
@@ -274,14 +331,8 @@ class Notification
else
@text.empty().append(data)
- color = @getColor()
- @container.find('[data-notify-style]').each ->
- s = $(@).attr 'data-notify-style'
- $(@).attr 'style', s.replace /\{\{\s*color\s*\}\}/ig, color
- @arrow.remove() if @arrow
- @buildArrow()
- @container.prepend @arrow
+ @updatePosition()
@show true
@@ -300,10 +351,11 @@ $ ->
$("link").each ->
src = $(@).attr 'href'
if src.match /bootstrap[^\/]*\.css/
- $[pluginName].options {style:'bootstrap'}
+ bootstrapDetected = true
return false
#add core styles
- $("head").append(create("style").html(styles.core.css))
+ insertCSS styles.core
+
#watch all notifications clicks
$(document).on 'click', ".#{className}Wrapper", ->
inst = $(@).data pluginName